rustc_codegen_ssa: append blocks to functions w/o creating a builder.
This commit is contained in:
parent
402e9efc56
commit
0fcaf11455
@ -118,24 +118,16 @@ macro_rules! builder_methods_for_value_instructions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||||
fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
|
fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Self {
|
||||||
let mut bx = Builder::with_cx(cx);
|
let bx = Builder::with_cx(cx);
|
||||||
let llbb = unsafe {
|
unsafe {
|
||||||
let name = SmallCStr::new(name);
|
llvm::LLVMPositionBuilderAtEnd(bx.llbuilder, llbb);
|
||||||
llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name.as_ptr())
|
}
|
||||||
};
|
|
||||||
bx.position_at_end(llbb);
|
|
||||||
bx
|
bx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
|
fn cx(&self) -> &CodegenCx<'ll, 'tcx> {
|
||||||
// Create a fresh builder from the crate context.
|
self.cx
|
||||||
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
|
|
||||||
Builder { llbuilder, cx }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_sibling_block(&self, name: &str) -> Self {
|
|
||||||
Builder::new_block(self.cx, self.llfn(), name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn llbb(&self) -> &'ll BasicBlock {
|
fn llbb(&self) -> &'ll BasicBlock {
|
||||||
@ -144,12 +136,22 @@ fn llbb(&self) -> &'ll BasicBlock {
|
|||||||
|
|
||||||
fn set_span(&mut self, _span: Span) {}
|
fn set_span(&mut self, _span: Span) {}
|
||||||
|
|
||||||
fn position_at_end(&mut self, llbb: &'ll BasicBlock) {
|
fn append_block(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &str) -> &'ll BasicBlock {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
|
let name = SmallCStr::new(name);
|
||||||
|
llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name.as_ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn append_sibling_block(&mut self, name: &str) -> &'ll BasicBlock {
|
||||||
|
Self::append_block(self.cx, self.llfn(), name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_sibling_block(&mut self, name: &str) -> Self {
|
||||||
|
let llbb = self.append_sibling_block(name);
|
||||||
|
Self::build(self.cx, llbb)
|
||||||
|
}
|
||||||
|
|
||||||
fn ret_void(&mut self) {
|
fn ret_void(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildRetVoid(self.llbuilder);
|
llvm::LLVMBuildRetVoid(self.llbuilder);
|
||||||
@ -1144,10 +1146,6 @@ fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
|
|||||||
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
|
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cx(&self) -> &CodegenCx<'ll, 'tcx> {
|
|
||||||
self.cx
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_not_inline(&mut self, llret: &'ll Value) {
|
fn do_not_inline(&mut self, llret: &'ll Value) {
|
||||||
llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
|
llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
|
||||||
}
|
}
|
||||||
@ -1161,6 +1159,12 @@ fn get_static(&mut self, def_id: DefId) -> &'ll Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Builder<'a, 'll, 'tcx> {
|
impl Builder<'a, 'll, 'tcx> {
|
||||||
|
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
|
||||||
|
// Create a fresh builder from the crate context.
|
||||||
|
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
|
||||||
|
Builder { llbuilder, cx }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn llfn(&self) -> &'ll Value {
|
pub fn llfn(&self) -> &'ll Value {
|
||||||
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
|
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,8 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx
|
|||||||
|
|
||||||
fn codegen_unused_fn_and_counter(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) {
|
fn codegen_unused_fn_and_counter(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) {
|
||||||
let llfn = cx.get_fn(instance);
|
let llfn = cx.get_fn(instance);
|
||||||
let mut bx = Builder::new_block(cx, llfn, "unused_function");
|
let llbb = Builder::append_block(cx, llfn, "unused_function");
|
||||||
|
let mut bx = Builder::build(cx, llbb);
|
||||||
let fn_name = bx.get_pgo_func_name_var(instance);
|
let fn_name = bx.get_pgo_func_name_var(instance);
|
||||||
let hash = bx.const_u64(0);
|
let hash = bx.const_u64(0);
|
||||||
let num_counters = bx.const_u32(1);
|
let num_counters = bx.const_u32(1);
|
||||||
|
@ -678,7 +678,8 @@ fn gen_fn<'ll, 'tcx>(
|
|||||||
cx.apply_target_cpu_attr(llfn);
|
cx.apply_target_cpu_attr(llfn);
|
||||||
// FIXME(eddyb) find a nicer way to do this.
|
// FIXME(eddyb) find a nicer way to do this.
|
||||||
unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) };
|
unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) };
|
||||||
let bx = Builder::new_block(cx, llfn, "entry-block");
|
let llbb = Builder::append_block(cx, llfn, "entry-block");
|
||||||
|
let bx = Builder::build(cx, llbb);
|
||||||
codegen(bx);
|
codegen(bx);
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,8 @@ fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||||||
cx.set_frame_pointer_elimination(llfn);
|
cx.set_frame_pointer_elimination(llfn);
|
||||||
cx.apply_target_cpu_attr(llfn);
|
cx.apply_target_cpu_attr(llfn);
|
||||||
|
|
||||||
let mut bx = Bx::new_block(&cx, llfn, "top");
|
let llbb = Bx::append_block(&cx, llfn, "top");
|
||||||
|
let mut bx = Bx::build(&cx, llbb);
|
||||||
|
|
||||||
bx.insert_reference_to_gdb_debug_scripts_section_global();
|
bx.insert_reference_to_gdb_debug_scripts_section_global();
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ fn codegen_assert_terminator(
|
|||||||
|
|
||||||
// Create the failure block and the conditional branch to it.
|
// Create the failure block and the conditional branch to it.
|
||||||
let lltarget = helper.llblock(self, target);
|
let lltarget = helper.llblock(self, target);
|
||||||
let panic_block = self.new_block("panic");
|
let panic_block = bx.build_sibling_block("panic");
|
||||||
if expected {
|
if expected {
|
||||||
bx.cond_br(cond, lltarget, panic_block.llbb());
|
bx.cond_br(cond, lltarget, panic_block.llbb());
|
||||||
} else {
|
} else {
|
||||||
@ -1289,8 +1289,11 @@ fn unreachable_block(&mut self) -> Bx::BasicBlock {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_block(&self, name: &str) -> Bx {
|
// FIXME(eddyb) replace with `build_sibling_block`/`append_sibling_block`
|
||||||
Bx::new_block(self.cx, self.llfn, name)
|
// (which requires having a `Bx` already, and not all callers do).
|
||||||
|
fn new_block(&self, name: &str) -> Bx {
|
||||||
|
let llbb = Bx::append_block(self.cx, self.llfn, name);
|
||||||
|
Bx::build(self.cx, llbb)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the backend `BasicBlock` for a MIR `BasicBlock`, either already
|
/// Get the backend `BasicBlock` for a MIR `BasicBlock`, either already
|
||||||
@ -1300,17 +1303,15 @@ pub fn new_block(&self, name: &str) -> Bx {
|
|||||||
pub fn llbb(&mut self, bb: mir::BasicBlock) -> Bx::BasicBlock {
|
pub fn llbb(&mut self, bb: mir::BasicBlock) -> Bx::BasicBlock {
|
||||||
self.cached_llbbs[bb].unwrap_or_else(|| {
|
self.cached_llbbs[bb].unwrap_or_else(|| {
|
||||||
// FIXME(eddyb) only name the block if `fewer_names` is `false`.
|
// FIXME(eddyb) only name the block if `fewer_names` is `false`.
|
||||||
// FIXME(eddyb) create the block directly, without a builder.
|
let llbb = Bx::append_block(self.cx, self.llfn, &format!("{:?}", bb));
|
||||||
let llbb = self.new_block(&format!("{:?}", bb)).llbb();
|
|
||||||
self.cached_llbbs[bb] = Some(llbb);
|
self.cached_llbbs[bb] = Some(llbb);
|
||||||
llbb
|
llbb
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_block(&mut self, bb: mir::BasicBlock) -> Bx {
|
pub fn build_block(&mut self, bb: mir::BasicBlock) -> Bx {
|
||||||
let mut bx = Bx::with_cx(self.cx);
|
let llbb = self.llbb(bb);
|
||||||
bx.position_at_end(self.llbb(bb));
|
Bx::build(self.cx, llbb)
|
||||||
bx
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_return_dest(
|
fn make_return_dest(
|
||||||
|
@ -144,7 +144,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||||||
|
|
||||||
let debug_context = cx.create_function_debug_context(instance, &fn_abi, llfn, &mir);
|
let debug_context = cx.create_function_debug_context(instance, &fn_abi, llfn, &mir);
|
||||||
|
|
||||||
let mut bx = Bx::new_block(cx, llfn, "start");
|
let start_llbb = Bx::append_block(cx, llfn, "start");
|
||||||
|
let mut bx = Bx::build(cx, start_llbb);
|
||||||
|
|
||||||
if mir.basic_blocks().iter().any(|bb| bb.is_cleanup) {
|
if mir.basic_blocks().iter().any(|bb| bb.is_cleanup) {
|
||||||
bx.set_personality_fn(cx.eh_personality());
|
bx.set_personality_fn(cx.eh_personality());
|
||||||
@ -159,7 +160,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||||||
.indices()
|
.indices()
|
||||||
.map(|bb| {
|
.map(|bb| {
|
||||||
if bb == mir::START_BLOCK && !reentrant_start_block {
|
if bb == mir::START_BLOCK && !reentrant_start_block {
|
||||||
Some(bx.llbb())
|
Some(start_llbb)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -40,14 +40,21 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||||||
+ HasParamEnv<'tcx>
|
+ HasParamEnv<'tcx>
|
||||||
+ HasTargetSpec
|
+ HasTargetSpec
|
||||||
{
|
{
|
||||||
fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &'b str) -> Self;
|
fn build(cx: &'a Self::CodegenCx, llbb: Self::BasicBlock) -> Self;
|
||||||
fn with_cx(cx: &'a Self::CodegenCx) -> Self;
|
|
||||||
fn build_sibling_block(&self, name: &str) -> Self;
|
|
||||||
fn cx(&self) -> &Self::CodegenCx;
|
fn cx(&self) -> &Self::CodegenCx;
|
||||||
fn llbb(&self) -> Self::BasicBlock;
|
fn llbb(&self) -> Self::BasicBlock;
|
||||||
|
|
||||||
fn set_span(&mut self, span: Span);
|
fn set_span(&mut self, span: Span);
|
||||||
|
|
||||||
fn position_at_end(&mut self, llbb: Self::BasicBlock);
|
// FIXME(eddyb) replace uses of this with `append_sibling_block`.
|
||||||
|
fn append_block(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &str) -> Self::BasicBlock;
|
||||||
|
|
||||||
|
fn append_sibling_block(&mut self, name: &str) -> Self::BasicBlock;
|
||||||
|
|
||||||
|
// FIXME(eddyb) replace with callers using `append_sibling_block`.
|
||||||
|
fn build_sibling_block(&mut self, name: &str) -> Self;
|
||||||
|
|
||||||
fn ret_void(&mut self);
|
fn ret_void(&mut self);
|
||||||
fn ret(&mut self, v: Self::Value);
|
fn ret(&mut self, v: Self::Value);
|
||||||
fn br(&mut self, dest: Self::BasicBlock);
|
fn br(&mut self, dest: Self::BasicBlock);
|
||||||
|
Loading…
Reference in New Issue
Block a user