diff options
author | Daniil Fukalov <daniil.fukalov@amd.com> | 2018-09-25 18:37:38 +0000 |
---|---|---|
committer | Daniil Fukalov <daniil.fukalov@amd.com> | 2018-09-25 18:37:38 +0000 |
commit | 349b5943b475cf87d6dbf8a190e33814a0d8199c (patch) | |
tree | 1e1102dbd50e1040c2f38fa87c743e9b452619ef /llvm/lib/CodeGen | |
parent | c06ee8367aa565d6d5c1b318d5e36aef6149ac44 (diff) | |
download | bcm5719-llvm-349b5943b475cf87d6dbf8a190e33814a0d8199c.tar.gz bcm5719-llvm-349b5943b475cf87d6dbf8a190e33814a0d8199c.zip |
[RegAllocGreedy] avoid using physreg candidates that cannot be correctly spilled
For the AMDGPU target if a MBB contains exec mask restore preamble, SplitEditor may get state when it cannot insert a spill instruction.
E.g. for a MIR
bb.100:
%1 = S_OR_SAVEEXEC_B64 %2, implicit-def $exec, implicit-def $scc, implicit $exec
and if the regalloc will try to allocate a virtreg to the physreg already assigned to virtreg %1, it should insert spill instruction before the S_OR_SAVEEXEC_B64 instruction.
But it is not possible since can generate incorrect code in terms of exec mask.
The change makes regalloc to ignore such physreg candidates.
Reviewed By: rampitec
Differential Revision: https://reviews.llvm.org/D52052
llvm-svn: 343004
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/RegAllocGreedy.cpp | 41 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SplitKit.h | 17 |
2 files changed, 49 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index 54f800832d2..64da8485389 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -449,8 +449,8 @@ private: BlockFrequency calcSpillCost(); bool addSplitConstraints(InterferenceCache::Cursor, BlockFrequency&); - void addThroughConstraints(InterferenceCache::Cursor, ArrayRef<unsigned>); - void growRegion(GlobalSplitCandidate &Cand); + bool addThroughConstraints(InterferenceCache::Cursor, ArrayRef<unsigned>); + bool growRegion(GlobalSplitCandidate &Cand); bool splitCanCauseEvictionChain(unsigned Evictee, GlobalSplitCandidate &Cand, unsigned BBNumber, const AllocationOrder &Order); @@ -1203,6 +1203,13 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf, } else if (Intf.first() < BI.LastInstr) { ++Ins; } + + // Abort if the spill cannot be inserted at the MBB' start + if (((BC.Entry == SpillPlacement::MustSpill) || + (BC.Entry == SpillPlacement::PrefSpill)) && + SlotIndex::isEarlierInstr(BI.FirstInstr, + SA->getFirstSplitPoint(BC.Number))) + return false; } // Interference for the live-out value. @@ -1232,7 +1239,7 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf, /// addThroughConstraints - Add constraints and links to SpillPlacer from the /// live-through blocks in Blocks. -void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf, +bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf, ArrayRef<unsigned> Blocks) { const unsigned GroupSize = 8; SpillPlacement::BlockConstraint BCS[GroupSize]; @@ -1256,6 +1263,12 @@ void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf, assert(B < GroupSize && "Array overflow"); BCS[B].Number = Number; + // Abort if the spill cannot be inserted at the MBB' start + MachineBasicBlock *MBB = MF->getBlockNumbered(Number); + if (!MBB->empty() && + SlotIndex::isEarlierInstr(LIS->getInstructionIndex(MBB->instr_front()), + SA->getFirstSplitPoint(Number))) + return false; // Interference for the live-in value. if (Intf.first() <= Indexes->getMBBStartIdx(Number)) BCS[B].Entry = SpillPlacement::MustSpill; @@ -1276,9 +1289,10 @@ void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf, SpillPlacer->addConstraints(makeArrayRef(BCS, B)); SpillPlacer->addLinks(makeArrayRef(TBS, T)); + return true; } -void RAGreedy::growRegion(GlobalSplitCandidate &Cand) { +bool RAGreedy::growRegion(GlobalSplitCandidate &Cand) { // Keep track of through blocks that have not been added to SpillPlacer. BitVector Todo = SA->getThroughBlocks(); SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks; @@ -1314,9 +1328,10 @@ void RAGreedy::growRegion(GlobalSplitCandidate &Cand) { // Compute through constraints from the interference, or assume that all // through blocks prefer spilling when forming compact regions. auto NewBlocks = makeArrayRef(ActiveBlocks).slice(AddedTo); - if (Cand.PhysReg) - addThroughConstraints(Cand.Intf, NewBlocks); - else + if (Cand.PhysReg) { + if (!addThroughConstraints(Cand.Intf, NewBlocks)) + return false; + } else // Provide a strong negative bias on through blocks to prevent unwanted // liveness on loop backedges. SpillPlacer->addPrefSpill(NewBlocks, /* Strong= */ true); @@ -1326,6 +1341,7 @@ void RAGreedy::growRegion(GlobalSplitCandidate &Cand) { SpillPlacer->iterate(); } LLVM_DEBUG(dbgs() << ", v=" << Visited); + return true; } /// calcCompactRegion - Compute the set of edge bundles that should be live @@ -1356,7 +1372,11 @@ bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) { return false; } - growRegion(Cand); + if (!growRegion(Cand)) { + LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n"); + return false; + } + SpillPlacer->finish(); if (!Cand.LiveBundles.any()) { @@ -1886,7 +1906,10 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg, }); continue; } - growRegion(Cand); + if (!growRegion(Cand)) { + LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n"); + continue; + } SpillPlacer->finish(); diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h index 8fbe724045e..bcc8f8cf18b 100644 --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -25,6 +25,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SlotIndexes.h" @@ -76,6 +77,18 @@ public: /// Returns the last insert point as an iterator for \pCurLI in \pMBB. MachineBasicBlock::iterator getLastInsertPointIter(const LiveInterval &CurLI, MachineBasicBlock &MBB); + + /// Return the base index of the first insert point in \pMBB. + SlotIndex getFirstInsertPoint(MachineBasicBlock &MBB) { + SlotIndex Res = LIS.getMBBStartIdx(&MBB); + if (!MBB.empty()) { + MachineBasicBlock::iterator MII = MBB.SkipPHIsLabelsAndDebug(MBB.begin()); + if (MII != MBB.end()) + Res = LIS.getInstructionIndex(*MII); + } + return Res; + } + }; /// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting @@ -225,6 +238,10 @@ public: MachineBasicBlock::iterator getLastSplitPointIter(MachineBasicBlock *BB) { return IPA.getLastInsertPointIter(*CurLI, *BB); } + + SlotIndex getFirstSplitPoint(unsigned Num) { + return IPA.getFirstInsertPoint(*MF.getBlockNumbered(Num)); + } }; /// SplitEditor - Edit machine code and LiveIntervals for live range |