"llvm/lib/git@repo.hca.bsc.es:rferrer/llvm-epi-0.8.git" did not exist on "d2c38d684a733ef0facf670bbd0a85040ca48a9c"
Newer
Older
Jakob Stoklund Olesen
committed
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
// Insert copies in the predecessors.
for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Preds.begin(),
E = Blocks.Preds.end(); I != E; ++I) {
MachineBasicBlock &MBB = const_cast<MachineBasicBlock&>(**I);
Jakob Stoklund Olesen
committed
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
//===----------------------------------------------------------------------===//
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
/// 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) {
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
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
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();