Index: lib/CodeGen/RegAllocFast.cpp =================================================================== --- lib/CodeGen/RegAllocFast.cpp +++ lib/CodeGen/RegAllocFast.cpp @@ -102,6 +102,10 @@ DenseMap> LiveDbgValueMap; + /// Has a bit set for every virtual register for which it was determined + /// that it is alive accross blocks. + BitVector MayLiveAccrossBlocks; + /// State of a physical register. enum RegState { /// A disabled register is not available for allocation, but an alias may @@ -209,7 +213,7 @@ unsigned Hint); LiveReg &reloadVirtReg(MachineInstr &MI, unsigned OpNum, unsigned VirtReg, unsigned Hint); - void spillAll(MachineBasicBlock::iterator MI); + void spillAll(MachineBasicBlock::iterator MI, bool OnlyLiveOut); bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg); int getStackSpaceFor(unsigned VirtReg); @@ -218,6 +222,8 @@ void reload(MachineBasicBlock::iterator Before, unsigned VirtReg, MCPhysReg PhysReg); + bool mayLiveOut(unsigned VirtReg); + void dumpState(); }; @@ -252,6 +258,33 @@ return FrameIdx; } +/// Returns false if \p VirtReg is known to not live out of the current block. +bool RegAllocFast::mayLiveOut(unsigned VirtReg) { + if (MayLiveAccrossBlocks.test(TargetRegisterInfo::virtReg2Index(VirtReg))) { + // Cannot be live-out if there are no successors. + return !MBB->succ_empty(); + } + + // See if the first \p Limit uses of the register are all in the current + // block. + MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(VirtReg); + if (I == MRI->reg_nodbg_end()) + return false; + const MachineBasicBlock *FirstMBB = I->getParent()->getParent(); + + static const unsigned Limit = 8; + unsigned C = 0; + for (const MachineOperand &Use : + make_range(std::next(I), MRI->reg_nodbg_end())) { + if (Use.getParent()->getParent() != FirstMBB || ++C >= Limit) { + MayLiveAccrossBlocks.set(TargetRegisterInfo::virtReg2Index(VirtReg)); + // Cannot be live-out if there are no successors. + return !MBB->succ_empty(); + } + } + return false; +} + /// Insert spill instruction for \p AssignedReg before \p Before. Update /// DBG_VALUEs with \p VirtReg operands with the stack slot. void RegAllocFast::spill(MachineBasicBlock::iterator Before, unsigned VirtReg, @@ -375,7 +408,7 @@ } /// Spill all dirty virtregs without killing them. -void RegAllocFast::spillAll(MachineBasicBlock::iterator MI) { +void RegAllocFast::spillAll(MachineBasicBlock::iterator MI, bool OnlyLiveOut) { if (LiveVirtRegs.empty()) return; // The LiveRegMap is keyed by an unsigned (the virtreg number), so the order @@ -383,6 +416,8 @@ for (LiveReg &LR : LiveVirtRegs) { if (!LR.PhysReg) continue; + if (OnlyLiveOut && !mayLiveOut(LR.VirtReg)) + continue; spillVirtReg(MI, LR); } LiveVirtRegs.clear(); @@ -1019,7 +1054,7 @@ // definitions may be used later on and we do not want to reuse // those for virtual registers in between. LLVM_DEBUG(dbgs() << " Spilling remaining registers before call.\n"); - spillAll(MI); + spillAll(MI, false); } // Third scan. @@ -1129,7 +1164,7 @@ // Spill all physical registers holding virtual registers now. LLVM_DEBUG(dbgs() << "Spilling live registers at end of block.\n"); - spillAll(MBB.getFirstTerminator()); + spillAll(MBB.getFirstTerminator(), true); // Erase all the coalesced copies. We are delaying it until now because // LiveVirtRegs might refer to the instrs. @@ -1158,6 +1193,8 @@ unsigned NumVirtRegs = MRI->getNumVirtRegs(); StackSlotForVirtReg.resize(NumVirtRegs); LiveVirtRegs.setUniverse(NumVirtRegs); + MayLiveAccrossBlocks.clear(); + MayLiveAccrossBlocks.resize(NumVirtRegs); // Loop over all of the basic blocks, eliminating virtual register references for (MachineBasicBlock &MBB : MF)