diff options
author | Owen Anderson <resistor@mac.com> | 2008-07-30 00:21:16 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2008-07-30 00:21:16 +0000 |
commit | b9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8 (patch) | |
tree | 25fdcb3e80c50c482de10a3f7324a5933cc08ecc /lib/CodeGen/StrongPHIElimination.cpp | |
parent | 068acc3caa113db0925766d327bf9cae6a9eb885 (diff) | |
download | external_llvm-b9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8.zip external_llvm-b9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8.tar.gz external_llvm-b9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8.tar.bz2 |
When merging live intervals, we also need to merge in any live ranges that are inputs to two-address instructions
that themselves define a range we already care about.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54185 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/StrongPHIElimination.cpp')
-rw-r--r-- | lib/CodeGen/StrongPHIElimination.cpp | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp index 3d23efe..0f1acc2 100644 --- a/lib/CodeGen/StrongPHIElimination.cpp +++ b/lib/CodeGen/StrongPHIElimination.cpp @@ -792,20 +792,49 @@ void StrongPHIElimination::mergeLiveIntervals(unsigned primary, VNInfo* NewVN = LHS.getNextValue(RangeMergingIn->valno->def, RangeMergingIn->valno->copy, LI.getVNInfoAllocator()); - - for (LiveInterval::iterator RI = RHS.begin(), RE = RHS.end(); - RI != RE; ) - if (RI->valno == RHSVN) { - NewVN->hasPHIKill = true; - LiveRange NewRange(RI->start, RI->end, NewVN); - LHS.addRange(NewRange); + + // If we discover that a live range was defined by a two-addr + // instruction, we need to merge over the input as well, even if + // it has a different VNInfo. + SmallPtrSet<VNInfo*, 4> MergedVNs; + MergedVNs.insert(RHSVN); + + DenseMap<VNInfo*, VNInfo*> VNMap; + VNMap.insert(std::make_pair(RangeMergingIn->valno, NewVN)); + + bool changed = true; + while (changed) { + changed = false; + for (LiveInterval::iterator RI = RHS.begin(), RE = RHS.end(); + RI != RE; ) + if (MergedVNs.count(RI->valno)) { + NewVN->hasPHIKill = true; + LiveRange NewRange(RI->start, RI->end, VNMap[RI->valno]); + LHS.addRange(NewRange); + + MachineInstr* instr = LI.getInstructionFromIndex(RI->start); + for (unsigned i = 0; i < instr->getNumOperands(); ++i) { + if (instr->getOperand(i).isReg() && + instr->getOperand(i).getReg() == secondary) + if (instr->isRegReDefinedByTwoAddr(secondary, i)) { + VNInfo* twoaddr = RHS.getLiveRangeContaining(RI->start-1)->valno; + MergedVNs.insert(twoaddr); + + VNInfo* NextVN = LHS.getNextValue(twoaddr->def, + twoaddr->copy, + LI.getVNInfoAllocator()); + VNMap.insert(std::make_pair(twoaddr, NextVN)); + } + } - unsigned start = RI->start; - unsigned end = RI->end; - ++RI; - RHS.removeRange(start, end, true); - } else - ++RI; + unsigned start = RI->start; + unsigned end = RI->end; + ++RI; + RHS.removeRange(start, end, true); + changed = true; + } else + ++RI; + } if (RHS.begin() == RHS.end()) LI.removeInterval(RHS.reg); |