diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/RegAllocFast.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/RegAllocFast.cpp | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/contrib/llvm/lib/CodeGen/RegAllocFast.cpp b/contrib/llvm/lib/CodeGen/RegAllocFast.cpp index 8d7a721..55fb33e 100644 --- a/contrib/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/contrib/llvm/lib/CodeGen/RegAllocFast.cpp @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/Passes.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/STLExtras.h" @@ -25,13 +24,12 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/RegisterClassInfo.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/Support/CommandLine.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" #include <algorithm> @@ -52,6 +50,7 @@ namespace { static char ID; RAFast() : MachineFunctionPass(ID), StackSlotForVirtReg(-1), isBulkSpilling(false) {} + private: MachineFunction *MF; MachineRegisterInfo *MRI; @@ -159,6 +158,11 @@ namespace { MachineFunctionPass::getAnalysisUsage(AU); } + MachineFunctionProperties getSetProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::AllVRegsAllocated); + } + private: bool runOnMachineFunction(MachineFunction &Fn) override; void AllocateBasicBlock(); @@ -174,7 +178,7 @@ namespace { void spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg); void usePhysReg(MachineOperand&); - void definePhysReg(MachineInstr *MI, unsigned PhysReg, RegState NewState); + void definePhysReg(MachineInstr &MI, unsigned PhysReg, RegState NewState); unsigned calcSpillCost(unsigned PhysReg) const; void assignVirtToPhysReg(LiveReg&, unsigned PhysReg); LiveRegMap::iterator findLiveVirtReg(unsigned VirtReg) { @@ -184,11 +188,11 @@ namespace { return LiveVirtRegs.find(TargetRegisterInfo::virtReg2Index(VirtReg)); } LiveRegMap::iterator assignVirtToPhysReg(unsigned VReg, unsigned PhysReg); - LiveRegMap::iterator allocVirtReg(MachineInstr *MI, LiveRegMap::iterator, + LiveRegMap::iterator allocVirtReg(MachineInstr &MI, LiveRegMap::iterator, unsigned Hint); - LiveRegMap::iterator defineVirtReg(MachineInstr *MI, unsigned OpNum, + LiveRegMap::iterator defineVirtReg(MachineInstr &MI, unsigned OpNum, unsigned VirtReg, unsigned Hint); - LiveRegMap::iterator reloadVirtReg(MachineInstr *MI, unsigned OpNum, + LiveRegMap::iterator reloadVirtReg(MachineInstr &MI, unsigned OpNum, unsigned VirtReg, unsigned Hint); void spillAll(MachineBasicBlock::iterator MI); bool setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg); @@ -280,7 +284,7 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, if (LR.Dirty) { // If this physreg is used by the instruction, we want to kill it on the // instruction, not on the spill. - bool SpillKill = LR.LastUse != MI; + bool SpillKill = MachineBasicBlock::iterator(LR.LastUse) != MI; LR.Dirty = false; DEBUG(dbgs() << "Spilling " << PrintReg(LRI->VirtReg, TRI) << " in " << PrintReg(LR.PhysReg, TRI)); @@ -345,6 +349,11 @@ void RAFast::usePhysReg(MachineOperand &MO) { unsigned PhysReg = MO.getReg(); assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && "Bad usePhysReg operand"); + + // Ignore undef uses. + if (MO.isUndef()) + return; + markRegUsedInInstr(PhysReg); switch (PhysRegState[PhysReg]) { case regDisabled: @@ -404,7 +413,7 @@ void RAFast::usePhysReg(MachineOperand &MO) { /// definePhysReg - Mark PhysReg as reserved or free after spilling any /// virtregs. This is very similar to defineVirtReg except the physreg is /// reserved instead of allocated. -void RAFast::definePhysReg(MachineInstr *MI, unsigned PhysReg, +void RAFast::definePhysReg(MachineInstr &MI, unsigned PhysReg, RegState NewState) { markRegUsedInInstr(PhysReg); switch (unsigned VirtReg = PhysRegState[PhysReg]) { @@ -512,7 +521,7 @@ RAFast::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) { } /// allocVirtReg - Allocate a physical register for VirtReg. -RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr *MI, +RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr &MI, LiveRegMap::iterator LRI, unsigned Hint) { const unsigned VirtReg = LRI->VirtReg; @@ -577,18 +586,19 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr *MI, } // Nothing we can do. Report an error and keep going with a bad allocation. - if (MI->isInlineAsm()) - MI->emitError("inline assembly requires more registers than available"); + if (MI.isInlineAsm()) + MI.emitError("inline assembly requires more registers than available"); else - MI->emitError("ran out of registers during register allocation"); + MI.emitError("ran out of registers during register allocation"); definePhysReg(MI, *AO.begin(), regFree); return assignVirtToPhysReg(VirtReg, *AO.begin()); } /// defineVirtReg - Allocate a register for VirtReg and mark it as dirty. -RAFast::LiveRegMap::iterator -RAFast::defineVirtReg(MachineInstr *MI, unsigned OpNum, - unsigned VirtReg, unsigned Hint) { +RAFast::LiveRegMap::iterator RAFast::defineVirtReg(MachineInstr &MI, + unsigned OpNum, + unsigned VirtReg, + unsigned Hint) { assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual register"); LiveRegMap::iterator LRI; @@ -607,11 +617,11 @@ RAFast::defineVirtReg(MachineInstr *MI, unsigned OpNum, } else if (LRI->LastUse) { // Redefining a live register - kill at the last use, unless it is this // instruction defining VirtReg multiple times. - if (LRI->LastUse != MI || LRI->LastUse->getOperand(LRI->LastOpNum).isUse()) + if (LRI->LastUse != &MI || LRI->LastUse->getOperand(LRI->LastOpNum).isUse()) addKillFlag(*LRI); } assert(LRI->PhysReg && "Register not assigned"); - LRI->LastUse = MI; + LRI->LastUse = &MI; LRI->LastOpNum = OpNum; LRI->Dirty = true; markRegUsedInInstr(LRI->PhysReg); @@ -619,15 +629,16 @@ RAFast::defineVirtReg(MachineInstr *MI, unsigned OpNum, } /// reloadVirtReg - Make sure VirtReg is available in a physreg and return it. -RAFast::LiveRegMap::iterator -RAFast::reloadVirtReg(MachineInstr *MI, unsigned OpNum, - unsigned VirtReg, unsigned Hint) { +RAFast::LiveRegMap::iterator RAFast::reloadVirtReg(MachineInstr &MI, + unsigned OpNum, + unsigned VirtReg, + unsigned Hint) { assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual register"); LiveRegMap::iterator LRI; bool New; std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg)); - MachineOperand &MO = MI->getOperand(OpNum); + MachineOperand &MO = MI.getOperand(OpNum); if (New) { LRI = allocVirtReg(MI, LRI, Hint); const TargetRegisterClass *RC = MRI->getRegClass(VirtReg); @@ -662,7 +673,7 @@ RAFast::reloadVirtReg(MachineInstr *MI, unsigned OpNum, MO.setIsDead(false); } assert(LRI->PhysReg && "Register not assigned"); - LRI->LastUse = MI; + LRI->LastUse = &MI; LRI->LastOpNum = OpNum; markRegUsedInInstr(LRI->PhysReg); return LRI; @@ -728,7 +739,7 @@ void RAFast::handleThroughOperands(MachineInstr *MI, markRegUsedInInstr(Reg); for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { if (ThroughRegs.count(PhysRegState[*AI])) - definePhysReg(MI, *AI, regFree); + definePhysReg(*MI, *AI, regFree); } } @@ -744,7 +755,7 @@ void RAFast::handleThroughOperands(MachineInstr *MI, if (!MI->isRegTiedToDefOperand(i, &DefIdx)) continue; DEBUG(dbgs() << "Operand " << i << "("<< MO << ") is tied to operand " << DefIdx << ".\n"); - LiveRegMap::iterator LRI = reloadVirtReg(MI, i, Reg, 0); + LiveRegMap::iterator LRI = reloadVirtReg(*MI, i, Reg, 0); unsigned PhysReg = LRI->PhysReg; setPhysReg(MI, i, PhysReg); // Note: we don't update the def operand yet. That would cause the normal @@ -753,7 +764,7 @@ void RAFast::handleThroughOperands(MachineInstr *MI, DEBUG(dbgs() << "Partial redefine: " << MO << "\n"); // Reload the register, but don't assign to the operand just yet. // That would confuse the later phys-def processing pass. - LiveRegMap::iterator LRI = reloadVirtReg(MI, i, Reg, 0); + LiveRegMap::iterator LRI = reloadVirtReg(*MI, i, Reg, 0); PartialDefs.push_back(LRI->PhysReg); } } @@ -767,7 +778,7 @@ void RAFast::handleThroughOperands(MachineInstr *MI, if (!MO.isEarlyClobber()) continue; // Note: defineVirtReg may invalidate MO. - LiveRegMap::iterator LRI = defineVirtReg(MI, i, Reg, 0); + LiveRegMap::iterator LRI = defineVirtReg(*MI, i, Reg, 0); unsigned PhysReg = LRI->PhysReg; if (setPhysReg(MI, i, PhysReg)) VirtDead.push_back(Reg); @@ -801,14 +812,14 @@ void RAFast::AllocateBasicBlock() { // Add live-in registers as live. for (const auto &LI : MBB->liveins()) if (MRI->isAllocatable(LI.PhysReg)) - definePhysReg(MII, LI.PhysReg, regReserved); + definePhysReg(*MII, LI.PhysReg, regReserved); SmallVector<unsigned, 8> VirtDead; SmallVector<MachineInstr*, 32> Coalesced; // Otherwise, sequentially allocate each instruction in the MBB. while (MII != MBB->end()) { - MachineInstr *MI = MII++; + MachineInstr *MI = &*MII++; const MCInstrDesc &MCID = MI->getDesc(); DEBUG({ dbgs() << "\n>> " << *MI << "Regs:"; @@ -943,8 +954,8 @@ void RAFast::AllocateBasicBlock() { if (MO.isUse()) { usePhysReg(MO); } else if (MO.isEarlyClobber()) { - definePhysReg(MI, Reg, (MO.isImplicit() || MO.isDead()) ? - regFree : regReserved); + definePhysReg(*MI, Reg, + (MO.isImplicit() || MO.isDead()) ? regFree : regReserved); hasEarlyClobbers = true; } else hasPhysDefs = true; @@ -977,7 +988,7 @@ void RAFast::AllocateBasicBlock() { unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; if (MO.isUse()) { - LiveRegMap::iterator LRI = reloadVirtReg(MI, i, Reg, CopyDst); + LiveRegMap::iterator LRI = reloadVirtReg(*MI, i, Reg, CopyDst); unsigned PhysReg = LRI->PhysReg; CopySrc = (CopySrc == Reg || CopySrc == PhysReg) ? PhysReg : 0; if (setPhysReg(MI, i, PhysReg)) @@ -1027,10 +1038,10 @@ void RAFast::AllocateBasicBlock() { if (TargetRegisterInfo::isPhysicalRegister(Reg)) { if (!MRI->isAllocatable(Reg)) continue; - definePhysReg(MI, Reg, MO.isDead() ? regFree : regReserved); + definePhysReg(*MI, Reg, MO.isDead() ? regFree : regReserved); continue; } - LiveRegMap::iterator LRI = defineVirtReg(MI, i, Reg, CopySrc); + LiveRegMap::iterator LRI = defineVirtReg(*MI, i, Reg, CopySrc); unsigned PhysReg = LRI->PhysReg; if (setPhysReg(MI, i, PhysReg)) { VirtDead.push_back(Reg); |