X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FCodeGen%2FRegisterScavenging.cpp;h=4176686d1f7f68464b64a36788d7e6e437bb9013;hb=f67f2c25fec8c195adcf0bdfe583e355dd32f0e1;hp=1757fc5d68dc5864a0306136404e3f106fedb9f8;hpb=84f7f350c3f8e33c2143ff44aa0a3fbbfd82657f;p=oota-llvm.git diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 1757fc5d68d..4176686d1f7 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -14,7 +14,6 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "reg-scavenging" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -25,33 +24,27 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; -/// setUsed - Set the register and its sub-registers as being used. -void RegScavenger::setUsed(unsigned Reg) { - for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true); - SubRegs.isValid(); ++SubRegs) - RegsAvailable.reset(*SubRegs); -} +#define DEBUG_TYPE "reg-scavenging" -bool RegScavenger::isAliasUsed(unsigned Reg) const { - for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) - if (isUsed(*AI, *AI == Reg)) - return true; - return false; +/// setUsed - Set the register units of this register as used. +void RegScavenger::setRegUsed(unsigned Reg) { + for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) + RegUnitsAvailable.reset(*RUI); } void RegScavenger::initRegState() { for (SmallVectorImpl::iterator I = Scavenged.begin(), IE = Scavenged.end(); I != IE; ++I) { I->Reg = 0; - I->Restore = NULL; + I->Restore = nullptr; } - // All registers started out unused. - RegsAvailable.set(); + // All register units start out unused. + RegUnitsAvailable.set(); if (!MBB) return; @@ -59,22 +52,22 @@ void RegScavenger::initRegState() { // Live-in registers are in use. for (MachineBasicBlock::livein_iterator I = MBB->livein_begin(), E = MBB->livein_end(); I != E; ++I) - setUsed(*I); + setRegUsed(*I); // Pristine CSRs are also unavailable. - BitVector PR = MBB->getParent()->getFrameInfo()->getPristineRegs(MBB); + const MachineFunction &MF = *MBB->getParent(); + BitVector PR = MF.getFrameInfo()->getPristineRegs(MF); for (int I = PR.find_first(); I>0; I = PR.find_next(I)) - setUsed(I); + setRegUsed(I); } void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { MachineFunction &MF = *mbb->getParent(); - const TargetMachine &TM = MF.getTarget(); - TII = TM.getInstrInfo(); - TRI = TM.getRegisterInfo(); + TII = MF.getSubtarget().getInstrInfo(); + TRI = MF.getSubtarget().getRegisterInfo(); MRI = &MF.getRegInfo(); - assert((NumPhysRegs == 0 || NumPhysRegs == TRI->getNumRegs()) && + assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) && "Target changed?"); // It is not possible to use the register scavenger after late optimization @@ -84,17 +77,11 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { // Self-initialize. if (!MBB) { - NumPhysRegs = TRI->getNumRegs(); - RegsAvailable.resize(NumPhysRegs); - KillRegs.resize(NumPhysRegs); - DefRegs.resize(NumPhysRegs); - - // Create callee-saved registers bitvector. - CalleeSavedRegs.resize(NumPhysRegs); - const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF); - if (CSRegs != NULL) - for (unsigned i = 0; CSRegs[i]; ++i) - CalleeSavedRegs.set(CSRegs[i]); + NumRegUnits = TRI->getNumRegUnits(); + RegUnitsAvailable.resize(NumRegUnits); + KillRegUnits.resize(NumRegUnits); + DefRegUnits.resize(NumRegUnits); + TmpRegUnits.resize(NumRegUnits); } MBB = mbb; @@ -103,10 +90,9 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { Tracking = false; } -void RegScavenger::addRegWithSubRegs(BitVector &BV, unsigned Reg) { - for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true); - SubRegs.isValid(); ++SubRegs) - BV.set(*SubRegs); +void RegScavenger::addRegUnits(BitVector &BV, unsigned Reg) { + for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) + BV.set(*RUI); } void RegScavenger::determineKillsAndDefs() { @@ -117,16 +103,25 @@ void RegScavenger::determineKillsAndDefs() { // Find out which registers are early clobbered, killed, defined, and marked // def-dead in this instruction. - // FIXME: The scavenger is not predication aware. If the instruction is - // predicated, conservatively assume "kill" markers do not actually kill the - // register. Similarly ignores "dead" markers. - bool isPred = TII->isPredicated(MI); - KillRegs.reset(); - DefRegs.reset(); + KillRegUnits.reset(); + DefRegUnits.reset(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (MO.isRegMask()) - (isPred ? DefRegs : KillRegs).setBitsNotInMask(MO.getRegMask()); + if (MO.isRegMask()) { + + TmpRegUnits.clear(); + for (unsigned RU = 0, RUEnd = TRI->getNumRegUnits(); RU != RUEnd; ++RU) { + for (MCRegUnitRootIterator RURI(RU, TRI); RURI.isValid(); ++RURI) { + if (MO.clobbersPhysReg(*RURI)) { + TmpRegUnits.set(RU); + break; + } + } + } + + // Apply the mask. + KillRegUnits |= TmpRegUnits; + } if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); @@ -137,14 +132,14 @@ void RegScavenger::determineKillsAndDefs() { // Ignore undef uses. if (MO.isUndef()) continue; - if (!isPred && MO.isKill()) - addRegWithSubRegs(KillRegs, Reg); + if (MO.isKill()) + addRegUnits(KillRegUnits, Reg); } else { assert(MO.isDef()); - if (!isPred && MO.isDead()) - addRegWithSubRegs(KillRegs, Reg); + if (MO.isDead()) + addRegUnits(KillRegUnits, Reg); else - addRegWithSubRegs(DefRegs, Reg); + addRegUnits(DefRegUnits, Reg); } } } @@ -157,12 +152,12 @@ void RegScavenger::unprocess() { determineKillsAndDefs(); // Commit the changes. - setUsed(KillRegs); - setUnused(DefRegs); + setUsed(KillRegUnits); + setUnused(DefRegUnits); } if (MBBI == MBB->begin()) { - MBBI = MachineBasicBlock::iterator(NULL); + MBBI = MachineBasicBlock::iterator(nullptr); Tracking = false; } else --MBBI; @@ -187,7 +182,7 @@ void RegScavenger::forward() { continue; I->Reg = 0; - I->Restore = NULL; + I->Restore = nullptr; } if (MI->isDebugValue()) @@ -207,7 +202,7 @@ void RegScavenger::forward() { if (MO.isUse()) { if (MO.isUndef()) continue; - if (!isUsed(Reg)) { + if (!isRegUsed(Reg)) { // Check if it's partial live: e.g. // D0 = insert_subreg D0, S0 // ... D0 @@ -218,15 +213,23 @@ void RegScavenger::forward() { // insert_subreg around causes both correctness and performance issues. bool SubUsed = false; for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) - if (isUsed(*SubRegs)) { + if (isRegUsed(*SubRegs)) { SubUsed = true; break; } - if (!SubUsed) { - MBB->getParent()->verify(NULL, "In Register Scavenger"); + bool SuperUsed = false; + for (MCSuperRegIterator SR(Reg, TRI); SR.isValid(); ++SR) { + if (isRegUsed(*SR)) { + SuperUsed = true; + break; + } + } + if (!SubUsed && !SuperUsed) { + MBB->getParent()->verify(nullptr, "In Register Scavenger"); llvm_unreachable("Using an undefined register!"); } (void)SubUsed; + (void)SuperUsed; } } else { assert(MO.isDef()); @@ -242,23 +245,23 @@ void RegScavenger::forward() { #endif // NDEBUG // Commit the changes. - setUnused(KillRegs); - setUsed(DefRegs); + setUnused(KillRegUnits); + setUsed(DefRegUnits); } -void RegScavenger::getRegsUsed(BitVector &used, bool includeReserved) { - used = RegsAvailable; - used.flip(); - if (includeReserved) - used |= MRI->getReservedRegs(); - else - used.reset(MRI->getReservedRegs()); +bool RegScavenger::isRegUsed(unsigned Reg, bool includeReserved) const { + if (includeReserved && isReserved(Reg)) + return true; + for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) + if (!RegUnitsAvailable.test(*RUI)) + return true; + return false; } unsigned RegScavenger::FindUnusedReg(const TargetRegisterClass *RC) const { for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); I != E; ++I) - if (!isAliasUsed(*I)) { + if (!isRegUsed(*I)) { DEBUG(dbgs() << "Scavenger found unused reg: " << TRI->getName(*I) << "\n"); return *I; @@ -272,13 +275,13 @@ BitVector RegScavenger::getRegsAvailable(const TargetRegisterClass *RC) { BitVector Mask(TRI->getNumRegs()); for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); I != E; ++I) - if (!isAliasUsed(*I)) + if (!isRegUsed(*I)) Mask.set(*I); return Mask; } /// findSurvivorReg - Return the candidate register that is unused for the -/// longest after StargMII. UseMI is set to the instruction where the search +/// longest after StartMII. UseMI is set to the instruction where the search /// stopped. /// /// No more than InstrLimit instructions are inspected. @@ -374,9 +377,7 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, } // Try to find a register that's unused if there is one, as then we won't - // have to spill. Search explicitly rather than masking out based on - // RegsAvailable, as RegsAvailable does not take aliases into account. - // That's what getRegsAvailable() is for. + // have to spill. BitVector Available = getRegsAvailable(RC); Available &= Candidates; if (Available.any()) @@ -387,7 +388,7 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, unsigned SReg = findSurvivorReg(I, Candidates, 25, UseMI); // If we found an unused register there is no reason to spill it. - if (!isAliasUsed(SReg)) { + if (!isRegUsed(SReg)) { DEBUG(dbgs() << "Scavenged register: " << TRI->getName(SReg) << "\n"); return SReg; }