Newer
Older
Eric Christopher
committed
// Did this value escape?
if (DupLI.isMapped(VNI))
truncatedValues.insert(VNI);
else
deadValues.insert(VNI);
continue;
Jakob Stoklund Olesen
committed
}
Eric Christopher
committed
// Add minimal live range at the definition.
VNInfo *DVNI = DupLI.defValue(VNI, VNI->def);
DupLI.getLI()->addRange(LiveRange(VNI->def, VNI->def.getNextSlot(), DVNI));
Jakob Stoklund Olesen
committed
}
Jakob Stoklund Olesen
committed
Eric Christopher
committed
// Add all ranges to dupli.
for (LiveInterval::const_iterator I = parent.begin(), E = parent.end();
I != E; ++I) {
const LiveRange &LR = *I;
if (truncatedValues.count(LR.valno)) {
// recolor after removing intervals_.
addTruncSimpleRange(LR.start, LR.end, LR.valno);
} else if (!deadValues.count(LR.valno)) {
// recolor without truncation.
DupLI.addSimpleRange(LR.start, LR.end, LR.valno);
}
}
Jakob Stoklund Olesen
committed
Eric Christopher
committed
// Extend DupLI to be live out of any critical loop predecessors.
// This means we have multiple registers live out of those blocks.
// The alternative would be to split the critical edges.
if (criticalPreds_.empty())
return;
for (SplitAnalysis::BlockPtrSet::iterator I = criticalPreds_.begin(),
E = criticalPreds_.end(); I != E; ++I)
DupLI.extendTo(*I, LIS.getMBBEndIdx(*I).getPrevSlot());
criticalPreds_.clear();
}
void SplitEditor::finish() {
assert(!OpenLI.getLI() && "Previous LI not closed before rewrite");
assert(DupLI.getLI() && "No dupli for rewrite. Noop spilt?");
// Complete dupli liveness.
computeRemainder();
Jakob Stoklund Olesen
committed
Jakob Stoklund Olesen
committed
// Get rid of unused values and set phi-kill flags.
for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I)
(*I)->RenumberValues(LIS);
Jakob Stoklund Olesen
committed
Eric Christopher
committed
// Rewrite instructions.
rewrite(Edit.getReg());
Jakob Stoklund Olesen
committed
// Now check if any registers were separated into multiple components.
ConnectedVNInfoEqClasses ConEQ(LIS);
for (unsigned i = 0, e = Edit.size(); i != e; ++i) {
Jakob Stoklund Olesen
committed
// Don't use iterators, they are invalidated by create() below.
LiveInterval *li = Edit.get(i);
Jakob Stoklund Olesen
committed
unsigned NumComp = ConEQ.Classify(li);
if (NumComp <= 1)
continue;
DEBUG(dbgs() << " " << NumComp << " components: " << *li << '\n');
SmallVector<LiveInterval*, 8> dups;
dups.push_back(li);
for (unsigned i = 1; i != NumComp; ++i)
dups.push_back(&Edit.create(MRI, LIS, VRM));
Jakob Stoklund Olesen
committed
ConEQ.Distribute(&dups[0]);
Eric Christopher
committed
// Rewrite uses to the new regs.
rewrite(li->reg);
Jakob Stoklund Olesen
committed
}
Jakob Stoklund Olesen
committed
// Calculate spill weight and allocation hints for new intervals.
VirtRegAuxInfo vrai(VRM.getMachineFunction(), LIS, sa_.Loops);
for (LiveRangeEdit::iterator I = Edit.begin(), E = Edit.end(); I != E; ++I){
Jakob Stoklund Olesen
committed
LiveInterval &li = **I;
vrai.CalculateRegClass(li.reg);
Jakob Stoklund Olesen
committed
vrai.CalculateWeightAndHint(li);
DEBUG(dbgs() << " new interval " << MRI.getRegClass(li.reg)->getName()
Jakob Stoklund Olesen
committed
}
Jakob Stoklund Olesen
committed
}
//===----------------------------------------------------------------------===//
// Loop Splitting
//===----------------------------------------------------------------------===//
Jakob Stoklund Olesen
committed
void SplitEditor::splitAroundLoop(const MachineLoop *Loop) {
Jakob Stoklund Olesen
committed
SplitAnalysis::LoopBlocks Blocks;
sa_.getLoopBlocks(Loop, Blocks);
dbgs() << " splitAround"; sa_.print(Blocks, dbgs()); dbgs() << '\n';
Jakob Stoklund Olesen
committed
// Break critical edges as needed.
SplitAnalysis::BlockPtrSet CriticalExits;
sa_.getCriticalExits(Blocks, CriticalExits);
assert(CriticalExits.empty() && "Cannot break critical exits yet");
Eric Christopher
committed
// Get critical predecessors so computeRemainder can deal with them.
sa_.getCriticalPreds(Blocks, criticalPreds_);
Jakob Stoklund Olesen
committed
// Create new live interval for the loop.
Jakob Stoklund Olesen
committed
Jakob Stoklund Olesen
committed
// Insert copies in the predecessors if live-in to the header.
if (LIS.isLiveInToMBB(Edit.getParent(), Loop->getHeader())) {
Jakob Stoklund Olesen
committed
for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Preds.begin(),
E = Blocks.Preds.end(); I != E; ++I) {
MachineBasicBlock &MBB = const_cast<MachineBasicBlock&>(**I);
enterIntvAtEnd(MBB);
}
Jakob Stoklund Olesen
committed
}
// Switch all loop blocks.
for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Loop.begin(),
E = Blocks.Loop.end(); I != E; ++I)
Jakob Stoklund Olesen
committed
// Insert back copies in the exit blocks.
for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Exits.begin(),
E = Blocks.Exits.end(); I != E; ++I) {
MachineBasicBlock &MBB = const_cast<MachineBasicBlock&>(**I);
Jakob Stoklund Olesen
committed
}
// Done.
Jakob Stoklund Olesen
committed
finish();
}
//===----------------------------------------------------------------------===//
// Single Block Splitting
//===----------------------------------------------------------------------===//
/// getMultiUseBlocks - if CurLI has more than one use in a basic block, it
/// may be an advantage to split CurLI for the duration of the block.
bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
// If CurLI is local to one block, there is no point to splitting it.
if (UsingBlocks.size() <= 1)
return false;
// Add blocks with multiple uses.
for (BlockCountMap::iterator I = UsingBlocks.begin(), E = UsingBlocks.end();
I != E; ++I)
switch (I->second) {
case 0:
case 1:
continue;
case 2: {
// When there are only two uses and CurLI is both live in and live out,
// we don't really win anything by isolating the block since we would be
// inserting two copies.
// The remaing register would still have two uses in the block. (Unless it
// separates into disconnected components).
if (LIS.isLiveInToMBB(*CurLI, I->first) &&
LIS.isLiveOutOfMBB(*CurLI, I->first))
continue;
} // Fall through.
default:
Blocks.insert(I->first);
}
return !Blocks.empty();
}
/// splitSingleBlocks - Split CurLI into a separate live interval inside each
Jakob Stoklund Olesen
committed
/// basic block in Blocks.
void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks) {
DEBUG(dbgs() << " splitSingleBlocks for " << Blocks.size() << " blocks.\n");
// Determine the first and last instruction using CurLI in each block.
typedef std::pair<SlotIndex,SlotIndex> IndexPair;
typedef DenseMap<const MachineBasicBlock*,IndexPair> IndexPairMap;
IndexPairMap MBBRange;
for (SplitAnalysis::InstrPtrSet::const_iterator I = sa_.UsingInstrs.begin(),
E = sa_.UsingInstrs.end(); I != E; ++I) {
const MachineBasicBlock *MBB = (*I)->getParent();
if (!Blocks.count(MBB))
continue;
SlotIndex Idx = LIS.getInstructionIndex(*I);
DEBUG(dbgs() << " BB#" << MBB->getNumber() << '\t' << Idx << '\t' << **I);
IndexPair &IP = MBBRange[MBB];
if (!IP.first.isValid() || Idx < IP.first)
IP.first = Idx;
if (!IP.second.isValid() || Idx > IP.second)
IP.second = Idx;
}
// Create a new interval for each block.
for (SplitAnalysis::BlockPtrSet::const_iterator I = Blocks.begin(),
E = Blocks.end(); I != E; ++I) {
IndexPair &IP = MBBRange[*I];
DEBUG(dbgs() << " splitting for BB#" << (*I)->getNumber() << ": ["
<< IP.first << ';' << IP.second << ")\n");
assert(IP.first.isValid() && IP.second.isValid());
openIntv();
enterIntvBefore(IP.first);
useIntv(IP.first.getBaseIndex(), IP.second.getBoundaryIndex());
leaveIntvAfter(IP.second);
closeIntv();
}
Jakob Stoklund Olesen
committed
finish();
//===----------------------------------------------------------------------===//
// Sub Block Splitting
//===----------------------------------------------------------------------===//
/// getBlockForInsideSplit - If CurLI is contained inside a single basic block,
/// and it wou pay to subdivide the interval inside that block, return it.
/// Otherwise return NULL. The returned block can be passed to
/// SplitEditor::splitInsideBlock.
const MachineBasicBlock *SplitAnalysis::getBlockForInsideSplit() {
// The interval must be exclusive to one block.
if (UsingBlocks.size() != 1)
return 0;
// Don't to this for less than 4 instructions. We want to be sure that
// splitting actually reduces the instruction count per interval.
if (UsingInstrs.size() < 4)
return UsingBlocks.begin()->first;
/// splitInsideBlock - Split CurLI into multiple intervals inside MBB.
Jakob Stoklund Olesen
committed
void SplitEditor::splitInsideBlock(const MachineBasicBlock *MBB) {
SmallVector<SlotIndex, 32> Uses;
Uses.reserve(sa_.UsingInstrs.size());
for (SplitAnalysis::InstrPtrSet::const_iterator I = sa_.UsingInstrs.begin(),
E = sa_.UsingInstrs.end(); I != E; ++I)
if ((*I)->getParent() == MBB)
Uses.push_back(LIS.getInstructionIndex(*I));
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
DEBUG(dbgs() << " splitInsideBlock BB#" << MBB->getNumber() << " for "
<< Uses.size() << " instructions.\n");
assert(Uses.size() >= 3 && "Need at least 3 instructions");
array_pod_sort(Uses.begin(), Uses.end());
// Simple algorithm: Find the largest gap between uses as determined by slot
// indices. Create new intervals for instructions before the gap and after the
// gap.
unsigned bestPos = 0;
int bestGap = 0;
DEBUG(dbgs() << " dist (" << Uses[0]);
for (unsigned i = 1, e = Uses.size(); i != e; ++i) {
int g = Uses[i-1].distance(Uses[i]);
DEBUG(dbgs() << ") -" << g << "- (" << Uses[i]);
if (g > bestGap)
bestPos = i, bestGap = g;
}
DEBUG(dbgs() << "), best: -" << bestGap << "-\n");
// bestPos points to the first use after the best gap.
assert(bestPos > 0 && "Invalid gap");
// FIXME: Don't create intervals for low densities.
// First interval before the gap. Don't create single-instr intervals.
if (bestPos > 1) {
openIntv();
enterIntvBefore(Uses.front());
useIntv(Uses.front().getBaseIndex(), Uses[bestPos-1].getBoundaryIndex());
leaveIntvAfter(Uses[bestPos-1]);
closeIntv();
}
// Second interval after the gap.
if (bestPos < Uses.size()-1) {
openIntv();
enterIntvBefore(Uses[bestPos]);
useIntv(Uses[bestPos].getBaseIndex(), Uses.back().getBoundaryIndex());
leaveIntvAfter(Uses.back());
closeIntv();
}
Jakob Stoklund Olesen
committed
finish();