Skip to content

Commit 5a9e6b8

Browse files
irinagpopaeddyb
authored andcommitted
rustc_codegen_llvm: begin generalizing over backend values.
1 parent 6b9b97b commit 5a9e6b8

File tree

9 files changed

+107
-75
lines changed

9 files changed

+107
-75
lines changed

src/librustc_codegen_llvm/abi.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,13 @@ impl LlvmType for CastTarget {
167167

168168
pub trait ArgTypeExt<'ll, 'tcx> {
169169
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
170-
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>);
171-
fn store_fn_arg(&self, bx: &Builder<'_, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>);
170+
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'tcx, &'ll Value>);
171+
fn store_fn_arg(
172+
&self,
173+
bx: &Builder<'_, 'll, 'tcx>,
174+
idx: &mut usize,
175+
dst: PlaceRef<'tcx, &'ll Value>,
176+
);
172177
}
173178

174179
impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
@@ -182,7 +187,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
182187
/// place for the original Rust type of this argument/return.
183188
/// Can be used for both storing formal arguments into Rust variables
184189
/// or results of call/invoke instructions into their destinations.
185-
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>) {
190+
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'tcx, &'ll Value>) {
186191
if self.is_ignore() {
187192
return;
188193
}
@@ -238,7 +243,12 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
238243
}
239244
}
240245

241-
fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>) {
246+
fn store_fn_arg(
247+
&self,
248+
bx: &Builder<'a, 'll, 'tcx>,
249+
idx: &mut usize,
250+
dst: PlaceRef<'tcx, &'ll Value>,
251+
) {
242252
let mut next = || {
243253
let val = llvm::get_param(bx.llfn(), *idx as c_uint);
244254
*idx += 1;

src/librustc_codegen_llvm/asm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use libc::{c_uint, c_char};
2828
pub fn codegen_inline_asm(
2929
bx: &Builder<'a, 'll, 'tcx>,
3030
ia: &hir::InlineAsm,
31-
outputs: Vec<PlaceRef<'ll, 'tcx>>,
31+
outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
3232
mut inputs: Vec<&'ll Value>
3333
) -> bool {
3434
let mut ext_constraints = vec![];

src/librustc_codegen_llvm/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,8 @@ pub fn unsize_thin_ptr(
275275
/// to a value of type `dst_ty` and store the result in `dst`
276276
pub fn coerce_unsized_into(
277277
bx: &Builder<'a, 'll, 'tcx>,
278-
src: PlaceRef<'ll, 'tcx>,
279-
dst: PlaceRef<'ll, 'tcx>
278+
src: PlaceRef<'tcx, &'ll Value>,
279+
dst: PlaceRef<'tcx, &'ll Value>
280280
) {
281281
let src_ty = src.layout.ty;
282282
let dst_ty = dst.layout.ty;

src/librustc_codegen_llvm/intrinsic.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub fn codegen_intrinsic_call(
9191
bx: &Builder<'a, 'll, 'tcx>,
9292
callee_ty: Ty<'tcx>,
9393
fn_ty: &FnType<'tcx, Ty<'tcx>>,
94-
args: &[OperandRef<'ll, 'tcx>],
94+
args: &[OperandRef<'tcx, &'ll Value>],
9595
llresult: &'ll Value,
9696
span: Span,
9797
) {
@@ -614,7 +614,7 @@ pub fn codegen_intrinsic_call(
614614
fn modify_as_needed(
615615
bx: &Builder<'a, 'll, 'tcx>,
616616
t: &intrinsics::Type,
617-
arg: &OperandRef<'ll, 'tcx>,
617+
arg: &OperandRef<'tcx, &'ll Value>,
618618
) -> Vec<&'ll Value> {
619619
match *t {
620620
intrinsics::Type::Aggregate(true, ref contents) => {
@@ -992,7 +992,7 @@ fn generic_simd_intrinsic(
992992
bx: &Builder<'a, 'll, 'tcx>,
993993
name: &str,
994994
callee_ty: Ty<'tcx>,
995-
args: &[OperandRef<'ll, 'tcx>],
995+
args: &[OperandRef<'tcx, &'ll Value>],
996996
ret_ty: Ty<'tcx>,
997997
llret_ty: &'ll Type,
998998
span: Span
@@ -1167,7 +1167,7 @@ fn generic_simd_intrinsic(
11671167
in_len: usize,
11681168
bx: &Builder<'a, 'll, 'tcx>,
11691169
span: Span,
1170-
args: &[OperandRef<'ll, 'tcx>],
1170+
args: &[OperandRef<'tcx, &'ll Value>],
11711171
) -> Result<&'ll Value, ()> {
11721172
macro_rules! emit_error {
11731173
($msg: tt) => {

src/librustc_codegen_llvm/mir/block.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
115115
fn_ty: FnType<'tcx, Ty<'tcx>>,
116116
fn_ptr: &'ll Value,
117117
llargs: &[&'ll Value],
118-
destination: Option<(ReturnDest<'ll, 'tcx>, mir::BasicBlock)>,
118+
destination: Option<(ReturnDest<'tcx, &'ll Value>, mir::BasicBlock)>,
119119
cleanup: Option<mir::BasicBlock>
120120
| {
121121
if let Some(cleanup) = cleanup {
@@ -731,7 +731,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
731731

732732
fn codegen_argument(&mut self,
733733
bx: &Builder<'a, 'll, 'tcx>,
734-
op: OperandRef<'ll, 'tcx>,
734+
op: OperandRef<'tcx, &'ll Value>,
735735
llargs: &mut Vec<&'ll Value>,
736736
arg: &ArgType<'tcx, Ty<'tcx>>) {
737737
// Fill padding with undef value, where applicable.
@@ -843,7 +843,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
843843
}
844844
}
845845

846-
fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'ll, 'tcx> {
846+
fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'tcx, &'ll Value> {
847847
let cx = bx.cx;
848848
if let Some(slot) = self.personality_slot {
849849
slot
@@ -919,7 +919,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
919919
fn make_return_dest(&mut self, bx: &Builder<'a, 'll, 'tcx>,
920920
dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>,
921921
llargs: &mut Vec<&'ll Value>, is_intrinsic: bool)
922-
-> ReturnDest<'ll, 'tcx> {
922+
-> ReturnDest<'tcx, &'ll Value> {
923923
// If the return is ignored, we can just return a do-nothing ReturnDest
924924
if fn_ret.is_ignore() {
925925
return ReturnDest::Nothing;
@@ -1003,7 +1003,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
10031003

10041004
fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>,
10051005
src: &mir::Operand<'tcx>,
1006-
dst: PlaceRef<'ll, 'tcx>) {
1006+
dst: PlaceRef<'tcx, &'ll Value>) {
10071007
let src = self.codegen_operand(bx, src);
10081008
let llty = src.layout.llvm_type(bx.cx);
10091009
let cast_ptr = bx.pointercast(dst.llval, llty.ptr_to());
@@ -1015,7 +1015,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
10151015
// Stores the return value of a function call into it's final location.
10161016
fn store_return(&mut self,
10171017
bx: &Builder<'a, 'll, 'tcx>,
1018-
dest: ReturnDest<'ll, 'tcx>,
1018+
dest: ReturnDest<'tcx, &'ll Value>,
10191019
ret_ty: &ArgType<'tcx, Ty<'tcx>>,
10201020
llval: &'ll Value) {
10211021
use self::ReturnDest::*;
@@ -1046,13 +1046,13 @@ impl FunctionCx<'a, 'll, 'tcx> {
10461046
}
10471047
}
10481048

1049-
enum ReturnDest<'ll, 'tcx> {
1049+
enum ReturnDest<'tcx, V> {
10501050
// Do nothing, the return value is indirect or ignored
10511051
Nothing,
10521052
// Store the return value to the pointer
1053-
Store(PlaceRef<'ll, 'tcx>),
1053+
Store(PlaceRef<'tcx, V>),
10541054
// Stores an indirect return value to an operand local place
1055-
IndirectOperand(PlaceRef<'ll, 'tcx>, mir::Local),
1055+
IndirectOperand(PlaceRef<'tcx, V>, mir::Local),
10561056
// Stores a direct return value to an operand local place
10571057
DirectOperand(mir::Local)
10581058
}

src/librustc_codegen_llvm/mir/mod.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
6464
/// don't really care about it very much. Anyway, this value
6565
/// contains an alloca into which the personality is stored and
6666
/// then later loaded when generating the DIVERGE_BLOCK.
67-
personality_slot: Option<PlaceRef<'ll, 'tcx>>,
67+
personality_slot: Option<PlaceRef<'tcx, &'ll Value>>,
6868

6969
/// A `Block` for each MIR `BasicBlock`
7070
blocks: IndexVec<mir::BasicBlock, &'ll BasicBlock>,
@@ -98,7 +98,7 @@ pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
9898
///
9999
/// Avoiding allocs can also be important for certain intrinsics,
100100
/// notably `expect`.
101-
locals: IndexVec<mir::Local, LocalRef<'ll, 'tcx>>,
101+
locals: IndexVec<mir::Local, LocalRef<'tcx, &'ll Value>>,
102102

103103
/// Debug information for MIR scopes.
104104
scopes: IndexVec<mir::SourceScope, debuginfo::MirDebugScope<'ll>>,
@@ -179,18 +179,21 @@ impl FunctionCx<'a, 'll, 'tcx> {
179179
}
180180
}
181181

182-
enum LocalRef<'ll, 'tcx> {
183-
Place(PlaceRef<'ll, 'tcx>),
182+
enum LocalRef<'tcx, V> {
183+
Place(PlaceRef<'tcx, V>),
184184
/// `UnsizedPlace(p)`: `p` itself is a thin pointer (indirect place).
185185
/// `*p` is the fat pointer that references the actual unsized place.
186186
/// Every time it is initialized, we have to reallocate the place
187187
/// and update the fat pointer. That's the reason why it is indirect.
188-
UnsizedPlace(PlaceRef<'ll, 'tcx>),
189-
Operand(Option<OperandRef<'ll, 'tcx>>),
188+
UnsizedPlace(PlaceRef<'tcx, V>),
189+
Operand(Option<OperandRef<'tcx, V>>),
190190
}
191191

192-
impl LocalRef<'ll, 'tcx> {
193-
fn new_operand(cx: &CodegenCx<'ll, 'tcx>, layout: TyLayout<'tcx>) -> LocalRef<'ll, 'tcx> {
192+
impl LocalRef<'tcx, &'ll Value> {
193+
fn new_operand(
194+
cx: &CodegenCx<'ll, 'tcx>,
195+
layout: TyLayout<'tcx>,
196+
) -> LocalRef<'tcx, &'ll Value> {
194197
if layout.is_zst() {
195198
// Zero-size temporaries aren't always initialized, which
196199
// doesn't matter because they don't contain data, but
@@ -437,7 +440,7 @@ fn arg_local_refs(
437440
fx: &FunctionCx<'a, 'll, 'tcx>,
438441
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope<'ll>>,
439442
memory_locals: &BitSet<mir::Local>,
440-
) -> Vec<LocalRef<'ll, 'tcx>> {
443+
) -> Vec<LocalRef<'tcx, &'ll Value>> {
441444
let mir = fx.mir;
442445
let tcx = bx.tcx();
443446
let mut idx = 0;

src/librustc_codegen_llvm/mir/operand.rs

+35-23
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ use super::place::PlaceRef;
3131
/// uniquely determined by the value's type, but is kept as a
3232
/// safety check.
3333
#[derive(Copy, Clone, Debug)]
34-
pub enum OperandValue<'ll> {
34+
pub enum OperandValue<V> {
3535
/// A reference to the actual operand. The data is guaranteed
3636
/// to be valid for the operand's lifetime.
3737
/// The second value, if any, is the extra data (vtable or length)
3838
/// which indicates that it refers to an unsized rvalue.
39-
Ref(&'ll Value, Option<&'ll Value>, Align),
39+
Ref(V, Option<V>, Align),
4040
/// A single LLVM value.
41-
Immediate(&'ll Value),
41+
Immediate(V),
4242
/// A pair of immediate LLVM values. Used by fat pointers too.
43-
Pair(&'ll Value, &'ll Value)
43+
Pair(V, V)
4444
}
4545

4646
/// An `OperandRef` is an "SSA" reference to a Rust value, along with
@@ -52,23 +52,23 @@ pub enum OperandValue<'ll> {
5252
/// directly is sure to cause problems -- use `OperandRef::store`
5353
/// instead.
5454
#[derive(Copy, Clone)]
55-
pub struct OperandRef<'ll, 'tcx> {
55+
pub struct OperandRef<'tcx, V> {
5656
// The value.
57-
pub val: OperandValue<'ll>,
57+
pub val: OperandValue<V>,
5858

5959
// The layout of value, based on its Rust type.
6060
pub layout: TyLayout<'tcx>,
6161
}
6262

63-
impl fmt::Debug for OperandRef<'ll, 'tcx> {
63+
impl fmt::Debug for OperandRef<'tcx, &'ll Value> {
6464
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6565
write!(f, "OperandRef({:?} @ {:?})", self.val, self.layout)
6666
}
6767
}
6868

69-
impl OperandRef<'ll, 'tcx> {
69+
impl OperandRef<'tcx, &'ll Value> {
7070
pub fn new_zst(cx: &CodegenCx<'ll, 'tcx>,
71-
layout: TyLayout<'tcx>) -> OperandRef<'ll, 'tcx> {
71+
layout: TyLayout<'tcx>) -> OperandRef<'tcx, &'ll Value> {
7272
assert!(layout.is_zst());
7373
OperandRef {
7474
val: OperandValue::Immediate(C_undef(layout.immediate_llvm_type(cx))),
@@ -78,7 +78,7 @@ impl OperandRef<'ll, 'tcx> {
7878

7979
pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
8080
val: &'tcx ty::Const<'tcx>)
81-
-> Result<OperandRef<'ll, 'tcx>, ErrorHandled> {
81+
-> Result<OperandRef<'tcx, &'ll Value>, ErrorHandled> {
8282
let layout = bx.cx.layout_of(val.ty);
8383

8484
if layout.is_zst() {
@@ -140,7 +140,7 @@ impl OperandRef<'ll, 'tcx> {
140140
}
141141
}
142142

143-
pub fn deref(self, cx: &CodegenCx<'ll, 'tcx>) -> PlaceRef<'ll, 'tcx> {
143+
pub fn deref(self, cx: &CodegenCx<'ll, 'tcx>) -> PlaceRef<'tcx, &'ll Value> {
144144
let projected_ty = self.layout.ty.builtin_deref(true)
145145
.unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty;
146146
let (llptr, llextra) = match self.val {
@@ -178,7 +178,7 @@ impl OperandRef<'ll, 'tcx> {
178178
pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'll, 'tcx>,
179179
llval: &'ll Value,
180180
layout: TyLayout<'tcx>)
181-
-> OperandRef<'ll, 'tcx> {
181+
-> OperandRef<'tcx, &'ll Value> {
182182
let val = if let layout::Abi::ScalarPair(ref a, ref b) = layout.abi {
183183
debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}",
184184
llval, layout);
@@ -193,7 +193,11 @@ impl OperandRef<'ll, 'tcx> {
193193
OperandRef { val, layout }
194194
}
195195

196-
pub fn extract_field(&self, bx: &Builder<'a, 'll, 'tcx>, i: usize) -> OperandRef<'ll, 'tcx> {
196+
pub fn extract_field(
197+
&self,
198+
bx: &Builder<'a, 'll, 'tcx>,
199+
i: usize,
200+
) -> OperandRef<'tcx, &'ll Value> {
197201
let field = self.layout.field(bx.cx, i);
198202
let offset = self.layout.fields.offset(i);
199203

@@ -251,27 +255,31 @@ impl OperandRef<'ll, 'tcx> {
251255
}
252256
}
253257

254-
impl OperandValue<'ll> {
255-
pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
258+
impl OperandValue<&'ll Value> {
259+
pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
256260
self.store_with_flags(bx, dest, MemFlags::empty());
257261
}
258262

259-
pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
263+
pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
260264
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
261265
}
262266

263-
pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
267+
pub fn unaligned_volatile_store(
268+
self,
269+
bx: &Builder<'a, 'll, 'tcx>,
270+
dest: PlaceRef<'tcx, &'ll Value>,
271+
) {
264272
self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
265273
}
266274

267-
pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'ll, 'tcx>) {
275+
pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx, &'ll Value>) {
268276
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
269277
}
270278

271279
fn store_with_flags(
272280
self,
273281
bx: &Builder<'a, 'll, 'tcx>,
274-
dest: PlaceRef<'ll, 'tcx>,
282+
dest: PlaceRef<'tcx, &'ll Value>,
275283
flags: MemFlags,
276284
) {
277285
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
@@ -302,7 +310,11 @@ impl OperandValue<'ll> {
302310
}
303311
}
304312

305-
pub fn store_unsized(self, bx: &Builder<'a, 'll, 'tcx>, indirect_dest: PlaceRef<'ll, 'tcx>) {
313+
pub fn store_unsized(
314+
self,
315+
bx: &Builder<'a, 'll, 'tcx>,
316+
indirect_dest: PlaceRef<'tcx, &'ll Value>,
317+
) {
306318
debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest);
307319
let flags = MemFlags::empty();
308320

@@ -336,7 +348,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
336348
fn maybe_codegen_consume_direct(&mut self,
337349
bx: &Builder<'a, 'll, 'tcx>,
338350
place: &mir::Place<'tcx>)
339-
-> Option<OperandRef<'ll, 'tcx>>
351+
-> Option<OperandRef<'tcx, &'ll Value>>
340352
{
341353
debug!("maybe_codegen_consume_direct(place={:?})", place);
342354

@@ -384,7 +396,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
384396
pub fn codegen_consume(&mut self,
385397
bx: &Builder<'a, 'll, 'tcx>,
386398
place: &mir::Place<'tcx>)
387-
-> OperandRef<'ll, 'tcx>
399+
-> OperandRef<'tcx, &'ll Value>
388400
{
389401
debug!("codegen_consume(place={:?})", place);
390402

@@ -408,7 +420,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
408420
pub fn codegen_operand(&mut self,
409421
bx: &Builder<'a, 'll, 'tcx>,
410422
operand: &mir::Operand<'tcx>)
411-
-> OperandRef<'ll, 'tcx>
423+
-> OperandRef<'tcx, &'ll Value>
412424
{
413425
debug!("codegen_operand(operand={:?})", operand);
414426

0 commit comments

Comments
 (0)