From ec7fdeb8ed188275894057f967fd6a49f1439c74 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 20 May 2021 20:38:50 -0700 Subject: [PATCH] Properly handle RReg-RReg moves in new scheme --- src/ion/mod.rs | 60 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/src/ion/mod.rs b/src/ion/mod.rs index 3fc4279..6b28a33 100644 --- a/src/ion/mod.rs +++ b/src/ion/mod.rs @@ -1127,12 +1127,59 @@ impl<'a, F: Function> Env<'a, F> { assert_eq!(dst.kind(), OperandKind::Def); assert_eq!(dst.pos(), OperandPos::After); + // If both src and dest are pinned, emit the + // move right here, right now. + if self.vregs[src.vreg().vreg()].is_pinned + && self.vregs[dst.vreg().vreg()].is_pinned + { + // Update LRs. + if !live.get(src.vreg().vreg()) { + let lr = self.add_liverange_to_vreg( + VRegIndex::new(src.vreg().vreg()), + CodeRange { + from: self.cfginfo.block_entry[block.index()], + to: ProgPoint::after(inst), + }, + ); + live.set(src.vreg().vreg(), true); + vreg_ranges[src.vreg().vreg()] = lr; + } + if live.get(dst.vreg().vreg()) { + let lr = vreg_ranges[dst.vreg().vreg()]; + self.ranges[lr.index()].range.from = ProgPoint::after(inst); + live.set(dst.vreg().vreg(), false); + } else { + self.add_liverange_to_vreg( + VRegIndex::new(dst.vreg().vreg()), + CodeRange { + from: ProgPoint::after(inst), + to: ProgPoint::before(inst.next()), + }, + ); + } + + let src_preg = match src.policy() { + OperandPolicy::FixedReg(r) => r, + _ => unreachable!(), + }; + let dst_preg = match dst.policy() { + OperandPolicy::FixedReg(r) => r, + _ => unreachable!(), + }; + self.insert_move( + ProgPoint::before(inst), + InsertMovePrio::MultiFixedReg, + Allocation::reg(src_preg), + Allocation::reg(dst_preg), + Some(dst.vreg()), + ); + } // If exactly one of source and dest (but not // both) is a pinned-vreg, convert this into a // ghost use on the other vreg with a FixedReg // policy. - if self.vregs[src.vreg().vreg()].is_pinned - ^ self.vregs[dst.vreg().vreg()].is_pinned + else if self.vregs[src.vreg().vreg()].is_pinned + || self.vregs[dst.vreg().vreg()].is_pinned { log::debug!( " -> exactly one of src/dst is pinned; converting to ghost use" @@ -1155,14 +1202,7 @@ impl<'a, F: Function> Env<'a, F> { src.vreg(), dst.vreg(), OperandKind::Use, - // Use comes late to avoid interfering with a potential - // prior move instruction - // reserving the preg, which - // creates a use or def *at* - // our Before pos (because - // progmoves happen between - // insts). - OperandPos::After, + OperandPos::Before, ProgPoint::after(inst), ) };