Skip to content

Commit 544f615

Browse files
committed
auto merge of #7259 : dotdash/rust/ir_improvement, r=graydon
The changes in these commits improve the IR codegen by removing unnecessary copies for certain function call arguments and stopping to allocate return values for functions returning nil. They reduce compile times by about 10% in total.
2 parents 45f588e + 4fb2c09 commit 544f615

File tree

8 files changed

+76
-49
lines changed

8 files changed

+76
-49
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,7 +1653,9 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16531653
fcx.llenv = unsafe {
16541654
llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
16551655
};
1656-
fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
1656+
if !ty::type_is_nil(substd_output_type) {
1657+
fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
1658+
}
16571659
fcx
16581660
}
16591661

@@ -1808,7 +1810,7 @@ pub fn build_return_block(fcx: fn_ctxt) {
18081810
let ret_cx = raw_block(fcx, false, fcx.llreturn);
18091811

18101812
// Return the value if this function immediate; otherwise, return void.
1811-
if fcx.has_immediate_return_value {
1813+
if fcx.llretptr.is_some() && fcx.has_immediate_return_value {
18121814
Ret(ret_cx, Load(ret_cx, fcx.llretptr.get()))
18131815
} else {
18141816
RetVoid(ret_cx)
@@ -2340,8 +2342,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23402342
llvm::LLVMGetParam(llfdecl, env_arg as c_uint)
23412343
};
23422344
let args = ~[llenvarg];
2343-
let llresult = Call(bcx, main_llfn, args);
2344-
Store(bcx, llresult, fcx.llretptr.get());
2345+
Call(bcx, main_llfn, args);
23452346
23462347
build_return(bcx);
23472348
finish_fn(fcx, lltop);

src/librustc/middle/trans/cabi.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,18 @@ impl FnType {
179179
}
180180
}
181181

182-
let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]);
183-
let llretval = if self.ret_ty.cast {
184-
let retptr = BitCast(bcx, llretval, T_ptr(self.ret_ty.ty));
185-
Load(bcx, retptr)
186-
} else {
187-
Load(bcx, llretval)
188-
};
189-
let llretptr = BitCast(bcx,
190-
bcx.fcx.llretptr.get(),
191-
T_ptr(self.ret_ty.ty));
192-
Store(bcx, llretval, llretptr);
182+
if bcx.fcx.llretptr.is_some() {
183+
let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]);
184+
let llretval = if self.ret_ty.cast {
185+
let retptr = BitCast(bcx, llretval, T_ptr(self.ret_ty.ty));
186+
Load(bcx, retptr)
187+
} else {
188+
Load(bcx, llretval)
189+
};
190+
let llretptr = BitCast(bcx,
191+
bcx.fcx.llretptr.get(),
192+
T_ptr(self.ret_ty.ty));
193+
Store(bcx, llretval, llretptr);
194+
}
193195
}
194196
}

src/librustc/middle/trans/cabi_x86.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ impl ABIInfo for X86_ABIInfo {
6060
cast: false,
6161
ty: T_void(),
6262
};
63+
} else if !ret_def {
64+
ret_ty = LLVMType {
65+
cast: false,
66+
ty: T_void()
67+
};
6368
}
6469

6570
return FnType {

src/librustc/middle/trans/callee.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -801,24 +801,33 @@ pub fn trans_arg_expr(bcx: block,
801801
val = arg_datum.to_ref_llval(bcx);
802802
}
803803
ty::ByCopy => {
804-
debug!("by copy arg with type %s, storing to scratch",
805-
bcx.ty_to_str(arg_datum.ty));
806-
let scratch = scratch_datum(bcx, arg_datum.ty, false);
807-
808-
arg_datum.store_to_datum(bcx,
809-
arg_expr.id,
810-
INIT,
811-
scratch);
812-
813-
// Technically, ownership of val passes to the callee.
814-
// However, we must cleanup should we fail before the
815-
// callee is actually invoked.
816-
scratch.add_clean(bcx);
817-
temp_cleanups.push(scratch.val);
818-
819-
match arg_datum.appropriate_mode() {
820-
ByValue => val = Load(bcx, scratch.val),
821-
ByRef(_) => val = scratch.val,
804+
if ty::type_needs_drop(bcx.tcx(), arg_datum.ty) ||
805+
arg_datum.appropriate_mode().is_by_ref() {
806+
debug!("by copy arg with type %s, storing to scratch",
807+
bcx.ty_to_str(arg_datum.ty));
808+
let scratch = scratch_datum(bcx, arg_datum.ty, false);
809+
810+
arg_datum.store_to_datum(bcx,
811+
arg_expr.id,
812+
INIT,
813+
scratch);
814+
815+
// Technically, ownership of val passes to the callee.
816+
// However, we must cleanup should we fail before the
817+
// callee is actually invoked.
818+
scratch.add_clean(bcx);
819+
temp_cleanups.push(scratch.val);
820+
821+
match scratch.appropriate_mode() {
822+
ByValue => val = Load(bcx, scratch.val),
823+
ByRef(_) => val = scratch.val,
824+
}
825+
} else {
826+
debug!("by copy arg with type %s");
827+
match arg_datum.mode {
828+
ByRef(_) => val = Load(bcx, arg_datum.val),
829+
ByValue => val = arg_datum.val,
830+
}
822831
}
823832
}
824833
}

src/librustc/middle/trans/closure.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,10 @@ pub fn build_closure(bcx0: block,
297297
// the right thing):
298298
let ret_true = match bcx.fcx.loop_ret {
299299
Some((_, retptr)) => retptr,
300-
None => bcx.fcx.llretptr.get()
300+
None => match bcx.fcx.llretptr {
301+
None => C_null(T_ptr(T_nil())),
302+
Some(retptr) => retptr,
303+
}
301304
};
302305
let ret_casted = PointerCast(bcx, ret_true, T_ptr(T_nil()));
303306
let ret_datum = Datum {val: ret_casted, ty: ty::mk_nil(),

src/librustc/middle/trans/controlflow.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,24 +298,27 @@ pub fn trans_cont(bcx: block, label_opt: Option<ident>) -> block {
298298
pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block {
299299
let _icx = bcx.insn_ctxt("trans_ret");
300300
let mut bcx = bcx;
301-
let retptr = match copy bcx.fcx.loop_ret {
301+
let dest = match copy bcx.fcx.loop_ret {
302302
Some((flagptr, retptr)) => {
303303
// This is a loop body return. Must set continue flag (our retptr)
304304
// to false, return flag to true, and then store the value in the
305305
// parent's retptr.
306306
Store(bcx, C_bool(true), flagptr);
307307
Store(bcx, C_bool(false), bcx.fcx.llretptr.get());
308-
match e {
308+
expr::SaveIn(match e {
309309
Some(x) => PointerCast(bcx, retptr,
310310
T_ptr(type_of(bcx.ccx(), expr_ty(bcx, x)))),
311311
None => retptr
312-
}
312+
})
313+
}
314+
None => match bcx.fcx.llretptr {
315+
None => expr::Ignore,
316+
Some(retptr) => expr::SaveIn(retptr),
313317
}
314-
None => bcx.fcx.llretptr.get()
315318
};
316319
match e {
317320
Some(x) => {
318-
bcx = expr::trans_into(bcx, x, expr::SaveIn(retptr));
321+
bcx = expr::trans_into(bcx, x, dest);
319322
}
320323
_ => ()
321324
}

src/librustc/middle/trans/foreign.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes {
127127
llsig: llsig,
128128
ret_def: ret_def,
129129
bundle_ty: bundle_ty,
130-
shim_fn_ty: T_fn([T_ptr(bundle_ty)], T_nil()),
130+
shim_fn_ty: T_fn([T_ptr(bundle_ty)], T_void()),
131131
fn_ty: fn_ty
132132
}
133133
}
@@ -170,7 +170,7 @@ fn build_shim_fn_(ccx: @mut CrateContext,
170170
tie_up_header_blocks(fcx, lltop);
171171

172172
let ret_cx = raw_block(fcx, false, fcx.llreturn);
173-
Ret(ret_cx, C_null(T_nil()));
173+
RetVoid(ret_cx);
174174

175175
return llshimfn;
176176
}
@@ -530,17 +530,21 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext,
530530

531531
store_inbounds(bcx, llargval, llargbundle, [0u, i]);
532532
}
533-
let llretptr = bcx.fcx.llretptr.get();
534-
store_inbounds(bcx, llretptr, llargbundle, [0u, n]);
533+
534+
for bcx.fcx.llretptr.iter().advance |&retptr| {
535+
store_inbounds(bcx, retptr, llargbundle, [0u, n]);
536+
}
535537
}
536538

537539
fn build_ret(bcx: block,
538540
shim_types: &ShimTypes,
539541
llargbundle: ValueRef) {
540542
let _icx = bcx.insn_ctxt("foreign::wrap::build_ret");
541543
let arg_count = shim_types.fn_sig.inputs.len();
542-
let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]);
543-
Store(bcx, Load(bcx, llretptr), bcx.fcx.llretptr.get());
544+
for bcx.fcx.llretptr.iter().advance |&retptr| {
545+
let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]);
546+
Store(bcx, Load(bcx, llretptr), retptr);
547+
}
544548
build_return(bcx);
545549
}
546550
}
@@ -1294,7 +1298,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
12941298
shim_types: &ShimTypes,
12951299
llargbundle: ValueRef,
12961300
llretval: ValueRef) {
1297-
if ty::type_is_immediate(shim_types.fn_sig.output) {
1301+
if bcx.fcx.llretptr.is_some() && ty::type_is_immediate(shim_types.fn_sig.output) {
12981302
// Write the value into the argument bundle.
12991303
let arg_count = shim_types.fn_sig.inputs.len();
13001304
let llretptr = load_inbounds(bcx,

src/librustc/middle/trans/type_of.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t)
5555
atys.push_all(type_of_explicit_args(cx, inputs));
5656

5757
// Use the output as the actual return value if it's immediate.
58-
if output_is_immediate {
58+
if output_is_immediate && !ty::type_is_nil(output) {
5959
T_fn(atys, lloutputtype)
6060
} else {
6161
T_fn(atys, llvm::LLVMVoidTypeInContext(cx.llcx))
@@ -352,7 +352,7 @@ pub fn llvm_type_name(cx: &CrateContext,
352352
}
353353

354354
pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> TypeRef {
355-
T_fn([T_ptr(type_of(ccx, self_ty))] /* self */, T_nil())
355+
T_fn([T_ptr(type_of(ccx, self_ty))] /* self */, T_void())
356356
}
357357

358358
pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> TypeRef {
@@ -364,5 +364,5 @@ pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> TypeRef {
364364

365365
pub fn type_of_glue_fn(ccx: &CrateContext) -> TypeRef {
366366
let tydescpp = T_ptr(T_ptr(ccx.tydesc_type));
367-
return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_nil());
367+
return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void());
368368
}

0 commit comments

Comments
 (0)