Skip to content

Commit 4fb2c09

Browse files
committed
Avoid pointless allocas for "nil" return values
By using "void" instead of "{}" as the LLVM type for nil, we can avoid the alloca/store/load sequence for the return value, resulting in less and simpler IR code. This reduces compile times by about 10%.
1 parent dc262d9 commit 4fb2c09

File tree

7 files changed

+49
-31
lines changed

7 files changed

+49
-31
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/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)