From 8efadf94b568c08de3ff8ce35fd904a935387406 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 6 Jan 2010 00:29:28 +0000 Subject: [PATCH] Add and operands when replacing virtual sub-register defs and kills. An instruction like this: %reg1097:1 = VMOVSR %R3, 14, %reg0 Must be replaced with this when substituting physical registers: %S0 = VMOVSR %R3, 14, %reg0, %D0 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92812 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineInstr.h | 7 +++- lib/CodeGen/MachineInstr.cpp | 9 +++++ lib/CodeGen/VirtRegRewriter.cpp | 54 ++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 87b67d6242d..c2a057822ff 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -288,7 +288,7 @@ public: bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound = false); - + /// addRegisterDead - We have determined MI defined a register without a use. /// Look for the operand that defines it and mark it as IsDead. If /// AddIfNotFound is true, add a implicit operand if it's not found. Returns @@ -296,6 +296,11 @@ public: bool addRegisterDead(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound = false); + /// addRegisterDefined - We have determined MI defines a register. Make sure + /// there is an operand defining Reg. + void addRegisterDefined(unsigned IncomingReg, + const TargetRegisterInfo *RegInfo); + /// isSafeToMove - Return true if it is safe to move this instruction. If /// SawStore is set to true, it means that there is a store (or call) between /// the instruction's location and its intended destination. diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 358ea3fd71a..f9c20e64730 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -1314,3 +1314,12 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg, true /*IsDead*/)); return true; } + +void MachineInstr::addRegisterDefined(unsigned IncomingReg, + const TargetRegisterInfo *RegInfo) { + MachineOperand *MO = findRegisterDefOperand(IncomingReg, false, RegInfo); + if (!MO || MO->getSubReg()) + addOperand(MachineOperand::CreateReg(IncomingReg, + true /*IsDef*/, + true /*IsImp*/)); +} diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index 81dd1c89f15..df2b8d28c93 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -60,6 +60,33 @@ ScheduleSpills("schedule-spills", VirtRegRewriter::~VirtRegRewriter() {} +/// substitutePhysReg - Replace virtual register in MachineOperand with a +/// physical register. Do the right thing with the sub-register index. +static void substitutePhysReg(MachineOperand &MO, unsigned Reg, + const TargetRegisterInfo &TRI) { + if (unsigned SubIdx = MO.getSubReg()) { + // Insert the physical subreg and reset the subreg field. + MO.setReg(TRI.getSubReg(Reg, SubIdx)); + MO.setSubReg(0); + + // Any def, dead, and kill flags apply to the full virtual register, so they + // also apply to the full physical register. Add imp-def/dead and imp-kill + // as needed. + MachineInstr &MI = *MO.getParent(); + if (MO.isDef()) + if (MO.isDead()) + MI.addRegisterDead(Reg, &TRI, /*AddIfNotFound=*/ true); + else + MI.addRegisterDefined(Reg, &TRI); + else if (!MO.isUndef() && + (MO.isKill() || + MI.isRegTiedToDefOperand(&MO-&MI.getOperand(0)))) + MI.addRegisterKilled(Reg, &TRI, /*AddIfNotFound=*/ true); + } else { + MO.setReg(Reg); + } +} + namespace { /// This class is intended for use with the new spilling framework only. It @@ -101,10 +128,7 @@ struct TrivialRewriter : public VirtRegRewriter { MachineOperand &mop = regItr.getOperand(); assert(mop.isReg() && mop.getReg() == reg && "reg_iterator broken?"); ++regItr; - unsigned subRegIdx = mop.getSubReg(); - unsigned pRegOp = subRegIdx ? tri->getSubReg(pReg, subRegIdx) : pReg; - mop.setReg(pRegOp); - mop.setSubReg(0); + substitutePhysReg(mop, pReg, *tri); changed = true; } } @@ -647,12 +671,9 @@ static void ReMaterialize(MachineBasicBlock &MBB, if (TargetRegisterInfo::isPhysicalRegister(VirtReg)) continue; assert(MO.isUse()); - unsigned SubIdx = MO.getSubReg(); unsigned Phys = VRM.getPhys(VirtReg); assert(Phys && "Virtual register is not assigned a register?"); - unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys; - MO.setReg(RReg); - MO.setSubReg(0); + substitutePhysReg(MO, Phys, *TRI); } ++NumReMats; } @@ -1004,11 +1025,12 @@ static unsigned FindFreeRegister(MachineBasicBlock::iterator MII, } static -void AssignPhysToVirtReg(MachineInstr *MI, unsigned VirtReg, unsigned PhysReg) { +void AssignPhysToVirtReg(MachineInstr *MI, unsigned VirtReg, unsigned PhysReg, + const TargetRegisterInfo &TRI) { for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); if (MO.isReg() && MO.getReg() == VirtReg) - MO.setReg(PhysReg); + substitutePhysReg(MO, PhysReg, TRI); } } @@ -1175,7 +1197,7 @@ private: if (!TII->unfoldMemoryOperand(MF, &MI, VirtReg, false, false, NewMIs)) llvm_unreachable("Unable unfold the load / store folding instruction!"); assert(NewMIs.size() == 1); - AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg); + AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg, *TRI); VRM.transferRestorePts(&MI, NewMIs[0]); MII = MBB.insert(MII, NewMIs[0]); InvalidateKills(MI, TRI, RegKills, KillOps); @@ -1191,7 +1213,7 @@ private: if (!TII->unfoldMemoryOperand(MF, &NextMI, VirtReg, false, false, NewMIs)) llvm_unreachable("Unable unfold the load / store folding instruction!"); assert(NewMIs.size() == 1); - AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg); + AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg, *TRI); VRM.transferRestorePts(&NextMI, NewMIs[0]); MBB.insert(NextMII, NewMIs[0]); InvalidateKills(NextMI, TRI, RegKills, KillOps); @@ -1840,16 +1862,14 @@ private: RegInfo->setPhysRegUsed(Phys); if (MO.isDef()) ReusedOperands.markClobbered(Phys); - unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys; - MI.getOperand(i).setReg(RReg); - MI.getOperand(i).setSubReg(0); + substitutePhysReg(MO, Phys, *TRI); if (VRM.isImplicitlyDefined(VirtReg)) // FIXME: Is this needed? BuildMI(MBB, &MI, MI.getDebugLoc(), - TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg); + TII->get(TargetInstrInfo::IMPLICIT_DEF), Phys); continue; } - + // This virtual register is now known to be a spilled value. if (!MO.isUse()) continue; // Handle defs in the loop below (handle use&def here though)