summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2013-04-10 06:42:34 +0000
committerHal Finkel <hfinkel@anl.gov>2013-04-10 06:42:34 +0000
commit500b004566138520174c4d4ef2c1f741a324f3a5 (patch)
tree2277e558a8630070af99933b8f310e8eef715761 /llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
parent3365e52fa51aa56975adcfb9612df7f481d0acf7 (diff)
downloadbcm5719-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.cpp21
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;
}
}
OpenPOWER on IntegriCloud