Skip to content

Commit 5efe871

Browse files
committed
LiveInterval: Distribute subregister liveranges to new intervals in ConnectedVNInfoEqClasses::Distribute()
This improves ConnectedVNInfoEqClasses::Distribute() to distribute the segments and value numbers in the subranges instead of conservatively clearing all subregister info. No separate test here, just clearing the subrange instead of properly distributing them would however break my upcoming fix regarding dead super register definitions. Differential Revision: http://reviews.llvm.org/D13075 llvm-svn: 248334
1 parent deade19 commit 5efe871

File tree

1 file changed

+65
-29
lines changed

1 file changed

+65
-29
lines changed

llvm/lib/CodeGen/LiveInterval.cpp

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,40 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
13721372
return EqClass.getNumClasses();
13731373
}
13741374

1375+
template<typename LiveRangeT, typename EqClassesT>
1376+
static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[],
1377+
EqClassesT VNIClasses) {
1378+
// Move segments to new intervals.
1379+
LiveRange::iterator J = LR.begin(), E = LR.end();
1380+
while (J != E && VNIClasses[J->valno->id] == 0)
1381+
++J;
1382+
for (LiveRange::iterator I = J; I != E; ++I) {
1383+
if (unsigned eq = VNIClasses[I->valno->id]) {
1384+
assert((SplitLRs[eq-1]->empty() || SplitLRs[eq-1]->expiredAt(I->start)) &&
1385+
"New intervals should be empty");
1386+
SplitLRs[eq-1]->segments.push_back(*I);
1387+
} else
1388+
*J++ = *I;
1389+
}
1390+
LR.segments.erase(J, E);
1391+
1392+
// Transfer VNInfos to their new owners and renumber them.
1393+
unsigned j = 0, e = LR.getNumValNums();
1394+
while (j != e && VNIClasses[j] == 0)
1395+
++j;
1396+
for (unsigned i = j; i != e; ++i) {
1397+
VNInfo *VNI = LR.getValNumInfo(i);
1398+
if (unsigned eq = VNIClasses[i]) {
1399+
VNI->id = SplitLRs[eq-1]->getNumValNums();
1400+
SplitLRs[eq-1]->valnos.push_back(VNI);
1401+
} else {
1402+
VNI->id = j;
1403+
LR.valnos[j++] = VNI;
1404+
}
1405+
}
1406+
LR.valnos.resize(j);
1407+
}
1408+
13751409
void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
13761410
MachineRegisterInfo &MRI) {
13771411
// Rewrite instructions.
@@ -1399,35 +1433,37 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
13991433
MO.setReg(LIV[EqClass-1]->reg);
14001434
}
14011435

1402-
// Move runs to new intervals.
1403-
LiveInterval::iterator J = LI.begin(), E = LI.end();
1404-
while (J != E && EqClass[J->valno->id] == 0)
1405-
++J;
1406-
for (LiveInterval::iterator I = J; I != E; ++I) {
1407-
if (unsigned eq = EqClass[I->valno->id]) {
1408-
assert((LIV[eq-1]->empty() || LIV[eq-1]->expiredAt(I->start)) &&
1409-
"New intervals should be empty");
1410-
LIV[eq-1]->segments.push_back(*I);
1411-
} else
1412-
*J++ = *I;
1413-
}
1414-
// TODO: do not cheat anymore by simply cleaning all subranges
1415-
LI.clearSubRanges();
1416-
LI.segments.erase(J, E);
1417-
1418-
// Transfer VNInfos to their new owners and renumber them.
1419-
unsigned j = 0, e = LI.getNumValNums();
1420-
while (j != e && EqClass[j] == 0)
1421-
++j;
1422-
for (unsigned i = j; i != e; ++i) {
1423-
VNInfo *VNI = LI.getValNumInfo(i);
1424-
if (unsigned eq = EqClass[i]) {
1425-
VNI->id = LIV[eq-1]->getNumValNums();
1426-
LIV[eq-1]->valnos.push_back(VNI);
1427-
} else {
1428-
VNI->id = j;
1429-
LI.valnos[j++] = VNI;
1436+
// Distribute subregister liveranges.
1437+
if (LI.hasSubRanges()) {
1438+
unsigned NumComponents = EqClass.getNumClasses();
1439+
SmallVector<unsigned, 8> VNIMapping;
1440+
SmallVector<LiveInterval::SubRange*, 8> SubRanges;
1441+
BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator();
1442+
for (LiveInterval::SubRange &SR : LI.subranges()) {
1443+
// Create new subranges in the split intervals and construct a mapping
1444+
// for the VNInfos in the subrange.
1445+
unsigned NumValNos = SR.valnos.size();
1446+
VNIMapping.clear();
1447+
VNIMapping.reserve(NumValNos);
1448+
SubRanges.clear();
1449+
SubRanges.resize(NumComponents-1, nullptr);
1450+
for (unsigned I = 0; I < NumValNos; ++I) {
1451+
const VNInfo &VNI = *SR.valnos[I];
1452+
const VNInfo *MainRangeVNI = LI.getVNInfoAt(VNI.def);
1453+
assert(MainRangeVNI != nullptr
1454+
&& "SubRange def must have corresponding main range def");
1455+
unsigned ComponentNum = getEqClass(MainRangeVNI);
1456+
VNIMapping.push_back(ComponentNum);
1457+
if (ComponentNum > 0 && SubRanges[ComponentNum-1] == nullptr) {
1458+
SubRanges[ComponentNum-1]
1459+
= LIV[ComponentNum-1]->createSubRange(Allocator, SR.LaneMask);
1460+
}
1461+
}
1462+
DistributeRange(SR, SubRanges.data(), VNIMapping);
14301463
}
1464+
LI.removeEmptySubRanges();
14311465
}
1432-
LI.valnos.resize(j);
1466+
1467+
// Distribute main liverange.
1468+
DistributeRange(LI, LIV, EqClass);
14331469
}

0 commit comments

Comments
 (0)