summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegisterCoalescer.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-06-30 01:45:55 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-06-30 01:45:55 +0000
commit682e8d05c7def2b82edc354abf1d38df607d39c8 (patch)
treea2620349107fe41368c65ab0a111b2377843462e /lib/CodeGen/RegisterCoalescer.cpp
parentea4755300665eaf03599d0cc55cfdd2c27946a19 (diff)
downloadllvm-682e8d05c7def2b82edc354abf1d38df607d39c8.tar.gz
llvm-682e8d05c7def2b82edc354abf1d38df607d39c8.tar.bz2
llvm-682e8d05c7def2b82edc354abf1d38df607d39c8.tar.xz
Handle implicit_defs in the register coalescer. I am still trying to produce
a reduced testcase, but this fixes pr13209. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159479 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterCoalescer.cpp')
-rw-r--r--lib/CodeGen/RegisterCoalescer.cpp67
1 files changed, 40 insertions, 27 deletions
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index 19b6ffcb51..6ef098d1a1 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -1172,14 +1172,11 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li,
MachineInstr *MI = li.getInstructionFromIndex(VNI->def);
- if (!MI || !MI->isFullCopy() || CP.isPartial() || CP.isPhys())
+ if (!MI || CP.isPartial() || CP.isPhys())
return false;
unsigned Dst = MI->getOperand(0).getReg();
- unsigned Src = MI->getOperand(1).getReg();
-
- if (!TargetRegisterInfo::isVirtualRegister(Src) ||
- !TargetRegisterInfo::isVirtualRegister(Dst))
+ if (!TargetRegisterInfo::isVirtualRegister(Dst))
return false;
unsigned A = CP.getDstReg();
@@ -1189,34 +1186,47 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li,
std::swap(A, B);
assert(Dst == A);
- const MachineInstr *OtherMI = li.getInstructionFromIndex(OtherVNI->def);
+ MachineInstr *OtherMI = li.getInstructionFromIndex(OtherVNI->def);
- if (!OtherMI || !OtherMI->isFullCopy())
+ if (!OtherMI)
return false;
unsigned OtherDst = OtherMI->getOperand(0).getReg();
- unsigned OtherSrc = OtherMI->getOperand(1).getReg();
-
- if (!TargetRegisterInfo::isVirtualRegister(OtherSrc) ||
- !TargetRegisterInfo::isVirtualRegister(OtherDst))
+ if (!TargetRegisterInfo::isVirtualRegister(OtherDst))
return false;
assert(OtherDst == B);
- if (Src != OtherSrc)
- return false;
+ if (MI->isImplicitDef()) {
+ DupCopies.push_back(MI);
+ return true;
+ } else {
+ if (!MI->isFullCopy())
+ return false;
+ unsigned Src = MI->getOperand(1).getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(Src))
+ return false;
+ if (!OtherMI->isFullCopy())
+ return false;
+ unsigned OtherSrc = OtherMI->getOperand(1).getReg();
+ if (!TargetRegisterInfo::isVirtualRegister(OtherSrc))
+ return false;
- // If the copies use two different value numbers of X, we cannot merge
- // A and B.
- LiveInterval &SrcInt = li.getInterval(Src);
- // getVNInfoBefore returns NULL for undef copies. In this case, the
- // optimization is still safe.
- if (SrcInt.getVNInfoBefore(OtherVNI->def) != SrcInt.getVNInfoBefore(VNI->def))
- return false;
+ if (Src != OtherSrc)
+ return false;
- DupCopies.push_back(MI);
+ // If the copies use two different value numbers of X, we cannot merge
+ // A and B.
+ LiveInterval &SrcInt = li.getInterval(Src);
+ // getVNInfoBefore returns NULL for undef copies. In this case, the
+ // optimization is still safe.
+ if (SrcInt.getVNInfoBefore(OtherVNI->def) !=
+ SrcInt.getVNInfoBefore(VNI->def))
+ return false;
- return true;
+ DupCopies.push_back(MI);
+ return true;
+ }
}
/// joinIntervals - Attempt to join these two intervals. On failure, this
@@ -1254,7 +1264,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
continue;
MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
assert(MI && "Missing def");
- if (!MI->isCopyLike()) // Src not defined by a copy?
+ if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?
continue;
// Figure out the value # from the RHS.
@@ -1283,7 +1293,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
continue;
MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
assert(MI && "Missing def");
- if (!MI->isCopyLike()) // Src not defined by a copy?
+ if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?
continue;
// Figure out the value # from the LHS.
@@ -1429,14 +1439,17 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
if (!ErasedInstrs.insert(MI))
continue;
- // We have pretended that the assignment to B in
+ // If MI is a copy, then we have pretended that the assignment to B in
// A = X
// B = X
// was actually a copy from A. Now that we decided to coalesce A and B,
// transform the code into
// A = X
- unsigned Src = MI->getOperand(1).getReg();
- SourceRegisters.push_back(Src);
+ // In the case of the implicit_def, we just have to remove it.
+ if (!MI->isImplicitDef()) {
+ unsigned Src = MI->getOperand(1).getReg();
+ SourceRegisters.push_back(Src);
+ }
LIS->RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
}