summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveInterval.cpp
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2015-09-22 22:37:42 +0000
committerMatthias Braun <matze@braunis.de>2015-09-22 22:37:42 +0000
commitc047a220175f4d8c4c8539db1b386eca8fcc8ede (patch)
treee413d1f181c37d41a9e825ca6c4f0f7409ade55a /lib/CodeGen/LiveInterval.cpp
parent3286c1f6932e9e34b0f0280f52b3e3b2d5fd831b (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248334 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveInterval.cpp')
-rw-r--r--lib/CodeGen/LiveInterval.cpp94
1 files changed, 65 insertions, 29 deletions
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index 5c2dba4531a..f5e4f52455a 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -1372,6 +1372,40 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
return EqClass.getNumClasses();
}
+template<typename LiveRangeT, typename EqClassesT>
+static void DistributeRange(LiveRangeT &LR, LiveRangeT *SplitLRs[],
+ EqClassesT VNIClasses) {
+ // Move segments to new intervals.
+ LiveRange::iterator J = LR.begin(), E = LR.end();
+ while (J != E && VNIClasses[J->valno->id] == 0)
+ ++J;
+ for (LiveRange::iterator I = J; I != E; ++I) {
+ if (unsigned eq = VNIClasses[I->valno->id]) {
+ assert((SplitLRs[eq-1]->empty() || SplitLRs[eq-1]->expiredAt(I->start)) &&
+ "New intervals should be empty");
+ SplitLRs[eq-1]->segments.push_back(*I);
+ } else
+ *J++ = *I;
+ }
+ LR.segments.erase(J, E);
+
+ // Transfer VNInfos to their new owners and renumber them.
+ unsigned j = 0, e = LR.getNumValNums();
+ while (j != e && VNIClasses[j] == 0)
+ ++j;
+ for (unsigned i = j; i != e; ++i) {
+ VNInfo *VNI = LR.getValNumInfo(i);
+ if (unsigned eq = VNIClasses[i]) {
+ VNI->id = SplitLRs[eq-1]->getNumValNums();
+ SplitLRs[eq-1]->valnos.push_back(VNI);
+ } else {
+ VNI->id = j;
+ LR.valnos[j++] = VNI;
+ }
+ }
+ LR.valnos.resize(j);
+}
+
void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
MachineRegisterInfo &MRI) {
// Rewrite instructions.
@@ -1399,35 +1433,37 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
MO.setReg(LIV[EqClass-1]->reg);
}
- // Move runs to new intervals.
- LiveInterval::iterator J = LI.begin(), E = LI.end();
- while (J != E && EqClass[J->valno->id] == 0)
- ++J;
- for (LiveInterval::iterator I = J; I != E; ++I) {
- if (unsigned eq = EqClass[I->valno->id]) {
- assert((LIV[eq-1]->empty() || LIV[eq-1]->expiredAt(I->start)) &&
- "New intervals should be empty");
- LIV[eq-1]->segments.push_back(*I);
- } else
- *J++ = *I;
- }
- // TODO: do not cheat anymore by simply cleaning all subranges
- LI.clearSubRanges();
- LI.segments.erase(J, E);
-
- // Transfer VNInfos to their new owners and renumber them.
- unsigned j = 0, e = LI.getNumValNums();
- while (j != e && EqClass[j] == 0)
- ++j;
- for (unsigned i = j; i != e; ++i) {
- VNInfo *VNI = LI.getValNumInfo(i);
- if (unsigned eq = EqClass[i]) {
- VNI->id = LIV[eq-1]->getNumValNums();
- LIV[eq-1]->valnos.push_back(VNI);
- } else {
- VNI->id = j;
- LI.valnos[j++] = VNI;
+ // Distribute subregister liveranges.
+ if (LI.hasSubRanges()) {
+ unsigned NumComponents = EqClass.getNumClasses();
+ SmallVector<unsigned, 8> VNIMapping;
+ SmallVector<LiveInterval::SubRange*, 8> SubRanges;
+ BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator();
+ for (LiveInterval::SubRange &SR : LI.subranges()) {
+ // Create new subranges in the split intervals and construct a mapping
+ // for the VNInfos in the subrange.
+ unsigned NumValNos = SR.valnos.size();
+ VNIMapping.clear();
+ VNIMapping.reserve(NumValNos);
+ SubRanges.clear();
+ SubRanges.resize(NumComponents-1, nullptr);
+ for (unsigned I = 0; I < NumValNos; ++I) {
+ const VNInfo &VNI = *SR.valnos[I];
+ const VNInfo *MainRangeVNI = LI.getVNInfoAt(VNI.def);
+ assert(MainRangeVNI != nullptr
+ && "SubRange def must have corresponding main range def");
+ unsigned ComponentNum = getEqClass(MainRangeVNI);
+ VNIMapping.push_back(ComponentNum);
+ if (ComponentNum > 0 && SubRanges[ComponentNum-1] == nullptr) {
+ SubRanges[ComponentNum-1]
+ = LIV[ComponentNum-1]->createSubRange(Allocator, SR.LaneMask);
+ }
+ }
+ DistributeRange(SR, SubRanges.data(), VNIMapping);
}
+ LI.removeEmptySubRanges();
}
- LI.valnos.resize(j);
+
+ // Distribute main liverange.
+ DistributeRange(LI, LIV, EqClass);
}