diff options
author | Evan Cheng <evan.cheng@apple.com> | 2011-10-17 19:50:12 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2011-10-17 19:50:12 +0000 |
commit | 1025cce290d99fd325bccd0c1e89dab49eea8140 (patch) | |
tree | 0f77ee50c83201605b1264351fe1588affece51c /lib/CodeGen/MachineLICM.cpp | |
parent | 63aa7910ae35afa04d763df4fa56e3187fd68d33 (diff) | |
download | llvm-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.cpp | 29 |
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; |