diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index bbd676c87b4..1173fa49419 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1557,7 +1557,7 @@ pub fn alloca_maybe_zeroed(cx: block, ty: Type, name: &str, zero: bool) -> Value return llvm::LLVMGetUndef(ty.to_ref()); } } - let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas); + let initcx = base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas()); let p = Alloca(initcx, ty, name); if zero { memzero(initcx, p, ty); } p @@ -1570,21 +1570,18 @@ pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef { return llvm::LLVMGetUndef(ty.to_ref()); } } - return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty, v); + return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.get_llstaticallocas()), ty, v); } pub struct BasicBlocks { sa: BasicBlockRef, } -// Creates the standard set of basic blocks for a function -pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks { +pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef { unsafe { let cx = task_llcx(); - BasicBlocks { - sa: str::as_c_str("static_allocas", - |buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)), - } + str::as_c_str("static_allocas", + |buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)) } } @@ -1604,7 +1601,7 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef { llvm::LLVMGetParam(fcx.llfn, 0) } else { let lloutputtype = type_of::type_of(fcx.ccx, output_type); - alloca(raw_block(fcx, false, fcx.llstaticallocas), lloutputtype, + alloca(raw_block(fcx, false, fcx.get_llstaticallocas()), lloutputtype, "__make_return_pointer") } } @@ -1632,8 +1629,6 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, id, param_substs.repr(ccx.tcx)); - let llbbs = mk_standard_basic_blocks(llfndecl); - let substd_output_type = match param_substs { None => output_type, Some(substs) => { @@ -1647,7 +1642,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, llvm::LLVMGetUndef(Type::i8p().to_ref()) }, llretptr: None, - llstaticallocas: llbbs.sa, + llstaticallocas: None, llloadenv: None, llreturn: None, llself: None, @@ -1821,14 +1816,24 @@ pub fn build_return_block(fcx: fn_ctxt, ret_cx: block) { pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) { let _icx = push_ctxt("tie_up_header_blocks"); - match fcx.llloadenv { + let llnext = match fcx.llloadenv { Some(ll) => { - Br(raw_block(fcx, false, fcx.llstaticallocas), ll); + unsafe { + llvm::LLVMMoveBasicBlockBefore(ll, lltop); + } Br(raw_block(fcx, false, ll), lltop); + ll } - None => { - Br(raw_block(fcx, false, fcx.llstaticallocas), lltop); + None => lltop + }; + match fcx.llstaticallocas { + Some(ll) => { + unsafe { + llvm::LLVMMoveBasicBlockBefore(ll, llnext); + } + Br(raw_block(fcx, false, ll), llnext); } + None => () } } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 2e016377e75..83029a90260 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -178,7 +178,7 @@ pub struct fn_ctxt_ { // the function, due to LLVM's quirks. // A block for all the function's static allocas, so that LLVM // will coalesce them into a single alloca call. - llstaticallocas: BasicBlockRef, + llstaticallocas: Option, // A block containing code that copies incoming arguments to space // already allocated by code in one of the llallocas blocks. // (LLVM requires that arguments be copied to local allocas before @@ -251,6 +251,14 @@ impl fn_ctxt_ { } } + pub fn get_llstaticallocas(&mut self) -> BasicBlockRef { + if self.llstaticallocas.is_none() { + self.llstaticallocas = Some(base::mk_staticallocas_basic_block(self.llfn)); + } + + self.llstaticallocas.get() + } + pub fn get_llreturn(&mut self) -> BasicBlockRef { if self.llreturn.is_none() { self.llreturn = Some(base::mk_return_basic_block(self.llfn)); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 1ad5a543e66..edf003e3e52 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -197,7 +197,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, // the C ABI. if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) { let lloutputtype = type_of::type_of(fcx.ccx, tys.fn_sig.output); - fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.llstaticallocas), + fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.get_llstaticallocas()), lloutputtype, "")); }