Newer
Older
UMII2 = UseMIs.find(UseMBB);
UMII->second.push_back(&UseMO);
UMII2->second.insert(UseMI);
} else {
SmallVector<MachineOperand*, 4> Ops;
Ops.push_back(&UseMO);
Uses.insert(std::make_pair(UseMBB, Ops));
SmallPtrSet<MachineInstr*, 4> MIs;
MIs.insert(UseMI);
UseMIs.insert(std::make_pair(UseMBB, MIs));
}
}
// Walk up the predecessor chains.
SmallPtrSet<MachineBasicBlock*, 8> Visited;
ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI->getParent(), Visited,
Uses, UseMIs, UseMBBs);
// Remove live range from barrier to the restore. FIXME: Find a better
// point to re-start the live interval.
VNInfo* AfterValNo = UpdateRegisterInterval(ValNo,
LIs->getUseIndex(BarrierIdx)+1,
LIs->getDefIndex(RestoreIdx));
// Attempt to renumber the new valno into a new vreg.
RenumberValno(AfterValNo);
Owen Anderson
committed
/// RenumberValno - Split the given valno out into a new vreg, allowing it to
/// be allocated to a different register. This function creates a new vreg,
/// copies the valno and its live ranges over to the new vreg's interval,
/// removes them from the old interval, and rewrites all uses and defs of
/// the original reg to the new vreg within those ranges.
void PreAllocSplitting::RenumberValno(VNInfo* VN) {
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
SmallVector<VNInfo*, 4> Stack;
SmallVector<VNInfo*, 4> VNsToCopy;
Stack.push_back(VN);
// Walk through and copy the valno we care about, and any other valnos
// that are two-address redefinitions of the one we care about. These
// will need to be rewritten as well. We also check for safety of the
// renumbering here, by making sure that none of the valno involved has
// phi kills.
while (!Stack.empty()) {
VNInfo* OldVN = Stack.back();
Stack.pop_back();
// Bail out if we ever encounter a valno that has a PHI kill. We can't
// renumber these.
if (OldVN->hasPHIKill) return;
VNsToCopy.push_back(OldVN);
// Locate two-address redefinitions
for (SmallVector<unsigned, 4>::iterator KI = OldVN->kills.begin(),
KE = OldVN->kills.end(); KI != KE; ++KI) {
MachineInstr* MI = LIs->getInstructionFromIndex(*KI);
//if (!MI) continue;
unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg);
if (DefIdx == ~0U) continue;
if (MI->isRegReDefinedByTwoAddr(DefIdx)) {
VNInfo* NextVN =
CurrLI->findDefinedVNInfo(LiveIntervals::getDefIndex(*KI));
Stack.push_back(NextVN);
}
}
}
Owen Anderson
committed
// Create the new vreg
unsigned NewVReg = MRI->createVirtualRegister(MRI->getRegClass(CurrLI->reg));
// Create the new live interval
Owen Anderson
committed
LiveInterval& NewLI = LIs->getOrCreateInterval(NewVReg);
for (SmallVector<VNInfo*, 4>::iterator OI = VNsToCopy.begin(), OE =
VNsToCopy.end(); OI != OE; ++OI) {
VNInfo* OldVN = *OI;
// Copy the valno over
VNInfo* NewVN = NewLI.getNextValue(OldVN->def, OldVN->copy,
LIs->getVNInfoAllocator());
NewLI.copyValNumInfo(NewVN, OldVN);
NewLI.MergeValueInAsValue(*CurrLI, OldVN, NewVN);
// Remove the valno from the old interval
CurrLI->removeValNo(OldVN);
}
Owen Anderson
committed
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
// Rewrite defs and uses. This is done in two stages to avoid invalidating
// the reg_iterator.
SmallVector<std::pair<MachineInstr*, unsigned>, 8> OpsToChange;
for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(CurrLI->reg),
E = MRI->reg_end(); I != E; ++I) {
MachineOperand& MO = I.getOperand();
unsigned InstrIdx = LIs->getInstructionIndex(&*I);
if ((MO.isUse() && NewLI.liveAt(LiveIntervals::getUseIndex(InstrIdx))) ||
(MO.isDef() && NewLI.liveAt(LiveIntervals::getDefIndex(InstrIdx))))
OpsToChange.push_back(std::make_pair(&*I, I.getOperandNo()));
}
for (SmallVector<std::pair<MachineInstr*, unsigned>, 8>::iterator I =
OpsToChange.begin(), E = OpsToChange.end(); I != E; ++I) {
MachineInstr* Inst = I->first;
unsigned OpIdx = I->second;
MachineOperand& MO = Inst->getOperand(OpIdx);
MO.setReg(NewVReg);
}
NumRenumbers++;
Owen Anderson
committed
}
bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
MachineInstr* DefMI,
MachineBasicBlock::iterator RestorePt,
unsigned RestoreIdx,
SmallPtrSet<MachineInstr*, 4>& RefsInMBB) {
MachineBasicBlock& MBB = *RestorePt->getParent();
MachineBasicBlock::iterator KillPt = BarrierMBB->end();
unsigned KillIdx = 0;
if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB)
KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, KillIdx);
else
KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx);
if (KillPt == DefMI->getParent()->end())
return false;
TII->reMaterialize(MBB, RestorePt, vreg, DefMI);
LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx);
ReconstructLiveInterval(CurrLI);
unsigned RematIdx = LIs->getInstructionIndex(prior(RestorePt));
RematIdx = LiveIntervals::getDefIndex(RematIdx);
RenumberValno(CurrLI->findDefinedVNInfo(RematIdx));
++NumSplits;
++NumRemats;
Owen Anderson
committed
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
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
1191
1192
1193
1194
return true;
}
MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg,
const TargetRegisterClass* RC,
MachineInstr* DefMI,
MachineInstr* Barrier,
MachineBasicBlock* MBB,
int& SS,
SmallPtrSet<MachineInstr*, 4>& RefsInMBB) {
MachineBasicBlock::iterator Pt = MBB->begin();
// Go top down if RefsInMBB is empty.
if (RefsInMBB.empty())
return 0;
MachineBasicBlock::iterator FoldPt = Barrier;
while (&*FoldPt != DefMI && FoldPt != MBB->begin() &&
!RefsInMBB.count(FoldPt))
--FoldPt;
int OpIdx = FoldPt->findRegisterDefOperandIdx(vreg, false);
if (OpIdx == -1)
return 0;
SmallVector<unsigned, 1> Ops;
Ops.push_back(OpIdx);
if (!TII->canFoldMemoryOperand(FoldPt, Ops))
return 0;
DenseMap<unsigned, int>::iterator I = IntervalSSMap.find(vreg);
if (I != IntervalSSMap.end()) {
SS = I->second;
} else {
SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
}
MachineInstr* FMI = TII->foldMemoryOperand(*MBB->getParent(),
FoldPt, Ops, SS);
if (FMI) {
LIs->ReplaceMachineInstrInMaps(FoldPt, FMI);
FMI = MBB->insert(MBB->erase(FoldPt), FMI);
++NumFolds;
IntervalSSMap[vreg] = SS;
CurrSLI = &LSs->getOrCreateInterval(SS);
if (CurrSLI->hasAtLeastOneValue())
CurrSValNo = CurrSLI->getValNumInfo(0);
else
CurrSValNo = CurrSLI->getNextValue(~0U, 0, LSs->getVNInfoAllocator());
}
Owen Anderson
committed
return FMI;
Evan Cheng
committed
/// SplitRegLiveInterval - Split (spill and restore) the given live interval
/// so it would not cross the barrier that's being processed. Shrink wrap
/// (minimize) the live interval to the last uses.
bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
CurrLI = LI;
// Find live range where current interval cross the barrier.
LiveInterval::iterator LR =
CurrLI->FindLiveRangeContaining(LIs->getUseIndex(BarrierIdx));
VNInfo *ValNo = LR->valno;
if (ValNo->def == ~1U) {
// Defined by a dead def? How can this be?
assert(0 && "Val# is defined by a dead def?");
abort();
}
Evan Cheng
committed
MachineInstr *DefMI = (ValNo->def != ~0U)
? LIs->getInstructionFromIndex(ValNo->def) : NULL;
Owen Anderson
committed
// If this would create a new join point, do not split.
if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier->getParent()))
return false;
Evan Cheng
committed
// Find all references in the barrier mbb.
SmallPtrSet<MachineInstr*, 4> RefsInMBB;
for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(CurrLI->reg),
E = MRI->reg_end(); I != E; ++I) {
MachineInstr *RefMI = &*I;
if (RefMI->getParent() == BarrierMBB)
RefsInMBB.insert(RefMI);
}
// Find a point to restore the value after the barrier.
Evan Cheng
committed
MachineBasicBlock::iterator RestorePt =
Evan Cheng
committed
findRestorePoint(BarrierMBB, Barrier, LR->end, RefsInMBB, RestoreIndex);
Evan Cheng
committed
if (RestorePt == BarrierMBB->end())
return false;
if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI))
if (Rematerialize(LI->reg, ValNo, DefMI, RestorePt,
RestoreIndex, RefsInMBB))
return true;
Evan Cheng
committed
// Add a spill either before the barrier or after the definition.
Evan Cheng
committed
MachineBasicBlock *DefMBB = DefMI ? DefMI->getParent() : NULL;
Evan Cheng
committed
const TargetRegisterClass *RC = MRI->getRegClass(CurrLI->reg);
unsigned SpillIndex = 0;
Evan Cheng
committed
MachineInstr *SpillMI = NULL;
Evan Cheng
committed
if (ValNo->def == ~0U) {
Evan Cheng
committed
// If it's defined by a phi, we must split just before the barrier.
Owen Anderson
committed
if ((SpillMI = FoldSpill(LI->reg, RC, 0, Barrier,
BarrierMBB, SS, RefsInMBB))) {
SpillIndex = LIs->getInstructionIndex(SpillMI);
} else {
MachineBasicBlock::iterator SpillPt =
findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB, SpillIndex);
if (SpillPt == BarrierMBB->begin())
return false; // No gap to insert spill.
// Add spill.
SS = CreateSpillStackSlot(CurrLI->reg, RC);
TII->storeRegToStackSlot(*BarrierMBB, SpillPt, CurrLI->reg, true, SS, RC);
SpillMI = prior(SpillPt);
LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex);
}
Evan Cheng
committed
} else if (!IsAvailableInStack(DefMBB, CurrLI->reg, ValNo->def,
RestoreIndex, SpillIndex, SS)) {
Evan Cheng
committed
// If it's already split, just restore the value. There is no need to spill
// the def again.
if (!DefMI)
return false; // Def is dead. Do nothing.
Owen Anderson
committed
if ((SpillMI = FoldSpill(LI->reg, RC, DefMI, Barrier,
BarrierMBB, SS, RefsInMBB))) {
SpillIndex = LIs->getInstructionIndex(SpillMI);
Evan Cheng
committed
} else {
Owen Anderson
committed
// Check if it's possible to insert a spill after the def MI.
MachineBasicBlock::iterator SpillPt;
if (DefMBB == BarrierMBB) {
// Add spill after the def and the last use before the barrier.
SpillPt = findSpillPoint(BarrierMBB, Barrier, DefMI,
RefsInMBB, SpillIndex);
if (SpillPt == DefMBB->begin())
return false; // No gap to insert spill.
} else {
SpillPt = findNextEmptySlot(DefMBB, DefMI, SpillIndex);
if (SpillPt == DefMBB->end())
return false; // No gap to insert spill.
}
// Add spill. The store instruction kills the register if def is before
// the barrier in the barrier block.
SS = CreateSpillStackSlot(CurrLI->reg, RC);
TII->storeRegToStackSlot(*DefMBB, SpillPt, CurrLI->reg,
DefMBB == BarrierMBB, SS, RC);
SpillMI = prior(SpillPt);
LIs->InsertMachineInstrInMaps(SpillMI, SpillIndex);
Evan Cheng
committed
}
Evan Cheng
committed
}
Evan Cheng
committed
// Remember def instruction index to spill index mapping.
if (DefMI && SpillMI)
Def2SpillMap[ValNo->def] = SpillIndex;
Evan Cheng
committed
// Add restore.
TII->loadRegFromStackSlot(*BarrierMBB, RestorePt, CurrLI->reg, SS, RC);
MachineInstr *LoadMI = prior(RestorePt);
LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
// 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::getNumberOfSpills(
SmallPtrSet<MachineInstr*, 4>& MIs,
unsigned Reg, int FrameIndex) {
unsigned Spills = 0;
for (SmallPtrSet<MachineInstr*, 4>::iterator UI = MIs.begin(), UE = MIs.end();
UI != UI; ++UI) {
int StoreFrameIndex;
unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
if (StoreVReg == Reg && StoreFrameIndex == FrameIndex)
Spills++;
}
return Spills;
}
/// 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;
for (SmallPtrSet<LiveInterval*, 8>::iterator LI = split.begin(),
LE = split.end(); LI != LE; ++LI) {
Owen Anderson
committed
DenseMap<VNInfo*, SmallPtrSet<MachineInstr*, 4> > VNUseCount;
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);
}
for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(),
VE = (*LI)->vni_end(); VI != VE; ++VI) {
VNInfo* CurrVN = *VI;
if (CurrVN->hasPHIKill) continue;
unsigned DefIdx = CurrVN->def;
if (DefIdx == ~0U || DefIdx == ~1U) continue;
Owen Anderson
committed
MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx);
int FrameIndex;
if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue;
Owen Anderson
committed
if (VNUseCount[CurrVN].size() == 0) {
LIs->RemoveMachineInstrFromMaps(DefMI);
(*LI)->removeValNo(CurrVN);
DefMI->eraseFromParent();
NumDeadSpills++;
changed = true;
continue;
}
unsigned SpillCount = getNumberOfSpills(VNUseCount[CurrVN],
(*LI)->reg, FrameIndex);
if (SpillCount != VNUseCount[CurrVN].size()) continue;
Owen Anderson
committed
for (SmallPtrSet<MachineInstr*, 4>::iterator UI =
VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end();
UI != UI; ++UI) {
LIs->RemoveMachineInstrFromMaps(*UI);
(*UI)->eraseFromParent();
Owen Anderson
committed
}
LIs->RemoveMachineInstrFromMaps(DefMI);
(*LI)->removeValNo(CurrVN);
DefMI->eraseFromParent();
NumDeadSpills++;
changed = true;
}
}
return changed;
}
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
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));
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
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();
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;