summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineLICM.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2011-10-17 19:50:12 +0000
committerEvan Cheng <evan.cheng@apple.com>2011-10-17 19:50:12 +0000
commit1025cce290d99fd325bccd0c1e89dab49eea8140 (patch)
tree0f77ee50c83201605b1264351fe1588affece51c /lib/CodeGen/MachineLICM.cpp
parent63aa7910ae35afa04d763df4fa56e3187fd68d33 (diff)
downloadllvm-1025cce290d99fd325bccd0c1e89dab49eea8140.tar.gz
llvm-1025cce290d99fd325bccd0c1e89dab49eea8140.tar.bz2
llvm-1025cce290d99fd325bccd0c1e89dab49eea8140.tar.xz
Constraint register class with constrainRegClass() to CSE a virtual into another. rdar://10293289
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142234 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineLICM.cpp')
-rw-r--r--lib/CodeGen/MachineLICM.cpp29
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index 8f7a8ebb26..969a9b084d 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -1196,6 +1196,7 @@ bool MachineLICM::EliminateCSE(MachineInstr *MI,
// Replace virtual registers defined by MI by their counterparts defined
// by Dup.
+ SmallVector<unsigned, 2> Defs;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
@@ -1206,11 +1207,33 @@ bool MachineLICM::EliminateCSE(MachineInstr *MI,
"Instructions with different phys regs are not identical!");
if (MO.isReg() && MO.isDef() &&
- !TargetRegisterInfo::isPhysicalRegister(MO.getReg())) {
- MRI->replaceRegWith(MO.getReg(), Dup->getOperand(i).getReg());
- MRI->clearKillFlags(Dup->getOperand(i).getReg());
+ !TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+ Defs.push_back(i);
+ }
+
+ SmallVector<const TargetRegisterClass*, 2> OrigRCs;
+ for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
+ unsigned Idx = Defs[i];
+ unsigned Reg = MI->getOperand(Idx).getReg();
+ unsigned DupReg = Dup->getOperand(Idx).getReg();
+ OrigRCs.push_back(MRI->getRegClass(DupReg));
+
+ if (!MRI->constrainRegClass(DupReg, MRI->getRegClass(Reg))) {
+ // Restore old RCs if more than one defs.
+ for (unsigned j = 0; j != i; ++j)
+ MRI->setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
+ return false;
}
}
+
+ for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
+ unsigned Idx = Defs[i];
+ unsigned Reg = MI->getOperand(Idx).getReg();
+ unsigned DupReg = Dup->getOperand(Idx).getReg();
+ MRI->replaceRegWith(Reg, DupReg);
+ MRI->clearKillFlags(DupReg);
+ }
+
MI->eraseFromParent();
++NumCSEed;
return true;