Skip to content

Commit 8d3e13c

Browse files
committed
trans: Make everything used from within at_start Builder-friendly.
1 parent bf00d20 commit 8d3e13c

File tree

12 files changed

+169
-142
lines changed

12 files changed

+169
-142
lines changed

src/librustc_trans/trans/abi.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010

1111
use llvm::{self, ValueRef};
1212
use trans::base;
13-
use trans::build::B;
1413
use trans::builder::Builder;
15-
use trans::common::{type_is_fat_ptr, Block};
14+
use trans::common::{type_is_fat_ptr, BlockAndBuilder};
1615
use trans::context::CrateContext;
1716
use trans::cabi_x86;
1817
use trans::cabi_x86_64;
@@ -151,18 +150,16 @@ impl ArgType {
151150
}
152151
}
153152

154-
pub fn store_fn_arg(&self, bcx: Block, idx: &mut usize, dst: ValueRef) {
153+
pub fn store_fn_arg(&self, bcx: &BlockAndBuilder, idx: &mut usize, dst: ValueRef) {
155154
if self.pad.is_some() {
156155
*idx += 1;
157156
}
158157
if self.is_ignore() {
159158
return;
160159
}
161-
let val = llvm::get_param(bcx.fcx.llfn, *idx as c_uint);
160+
let val = llvm::get_param(bcx.fcx().llfn, *idx as c_uint);
162161
*idx += 1;
163-
if !bcx.unreachable.get() {
164-
self.store(&B(bcx), val, dst);
165-
}
162+
self.store(bcx, val, dst);
166163
}
167164
}
168165

src/librustc_trans/trans/adt.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,15 @@ pub fn num_args(r: &Repr, discr: Disr) -> usize {
10651065
/// Access a field, at a point when the value's case is known.
10661066
pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
10671067
val: MaybeSizedValue, discr: Disr, ix: usize) -> ValueRef {
1068+
trans_field_ptr_builder(&bcx.build(), r, val, discr, ix)
1069+
}
1070+
1071+
/// Access a field, at a point when the value's case is known.
1072+
pub fn trans_field_ptr_builder<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
1073+
r: &Repr<'tcx>,
1074+
val: MaybeSizedValue,
1075+
discr: Disr, ix: usize)
1076+
-> ValueRef {
10681077
// Note: if this ever needs to generate conditionals (e.g., if we
10691078
// decide to do some kind of cdr-coding-like non-unique repr
10701079
// someday), it will need to return a possibly-new bcx as well.
@@ -1087,13 +1096,15 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
10871096
assert_eq!(machine::llsize_of_alloc(bcx.ccx(), ty), 0);
10881097
// The contents of memory at this pointer can't matter, but use
10891098
// the value that's "reasonable" in case of pointer comparison.
1090-
PointerCast(bcx, val.value, ty.ptr_to())
1099+
if bcx.is_unreachable() { return C_undef(ty.ptr_to()); }
1100+
bcx.pointercast(val.value, ty.ptr_to())
10911101
}
10921102
RawNullablePointer { nndiscr, nnty, .. } => {
10931103
assert_eq!(ix, 0);
10941104
assert_eq!(discr, nndiscr);
10951105
let ty = type_of::type_of(bcx.ccx(), nnty);
1096-
PointerCast(bcx, val.value, ty.ptr_to())
1106+
if bcx.is_unreachable() { return C_undef(ty.ptr_to()); }
1107+
bcx.pointercast(val.value, ty.ptr_to())
10971108
}
10981109
StructWrappedNullablePointer { ref nonnull, nndiscr, .. } => {
10991110
assert_eq!(discr, nndiscr);
@@ -1102,33 +1113,39 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
11021113
}
11031114
}
11041115

1105-
pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, val: MaybeSizedValue,
1106-
ix: usize, needs_cast: bool) -> ValueRef {
1116+
fn struct_field_ptr<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
1117+
st: &Struct<'tcx>, val: MaybeSizedValue,
1118+
ix: usize, needs_cast: bool) -> ValueRef {
11071119
let ccx = bcx.ccx();
1120+
let fty = st.fields[ix];
1121+
let ll_fty = type_of::in_memory_type_of(bcx.ccx(), fty);
1122+
if bcx.is_unreachable() {
1123+
return C_undef(ll_fty.ptr_to());
1124+
}
1125+
11081126
let ptr_val = if needs_cast {
11091127
let fields = st.fields.iter().map(|&ty| {
11101128
type_of::in_memory_type_of(ccx, ty)
11111129
}).collect::<Vec<_>>();
11121130
let real_ty = Type::struct_(ccx, &fields[..], st.packed);
1113-
PointerCast(bcx, val.value, real_ty.ptr_to())
1131+
bcx.pointercast(val.value, real_ty.ptr_to())
11141132
} else {
11151133
val.value
11161134
};
11171135

1118-
let fty = st.fields[ix];
11191136
// Simple case - we can just GEP the field
11201137
// * First field - Always aligned properly
11211138
// * Packed struct - There is no alignment padding
11221139
// * Field is sized - pointer is properly aligned already
11231140
if ix == 0 || st.packed || type_is_sized(bcx.tcx(), fty) {
1124-
return StructGEP(bcx, ptr_val, ix);
1141+
return bcx.struct_gep(ptr_val, ix);
11251142
}
11261143

11271144
// If the type of the last field is [T] or str, then we don't need to do
11281145
// any adjusments
11291146
match fty.sty {
11301147
ty::TySlice(..) | ty::TyStr => {
1131-
return StructGEP(bcx, ptr_val, ix);
1148+
return bcx.struct_gep(ptr_val, ix);
11321149
}
11331150
_ => ()
11341151
}
@@ -1137,7 +1154,7 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
11371154
if !val.has_meta() {
11381155
debug!("Unsized field `{}`, of `{:?}` has no metadata for adjustment",
11391156
ix, Value(ptr_val));
1140-
return StructGEP(bcx, ptr_val, ix);
1157+
return bcx.struct_gep(ptr_val, ix);
11411158
}
11421159

11431160
let dbloc = DebugLoc::None;
@@ -1178,22 +1195,21 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
11781195
// (unaligned offset + (align - 1)) & -align
11791196

11801197
// Calculate offset
1181-
let align_sub_1 = Sub(bcx, align, C_uint(bcx.ccx(), 1u64), dbloc);
1182-
let offset = And(bcx,
1183-
Add(bcx, unaligned_offset, align_sub_1, dbloc),
1184-
Neg(bcx, align, dbloc),
1185-
dbloc);
1198+
dbloc.apply(bcx.fcx());
1199+
let align_sub_1 = bcx.sub(align, C_uint(bcx.ccx(), 1u64));
1200+
let offset = bcx.and(bcx.add(unaligned_offset, align_sub_1),
1201+
bcx.neg(align));
11861202

11871203
debug!("struct_field_ptr: DST field offset: {:?}", Value(offset));
11881204

11891205
// Cast and adjust pointer
1190-
let byte_ptr = PointerCast(bcx, ptr_val, Type::i8p(bcx.ccx()));
1191-
let byte_ptr = GEP(bcx, byte_ptr, &[offset]);
1206+
let byte_ptr = bcx.pointercast(ptr_val, Type::i8p(bcx.ccx()));
1207+
let byte_ptr = bcx.gep(byte_ptr, &[offset]);
11921208

11931209
// Finally, cast back to the type expected
11941210
let ll_fty = type_of::in_memory_type_of(bcx.ccx(), fty);
11951211
debug!("struct_field_ptr: Field type is {:?}", ll_fty);
1196-
PointerCast(bcx, byte_ptr, ll_fty.ptr_to())
1212+
bcx.pointercast(byte_ptr, ll_fty.ptr_to())
11971213
}
11981214

11991215
pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
@@ -1284,7 +1300,8 @@ pub fn trans_drop_flag_ptr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
12841300
}
12851301
));
12861302
bcx = fold_variants(bcx, r, val, |variant_cx, st, value| {
1287-
let ptr = struct_field_ptr(variant_cx, st, MaybeSizedValue::sized(value),
1303+
let ptr = struct_field_ptr(&variant_cx.build(), st,
1304+
MaybeSizedValue::sized(value),
12881305
(st.fields.len() - 1), false);
12891306
datum::Datum::new(ptr, ptr_ty, datum::Lvalue::new("adt::trans_drop_flag_ptr"))
12901307
.store_to(variant_cx, scratch.val)

src/librustc_trans/trans/base.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -912,33 +912,43 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, t: Ty<'
912912
/// differs from the type used for SSA values. Also handles various special cases where the type
913913
/// gives us better information about what we are loading.
914914
pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ptr: ValueRef, t: Ty<'tcx>) -> ValueRef {
915-
if cx.unreachable.get() || type_is_zero_size(cx.ccx(), t) {
915+
if cx.unreachable.get() {
916916
return C_undef(type_of::type_of(cx.ccx(), t));
917917
}
918+
load_ty_builder(&B(cx), ptr, t)
919+
}
920+
921+
pub fn load_ty_builder<'a, 'tcx>(b: &Builder<'a, 'tcx>, ptr: ValueRef, t: Ty<'tcx>) -> ValueRef {
922+
let ccx = b.ccx;
923+
if type_is_zero_size(ccx, t) {
924+
return C_undef(type_of::type_of(ccx, t));
925+
}
918926

919927
unsafe {
920928
let global = llvm::LLVMIsAGlobalVariable(ptr);
921929
if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True {
922930
let val = llvm::LLVMGetInitializer(global);
923931
if !val.is_null() {
924-
return to_immediate(cx, val, t);
932+
if t.is_bool() {
933+
return llvm::LLVMConstTrunc(val, Type::i1(ccx).to_ref());
934+
}
935+
return val;
925936
}
926937
}
927938
}
928939

929-
let val = if t.is_bool() {
930-
LoadRangeAssert(cx, ptr, 0, 2, llvm::False)
940+
if t.is_bool() {
941+
b.trunc(b.load_range_assert(ptr, 0, 2, llvm::False), Type::i1(ccx))
931942
} else if t.is_char() {
932943
// a char is a Unicode codepoint, and so takes values from 0
933944
// to 0x10FFFF inclusive only.
934-
LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False)
935-
} else if (t.is_region_ptr() || t.is_unique()) && !common::type_is_fat_ptr(cx.tcx(), t) {
936-
LoadNonNull(cx, ptr)
945+
b.load_range_assert(ptr, 0, 0x10FFFF + 1, llvm::False)
946+
} else if (t.is_region_ptr() || t.is_unique()) &&
947+
!common::type_is_fat_ptr(ccx.tcx(), t) {
948+
b.load_nonnull(ptr)
937949
} else {
938-
Load(cx, ptr)
939-
};
940-
941-
to_immediate(cx, val, t)
950+
b.load(ptr)
951+
}
942952
}
943953

944954
/// Helper for storing values in memory. Does the necessary conversion if the in-memory type
@@ -1659,13 +1669,14 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
16591669
uninit_reason,
16601670
arg_scope_id, |bcx, dst| {
16611671
debug!("FunctionContext::bind_args: {:?}: {:?}", hir_arg, arg_ty);
1672+
let b = &bcx.build();
16621673
if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
16631674
let meta = &self.fn_ty.args[idx];
16641675
idx += 1;
1665-
arg.store_fn_arg(bcx, &mut llarg_idx, expr::get_dataptr(bcx, dst));
1666-
meta.store_fn_arg(bcx, &mut llarg_idx, expr::get_meta(bcx, dst));
1676+
arg.store_fn_arg(b, &mut llarg_idx, expr::get_dataptr(bcx, dst));
1677+
meta.store_fn_arg(b, &mut llarg_idx, expr::get_meta(bcx, dst));
16671678
} else {
1668-
arg.store_fn_arg(bcx, &mut llarg_idx, dst);
1679+
arg.store_fn_arg(b, &mut llarg_idx, dst);
16691680
}
16701681
bcx
16711682
}))
@@ -1687,13 +1698,14 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
16871698
for (j, &tupled_arg_ty) in tupled_arg_tys.iter().enumerate() {
16881699
let dst = StructGEP(bcx, llval, j);
16891700
let arg = &self.fn_ty.args[idx];
1701+
let b = &bcx.build();
16901702
if common::type_is_fat_ptr(bcx.tcx(), tupled_arg_ty) {
16911703
let meta = &self.fn_ty.args[idx];
16921704
idx += 1;
1693-
arg.store_fn_arg(bcx, &mut llarg_idx, expr::get_dataptr(bcx, dst));
1694-
meta.store_fn_arg(bcx, &mut llarg_idx, expr::get_meta(bcx, dst));
1705+
arg.store_fn_arg(b, &mut llarg_idx, expr::get_dataptr(bcx, dst));
1706+
meta.store_fn_arg(b, &mut llarg_idx, expr::get_meta(bcx, dst));
16951707
} else {
1696-
arg.store_fn_arg(bcx, &mut llarg_idx, dst);
1708+
arg.store_fn_arg(b, &mut llarg_idx, dst);
16971709
}
16981710
}
16991711
bcx
@@ -2039,13 +2051,14 @@ pub fn trans_ctor_shim<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
20392051
let lldestptr = adt::trans_field_ptr(bcx, &repr, dest_val, Disr::from(disr), i);
20402052
let arg = &fcx.fn_ty.args[arg_idx];
20412053
arg_idx += 1;
2054+
let b = &bcx.build();
20422055
if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
20432056
let meta = &fcx.fn_ty.args[arg_idx];
20442057
arg_idx += 1;
2045-
arg.store_fn_arg(bcx, &mut llarg_idx, expr::get_dataptr(bcx, lldestptr));
2046-
meta.store_fn_arg(bcx, &mut llarg_idx, expr::get_meta(bcx, lldestptr));
2058+
arg.store_fn_arg(b, &mut llarg_idx, expr::get_dataptr(bcx, lldestptr));
2059+
meta.store_fn_arg(b, &mut llarg_idx, expr::get_meta(bcx, lldestptr));
20472060
} else {
2048-
arg.store_fn_arg(bcx, &mut llarg_idx, lldestptr);
2061+
arg.store_fn_arg(b, &mut llarg_idx, lldestptr);
20492062
}
20502063
}
20512064
adt::trans_set_discr(bcx, &repr, dest, disr);

src/librustc_trans/trans/closure.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
5252
let llenv = if kind == ty::ClosureKind::FnOnce && !env_arg.is_indirect() {
5353
let closure_ty = node_id_type(bcx, id);
5454
let llenv = rvalue_scratch_datum(bcx, closure_ty, "closure_env").val;
55-
env_arg.store_fn_arg(bcx, &mut env_idx, llenv);
55+
env_arg.store_fn_arg(&bcx.build(), &mut env_idx, llenv);
5656
llenv
5757
} else {
5858
get_param(bcx.fcx.llfn, env_idx as c_uint)
@@ -409,7 +409,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
409409
InitAlloca::Dropped,
410410
self_scope_id, |bcx, llval| {
411411
let mut llarg_idx = self_idx;
412-
env_arg.store_fn_arg(bcx, &mut llarg_idx, llval);
412+
env_arg.store_fn_arg(&bcx.build(), &mut llarg_idx, llval);
413413
bcx.fcx.schedule_lifetime_end(self_scope_id, llval);
414414
bcx
415415
})).val

src/librustc_trans/trans/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,10 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
688688

689689
// Methods delegated to bcx
690690

691+
pub fn is_unreachable(&self) -> bool {
692+
self.bcx.unreachable.get()
693+
}
694+
691695
pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
692696
self.bcx.ccx()
693697
}

0 commit comments

Comments
 (0)