diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/NEONMoveFix.cpp | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/lib/Target/ARM/NEONMoveFix.cpp b/lib/Target/ARM/NEONMoveFix.cpp index c85d1e9..bd8c882 100644 --- a/lib/Target/ARM/NEONMoveFix.cpp +++ b/lib/Target/ARM/NEONMoveFix.cpp @@ -40,6 +40,8 @@ namespace { typedef DenseMap<unsigned, const MachineInstr*> RegMap; bool InsertMoves(MachineBasicBlock &MBB); + + void TransferImpOps(MachineInstr &Old, MachineInstr &New); }; char NEONMoveFixPass::ID = 0; } @@ -49,6 +51,16 @@ static bool inNEONDomain(unsigned Domain, bool isA8) { (isA8 && (Domain & ARMII::DomainNEONA8)); } +/// Transfer implicit kill and def operands from Old to New. +void NEONMoveFixPass::TransferImpOps(MachineInstr &Old, MachineInstr &New) { + for (unsigned i = 0, e = Old.getNumOperands(); i != e; ++i) { + MachineOperand &MO = Old.getOperand(i); + if (!MO.isReg() || !MO.isImplicit()) + continue; + New.addOperand(MO); + } +} + bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) { RegMap Defs; bool Modified = false; @@ -82,17 +94,15 @@ bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) { DEBUG({errs() << "vmov convert: "; MI->dump();}); - // It's safe to ignore imp-defs / imp-uses here, since: - // - We're running late, no intelligent condegen passes should be run - // afterwards - // - The imp-defs / imp-uses are superregs only, we don't care about - // them. - AddDefaultPred(BuildMI(MBB, *MI, MI->getDebugLoc(), - TII->get(ARM::VORRd), DestReg) - .addReg(SrcReg).addReg(SrcReg)); + // We need to preserve imp-defs / imp-uses here. Following passes may + // use the register scavenger to update liveness. + MachineInstr *NewMI = + AddDefaultPred(BuildMI(MBB, *MI, MI->getDebugLoc(), + TII->get(ARM::VORRd), DestReg) + .addReg(SrcReg).addReg(SrcReg)); + TransferImpOps(*MI, *NewMI); MBB.erase(MI); - MachineBasicBlock::iterator I = prior(NextMII); - MI = &*I; + MI = NewMI; DEBUG({errs() << " into: "; MI->dump();}); |