|
@@ -449,8 +449,8 @@ private:
|
|
|
|
|
|
BlockFrequency calcSpillCost();
|
|
BlockFrequency calcSpillCost();
|
|
bool addSplitConstraints(InterferenceCache::Cursor, BlockFrequency&);
|
|
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,
|
|
bool splitCanCauseEvictionChain(unsigned Evictee, GlobalSplitCandidate &Cand,
|
|
unsigned BBNumber,
|
|
unsigned BBNumber,
|
|
const AllocationOrder &Order);
|
|
const AllocationOrder &Order);
|
|
@@ -1203,6 +1203,13 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf,
|
|
} else if (Intf.first() < BI.LastInstr) {
|
|
} else if (Intf.first() < BI.LastInstr) {
|
|
++Ins;
|
|
++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.
|
|
// 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
|
|
/// addThroughConstraints - Add constraints and links to SpillPlacer from the
|
|
/// live-through blocks in Blocks.
|
|
/// live-through blocks in Blocks.
|
|
-void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
|
|
|
|
|
|
+bool RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
|
|
ArrayRef<unsigned> Blocks) {
|
|
ArrayRef<unsigned> Blocks) {
|
|
const unsigned GroupSize = 8;
|
|
const unsigned GroupSize = 8;
|
|
SpillPlacement::BlockConstraint BCS[GroupSize];
|
|
SpillPlacement::BlockConstraint BCS[GroupSize];
|
|
@@ -1256,6 +1263,12 @@ void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
|
|
assert(B < GroupSize && "Array overflow");
|
|
assert(B < GroupSize && "Array overflow");
|
|
BCS[B].Number = Number;
|
|
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.
|
|
// Interference for the live-in value.
|
|
if (Intf.first() <= Indexes->getMBBStartIdx(Number))
|
|
if (Intf.first() <= Indexes->getMBBStartIdx(Number))
|
|
BCS[B].Entry = SpillPlacement::MustSpill;
|
|
BCS[B].Entry = SpillPlacement::MustSpill;
|
|
@@ -1276,9 +1289,10 @@ void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf,
|
|
|
|
|
|
SpillPlacer->addConstraints(makeArrayRef(BCS, B));
|
|
SpillPlacer->addConstraints(makeArrayRef(BCS, B));
|
|
SpillPlacer->addLinks(makeArrayRef(TBS, T));
|
|
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.
|
|
// Keep track of through blocks that have not been added to SpillPlacer.
|
|
BitVector Todo = SA->getThroughBlocks();
|
|
BitVector Todo = SA->getThroughBlocks();
|
|
SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
|
|
SmallVectorImpl<unsigned> &ActiveBlocks = Cand.ActiveBlocks;
|
|
@@ -1314,9 +1328,10 @@ void RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
|
|
// Compute through constraints from the interference, or assume that all
|
|
// Compute through constraints from the interference, or assume that all
|
|
// through blocks prefer spilling when forming compact regions.
|
|
// through blocks prefer spilling when forming compact regions.
|
|
auto NewBlocks = makeArrayRef(ActiveBlocks).slice(AddedTo);
|
|
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
|
|
// Provide a strong negative bias on through blocks to prevent unwanted
|
|
// liveness on loop backedges.
|
|
// liveness on loop backedges.
|
|
SpillPlacer->addPrefSpill(NewBlocks, /* Strong= */ true);
|
|
SpillPlacer->addPrefSpill(NewBlocks, /* Strong= */ true);
|
|
@@ -1326,6 +1341,7 @@ void RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
|
|
SpillPlacer->iterate();
|
|
SpillPlacer->iterate();
|
|
}
|
|
}
|
|
LLVM_DEBUG(dbgs() << ", v=" << Visited);
|
|
LLVM_DEBUG(dbgs() << ", v=" << Visited);
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
/// calcCompactRegion - Compute the set of edge bundles that should be live
|
|
/// calcCompactRegion - Compute the set of edge bundles that should be live
|
|
@@ -1356,7 +1372,11 @@ bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- growRegion(Cand);
|
|
|
|
|
|
+ if (!growRegion(Cand)) {
|
|
|
|
+ LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
SpillPlacer->finish();
|
|
SpillPlacer->finish();
|
|
|
|
|
|
if (!Cand.LiveBundles.any()) {
|
|
if (!Cand.LiveBundles.any()) {
|
|
@@ -1886,7 +1906,10 @@ unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,
|
|
});
|
|
});
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- growRegion(Cand);
|
|
|
|
|
|
+ if (!growRegion(Cand)) {
|
|
|
|
+ LLVM_DEBUG(dbgs() << ", cannot spill all interferences.\n");
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
|
|
SpillPlacer->finish();
|
|
SpillPlacer->finish();
|
|
|
|
|