Skip to content

Commit 06266eb

Browse files
committed
Refactor the MIR translator to use LLVM Builder directly
1 parent 8b77683 commit 06266eb

File tree

9 files changed

+394
-315
lines changed

9 files changed

+394
-315
lines changed

src/librustc_trans/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2003,7 +2003,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
20032003
let mut bcx = init_function(&fcx, false, output_type);
20042004

20052005
if attributes.iter().any(|item| item.check_name("rustc_mir")) {
2006-
mir::trans_mir(bcx);
2006+
mir::trans_mir(bcx.build());
20072007
fcx.cleanup();
20082008
return;
20092009
}

src/librustc_trans/trans/mir/block.rs

Lines changed: 105 additions & 92 deletions
Large diffs are not rendered by default.

src/librustc_trans/trans/mir/constant.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use middle::subst::Substs;
1414
use middle::ty::{Ty, TypeFoldable};
1515
use rustc::middle::const_eval::ConstVal;
1616
use rustc::mir::repr as mir;
17-
use trans::common::{self, Block, C_bool, C_bytes, C_floating_f64, C_integral, C_str_slice};
17+
use trans::common::{self, BlockAndBuilder, C_bool, C_bytes, C_floating_f64, C_integral,
18+
C_str_slice};
1819
use trans::consts;
1920
use trans::expr;
2021
use trans::type_of;
@@ -25,13 +26,13 @@ use super::MirContext;
2526

2627
impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
2728
pub fn trans_constval(&mut self,
28-
bcx: Block<'bcx, 'tcx>,
29+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
2930
cv: &ConstVal,
3031
ty: Ty<'tcx>)
3132
-> OperandRef<'tcx>
3233
{
3334
let ccx = bcx.ccx();
34-
let val = self.trans_constval_inner(bcx, cv, ty, bcx.fcx.param_substs);
35+
let val = self.trans_constval_inner(bcx, cv, ty, bcx.fcx().param_substs);
3536
let val = if common::type_is_immediate(ccx, ty) {
3637
OperandValue::Immediate(val)
3738
} else if common::type_is_fat_ptr(bcx.tcx(), ty) {
@@ -52,7 +53,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
5253

5354
/// Translate ConstVal into a bare LLVM ValueRef.
5455
fn trans_constval_inner(&mut self,
55-
bcx: common::Block<'bcx, 'tcx>,
56+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
5657
cv: &ConstVal,
5758
ty: Ty<'tcx>,
5859
param_substs: &'tcx Substs<'tcx>)
@@ -70,15 +71,17 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
7071
ConstVal::Struct(id) | ConstVal::Tuple(id) |
7172
ConstVal::Array(id, _) | ConstVal::Repeat(id, _) => {
7273
let expr = bcx.tcx().map.expect_expr(id);
73-
expr::trans(bcx, expr).datum.val
74+
bcx.with_block(|bcx| {
75+
expr::trans(bcx, expr).datum.val
76+
})
7477
},
7578
ConstVal::Function(did) =>
7679
self.trans_fn_ref(bcx, ty, param_substs, did).immediate()
7780
}
7881
}
7982

8083
pub fn trans_constant(&mut self,
81-
bcx: Block<'bcx, 'tcx>,
84+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
8285
constant: &mir::Constant<'tcx>)
8386
-> OperandRef<'tcx>
8487
{

src/librustc_trans/trans/mir/did.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc::middle::const_eval;
1818
use rustc::middle::def_id::DefId;
1919
use rustc::middle::traits;
2020
use rustc::mir::repr::ItemKind;
21-
use trans::common::{Block, fulfill_obligation};
21+
use trans::common::{BlockAndBuilder, fulfill_obligation};
2222
use trans::base;
2323
use trans::closure;
2424
use trans::expr;
@@ -32,7 +32,7 @@ use super::operand::{OperandRef, OperandValue};
3232
impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
3333
/// Translate reference to item.
3434
pub fn trans_item_ref(&mut self,
35-
bcx: Block<'bcx, 'tcx>,
35+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
3636
ty: Ty<'tcx>,
3737
kind: ItemKind,
3838
substs: &'tcx Substs<'tcx>,
@@ -53,7 +53,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
5353
.expect("def was const, but lookup_const_by_id failed");
5454
// FIXME: this is falling back to translating from HIR. This is not easy to fix,
5555
// because we would have somehow adapt const_eval to work on MIR rather than HIR.
56-
let d = expr::trans(bcx, expr);
56+
let d = bcx.with_block(|bcx| {
57+
expr::trans(bcx, expr)
58+
});
5759
OperandRef::from_rvalue_datum(d.datum.to_rvalue_datum(d.bcx, "").datum)
5860
}
5961
}
@@ -66,7 +68,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
6668
///
6769
/// This is an adaptation of callee::trans_fn_ref_with_substs.
6870
pub fn trans_fn_ref(&mut self,
69-
bcx: Block<'bcx, 'tcx>,
71+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
7072
ty: Ty<'tcx>,
7173
substs: &'tcx Substs<'tcx>,
7274
did: DefId)
@@ -101,7 +103,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
101103
///
102104
/// This is an adaptation of meth::trans_static_method_callee
103105
pub fn trans_trait_method(&mut self,
104-
bcx: Block<'bcx, 'tcx>,
106+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
105107
ty: Ty<'tcx>,
106108
method_id: DefId,
107109
trait_id: DefId,

src/librustc_trans/trans/mir/lvalue.rs

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ use rustc::mir::repr as mir;
1414
use rustc::mir::tcx::LvalueTy;
1515
use trans::adt;
1616
use trans::base;
17-
use trans::build;
18-
use trans::common::{self, Block};
19-
use trans::debuginfo::DebugLoc;
17+
use trans::common::{self, BlockAndBuilder};
2018
use trans::machine;
2119
use trans::type_of;
2220
use llvm;
@@ -43,20 +41,20 @@ impl<'tcx> LvalueRef<'tcx> {
4341
LvalueRef { llval: llval, llextra: ptr::null_mut(), ty: lvalue_ty }
4442
}
4543

46-
pub fn alloca<'bcx>(bcx: Block<'bcx, 'tcx>,
44+
pub fn alloca<'bcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
4745
ty: Ty<'tcx>,
4846
name: &str)
4947
-> LvalueRef<'tcx>
5048
{
5149
assert!(!ty.has_erasable_regions());
52-
let lltemp = base::alloc_ty(bcx, ty, name);
50+
let lltemp = bcx.with_block(|bcx| base::alloc_ty(bcx, ty, name));
5351
LvalueRef::new_sized(lltemp, LvalueTy::from_ty(ty))
5452
}
5553
}
5654

5755
impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
5856
pub fn lvalue_len(&mut self,
59-
bcx: Block<'bcx, 'tcx>,
57+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
6058
lvalue: LvalueRef<'tcx>)
6159
-> ValueRef {
6260
match lvalue.ty.to_ty(bcx.tcx()).sty {
@@ -70,13 +68,13 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
7068
}
7169

7270
pub fn trans_lvalue(&mut self,
73-
bcx: Block<'bcx, 'tcx>,
71+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
7472
lvalue: &mir::Lvalue<'tcx>)
7573
-> LvalueRef<'tcx> {
7674
debug!("trans_lvalue(lvalue={:?})", lvalue);
7775

78-
let fcx = bcx.fcx;
79-
let ccx = fcx.ccx;
76+
let fcx = bcx.fcx();
77+
let ccx = bcx.ccx();
8078
let tcx = bcx.tcx();
8179
match *lvalue {
8280
mir::Lvalue::Var(index) => self.vars[index as usize],
@@ -97,7 +95,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
9795
let fn_return_ty = bcx.monomorphize(&self.mir.return_ty);
9896
let return_ty = fn_return_ty.unwrap();
9997
let llval = if !common::return_type_is_void(bcx.ccx(), return_ty) {
100-
fcx.get_ret_slot(bcx, fn_return_ty, "")
98+
bcx.with_block(|bcx| {
99+
fcx.get_ret_slot(bcx, fn_return_ty, "")
100+
})
101101
} else {
102102
// This is a void return; that is, there’s no place to store the value and
103103
// there cannot really be one (or storing into it doesn’t make sense, anyway).
@@ -117,12 +117,14 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
117117
let (llprojected, llextra) = match projection.elem {
118118
mir::ProjectionElem::Deref => {
119119
let base_ty = tr_base.ty.to_ty(tcx);
120-
if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) {
121-
(base::load_ty(bcx, tr_base.llval, base_ty),
122-
ptr::null_mut())
123-
} else {
124-
base::load_fat_ptr(bcx, tr_base.llval, base_ty)
125-
}
120+
bcx.with_block(|bcx| {
121+
if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) {
122+
(base::load_ty(bcx, tr_base.llval, base_ty),
123+
ptr::null_mut())
124+
} else {
125+
base::load_fat_ptr(bcx, tr_base.llval, base_ty)
126+
}
127+
})
126128
}
127129
mir::ProjectionElem::Field(ref field) => {
128130
let base_ty = tr_base.ty.to_ty(tcx);
@@ -138,18 +140,21 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
138140
} else {
139141
adt::MaybeSizedValue::unsized_(tr_base.llval, tr_base.llextra)
140142
};
141-
(adt::trans_field_ptr(bcx, &base_repr, base, Disr(discr), field.index()),
142-
if is_sized {
143-
ptr::null_mut()
144-
} else {
145-
tr_base.llextra
146-
})
143+
let llprojected = bcx.with_block(|bcx| {
144+
adt::trans_field_ptr(bcx, &base_repr, base, Disr(discr), field.index())
145+
});
146+
let llextra = if is_sized {
147+
ptr::null_mut()
148+
} else {
149+
tr_base.llextra
150+
};
151+
(llprojected, llextra)
147152
}
148153
mir::ProjectionElem::Index(ref index) => {
149154
let index = self.trans_operand(bcx, index);
150155
let llindex = self.prepare_index(bcx, index.immediate());
151156
let zero = common::C_uint(bcx.ccx(), 0u64);
152-
(build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
157+
(bcx.inbounds_gep(tr_base.llval, &[zero, llindex]),
153158
ptr::null_mut())
154159
}
155160
mir::ProjectionElem::ConstantIndex { offset,
@@ -158,18 +163,18 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
158163
let lloffset = common::C_u32(bcx.ccx(), offset);
159164
let llindex = self.prepare_index(bcx, lloffset);
160165
let zero = common::C_uint(bcx.ccx(), 0u64);
161-
(build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
166+
(bcx.inbounds_gep(tr_base.llval, &[zero, llindex]),
162167
ptr::null_mut())
163168
}
164169
mir::ProjectionElem::ConstantIndex { offset,
165170
from_end: true,
166171
min_length: _ } => {
167172
let lloffset = common::C_u32(bcx.ccx(), offset);
168173
let lllen = self.lvalue_len(bcx, tr_base);
169-
let llindex = build::Sub(bcx, lllen, lloffset, DebugLoc::None);
174+
let llindex = bcx.sub(lllen, lloffset);
170175
let llindex = self.prepare_index(bcx, llindex);
171176
let zero = common::C_uint(bcx.ccx(), 0u64);
172-
(build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
177+
(bcx.inbounds_gep(tr_base.llval, &[zero, llindex]),
173178
ptr::null_mut())
174179
}
175180
mir::ProjectionElem::Downcast(..) => {
@@ -190,17 +195,17 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
190195
///
191196
/// nmatsakis: is this still necessary? Not sure.
192197
fn prepare_index(&mut self,
193-
bcx: Block<'bcx, 'tcx>,
198+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
194199
llindex: ValueRef)
195200
-> ValueRef
196201
{
197202
let ccx = bcx.ccx();
198203
let index_size = machine::llbitsize_of_real(bcx.ccx(), common::val_ty(llindex));
199204
let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type());
200205
if index_size < int_size {
201-
build::ZExt(bcx, llindex, ccx.int_type())
206+
bcx.zext(llindex, ccx.int_type())
202207
} else if index_size > int_size {
203-
build::Trunc(bcx, llindex, ccx.int_type())
208+
bcx.trunc(llindex, ccx.int_type())
204209
} else {
205210
llindex
206211
}

src/librustc_trans/trans/mir/mod.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use llvm::{self, ValueRef};
1313
use rustc::mir::repr as mir;
1414
use rustc::mir::tcx::LvalueTy;
1515
use trans::base;
16-
use trans::build;
17-
use trans::common::{self, Block, LandingPad};
18-
use trans::debuginfo::DebugLoc;
16+
use trans::common::{self, Block, BlockAndBuilder, LandingPad};
1917
use trans::expr;
2018
use trans::type_of;
2119

@@ -79,26 +77,28 @@ enum TempRef<'tcx> {
7977

8078
///////////////////////////////////////////////////////////////////////////
8179

82-
pub fn trans_mir<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>) {
83-
let fcx = bcx.fcx;
80+
pub fn trans_mir<'bcx, 'tcx>(bcx: BlockAndBuilder<'bcx, 'tcx>) {
81+
let fcx = bcx.fcx();
8482
let mir = bcx.mir();
8583

8684
let mir_blocks = bcx.mir().all_basic_blocks();
8785

8886
// Analyze the temps to determine which must be lvalues
8987
// FIXME
90-
let lvalue_temps = analyze::lvalue_temps(bcx, mir);
88+
let lvalue_temps = bcx.with_block(|bcx| {
89+
analyze::lvalue_temps(bcx, mir)
90+
});
9191

9292
// Allocate variable and temp allocas
9393
let vars = mir.var_decls.iter()
9494
.map(|decl| (bcx.monomorphize(&decl.ty), decl.name))
95-
.map(|(mty, name)| LvalueRef::alloca(bcx, mty, &name.as_str()))
95+
.map(|(mty, name)| LvalueRef::alloca(&bcx, mty, &name.as_str()))
9696
.collect();
9797
let temps = mir.temp_decls.iter()
9898
.map(|decl| bcx.monomorphize(&decl.ty))
9999
.enumerate()
100100
.map(|(i, mty)| if lvalue_temps.contains(i) {
101-
TempRef::Lvalue(LvalueRef::alloca(bcx,
101+
TempRef::Lvalue(LvalueRef::alloca(&bcx,
102102
mty,
103103
&format!("temp{:?}", i)))
104104
} else {
@@ -108,7 +108,7 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>) {
108108
TempRef::Operand(None)
109109
})
110110
.collect();
111-
let args = arg_value_refs(bcx, mir);
111+
let args = arg_value_refs(&bcx, mir);
112112

113113
// Allocate a `Block` for every basic block
114114
let block_bcxs: Vec<Block<'bcx,'tcx>> =
@@ -125,7 +125,7 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>) {
125125

126126
// Branch to the START block
127127
let start_bcx = block_bcxs[mir::START_BLOCK.index()];
128-
build::Br(bcx, start_bcx.llbb, DebugLoc::None);
128+
bcx.br(start_bcx.llbb);
129129

130130
let mut mircx = MirContext {
131131
mir: mir,
@@ -147,11 +147,11 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>) {
147147
/// Produce, for each argument, a `ValueRef` pointing at the
148148
/// argument's value. As arguments are lvalues, these are always
149149
/// indirect.
150-
fn arg_value_refs<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>,
150+
fn arg_value_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
151151
mir: &mir::Mir<'tcx>)
152152
-> Vec<LvalueRef<'tcx>> {
153153
// FIXME tupled_args? I think I'd rather that mapping is done in MIR land though
154-
let fcx = bcx.fcx;
154+
let fcx = bcx.fcx();
155155
let tcx = bcx.tcx();
156156
let mut idx = fcx.arg_offset() as c_uint;
157157
mir.arg_decls
@@ -174,17 +174,26 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>,
174174
let lldata = llvm::get_param(fcx.llfn, idx);
175175
let llextra = llvm::get_param(fcx.llfn, idx + 1);
176176
idx += 2;
177-
let lltemp = base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index));
178-
build::Store(bcx, lldata, expr::get_dataptr(bcx, lltemp));
179-
build::Store(bcx, llextra, expr::get_meta(bcx, lltemp));
177+
let lltemp = bcx.with_block(|bcx| {
178+
base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index))
179+
});
180+
let (dataptr, meta) = bcx.with_block(|bcx| {
181+
(expr::get_dataptr(bcx, lltemp), expr::get_meta(bcx, lltemp))
182+
});
183+
bcx.store(lldata, dataptr);
184+
bcx.store(llextra, meta);
180185
lltemp
181186
} else {
182187
// otherwise, arg is passed by value, so make a
183188
// temporary and store it there
184189
let llarg = llvm::get_param(fcx.llfn, idx);
185190
idx += 1;
186-
let lltemp = base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index));
187-
base::store_ty(bcx, llarg, lltemp, arg_ty);
191+
let lltemp = bcx.with_block(|bcx| {
192+
base::alloc_ty(bcx, arg_ty, &format!("arg{}", arg_index))
193+
});
194+
bcx.with_block(|bcx| {
195+
base::store_ty(bcx, llarg, lltemp, arg_ty)
196+
});
188197
lltemp
189198
};
190199
LvalueRef::new_sized(llval, LvalueTy::from_ty(arg_ty))

0 commit comments

Comments
 (0)