Skip to content

Commit 7a3eaf8

Browse files
committed
auto merge of #7941 : dotdash/rust/codegen, r=huonw
These changes remove unnecessary basic blocks and the associated branches from the LLVM IR that we emit. Together, they reduce the time for unoptimized builds in stage2 by about 10% on my box.
2 parents 7b2218d + 205baa6 commit 7a3eaf8

File tree

13 files changed

+1246
-688
lines changed

13 files changed

+1246
-688
lines changed

src/librustc/lib/llvm.rs

+2
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,8 @@ pub mod llvm {
984984
pub unsafe fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
985985
#[fast_ffi]
986986
pub unsafe fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
987+
#[fast_ffi]
988+
pub unsafe fn LLVMInstructionEraseFromParent(Inst: ValueRef);
987989

988990
/* Operations on call sites */
989991
#[fast_ffi]

src/librustc/middle/trans/base.rs

+40-50
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use middle::trans::_match;
4141
use middle::trans::adt;
4242
use middle::trans::base;
4343
use middle::trans::build::*;
44+
use middle::trans::builder::{Builder, noname};
4445
use middle::trans::callee;
4546
use middle::trans::common::*;
4647
use middle::trans::consts;
@@ -1499,34 +1500,35 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
14991500
}
15001501

15011502
pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) {
1503+
if cx.unreachable { return; }
15021504
let _icx = push_ctxt("zero_mem");
15031505
let bcx = cx;
15041506
let ccx = cx.ccx();
15051507
let llty = type_of::type_of(ccx, t);
1506-
memzero(bcx, llptr, llty);
1508+
memzero(&B(bcx), llptr, llty);
15071509
}
15081510

15091511
// Always use this function instead of storing a zero constant to the memory
15101512
// in question. If you store a zero constant, LLVM will drown in vreg
15111513
// allocation for large data structures, and the generated code will be
15121514
// awful. (A telltale sign of this is large quantities of
15131515
// `mov [byte ptr foo],0` in the generated code.)
1514-
pub fn memzero(cx: block, llptr: ValueRef, ty: Type) {
1516+
pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) {
15151517
let _icx = push_ctxt("memzero");
1516-
let ccx = cx.ccx();
1518+
let ccx = b.ccx;
15171519

15181520
let intrinsic_key = match ccx.sess.targ_cfg.arch {
15191521
X86 | Arm | Mips => "llvm.memset.p0i8.i32",
15201522
X86_64 => "llvm.memset.p0i8.i64"
15211523
};
15221524

15231525
let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key);
1524-
let llptr = PointerCast(cx, llptr, Type::i8().ptr_to());
1526+
let llptr = b.pointercast(llptr, Type::i8().ptr_to());
15251527
let llzeroval = C_u8(0);
1526-
let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type);
1528+
let size = machine::llsize_of(ccx, ty);
15271529
let align = C_i32(llalign_of_min(ccx, ty) as i32);
15281530
let volatile = C_i1(false);
1529-
Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
1531+
b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
15301532
}
15311533

15321534
pub fn alloc_ty(bcx: block, t: ty::t, name: &str) -> ValueRef {
@@ -1549,9 +1551,12 @@ pub fn alloca_maybe_zeroed(cx: block, ty: Type, name: &str, zero: bool) -> Value
15491551
return llvm::LLVMGetUndef(ty.ptr_to().to_ref());
15501552
}
15511553
}
1552-
let initcx = base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas());
1553-
let p = Alloca(initcx, ty, name);
1554-
if zero { memzero(initcx, p, ty); }
1554+
let p = Alloca(cx, ty, name);
1555+
if zero {
1556+
let b = cx.fcx.ccx.builder();
1557+
b.position_before(cx.fcx.alloca_insert_pt.get());
1558+
memzero(&b, p, ty);
1559+
}
15551560
p
15561561
}
15571562

@@ -1562,7 +1567,7 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef {
15621567
return llvm::LLVMGetUndef(ty.to_ref());
15631568
}
15641569
}
1565-
return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas()), ty, v);
1570+
return ArrayAlloca(cx, ty, v);
15661571
}
15671572

15681573
pub struct BasicBlocks {
@@ -1593,8 +1598,8 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
15931598
llvm::LLVMGetParam(fcx.llfn, 0)
15941599
} else {
15951600
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
1596-
alloca(raw_block(fcx, false, fcx.get_llstaticallocas()), lloutputtype,
1597-
"__make_return_pointer")
1601+
let bcx = fcx.entry_bcx.get();
1602+
Alloca(bcx, lloutputtype, "__make_return_pointer")
15981603
}
15991604
}
16001605
}
@@ -1612,6 +1617,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16121617
output_type: ty::t,
16131618
skip_retptr: bool,
16141619
param_substs: Option<@param_substs>,
1620+
opt_node_info: Option<NodeInfo>,
16151621
sp: Option<span>)
16161622
-> fn_ctxt {
16171623
for param_substs.iter().advance |p| { p.validate(); }
@@ -1635,8 +1641,8 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16351641
llvm::LLVMGetUndef(Type::i8p().to_ref())
16361642
},
16371643
llretptr: None,
1638-
llstaticallocas: None,
1639-
llloadenv: None,
1644+
entry_bcx: None,
1645+
alloca_insert_pt: None,
16401646
llreturn: None,
16411647
llself: None,
16421648
personality: None,
@@ -1654,6 +1660,15 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
16541660
fcx.llenv = unsafe {
16551661
llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
16561662
};
1663+
1664+
unsafe {
1665+
let entry_bcx = top_scope_block(fcx, opt_node_info);
1666+
Load(entry_bcx, C_null(Type::i8p()));
1667+
1668+
fcx.entry_bcx = Some(entry_bcx);
1669+
fcx.alloca_insert_pt = Some(llvm::LLVMGetFirstInstruction(entry_bcx.llbb));
1670+
}
1671+
16571672
if !ty::type_is_nil(substd_output_type) && !(is_immediate && skip_retptr) {
16581673
fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
16591674
}
@@ -1666,7 +1681,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
16661681
output_type: ty::t,
16671682
sp: Option<span>)
16681683
-> fn_ctxt {
1669-
new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, sp)
1684+
new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, None, sp)
16701685
}
16711686

16721687
// NB: must keep 4 fns in sync:
@@ -1781,9 +1796,8 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
17811796

17821797
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
17831798
// and builds the return block.
1784-
pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
1799+
pub fn finish_fn(fcx: fn_ctxt, last_bcx: block) {
17851800
let _icx = push_ctxt("finish_fn");
1786-
tie_up_header_blocks(fcx, lltop);
17871801

17881802
let ret_cx = match fcx.llreturn {
17891803
Some(llreturn) => {
@@ -1795,6 +1809,7 @@ pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef, last_bcx: block) {
17951809
None => last_bcx
17961810
};
17971811
build_return_block(fcx, ret_cx);
1812+
fcx.cleanup();
17981813
}
17991814

18001815
// Builds the return block for a function.
@@ -1807,29 +1822,6 @@ pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) {
18071822
}
18081823
}
18091824

1810-
pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) {
1811-
let _icx = push_ctxt("tie_up_header_blocks");
1812-
let llnext = match fcx.llloadenv {
1813-
Some(ll) => {
1814-
unsafe {
1815-
llvm::LLVMMoveBasicBlockBefore(ll, lltop);
1816-
}
1817-
Br(raw_block(fcx, false, ll), lltop);
1818-
ll
1819-
}
1820-
None => lltop
1821-
};
1822-
match fcx.llstaticallocas {
1823-
Some(ll) => {
1824-
unsafe {
1825-
llvm::LLVMMoveBasicBlockBefore(ll, llnext);
1826-
}
1827-
Br(raw_block(fcx, false, ll), llnext);
1828-
}
1829-
None => ()
1830-
}
1831-
}
1832-
18331825
pub enum self_arg { impl_self(ty::t, ty::SelfMode), no_self, }
18341826

18351827
// trans_closure: Builds an LLVM function out of a source function.
@@ -1862,6 +1854,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
18621854
output_type,
18631855
false,
18641856
param_substs,
1857+
body.info(),
18651858
Some(body.span));
18661859
let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs);
18671860

@@ -1873,9 +1866,8 @@ pub fn trans_closure(ccx: @mut CrateContext,
18731866

18741867
// Create the first basic block in the function and keep a handle on it to
18751868
// pass to finish_fn later.
1876-
let bcx_top = top_scope_block(fcx, body.info());
1869+
let bcx_top = fcx.entry_bcx.get();
18771870
let mut bcx = bcx_top;
1878-
let lltop = bcx.llbb;
18791871
let block_ty = node_id_type(bcx, body.id);
18801872

18811873
let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
@@ -1911,7 +1903,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
19111903
}
19121904

19131905
// Insert the mandatory first few basic blocks before lltop.
1914-
finish_fn(fcx, lltop, bcx);
1906+
finish_fn(fcx, bcx);
19151907
}
19161908

19171909
// trans_fn: creates an LLVM function corresponding to a source language
@@ -2081,12 +2073,12 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
20812073
result_ty,
20822074
false,
20832075
param_substs,
2076+
None,
20842077
None);
20852078

20862079
let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args);
20872080

2088-
let bcx = top_scope_block(fcx, None);
2089-
let lltop = bcx.llbb;
2081+
let bcx = fcx.entry_bcx.get();
20902082
let arg_tys = ty::ty_fn_args(ctor_ty);
20912083

20922084
insert_synthetic_type_entries(bcx, fn_args, arg_tys);
@@ -2104,7 +2096,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
21042096
let arg_ty = arg_tys[i];
21052097
memcpy_ty(bcx, lldestptr, llarg, arg_ty);
21062098
}
2107-
finish_fn(fcx, lltop, bcx);
2099+
finish_fn(fcx, bcx);
21082100
}
21092101

21102102
pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
@@ -2332,9 +2324,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23322324
// be updated if this assertion starts to fail.
23332325
assert!(fcx.has_immediate_return_value);
23342326

2335-
let bcx = top_scope_block(fcx, None);
2336-
let lltop = bcx.llbb;
2337-
2327+
let bcx = fcx.entry_bcx.get();
23382328
// Call main.
23392329
let llenvarg = unsafe {
23402330
let env_arg = fcx.env_arg_pos();
@@ -2343,7 +2333,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
23432333
let args = ~[llenvarg];
23442334
Call(bcx, main_llfn, args);
23452335

2346-
finish_fn(fcx, lltop, bcx);
2336+
finish_fn(fcx, bcx);
23472337
return llfdecl;
23482338
}
23492339

0 commit comments

Comments
 (0)