[PATCH] D13035: LiveIntervalAnalysis: Avoid multiple connected liveness components
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 15:16:52 PDT 2015
MatzeB updated this revision to Diff 35427.
MatzeB added a comment.
New version which uses the existing mechanisms to split the live interval into multiple components.
Repository:
rL LLVM
http://reviews.llvm.org/D13035
Files:
lib/CodeGen/LiveIntervalAnalysis.cpp
test/CodeGen/AMDGPU/partially-dead-super-register-immediate.ll
Index: test/CodeGen/AMDGPU/partially-dead-super-register-immediate.ll
===================================================================
--- test/CodeGen/AMDGPU/partially-dead-super-register-immediate.ll
+++ test/CodeGen/AMDGPU/partially-dead-super-register-immediate.ll
@@ -1,4 +1,3 @@
-; XFAIL: *
; RUN: llc -march=amdgcn -verify-machineinstrs -verify-coalescing < %s
; The original and requires materializing a 64-bit immediate for
Index: lib/CodeGen/LiveIntervalAnalysis.cpp
===================================================================
--- lib/CodeGen/LiveIntervalAnalysis.cpp
+++ lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -198,9 +198,16 @@
void LiveIntervals::computeVirtRegInterval(LiveInterval &LI) {
assert(LRCalc && "LRCalc not initialized.");
assert(LI.empty() && "Should only compute empty intervals.");
+ bool ShouldTrackSubRegLiveness = MRI->shouldTrackSubRegLiveness(LI.reg);
LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
- LRCalc->calculate(LI, MRI->shouldTrackSubRegLiveness(LI.reg));
- computeDeadValues(LI, nullptr);
+ LRCalc->calculate(LI, ShouldTrackSubRegLiveness);
+ bool SeparatedComponents = computeDeadValues(LI, nullptr);
+ if (SeparatedComponents) {
+ assert(ShouldTrackSubRegLiveness
+ && "Separated components should only occur for unused subreg defs");
+ SmallVector<LiveInterval*, 8> SplitLIs;
+ splitSeparateComponents(LI, SplitLIs);
+ }
}
void LiveIntervals::computeVirtRegs() {
@@ -457,7 +464,7 @@
bool LiveIntervals::computeDeadValues(LiveInterval &LI,
SmallVectorImpl<MachineInstr*> *dead) {
- bool PHIRemoved = false;
+ bool MayHaveSplitComponents = false;
for (auto VNI : LI.valnos) {
if (VNI->isUnused())
continue;
@@ -467,10 +474,13 @@
// Is the register live before? Otherwise we may have to add a read-undef
// flag for subregister defs.
- if (MRI->shouldTrackSubRegLiveness(LI.reg)) {
+ bool DeadBeforeDef = false;
+ unsigned VReg = LI.reg;
+ if (MRI->shouldTrackSubRegLiveness(VReg)) {
if ((I == LI.begin() || std::prev(I)->end < Def) && !VNI->isPHIDef()) {
MachineInstr *MI = getInstructionFromIndex(Def);
- MI->addRegisterDefReadUndef(LI.reg);
+ MI->addRegisterDefReadUndef(VReg);
+ DeadBeforeDef = true;
}
}
@@ -481,19 +491,27 @@
VNI->markUnused();
LI.removeSegment(I);
DEBUG(dbgs() << "Dead PHI at " << Def << " may separate interval\n");
- PHIRemoved = true;
+ MayHaveSplitComponents = true;
} else {
// This is a dead def. Make sure the instruction knows.
MachineInstr *MI = getInstructionFromIndex(Def);
assert(MI && "No instruction defining live value");
- MI->addRegisterDead(LI.reg, TRI);
+ MI->addRegisterDead(VReg, TRI);
+
+ // If we have a dead def that is completely separate from the rest of
+ // the liverange then we rewrite it to use a different VReg to not violate
+ // the rule that the liveness of a virtual register forms a connected
+ // component. This should only happen if subregister liveness is tracked.
+ if (DeadBeforeDef)
+ MayHaveSplitComponents = true;
+
if (dead && MI->allDefsAreDead()) {
DEBUG(dbgs() << "All defs dead: " << Def << '\t' << *MI);
dead->push_back(MI);
}
}
}
- return PHIRemoved;
+ return MayHaveSplitComponents;
}
void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13035.35427.patch
Type: text/x-patch
Size: 3536 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150922/84b2551e/attachment.bin>
More information about the llvm-commits
mailing list