diff options
author | Hal Finkel <hfinkel@anl.gov> | 2013-04-10 06:42:34 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2013-04-10 06:42:34 +0000 |
commit | 500b004566138520174c4d4ef2c1f741a324f3a5 (patch) | |
tree | 2277e558a8630070af99933b8f310e8eef715761 /llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | |
parent | 3365e52fa51aa56975adcfb9612df7f481d0acf7 (diff) | |
download | bcm5719-llvm-500b004566138520174c4d4ef2c1f741a324f3a5.tar.gz bcm5719-llvm-500b004566138520174c4d4ef2c1f741a324f3a5.zip |
PPC: Prep for if conversion of bctr[l]
This adds in-principle support for if-converting the bctr[l] instructions.
These instructions are used for indirect branching. It seems, however, that the
current if converter will never actually predicate these. To do so, it would
need the ability to hoist a few setup insts. out of the conditionally-executed
block. For example, code like this:
void foo(int a, int (*bar)()) { if (a != 0) bar(); }
becomes:
...
beq 0, .LBB0_2
std 2, 40(1)
mr 12, 4
ld 3, 0(4)
ld 11, 16(4)
ld 2, 8(4)
mtctr 3
bctrl
ld 2, 40(1)
.LBB0_2:
...
and it would be safe to do all of this unconditionally with a predicated
beqctrl instruction.
llvm-svn: 179156
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCInstrInfo.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index 51bc4f23cce..773b62326fb 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -882,6 +882,10 @@ bool PPCInstrInfo::isPredicated(const MachineInstr *MI) const { default: return false; case PPC::BCC: + case PPC::BCCTR: + case PPC::BCCTR8: + case PPC::BCCTRL: + case PPC::BCCTRL8: case PPC::BCLR: case PPC::BDZLR: case PPC::BDZLR8: @@ -938,6 +942,19 @@ bool PPCInstrInfo::PredicateInstruction( } return true; + } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || + OpC == PPC::BCTRL || OpC == PPC::BCTRL8) { + if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) + llvm_unreachable("Cannot predicate bctr[l] on the ctr register"); + + bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8; + bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); + MI->setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8) : + (setLR ? PPC::BCCTRL : PPC::BCCTR))); + MachineInstrBuilder(*MI->getParent()->getParent(), MI) + .addImm(Pred[0].getImm()) + .addReg(Pred[1].getReg()); + return true; } return false; @@ -1009,6 +1026,10 @@ bool PPCInstrInfo::isPredicable(MachineInstr *MI) const { return false; case PPC::B: case PPC::BLR: + case PPC::BCTR: + case PPC::BCTR8: + case PPC::BCTRL: + case PPC::BCTRL8: return true; } } |