"llvm/lib/git@repo.hca.bsc.es:lalbano/llvm-bpevl.git" did not exist on "41dd31f0b095c4ace9e3ab36062e2e11b8445d41"
Newer
Older
Evan Cheng
committed
// Update spill stack slot live interval.
Evan Cheng
committed
UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
LIs->getDefIndex(RestoreIndex));
ReconstructLiveInterval(CurrLI);
unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt));
RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx);
RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx));
++NumSplits;
Evan Cheng
committed
return true;
}
/// SplitRegLiveIntervals - Split all register live intervals that cross the
/// barrier that's being processed.
bool
PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs,
SmallPtrSet<LiveInterval*, 8>& Split) {
Evan Cheng
committed
// First find all the virtual registers whose live intervals are intercepted
// by the current barrier.
SmallVector<LiveInterval*, 8> Intervals;
for (const TargetRegisterClass **RC = RCs; *RC; ++RC) {
if (TII->IgnoreRegisterClassBarriers(*RC))
continue;
Evan Cheng
committed
std::vector<unsigned> &VRs = MRI->getRegClassVirtRegs(*RC);
for (unsigned i = 0, e = VRs.size(); i != e; ++i) {
unsigned Reg = VRs[i];
if (!LIs->hasInterval(Reg))
continue;
LiveInterval *LI = &LIs->getInterval(Reg);
if (LI->liveAt(BarrierIdx) && !Barrier->readsRegister(Reg))
// Virtual register live interval is intercepted by the barrier. We
// should split and shrink wrap its interval if possible.
Intervals.push_back(LI);
}
}
// Process the affected live intervals.
bool Change = false;
while (!Intervals.empty()) {
if (PreSplitLimit != -1 && (int)NumSplits == PreSplitLimit)
break;
else if (NumSplits == 4)
Change |= Change;
Evan Cheng
committed
LiveInterval *LI = Intervals.back();
Intervals.pop_back();
bool result = SplitRegLiveInterval(LI);
if (result) Split.insert(LI);
Change |= result;
Evan Cheng
committed
}
return Change;
}
unsigned PreAllocSplitting::getNumberOfNonSpills(
SmallPtrSet<MachineInstr*, 4>& MIs,
unsigned Reg, int FrameIndex,
bool& FeedsTwoAddr) {
unsigned NonSpills = 0;
for (SmallPtrSet<MachineInstr*, 4>::iterator UI = MIs.begin(), UE = MIs.end();
UI != UE; ++UI) {
int StoreFrameIndex;
unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
if (StoreVReg != Reg || StoreFrameIndex != FrameIndex)
NonSpills++;
int DefIdx = (*UI)->findRegisterDefOperandIdx(Reg);
if (DefIdx != -1 && (*UI)->isRegReDefinedByTwoAddr(DefIdx))
FeedsTwoAddr = true;
return NonSpills;
/// removeDeadSpills - After doing splitting, filter through all intervals we've
/// split, and see if any of the spills are unnecessary. If so, remove them.
bool PreAllocSplitting::removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split) {
bool changed = false;
// Walk over all of the live intervals that were touched by the splitter,
// and see if we can do any DCE and/or folding.
for (SmallPtrSet<LiveInterval*, 8>::iterator LI = split.begin(),
LE = split.end(); LI != LE; ++LI) {
Owen Anderson
committed
DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> > VNUseCount;
// First, collect all the uses of the vreg, and sort them by their
// reaching definition (VNInfo).
for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg),
UE = MRI->use_end(); UI != UE; ++UI) {
unsigned index = LIs->getInstructionIndex(&*UI);
index = LiveIntervals::getUseIndex(index);
const LiveRange* LR = (*LI)->getLiveRangeContaining(index);
Owen Anderson
committed
VNUseCount[LR->valno].insert(&*UI);
}
// Now, take the definitions (VNInfo's) one at a time and try to DCE
// and/or fold them away.
for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(),
VE = (*LI)->vni_end(); VI != VE; ++VI) {
if (DeadSplitLimit != -1 && (int)NumDeadSpills == DeadSplitLimit)
return changed;
VNInfo* CurrVN = *VI;
// We don't currently try to handle definitions with PHI kills, because
// it would involve processing more than one VNInfo at once.
if (CurrVN->hasPHIKill) continue;
// We also don't try to handle the results of PHI joins, since there's
// no defining instruction to analyze.
unsigned DefIdx = CurrVN->def;
if (DefIdx == ~0U || DefIdx == ~1U) continue;
Owen Anderson
committed
// We're only interested in eliminating cruft introduced by the splitter,
// is of the form load-use or load-use-store. First, check that the
// definition is a load, and remember what stack slot we loaded it from.
MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx);
int FrameIndex;
if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue;
// If the definition has no uses at all, just DCE it.
Owen Anderson
committed
if (VNUseCount[CurrVN].size() == 0) {
LIs->RemoveMachineInstrFromMaps(DefMI);
(*LI)->removeValNo(CurrVN);
DefMI->eraseFromParent();
Owen Anderson
committed
VNUseCount.erase(CurrVN);
Owen Anderson
committed
NumDeadSpills++;
changed = true;
// Second, get the number of non-store uses of the definition, as well as
// a flag indicating whether it feeds into a later two-address definition.
bool FeedsTwoAddr = false;
unsigned NonSpillCount = getNumberOfNonSpills(VNUseCount[CurrVN],
(*LI)->reg, FrameIndex,
FeedsTwoAddr);
// If there's one non-store use and it doesn't feed a two-addr, then
// this is a load-use-store case that we can try to fold.
if (NonSpillCount == 1 && !FeedsTwoAddr) {
// Start by finding the non-store use MachineInstr.
SmallPtrSet<MachineInstr*, 4>::iterator UI = VNUseCount[CurrVN].begin();
int StoreFrameIndex;
unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
while (UI != VNUseCount[CurrVN].end() &&
(StoreVReg == (*LI)->reg && StoreFrameIndex == FrameIndex)) {
++UI;
if (UI != VNUseCount[CurrVN].end())
StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
}
if (UI == VNUseCount[CurrVN].end()) continue;
MachineInstr* use = *UI;
int OpIdx = use->findRegisterUseOperandIdx((*LI)->reg, false);
if (OpIdx == -1) continue;
SmallVector<unsigned, 1> Ops;
Ops.push_back(OpIdx);
if (!TII->canFoldMemoryOperand(use, Ops)) continue;
MachineInstr* NewMI =
TII->foldMemoryOperand(*use->getParent()->getParent(),
use, Ops, FrameIndex);
if (!NewMI) continue;
LIs->RemoveMachineInstrFromMaps(DefMI);
LIs->ReplaceMachineInstrInMaps(use, NewMI);
(*LI)->removeValNo(CurrVN);
DefMI->eraseFromParent();
MachineBasicBlock* MBB = use->getParent();
NewMI = MBB->insert(MBB->erase(use), NewMI);
VNUseCount[CurrVN].erase(use);
// Remove deleted instructions. Note that we need to remove them from
// the VNInfo->use map as well, just to be safe.
for (SmallPtrSet<MachineInstr*, 4>::iterator II =
VNUseCount[CurrVN].begin(), IE = VNUseCount[CurrVN].end();
II != IE; ++II) {
for (DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> >::iterator
Owen Anderson
committed
VNI = VNUseCount.begin(), VNE = VNUseCount.end(); VNI != VNE;
++VNI)
if (VNI->first != CurrVN)
VNI->second.erase(*II);
LIs->RemoveMachineInstrFromMaps(*II);
(*II)->eraseFromParent();
}
Owen Anderson
committed
VNUseCount.erase(CurrVN);
for (DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> >::iterator
VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI)
if (VI->second.erase(use))
VI->second.insert(NewMI);
NumDeadSpills++;
changed = true;
continue;
}
// If there's more than one non-store instruction, we can't profitably
// fold it, so bail.
if (NonSpillCount) continue;
Owen Anderson
committed
// Otherwise, this is a load-store case, so DCE them.
for (SmallPtrSet<MachineInstr*, 4>::iterator UI =
VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end();
UI != UI; ++UI) {
LIs->RemoveMachineInstrFromMaps(*UI);
(*UI)->eraseFromParent();
Owen Anderson
committed
}
Owen Anderson
committed
VNUseCount.erase(CurrVN);
LIs->RemoveMachineInstrFromMaps(DefMI);
(*LI)->removeValNo(CurrVN);
DefMI->eraseFromParent();
NumDeadSpills++;
changed = true;
}
}
return changed;
}
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
bool PreAllocSplitting::createsNewJoin(LiveRange* LR,
MachineBasicBlock* DefMBB,
MachineBasicBlock* BarrierMBB) {
if (DefMBB == BarrierMBB)
return false;
if (LR->valno->hasPHIKill)
return false;
unsigned MBBEnd = LIs->getMBBEndIdx(BarrierMBB);
if (LR->end < MBBEnd)
return false;
MachineLoopInfo& MLI = getAnalysis<MachineLoopInfo>();
if (MLI.getLoopFor(DefMBB) != MLI.getLoopFor(BarrierMBB))
return true;
MachineDominatorTree& MDT = getAnalysis<MachineDominatorTree>();
SmallPtrSet<MachineBasicBlock*, 4> Visited;
typedef std::pair<MachineBasicBlock*,
MachineBasicBlock::succ_iterator> ItPair;
SmallVector<ItPair, 4> Stack;
Stack.push_back(std::make_pair(BarrierMBB, BarrierMBB->succ_begin()));
while (!Stack.empty()) {
ItPair P = Stack.back();
Stack.pop_back();
MachineBasicBlock* PredMBB = P.first;
MachineBasicBlock::succ_iterator S = P.second;
if (S == PredMBB->succ_end())
continue;
else if (Visited.count(*S)) {
Stack.push_back(std::make_pair(PredMBB, ++S));
continue;
} else
Owen Anderson
committed
Stack.push_back(std::make_pair(PredMBB, S+1));
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
MachineBasicBlock* MBB = *S;
Visited.insert(MBB);
if (MBB == BarrierMBB)
return true;
MachineDomTreeNode* DefMDTN = MDT.getNode(DefMBB);
MachineDomTreeNode* BarrierMDTN = MDT.getNode(BarrierMBB);
MachineDomTreeNode* MDTN = MDT.getNode(MBB)->getIDom();
while (MDTN) {
if (MDTN == DefMDTN)
return true;
else if (MDTN == BarrierMDTN)
break;
MDTN = MDTN->getIDom();
}
MBBEnd = LIs->getMBBEndIdx(MBB);
if (LR->end > MBBEnd)
Stack.push_back(std::make_pair(MBB, MBB->succ_begin()));
}
return false;
}
bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
CurrMF = &MF;
TM = &MF.getTarget();
Owen Anderson
committed
TRI = TM->getRegisterInfo();
TII = TM->getInstrInfo();
MFI = MF.getFrameInfo();
MRI = &MF.getRegInfo();
LIs = &getAnalysis<LiveIntervals>();
LSs = &getAnalysis<LiveStacks>();
Evan Cheng
committed
bool MadeChange = false;
// Make sure blocks are numbered in order.
MF.RenumberBlocks();
Evan Cheng
committed
MachineBasicBlock *Entry = MF.begin();
SmallPtrSet<MachineBasicBlock*,16> Visited;
SmallPtrSet<LiveInterval*, 8> Split;
Evan Cheng
committed
for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
DFI != E; ++DFI) {
BarrierMBB = *DFI;
for (MachineBasicBlock::iterator I = BarrierMBB->begin(),
E = BarrierMBB->end(); I != E; ++I) {
Barrier = &*I;
const TargetRegisterClass **BarrierRCs =
Barrier->getDesc().getRegClassBarriers();
if (!BarrierRCs)
continue;
BarrierIdx = LIs->getInstructionIndex(Barrier);
MadeChange |= SplitRegLiveIntervals(BarrierRCs, Split);
Evan Cheng
committed
}
}
Evan Cheng
committed
MadeChange |= removeDeadSpills(Split);
Evan Cheng
committed
return MadeChange;