Skip to content

Commit 2523a29

Browse files
committed
rustc_codegen_ssa: use a different type for "unpositioned" builders.
1 parent 7506228 commit 2523a29

File tree

3 files changed

+40
-25
lines changed

3 files changed

+40
-25
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -117,21 +117,36 @@ macro_rules! builder_methods_for_value_instructions {
117117
}
118118
}
119119

120+
// HACK(eddyb) this is an easy way to avoid a complex relationship between
121+
// `Builder` and `UnpositionedBuilder`, even if it seems lopsided.
122+
pub struct UnpositionedBuilder<'a, 'll, 'tcx>(Builder<'a, 'll, 'tcx>);
123+
120124
impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
125+
type Unpositioned = UnpositionedBuilder<'a, 'll, 'tcx>;
126+
127+
fn unpositioned(cx: &'a CodegenCx<'ll, 'tcx>) -> Self::Unpositioned {
128+
// Create a fresh builder from the crate context.
129+
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
130+
UnpositionedBuilder(Builder { llbuilder, cx })
131+
}
132+
133+
fn position_at_end(bx: Self::Unpositioned, llbb: &'ll BasicBlock) -> Self {
134+
unsafe {
135+
llvm::LLVMPositionBuilderAtEnd(bx.0.llbuilder, llbb);
136+
}
137+
bx.0
138+
}
139+
140+
fn into_unpositioned(self) -> Self::Unpositioned {
141+
UnpositionedBuilder(self)
142+
}
143+
121144
fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
122-
let mut bx = Builder::with_cx(cx);
123145
let llbb = unsafe {
124146
let name = SmallCStr::new(name);
125147
llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name.as_ptr())
126148
};
127-
bx.position_at_end(llbb);
128-
bx
129-
}
130-
131-
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
132-
// Create a fresh builder from the crate context.
133-
let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) };
134-
Builder { llbuilder, cx }
149+
Self::position_at_end(Self::unpositioned(cx), llbb)
135150
}
136151

137152
fn build_sibling_block(&self, name: &str) -> Self {
@@ -144,12 +159,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
144159

145160
fn set_span(&mut self, _span: Span) {}
146161

147-
fn position_at_end(&mut self, llbb: &'ll BasicBlock) {
148-
unsafe {
149-
llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
150-
}
151-
}
152-
153162
fn ret_void(&mut self) {
154163
unsafe {
155164
llvm::LLVMBuildRetVoid(self.llbuilder);
@@ -384,9 +393,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
384393
}
385394

386395
fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
387-
let mut bx = Builder::with_cx(self.cx);
388-
bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) });
389-
bx.dynamic_alloca(ty, align)
396+
let entry_llbb = unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) };
397+
Self::position_at_start(Self::unpositioned(self.cx), entry_llbb).dynamic_alloca(ty, align)
390398
}
391399

392400
fn dynamic_alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
@@ -1169,10 +1177,11 @@ impl Builder<'a, 'll, 'tcx> {
11691177
unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) }
11701178
}
11711179

1172-
fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
1180+
fn position_at_start(bx: UnpositionedBuilder<'a, 'll, 'tcx>, llbb: &'ll BasicBlock) -> Self {
11731181
unsafe {
1174-
llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
1182+
llvm::LLVMRustPositionBuilderAtStart(bx.0.llbuilder, llbb);
11751183
}
1184+
bx.0
11761185
}
11771186

11781187
pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,9 +1245,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12451245
}
12461246

12471247
pub fn build_block(&self, bb: mir::BasicBlock) -> Bx {
1248-
let mut bx = Bx::with_cx(self.cx);
1249-
bx.position_at_end(self.blocks[bb]);
1250-
bx
1248+
Bx::position_at_end(Bx::unpositioned(self.cx), self.blocks[bb])
12511249
}
12521250

12531251
fn make_return_dest(

compiler/rustc_codegen_ssa/src/traits/builder.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,22 @@ pub trait BuilderMethods<'a, 'tcx>:
4040
+ HasParamEnv<'tcx>
4141
+ HasTargetSpec
4242
{
43+
/// IR builder (like `Self`) that doesn't have a set (insert) position, and
44+
/// cannot be used until positioned (which converted it to `Self`).
45+
// FIXME(eddyb) maybe move this associated type to a different trait, and/or
46+
// provide an `UnpositionedBuilderMethods` trait for operations involving it.
47+
type Unpositioned;
48+
49+
fn unpositioned(cx: &'a Self::CodegenCx) -> Self::Unpositioned;
50+
fn position_at_end(bx: Self::Unpositioned, llbb: Self::BasicBlock) -> Self;
51+
fn into_unpositioned(self) -> Self::Unpositioned;
52+
4353
fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &'b str) -> Self;
44-
fn with_cx(cx: &'a Self::CodegenCx) -> Self;
4554
fn build_sibling_block(&self, name: &str) -> Self;
4655
fn cx(&self) -> &Self::CodegenCx;
4756
fn llbb(&self) -> Self::BasicBlock;
4857
fn set_span(&mut self, span: Span);
4958

50-
fn position_at_end(&mut self, llbb: Self::BasicBlock);
5159
fn ret_void(&mut self);
5260
fn ret(&mut self, v: Self::Value);
5361
fn br(&mut self, dest: Self::BasicBlock);

0 commit comments

Comments
 (0)