summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/LiveIntervalAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp32
1 files changed, 17 insertions, 15 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 2a93a35..a60d34f 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -53,7 +53,8 @@ static cl::opt<bool> DisableReMat("disable-rematerialization",
static cl::opt<bool> EnableFastSpilling("fast-spill",
cl::init(false), cl::Hidden);
-static cl::opt<bool> EarlyCoalescing("early-coalescing", cl::init(false));
+static cl::opt<bool> EarlyCoalescing("early-coalescing",
+ cl::init(false), cl::Hidden);
static cl::opt<int> CoalescingLimit("early-coalescing-limit",
cl::init(-1), cl::Hidden);
@@ -646,17 +647,17 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
0, false, VNInfoAllocator);
vni->setIsPHIDef(true);
LiveRange LR(start, end, vni);
-
+
interval.addRange(LR);
LR.valno->addKill(end);
DEBUG(errs() << " +" << LR << '\n');
}
-bool
-LiveIntervals::isProfitableToCoalesce(LiveInterval &DstInt, LiveInterval &SrcInt,
- SmallVector<MachineInstr*,16> &IdentCopies,
- SmallVector<MachineInstr*,16> &OtherCopies) {
- bool HaveConflict = false;
+bool LiveIntervals::
+isSafeAndProfitableToCoalesce(LiveInterval &DstInt,
+ LiveInterval &SrcInt,
+ SmallVector<MachineInstr*,16> &IdentCopies,
+ SmallVector<MachineInstr*,16> &OtherCopies) {
unsigned NumIdent = 0;
for (MachineRegisterInfo::def_iterator ri = mri_->def_begin(SrcInt.reg),
re = mri_->def_end(); ri != re; ++ri) {
@@ -665,16 +666,16 @@ LiveIntervals::isProfitableToCoalesce(LiveInterval &DstInt, LiveInterval &SrcInt
if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
return false;
if (SrcReg != DstInt.reg) {
+ // Non-identity copy - we cannot handle overlapping intervals
+ if (DstInt.liveAt(getInstructionIndex(MI)))
+ return false;
OtherCopies.push_back(MI);
- HaveConflict |= DstInt.liveAt(getInstructionIndex(MI));
} else {
IdentCopies.push_back(MI);
++NumIdent;
}
}
- if (!HaveConflict)
- return false; // Let coalescer handle it
return IdentCopies.size() > OtherCopies.size();
}
@@ -701,19 +702,21 @@ void LiveIntervals::performEarlyCoalescing() {
LiveInterval &SrcInt = getInterval(PHISrc);
SmallVector<MachineInstr*, 16> IdentCopies;
SmallVector<MachineInstr*, 16> OtherCopies;
- if (!isProfitableToCoalesce(DstInt, SrcInt, IdentCopies, OtherCopies))
+ if (!isSafeAndProfitableToCoalesce(DstInt, SrcInt,
+ IdentCopies, OtherCopies))
continue;
DEBUG(errs() << "PHI Join: " << *Join);
assert(DstInt.containsOneValue() && "PHI join should have just one val#!");
+ assert(std::distance(mri_->use_begin(PHISrc), mri_->use_end()) == 1 &&
+ "PHI join src should not be used elsewhere");
VNInfo *VNI = DstInt.getValNumInfo(0);
// Change the non-identity copies to directly target the phi destination.
for (unsigned i = 0, e = OtherCopies.size(); i != e; ++i) {
MachineInstr *PHICopy = OtherCopies[i];
- DEBUG(errs() << "Moving: " << *PHICopy);
-
SlotIndex MIIndex = getInstructionIndex(PHICopy);
+ DEBUG(errs() << "Moving: " << MIIndex << ' ' << *PHICopy);
SlotIndex DefIndex = MIIndex.getDefIndex();
LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
SlotIndex StartIndex = SLR->start;
@@ -724,8 +727,7 @@ void LiveIntervals::performEarlyCoalescing() {
SrcInt.removeValNo(SLR->valno);
DEBUG(errs() << " added range [" << StartIndex << ','
<< EndIndex << "] to reg" << DstInt.reg << '\n');
- if (DstInt.liveAt(StartIndex))
- DstInt.removeRange(StartIndex, EndIndex);
+ assert (!DstInt.liveAt(StartIndex) && "Cannot coalesce when dst live!");
VNInfo *NewVNI = DstInt.getNextValue(DefIndex, PHICopy, true,
VNInfoAllocator);
NewVNI->setHasPHIKill(true);
OpenPOWER on IntegriCloud