diff options
Diffstat (limited to 'llvm/lib/CodeGen/VirtRegMap.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/VirtRegMap.cpp | 98 |
1 files changed, 80 insertions, 18 deletions
diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp index 5e0ff9d9092c..0f164e2637a2 100644 --- a/llvm/lib/CodeGen/VirtRegMap.cpp +++ b/llvm/lib/CodeGen/VirtRegMap.cpp @@ -30,6 +30,7 @@ #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SlotIndexes.h" +#include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/TargetRegisterInfo.h" @@ -94,12 +95,18 @@ void VirtRegMap::assignVirt2Phys(Register virtReg, MCPhysReg physReg) { unsigned VirtRegMap::createSpillSlot(const TargetRegisterClass *RC) { unsigned Size = TRI->getSpillSize(*RC); Align Alignment = TRI->getSpillAlign(*RC); + // Set preferred alignment if we are still able to realign the stack + auto &ST = MF->getSubtarget(); + Align CurrentAlign = ST.getFrameLowering()->getStackAlign(); + if (Alignment > CurrentAlign && !ST.getRegisterInfo()->canRealignStack(*MF)) { + Alignment = CurrentAlign; + } int SS = MF->getFrameInfo().CreateSpillStackObject(Size, Alignment); ++NumSpillSlots; return SS; } -bool VirtRegMap::hasPreferredPhys(Register VirtReg) { +bool VirtRegMap::hasPreferredPhys(Register VirtReg) const { Register Hint = MRI->getSimpleHint(VirtReg); if (!Hint.isValid()) return false; @@ -108,7 +115,7 @@ bool VirtRegMap::hasPreferredPhys(Register VirtReg) { return Register(getPhys(VirtReg)) == Hint; } -bool VirtRegMap::hasKnownPreference(Register VirtReg) { +bool VirtRegMap::hasKnownPreference(Register VirtReg) const { std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(VirtReg); if (Register::isPhysicalRegister(Hint.second)) return true; @@ -181,27 +188,35 @@ class VirtRegRewriter : public MachineFunctionPass { SlotIndexes *Indexes; LiveIntervals *LIS; VirtRegMap *VRM; + LiveDebugVariables *DebugVars; + DenseSet<Register> RewriteRegs; + bool ClearVirtRegs; void rewrite(); void addMBBLiveIns(); bool readsUndefSubreg(const MachineOperand &MO) const; - void addLiveInsForSubRanges(const LiveInterval &LI, Register PhysReg) const; - void handleIdentityCopy(MachineInstr &MI) const; + void addLiveInsForSubRanges(const LiveInterval &LI, MCRegister PhysReg) const; + void handleIdentityCopy(MachineInstr &MI); void expandCopyBundle(MachineInstr &MI) const; bool subRegLiveThrough(const MachineInstr &MI, MCRegister SuperPhysReg) const; public: static char ID; - - VirtRegRewriter() : MachineFunctionPass(ID) {} + VirtRegRewriter(bool ClearVirtRegs_ = true) : + MachineFunctionPass(ID), + ClearVirtRegs(ClearVirtRegs_) {} void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnMachineFunction(MachineFunction&) override; MachineFunctionProperties getSetProperties() const override { - return MachineFunctionProperties().set( + if (ClearVirtRegs) { + return MachineFunctionProperties().set( MachineFunctionProperties::Property::NoVRegs); + } + + return MachineFunctionProperties(); } }; @@ -224,12 +239,17 @@ INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter", void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<LiveIntervals>(); + AU.addPreserved<LiveIntervals>(); AU.addRequired<SlotIndexes>(); AU.addPreserved<SlotIndexes>(); AU.addRequired<LiveDebugVariables>(); AU.addRequired<LiveStacks>(); AU.addPreserved<LiveStacks>(); AU.addRequired<VirtRegMap>(); + + if (!ClearVirtRegs) + AU.addPreserved<LiveDebugVariables>(); + MachineFunctionPass::getAnalysisUsage(AU); } @@ -241,6 +261,7 @@ bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) { Indexes = &getAnalysis<SlotIndexes>(); LIS = &getAnalysis<LiveIntervals>(); VRM = &getAnalysis<VirtRegMap>(); + DebugVars = getAnalysisIfAvailable<LiveDebugVariables>(); LLVM_DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n" << "********** Function: " << MF->getName() << '\n'); LLVM_DEBUG(VRM->dump()); @@ -254,18 +275,24 @@ bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) { // Rewrite virtual registers. rewrite(); - // Write out new DBG_VALUE instructions. - getAnalysis<LiveDebugVariables>().emitDebugValues(VRM); + if (DebugVars && ClearVirtRegs) { + // Write out new DBG_VALUE instructions. + + // We only do this if ClearVirtRegs is specified since this should be the + // final run of the pass and we don't want to emit them multiple times. + DebugVars->emitDebugValues(VRM); + + // All machine operands and other references to virtual registers have been + // replaced. Remove the virtual registers and release all the transient data. + VRM->clearAllVirt(); + MRI->clearVirtRegs(); + } - // All machine operands and other references to virtual registers have been - // replaced. Remove the virtual registers and release all the transient data. - VRM->clearAllVirt(); - MRI->clearVirtRegs(); return true; } void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI, - Register PhysReg) const { + MCRegister PhysReg) const { assert(!LI.empty()); assert(LI.hasSubRanges()); @@ -321,7 +348,12 @@ void VirtRegRewriter::addMBBLiveIns() { // This is a virtual register that is live across basic blocks. Its // assigned PhysReg must be marked as live-in to those blocks. Register PhysReg = VRM->getPhys(VirtReg); - assert(PhysReg != VirtRegMap::NO_PHYS_REG && "Unmapped virtual register."); + if (PhysReg == VirtRegMap::NO_PHYS_REG) { + // There may be no physical register assigned if only some register + // classes were already allocated. + assert(!ClearVirtRegs && "Unmapped virtual register"); + continue; + } if (LI.hasSubRanges()) { addLiveInsForSubRanges(LI, PhysReg); @@ -372,12 +404,21 @@ bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const { return true; } -void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) const { +void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) { if (!MI.isIdentityCopy()) return; LLVM_DEBUG(dbgs() << "Identity copy: " << MI); ++NumIdCopies; + Register DstReg = MI.getOperand(0).getReg(); + + // We may have deferred allocation of the virtual register, and the rewrite + // regs code doesn't handle the liveness update. + if (DstReg.isVirtual()) + return; + + RewriteRegs.insert(DstReg); + // Copies like: // %r0 = COPY undef %r0 // %al = COPY %al, implicit-def %eax @@ -517,8 +558,12 @@ void VirtRegRewriter::rewrite() { continue; Register VirtReg = MO.getReg(); MCRegister PhysReg = VRM->getPhys(VirtReg); - assert(PhysReg != VirtRegMap::NO_PHYS_REG && - "Instruction uses unmapped VirtReg"); + if (PhysReg == VirtRegMap::NO_PHYS_REG) + continue; + + assert(Register(PhysReg).isPhysical()); + + RewriteRegs.insert(PhysReg); assert(!MRI->isReserved(PhysReg) && "Reserved register assignment"); // Preserve semantics of sub-register operands. @@ -590,4 +635,21 @@ void VirtRegRewriter::rewrite() { handleIdentityCopy(*MI); } } + + if (LIS) { + // Don't bother maintaining accurate LiveIntervals for registers which were + // already allocated. + for (Register PhysReg : RewriteRegs) { + for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); + ++Units) { + LIS->removeRegUnit(*Units); + } + } + } + + RewriteRegs.clear(); +} + +FunctionPass *llvm::createVirtRegRewriter(bool ClearVirtRegs) { + return new VirtRegRewriter(ClearVirtRegs); } |
