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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179156 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Hal Finkel 2013-04-10 06:42:34 +00:00
parent a2561a0153
commit 90dd7fd167
3 changed files with 37 additions and 2 deletions

View File

@ -67,9 +67,14 @@ def HI48_64 : SDNodeXForm<imm, [{
//
let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
let isBranch = 1, isIndirectBranch = 1, Uses = [CTR8] in
let isBranch = 1, isIndirectBranch = 1, Uses = [CTR8] in {
def BCTR8 : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>,
Requires<[In64BitMode]>;
def BCCTR8 : XLForm_2_br<19, 528, 0, (outs), (ins pred:$cond),
"b${cond:cc}ctr ${cond:reg}", BrB, []>,
Requires<[In64BitMode]>;
}
}
let Defs = [LR8] in
@ -125,6 +130,9 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR8] in {
def BCTRL8 : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins),
"bctrl", BrB, [(PPCbctrl)]>,
Requires<[In64BitMode]>;
def BCCTRL8 : XLForm_2_br<19, 528, 1, (outs), (ins pred:$cond),
"b${cond:cc}ctrl ${cond:reg}", BrB, []>,
Requires<[In64BitMode]>;
}
}

View File

@ -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;
}
}

View File

@ -493,8 +493,12 @@ let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
let isReturn = 1, Uses = [LR, RM] in
def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (outs), (ins), "blr", BrB,
[(retflag)]>;
let isBranch = 1, isIndirectBranch = 1, Uses = [CTR] in
let isBranch = 1, isIndirectBranch = 1, Uses = [CTR] in {
def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>;
def BCCTR : XLForm_2_br<19, 528, 0, (outs), (ins pred:$cond),
"b${cond:cc}ctr ${cond:reg}", BrB, []>;
}
}
let Defs = [LR] in
@ -555,6 +559,8 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR] in {
def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins),
"bctrl", BrB, [(PPCbctrl)]>,
Requires<[In32BitMode]>;
def BCCTRL : XLForm_2_br<19, 528, 1, (outs), (ins pred:$cond),
"b${cond:cc}ctrl ${cond:reg}", BrB, []>;
}
}