From 441313fc0ca635be18d1175e7dc265ab9ffa9d7d Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Sun, 24 Mar 2013 00:59:44 -0700 Subject: [PATCH 1/3] librustc: emit loop for expr_repeat instead of 2n instructions in [x, ..n] --- src/librustc/middle/trans/tvec.rs | 57 ++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 586b29c19c90c..9910a62f1e0e7 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; + } } } From 89a7407c999449c56f9b00145cfbdfbb49fbde7c Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 24 Mar 2013 21:44:47 +1100 Subject: [PATCH 2/3] librustc: clean-up expr_repeat loop generation: use native integers --- src/librustc/middle/trans/tvec.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 9910a62f1e0e7..a86a4aec6b49f 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -427,8 +427,8 @@ pub fn write_content(bcx: block, let loop_counter = { // i = 0 - let i = alloca(loop_bcx, T_i64()); - Store(loop_bcx, C_i64(0), i); + let i = alloca(loop_bcx, bcx.ccx().int_type); + Store(loop_bcx, C_uint(bcx.ccx(), 0), i); Br(loop_bcx, cond_bcx.llbb); i @@ -436,10 +436,8 @@ pub fn write_content(bcx: block, { // 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)); + let rhs = C_uint(bcx.ccx(), count); + let cond_val = ICmp(cond_bcx, lib::llvm::IntULT, lhs, rhs); CondBr(cond_bcx, cond_val, set_bcx.llbb, next_bcx.llbb); } @@ -454,7 +452,7 @@ pub fn write_content(bcx: block, { // i += 1 let i = Load(inc_bcx, loop_counter); - let plusone = Add(inc_bcx, i, C_i64(1)); + let plusone = Add(inc_bcx, i, C_uint(bcx.ccx(), 1)); Store(inc_bcx, plusone, loop_counter); Br(inc_bcx, cond_bcx.llbb); From e7f42f140b8d2271888f97ba62c5e0570032b6e5 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Mon, 25 Mar 2013 15:46:10 -0700 Subject: [PATCH 3/3] Expand on cleanups in trans for expr_repeat and add to tests. --- src/librustc/middle/trans/tvec.rs | 5 +++++ src/test/run-pass/repeated-vector-syntax.rs | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index a86a4aec6b49f..90f6bf8757865 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -414,6 +414,11 @@ pub fn write_content(bcx: block, return bcx; } + // Some cleanup would be required in the case in which failure happens + // during a copy. But given that copy constructors are not overridable, + // this can only happen as a result of OOM. So we just skip out on the + // cleanup since things would *probably* be broken at that point anyways. + let elem = unpack_datum!(bcx, { expr::trans_to_datum(bcx, element) }); diff --git a/src/test/run-pass/repeated-vector-syntax.rs b/src/test/run-pass/repeated-vector-syntax.rs index 49d0c49b3967e..a22384a6b53d0 100644 --- a/src/test/run-pass/repeated-vector-syntax.rs +++ b/src/test/run-pass/repeated-vector-syntax.rs @@ -9,8 +9,15 @@ // except according to those terms. pub fn main() { + struct Foo { a: ~str } + + let v = [ ~Foo { a: ~"Hello!" }, ..129 ]; + let w = [ ~"Hello!", ..129 ]; let x = [ @[true], ..512 ]; let y = [ 0, ..1 ]; + + error!("%?", v); + error!("%?", w); error!("%?", x); error!("%?", y); }