"llvm/lib/git@repo.hca.bsc.es:rferrer/llvm-epi-0.8.git" did not exist on "2c54a0db79bf5c8e90bbafd25ec6fa6bfc79bf89"
Newer
Older
Jakob Stoklund Olesen
committed
// If the interval end was truncated, we can try again from next.
if (next <= sidx)
break;
sidx = next;
Jakob Stoklund Olesen
committed
}
Jakob Stoklund Olesen
committed
void SplitEditor::computeRemainder() {
Jakob Stoklund Olesen
committed
// First we need to fill in the live ranges in dupli.
// If values were redefined, we need a full recoloring with SSA update.
// If values were truncated, we only need to truncate the ranges.
// If values were partially rematted, we should shrink to uses.
// If values were fully rematted, they should be omitted.
// FIXME: If a single value is redefined, just move the def and truncate.
Jakob Stoklund Olesen
committed
LiveInterval &parent = edit_.getParent();
Jakob Stoklund Olesen
committed
// Values that are fully contained in the split intervals.
SmallPtrSet<const VNInfo*, 8> deadValues;
// Map all curli values that should have live defs in dupli.
Jakob Stoklund Olesen
committed
for (LiveInterval::const_vni_iterator I = parent.vni_begin(),
E = parent.vni_end(); I != E; ++I) {
Jakob Stoklund Olesen
committed
const VNInfo *VNI = *I;
Jakob Stoklund Olesen
committed
// Don't transfer unused values to the new intervals.
if (VNI->isUnused())
continue;
Jakob Stoklund Olesen
committed
// Original def is contained in the split intervals.
if (intervalsLiveAt(VNI->def)) {
// Did this value escape?
if (dupli_.isMapped(VNI))
truncatedValues.insert(VNI);
else
deadValues.insert(VNI);
continue;
}
// Add minimal live range at the definition.
VNInfo *DVNI = dupli_.defValue(VNI, VNI->def);
dupli_.getLI()->addRange(LiveRange(VNI->def, VNI->def.getNextSlot(), DVNI));
}
// Add all ranges to dupli.
Jakob Stoklund Olesen
committed
for (LiveInterval::const_iterator I = parent.begin(), E = parent.end();
Jakob Stoklund Olesen
committed
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
// 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();
Jakob Stoklund Olesen
committed
}
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.
Jakob Stoklund Olesen
committed
for (LiveRangeEdit::iterator I = edit_.begin(), E = edit_.end(); I != E; ++I)
(*I)->RenumberValues(lis_);
Jakob Stoklund Olesen
committed
// Rewrite instructions.
Jakob Stoklund Olesen
committed
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) {
// Don't use iterators, they are invalidated by create() below.
LiveInterval *li = edit_.get(i);
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_));
ConEQ.Distribute(&dups[0]);
// Rewrite uses to the new regs.
rewrite(li->reg);
}
Jakob Stoklund Olesen
committed
// Calculate spill weight and allocation hints for new intervals.
VirtRegAuxInfo vrai(vrm_.getMachineFunction(), lis_, sa_.loops_);
Jakob Stoklund Olesen
committed
for (LiveRangeEdit::iterator I = edit_.begin(), E = edit_.end(); I != E; ++I){
LiveInterval &li = **I;
vrai.CalculateRegClass(li.reg);
Jakob Stoklund Olesen
committed
vrai.CalculateWeightAndHint(li);
DEBUG(dbgs() << " new interval " << mri_.getRegClass(li.reg)->getName()
<< ":" << li << '\n');
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");
Jakob Stoklund Olesen
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())) {
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
//===----------------------------------------------------------------------===//
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
/// 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 0;
return usingBlocks_.begin()->first;
}
Jakob Stoklund Olesen
committed
/// splitInsideBlock - Split curli into multiple intervals inside MBB.
void SplitEditor::splitInsideBlock(const MachineBasicBlock *MBB) {
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
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));
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();