summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveIntervalAnalysis.cpp
diff options
context:
space:
mode:
authorCameron Zwarich <zwarich@apple.com>2013-02-20 22:09:57 +0000
committerCameron Zwarich <zwarich@apple.com>2013-02-20 22:09:57 +0000
commit0e827ebc783ded58c11aeb0d66bed43e214de2de (patch)
tree813c01e20c359a5126f4e5c694a8041cac71c669 /lib/CodeGen/LiveIntervalAnalysis.cpp
parentc46e2df74cf75a33742f57d2b4d6c6fcf73bced9 (diff)
downloadllvm-0e827ebc783ded58c11aeb0d66bed43e214de2de.tar.gz
llvm-0e827ebc783ded58c11aeb0d66bed43e214de2de.tar.bz2
llvm-0e827ebc783ded58c11aeb0d66bed43e214de2de.tar.xz
Make repairIntervalsInRange() more robust. There are now no longer any liveness-
related failures when running 'make check' without LiveVariables with the verifier enabled. Some of the remaining failures elsewhere may still be fallout from incorrect updating of LiveIntervals or the few missing cases left in the two-address pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175672 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp73
1 files changed, 58 insertions, 15 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 8177db6194..e07922b54c 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1066,13 +1066,27 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
continue;
LiveInterval &LI = getInterval(Reg);
- LiveInterval::iterator LII = LI.FindLiveRangeContaining(endIdx);
+ // FIXME: Should we support undefs that gain defs?
+ if (!LI.hasAtLeastOneValue())
+ continue;
+
+ LiveInterval::iterator LII = LI.find(endIdx);
+ SlotIndex lastUseIdx;
+ if (LII != LI.end() && LII->start < endIdx)
+ lastUseIdx = LII->end;
+ else
+ --LII;
for (MachineBasicBlock::iterator I = End; I != Begin;) {
--I;
MachineInstr *MI = I;
SlotIndex instrIdx = getInstructionIndex(MI);
+ bool isStartValid = getInstructionFromIndex(LII->start);
+ bool isEndValid = getInstructionFromIndex(LII->end);
+
+ // FIXME: This doesn't currently handle early-clobber or multiple removed
+ // defs inside of the region to repair.
for (MachineInstr::mop_iterator OI = MI->operands_begin(),
OE = MI->operands_end(); OI != OE; ++OI) {
const MachineOperand &MO = *OI;
@@ -1080,25 +1094,54 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
continue;
if (MO.isDef()) {
- assert(LII != LI.end() &&
- "Dead register defs are not yet supported.");
- if (!Indexes->getInstructionFromIndex(LII->start)) {
- LII->start = instrIdx.getRegSlot();
- LII->valno->def = instrIdx.getRegSlot();
+ if (!isStartValid) {
+ if (LII->end.isDead()) {
+ SlotIndex prevStart;
+ if (LII != LI.begin())
+ prevStart = llvm::prior(LII)->start;
+
+ // FIXME: This could be more efficient if there was a removeRange
+ // method that returned an iterator.
+ LI.removeRange(*LII, true);
+ if (prevStart.isValid())
+ LII = LI.find(prevStart);
+ else
+ LII = LI.begin();
+ } else {
+ LII->start = instrIdx.getRegSlot();
+ LII->valno->def = instrIdx.getRegSlot();
+ if (MO.getSubReg() && !MO.isUndef())
+ lastUseIdx = instrIdx.getRegSlot();
+ else
+ lastUseIdx = SlotIndex();
+ continue;
+ }
+ }
+
+ if (!lastUseIdx.isValid()) {
+ VNInfo *VNI = LI.getNextValue(instrIdx.getRegSlot(),
+ VNInfoAllocator);
+ LiveRange LR(instrIdx.getRegSlot(), instrIdx.getDeadSlot(), VNI);
+ LII = LI.addRange(LR);
} else if (LII->start != instrIdx.getRegSlot()) {
- VNInfo *VNI = LI.getNextValue(instrIdx.getRegSlot(), VNInfoAllocator);
- LiveRange LR = LiveRange(instrIdx.getRegSlot(), LII->start, VNI);
+ VNInfo *VNI = LI.getNextValue(instrIdx.getRegSlot(),
+ VNInfoAllocator);
+ LiveRange LR(instrIdx.getRegSlot(), lastUseIdx, VNI);
LII = LI.addRange(LR);
}
- } else if (MO.isUse()) {
- if (LII == LI.end())
- --LII;
- assert(LII->start < instrIdx &&
- "Registers with multiple used live ranges are not yet supported.");
- SlotIndex endIdx = LII->end;
- if (!endIdx.isBlock() && !Indexes->getInstructionFromIndex(endIdx))
+ if (MO.getSubReg() && !MO.isUndef())
+ lastUseIdx = instrIdx.getRegSlot();
+ else
+ lastUseIdx = SlotIndex();
+ } else if (MO.isUse()) {
+ // FIXME: This should probably be handled outside of this branch,
+ // either as part of the def case (for defs inside of the region) or
+ // after the loop over the region.
+ if (!isEndValid && !LII->end.isBlock())
LII->end = instrIdx.getRegSlot();
+ if (!lastUseIdx.isValid())
+ lastUseIdx = instrIdx.getRegSlot();
}
}
}