summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDaniil Fukalov <daniil.fukalov@amd.com>2018-09-25 18:37:38 +0000
committerDaniil Fukalov <daniil.fukalov@amd.com>2018-09-25 18:37:38 +0000
commit349b5943b475cf87d6dbf8a190e33814a0d8199c (patch)
tree1e1102dbd50e1040c2f38fa87c743e9b452619ef /llvm/lib/CodeGen
parentc06ee8367aa565d6d5c1b318d5e36aef6149ac44 (diff)
downloadbcm5719-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.cpp41
-rw-r--r--llvm/lib/CodeGen/SplitKit.h17
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
OpenPOWER on IntegriCloud