trans: support uses of projections of immediate pairs.

This commit is contained in:
Eduard Burtescu 2016-05-25 11:58:08 +03:00
parent f1f453cf3b
commit cab35ff4b8
2 changed files with 37 additions and 0 deletions

View File

@ -39,6 +39,8 @@ pub fn lvalue_temps<'bcx,'tcx>(bcx: Block<'bcx,'tcx>,
// in an ValueRef without an alloca.
assert!(common::type_is_immediate(bcx.ccx(), ty) ||
common::type_is_fat_ptr(bcx.tcx(), ty));
} else if common::type_is_imm_pair(bcx.ccx(), ty) {
// We allow pairs and uses of any of their 2 fields.
} else {
// These sorts of types require an alloca. Note that
// type_is_immediate() may *still* be true, particularly
@ -111,6 +113,21 @@ impl<'mir, 'bcx, 'tcx> Visitor<'tcx> for TempAnalyzer<'mir, 'bcx, 'tcx> {
context: LvalueContext) {
debug!("visit_lvalue(lvalue={:?}, context={:?})", lvalue, context);
// Allow uses of projections of immediate pair fields.
if let mir::Lvalue::Projection(ref proj) = *lvalue {
if let mir::Lvalue::Temp(index) = proj.base {
let ty = self.mir.temp_decls[index as usize].ty;
let ty = self.bcx.monomorphize(&ty);
if common::type_is_imm_pair(self.bcx.ccx(), ty) {
if let mir::ProjectionElem::Field(..) = proj.elem {
if let LvalueContext::Consume = context {
return;
}
}
}
}
}
match *lvalue {
mir::Lvalue::Temp(index) => {
match context {

View File

@ -187,6 +187,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
}
}
// Moves out of pair fields are trivial.
if let &mir::Lvalue::Projection(ref proj) = lvalue {
if let mir::Lvalue::Temp(index) = proj.base {
let temp_ref = &self.temps[index as usize];
if let &TempRef::Operand(Some(o)) = temp_ref {
match (o.val, &proj.elem) {
(OperandValue::Pair(a, b),
&mir::ProjectionElem::Field(ref f, ty)) => {
let llval = [a, b][f.index()];
return OperandRef {
val: OperandValue::Immediate(llval),
ty: bcx.monomorphize(&ty)
};
}
_ => {}
}
}
}
}
// for most lvalues, to consume them we just load them
// out from their home
let tr_lvalue = self.trans_lvalue(bcx, lvalue);