diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 18822337e65..607f18c8ab7 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -181,13 +181,14 @@ class VirtRegRewriter : public MachineFunctionPass { SlotIndexes *Indexes; LiveIntervals *LIS; VirtRegMap *VRM; + DenseSet 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; @@ -230,6 +231,7 @@ INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter", void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); @@ -274,7 +276,7 @@ bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) { } void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI, - Register PhysReg) const { + MCRegister PhysReg) const { assert(!LI.empty()); assert(LI.hasSubRanges()); @@ -330,7 +332,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); @@ -381,12 +388,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 @@ -526,8 +542,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. @@ -599,6 +619,19 @@ 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) {