librustc: emit loop for expr_repeat instead of 2n instructions in [x, ..n]
This commit is contained in:
parent
a56ec8c134
commit
441313fc0c
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user