X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FRegisterScavenging.cpp;h=e1c8f2fe22eeb44a200976ac5492c573b1326a0e;hb=2caf1b212e2db36c52f3a7c3e391ea2800802c60;hp=58f4284ac75503f4b44252b174d6080cc4d9d520;hpb=2578ba26e72e36dde64be0f52a2788480aad3378;p=oota-llvm.git diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 58f4284ac75..e1c8f2fe22e 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -56,29 +57,31 @@ static bool RedefinesSuperRegPart(const MachineInstr *MI, return RedefinesSuperRegPart(MI, MO.getReg(), TRI); } +bool RegScavenger::isSuperRegUsed(unsigned Reg) const { + for (const unsigned *SuperRegs = TRI->getSuperRegisters(Reg); + unsigned SuperReg = *SuperRegs; ++SuperRegs) + if (isUsed(SuperReg)) + return true; + return false; +} + /// setUsed - Set the register and its sub-registers as being used. -void RegScavenger::setUsed(unsigned Reg, bool ImpDef) { +void RegScavenger::setUsed(unsigned Reg) { RegsAvailable.reset(Reg); - ImplicitDefed[Reg] = ImpDef; for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); - unsigned SubReg = *SubRegs; ++SubRegs) { + unsigned SubReg = *SubRegs; ++SubRegs) RegsAvailable.reset(SubReg); - ImplicitDefed[SubReg] = ImpDef; - } } /// setUnused - Set the register and its sub-registers as being unused. void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) { RegsAvailable.set(Reg); - ImplicitDefed.reset(Reg); for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) - if (!RedefinesSuperRegPart(MI, Reg, TRI)) { + if (!RedefinesSuperRegPart(MI, Reg, TRI)) RegsAvailable.set(SubReg); - ImplicitDefed.reset(SubReg); - } } void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { @@ -94,7 +97,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { if (!MBB) { NumPhysRegs = TRI->getNumRegs(); RegsAvailable.resize(NumPhysRegs); - ImplicitDefed.resize(NumPhysRegs); // Create reserved registers bitvector. ReservedRegs = TRI->getReservedRegs(MF); @@ -113,7 +115,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { ScavengeRestore = NULL; CurrDist = 0; DistanceMap.clear(); - ImplicitDefed.reset(); // All registers started out unused. RegsAvailable.set(); @@ -162,6 +163,9 @@ static bool isLiveInButUnusedBefore(unsigned Reg, MachineInstr *MI, SmallPtrSet UsesInMBB; for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg), UE = MRI->use_end(); UI != UE; ++UI) { + MachineOperand &UseMO = UI.getOperand(); + if (UseMO.isReg() && UseMO.isUndef()) + continue; MachineInstr *UseMI = &*UI; if (UseMI->getParent() == MBB) UsesInMBB.insert(UseMI); @@ -195,7 +199,10 @@ void RegScavenger::forward() { ScavengeRestore = NULL; } - bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF; +#if 0 + if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) + return; +#endif // Separate register operands into 3 classes: uses, defs, earlyclobbers. SmallVector, 4> UseMOs; @@ -219,16 +226,9 @@ void RegScavenger::forward() { const MachineOperand MO = *UseMOs[i].first; unsigned Reg = MO.getReg(); - assert(isUsed(Reg) && "Using an undefined register!"); + assert((MO.isImplicit() || isUsed(Reg)) && "Using an undefined register!"); - // Kill of implicit_def defined registers are ignored. e.g. - // entry: 0x2029ab8, LLVM BB @0x1b06080, ID#0: - // Live Ins: %R0 - // %R0 = IMPLICIT_DEF - // %R0 = IMPLICIT_DEF - // STR %R0, %R0, %reg0, 0, 14, %reg0, Mem:ST(4,4) [0x1b06510 + 0] - // %R1 = LDR %R0, %reg0, 24, 14, %reg0, Mem:LD(4,4) [0x1b065bc + 0] - if (MO.isKill() && !isReserved(Reg) && !isImplicitlyDefined(Reg)) { + if (MO.isKill() && !isReserved(Reg)) { KillRegs.set(Reg); // Mark sub-registers as used. @@ -277,11 +277,11 @@ void RegScavenger::forward() { // Implicit def is allowed to "re-define" any register. Similarly, // implicitly defined registers can be clobbered. - assert((isReserved(Reg) || isUnused(Reg) || - IsImpDef || isImplicitlyDefined(Reg) || + assert((MO.isImplicit() || isReserved(Reg) || isUnused(Reg) || + isSuperRegUsed(Reg) || isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) && "Re-defining a live register!"); - setUsed(Reg, IsImpDef); + setUsed(Reg); } } @@ -438,7 +438,7 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, // Mask off the registers which are not in the TargetRegisterClass. BitVector Candidates(NumPhysRegs, false); CreateRegClassMask(RC, Candidates); - Candidates ^= ReservedRegs; // Do not include reserved registers. + Candidates ^= ReservedRegs & Candidates; // Do not include reserved registers. // Exclude all the registers being used by the instruction. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { @@ -471,9 +471,14 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, Reg = Candidates.find_next(Reg); } - if (ScavengedReg != 0) { - assert(0 && "Scavenger slot is live, unable to scavenge another register!"); - abort(); + assert(ScavengedReg == 0 && + "Scavenger slot is live, unable to scavenge another register!"); + + // Make sure SReg is marked as used. It could be considered available if it is + // one of the callee saved registers, but hasn't been spilled. + if (!isUsed(SReg)) { + MBB->addLiveIn(SReg); + setUsed(SReg); } // Spill the scavenged register before I.