about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLuqman Aden <me@luqman.ca>2013-03-24 00:59:44 -0700
committerLuqman Aden <me@luqman.ca>2013-03-24 00:59:44 -0700
commit441313fc0ca635be18d1175e7dc265ab9ffa9d7d (patch)
treeb6762f9880d0bb7b9c4adbef955de8915224bf56 /src
parenta56ec8c1342453a88be79e192a11501844375d40 (diff)
downloadrust-441313fc0ca635be18d1175e7dc265ab9ffa9d7d.tar.gz
rust-441313fc0ca635be18d1175e7dc265ab9ffa9d7d.zip
librustc: emit loop for expr_repeat instead of 2n instructions in [x, ..n]
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/tvec.rs57
1 files changed, 41 insertions, 16 deletions
diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs
index 586b29c19c9..9910a62f1e0 100644
--- a/src/librustc/middle/trans/tvec.rs
+++ b/src/librustc/middle/trans/tvec.rs
@@ -27,6 +27,7 @@ use middle::ty;
 use util::common::indenter;
 use util::ppaux::ty_to_str;
 
+use core::option::None;
 use core::uint;
 use core::vec;
 use syntax::ast;
@@ -413,30 +414,54 @@ pub fn write_content(bcx: block,
                         return bcx;
                     }
 
-                    let tmpdatum = unpack_datum!(bcx, {
+                    let elem = unpack_datum!(bcx, {
                         expr::trans_to_datum(bcx, element)
                     });
 
-                    let mut temp_cleanups = ~[];
+                    let next_bcx = sub_block(bcx, ~"expr_repeat: while next");
+                    let loop_bcx = loop_scope_block(bcx, next_bcx, None, ~"expr_repeat", None);
+                    let cond_bcx = scope_block(loop_bcx, None, ~"expr_repeat: loop cond");
+                    let set_bcx = scope_block(loop_bcx, None, ~"expr_repeat: body: set");
+                    let inc_bcx = scope_block(loop_bcx, None, ~"expr_repeat: body: inc");
+                    Br(bcx, loop_bcx.llbb);
 
-                    for uint::range(0, count) |i| {
-                        let lleltptr = GEPi(bcx, lldest, [i]);
-                        if i < count - 1 {
-                            // Copy all but the last one in.
-                            bcx = tmpdatum.copy_to(bcx, INIT, lleltptr);
-                        } else {
-                            // Move the last one in.
-                            bcx = tmpdatum.move_to(bcx, INIT, lleltptr);
-                        }
-                        add_clean_temp_mem(bcx, lleltptr, vt.unit_ty);
-                        temp_cleanups.push(lleltptr);
+                    let loop_counter = {
+                        // i = 0
+                        let i = alloca(loop_bcx, T_i64());
+                        Store(loop_bcx, C_i64(0), i);
+
+                        Br(loop_bcx, cond_bcx.llbb);
+                        i
+                    };
+
+                    { // i < count
+                        let lhs = Load(cond_bcx, loop_counter);
+                        let rhs = C_integral(T_i64(), count as u64, lib::llvm::False);
+                        let cmp_lr = ICmp(cond_bcx, lib::llvm::IntULT, lhs, rhs);
+                        let zext = ZExt(cond_bcx, cmp_lr, T_i8());
+                        let cond_val = ICmp(cond_bcx, lib::llvm::IntNE, zext, C_u8(0));
+
+                        CondBr(cond_bcx, cond_val, set_bcx.llbb, next_bcx.llbb);
                     }
 
-                    for vec::each(temp_cleanups) |cleanup| {
-                        revoke_clean(bcx, *cleanup);
+                    { // v[i] = elem
+                        let i = Load(set_bcx, loop_counter);
+                        let lleltptr = InBoundsGEP(set_bcx, lldest, [i]);
+                        let set_bcx = elem.copy_to(set_bcx, INIT, lleltptr);
+
+                        Br(set_bcx, inc_bcx.llbb);
                     }
 
-                    return bcx;
+                    { // i += 1
+                        let i = Load(inc_bcx, loop_counter);
+                        let plusone = Add(inc_bcx, i, C_i64(1));
+                        Store(inc_bcx, plusone, loop_counter);
+
+                        Br(inc_bcx, cond_bcx.llbb);
+                    }
+
+                    return next_bcx;
+
                 }
             }
         }