summaryrefslogtreecommitdiff
path: root/lib/CodeGen/StrongPHIElimination.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2008-07-30 00:21:16 +0000
committerOwen Anderson <resistor@mac.com>2008-07-30 00:21:16 +0000
commitb9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8 (patch)
tree25fdcb3e80c50c482de10a3f7324a5933cc08ecc /lib/CodeGen/StrongPHIElimination.cpp
parent068acc3caa113db0925766d327bf9cae6a9eb885 (diff)
downloadllvm-b9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8.tar.gz
llvm-b9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8.tar.bz2
llvm-b9fb8d1e69aa910eb6bb03d3d66e5a2e25a20cd8.tar.xz
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.cpp55
1 files changed, 42 insertions, 13 deletions
diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp
index 3d23efec7b..0f1acc2d72 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);