diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-05-03 19:06:57 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-05-03 19:06:57 +0000 |
commit | b6c599afd3cfd02c49c49797fd1126afe63330fd (patch) | |
tree | 82fa3a448f0a57eb483477e2c1633b265fe8a7b3 /llvm/lib/CodeGen/RegAllocFast.cpp | |
parent | 13cf19dff098bf89216a14eee0314afd850278a2 (diff) | |
download | bcm5719-llvm-b6c599afd3cfd02c49c49797fd1126afe63330fd.tar.gz bcm5719-llvm-b6c599afd3cfd02c49c49797fd1126afe63330fd.zip |
Reapply r359906, "RegAllocFast: Add heuristic to detect values not live-out of a block"
This reverts commit r359912.
This should pass now, since the clang test was made less fragile in
r359918.
llvm-svn: 359919
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocFast.cpp')
-rw-r--r-- | llvm/lib/CodeGen/RegAllocFast.cpp | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp index a711db1c0eb..c11ae9cce1a 100644 --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -101,6 +101,10 @@ namespace { DenseMap<unsigned, SmallVector<MachineInstr *, 2>> LiveDbgValueMap; + /// Has a bit set for every virtual register for which it was determined + /// that it is alive across blocks. + BitVector MayLiveAcrossBlocks; + /// State of a physical register. enum RegState { /// A disabled register is not available for allocation, but an alias may @@ -208,7 +212,7 @@ namespace { 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); @@ -217,6 +221,8 @@ namespace { void reload(MachineBasicBlock::iterator Before, unsigned VirtReg, MCPhysReg PhysReg); + bool mayLiveOut(unsigned VirtReg); + void dumpState(); }; @@ -251,6 +257,33 @@ int RegAllocFast::getStackSpaceFor(unsigned VirtReg) { return FrameIdx; } +/// Returns false if \p VirtReg is known to not live out of the current block. +bool RegAllocFast::mayLiveOut(unsigned VirtReg) { + if (MayLiveAcrossBlocks.test(TargetRegisterInfo::virtReg2Index(VirtReg))) { + // Cannot be live-out if there are no successors. + return !MBB->succ_empty(); + } + + // If this block loops back to itself, it would be necessary to check whether + // the use comes after the def. + if (MBB->isSuccessor(MBB)) + return true; + + // See if the first \p Limit uses of the register are all in the current + // block. + static const unsigned Limit = 8; + unsigned C = 0; + for (const MachineInstr &UseInst : MRI->reg_nodbg_instructions(VirtReg)) { + if (UseInst.getParent() != MBB || ++C >= Limit) { + MayLiveAcrossBlocks.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, @@ -374,7 +407,7 @@ void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI, LiveReg &LR) { } /// 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 @@ -382,6 +415,8 @@ void RegAllocFast::spillAll(MachineBasicBlock::iterator MI) { for (LiveReg &LR : LiveVirtRegs) { if (!LR.PhysReg) continue; + if (OnlyLiveOut && !mayLiveOut(LR.VirtReg)) + continue; spillVirtReg(MI, LR); } LiveVirtRegs.clear(); @@ -1019,7 +1054,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) { // 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, /*OnlyLiveOut*/ false); } // Third scan. @@ -1129,7 +1164,7 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) { // 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(), /*OnlyLiveOut*/ true); // Erase all the coalesced copies. We are delaying it until now because // LiveVirtRegs might refer to the instrs. @@ -1158,6 +1193,8 @@ bool RegAllocFast::runOnMachineFunction(MachineFunction &MF) { unsigned NumVirtRegs = MRI->getNumVirtRegs(); StackSlotForVirtReg.resize(NumVirtRegs); LiveVirtRegs.setUniverse(NumVirtRegs); + MayLiveAcrossBlocks.clear(); + MayLiveAcrossBlocks.resize(NumVirtRegs); // Loop over all of the basic blocks, eliminating virtual register references for (MachineBasicBlock &MBB : MF) |