]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/tvec.rs
rustc_trans: remove the bulk of old trans and most of its support code.
[rust.git] / src / librustc_trans / tvec.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(non_camel_case_types)]
12
13 use llvm;
14 use llvm::ValueRef;
15 use base::*;
16 use build::*;
17 use common::*;
18 use debuginfo::DebugLoc;
19 use rustc::ty::Ty;
20
21 pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
22                                    data_ptr: ValueRef,
23                                    unit_ty: Ty<'tcx>,
24                                    len: ValueRef,
25                                    f: F)
26                                    -> Block<'blk, 'tcx> where
27     F: FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
28 {
29     let _icx = push_ctxt("tvec::iter_vec_raw");
30     let fcx = bcx.fcx;
31
32     if type_is_zero_size(bcx.ccx(), unit_ty) {
33         // Special-case vectors with elements of size 0  so they don't go out of bounds (#9890)
34         if bcx.unreachable.get() {
35             return bcx;
36         }
37
38         let loop_bcx = fcx.new_block("expr_repeat");
39         let next_bcx = fcx.new_block("expr_repeat: next");
40
41         Br(bcx, loop_bcx.llbb, DebugLoc::None);
42
43         let loop_counter = Phi(loop_bcx, bcx.ccx().int_type(),
44                             &[C_uint(bcx.ccx(), 0 as usize)], &[bcx.llbb]);
45
46         let bcx = loop_bcx;
47         let bcx = f(bcx, data_ptr, unit_ty);
48         let plusone = Add(bcx, loop_counter, C_uint(bcx.ccx(), 1usize), DebugLoc::None);
49         AddIncomingToPhi(loop_counter, plusone, bcx.llbb);
50
51         let cond_val = ICmp(bcx, llvm::IntULT, plusone, len, DebugLoc::None);
52         CondBr(bcx, cond_val, loop_bcx.llbb, next_bcx.llbb, DebugLoc::None);
53
54         next_bcx
55     } else {
56         // Calculate the last pointer address we want to handle.
57         let data_end_ptr = InBoundsGEP(bcx, data_ptr, &[len]);
58
59         // Now perform the iteration.
60         let header_bcx = fcx.new_block("iter_vec_loop_header");
61         Br(bcx, header_bcx.llbb, DebugLoc::None);
62         let data_ptr =
63             Phi(header_bcx, val_ty(data_ptr), &[data_ptr], &[bcx.llbb]);
64         let not_yet_at_end =
65             ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr, DebugLoc::None);
66         let body_bcx = fcx.new_block("iter_vec_loop_body");
67         let next_bcx = fcx.new_block("iter_vec_next");
68         CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
69         let body_bcx = f(body_bcx, data_ptr, unit_ty);
70         AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr,
71                                                &[C_int(bcx.ccx(), 1)]),
72                          body_bcx.llbb);
73         Br(body_bcx, header_bcx.llbb, DebugLoc::None);
74         next_bcx
75     }
76 }