Skip to content

Commit cab35ff

Browse files
committed
trans: support uses of projections of immediate pairs.
1 parent f1f453c commit cab35ff

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/librustc_trans/mir/analyze.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ pub fn lvalue_temps<'bcx,'tcx>(bcx: Block<'bcx,'tcx>,
3939
// in an ValueRef without an alloca.
4040
assert!(common::type_is_immediate(bcx.ccx(), ty) ||
4141
common::type_is_fat_ptr(bcx.tcx(), ty));
42+
} else if common::type_is_imm_pair(bcx.ccx(), ty) {
43+
// We allow pairs and uses of any of their 2 fields.
4244
} else {
4345
// These sorts of types require an alloca. Note that
4446
// type_is_immediate() may *still* be true, particularly
@@ -111,6 +113,21 @@ impl<'mir, 'bcx, 'tcx> Visitor<'tcx> for TempAnalyzer<'mir, 'bcx, 'tcx> {
111113
context: LvalueContext) {
112114
debug!("visit_lvalue(lvalue={:?}, context={:?})", lvalue, context);
113115

116+
// Allow uses of projections of immediate pair fields.
117+
if let mir::Lvalue::Projection(ref proj) = *lvalue {
118+
if let mir::Lvalue::Temp(index) = proj.base {
119+
let ty = self.mir.temp_decls[index as usize].ty;
120+
let ty = self.bcx.monomorphize(&ty);
121+
if common::type_is_imm_pair(self.bcx.ccx(), ty) {
122+
if let mir::ProjectionElem::Field(..) = proj.elem {
123+
if let LvalueContext::Consume = context {
124+
return;
125+
}
126+
}
127+
}
128+
}
129+
}
130+
114131
match *lvalue {
115132
mir::Lvalue::Temp(index) => {
116133
match context {

src/librustc_trans/mir/operand.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
187187
}
188188
}
189189

190+
// Moves out of pair fields are trivial.
191+
if let &mir::Lvalue::Projection(ref proj) = lvalue {
192+
if let mir::Lvalue::Temp(index) = proj.base {
193+
let temp_ref = &self.temps[index as usize];
194+
if let &TempRef::Operand(Some(o)) = temp_ref {
195+
match (o.val, &proj.elem) {
196+
(OperandValue::Pair(a, b),
197+
&mir::ProjectionElem::Field(ref f, ty)) => {
198+
let llval = [a, b][f.index()];
199+
return OperandRef {
200+
val: OperandValue::Immediate(llval),
201+
ty: bcx.monomorphize(&ty)
202+
};
203+
}
204+
_ => {}
205+
}
206+
}
207+
}
208+
}
209+
190210
// for most lvalues, to consume them we just load them
191211
// out from their home
192212
let tr_lvalue = self.trans_lvalue(bcx, lvalue);

0 commit comments

Comments
 (0)