diff options
author | Chris Lattner <sabre@nondot.org> | 2005-10-01 23:06:26 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-10-01 23:06:26 +0000 |
commit | ca0a4778a8e3036df7e51ed375cc867e6bf024bd (patch) | |
tree | e7a0176a6e3c1cfb91bcc38b28d21b470ddf32c5 | |
parent | b91956e7f80141c198d3348f06164b6990913233 (diff) |
Minor tweak to the branch selector. When emitting a two-way branch, and if
we're in a single-mbb loop, make sure to emit the backwards branch as the
conditional branch instead of the uncond branch. For example, emit this:
LBBl29_z__44:
stw r9, 0(r15)
stw r9, 4(r15)
stw r9, 8(r15)
stw r9, 12(r15)
addi r15, r15, 16
addi r8, r8, 1
cmpw cr0, r8, r28
ble cr0, LBBl29_z__44
b LBBl29_z__48 *** NOT PART OF LOOP
Instead of:
LBBl29_z__44:
stw r9, 0(r15)
stw r9, 4(r15)
stw r9, 8(r15)
stw r9, 12(r15)
addi r15, r15, 16
addi r8, r8, 1
cmpw cr0, r8, r28
bgt cr0, LBBl29_z__48 *** PART OF LOOP!
b LBBl29_z__44
The former sequence has one fewer dispatch group for the loop body.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23582 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 15d3e144aa..4721d3e02a 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -1445,20 +1445,31 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock(); ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get(); SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC); - unsigned Opc = getBCCForSetCC(CC); // If this is a two way branch, then grab the fallthrough basic block // argument and build a PowerPC branch pseudo-op, suitable for long branch // conversion if necessary by the branch selection pass. Otherwise, emit a // standard conditional branch. if (N->getOpcode() == ISD::BRTWOWAY_CC) { - MachineBasicBlock *Fallthrough = - cast<BasicBlockSDNode>(N->getOperand(5))->getBasicBlock(); + SDOperand CondTrueBlock = N->getOperand(4); + SDOperand CondFalseBlock = N->getOperand(5); + + // If the false case is the current basic block, then this is a self loop. + // We do not want to emit "Loop: ... brcond Out; br Loop", as it adds an + // extra dispatch group to the loop. Instead, invert the condition and + // emit "Loop: ... br!cond Loop; br Out + if (cast<BasicBlockSDNode>(CondFalseBlock)->getBasicBlock() == BB) { + std::swap(CondTrueBlock, CondFalseBlock); + CC = getSetCCInverse(CC, + MVT::isInteger(N->getOperand(2).getValueType())); + } + + unsigned Opc = getBCCForSetCC(CC); SDOperand CB = CurDAG->getTargetNode(PPC::COND_BRANCH, MVT::Other, CondCode, getI32Imm(Opc), - N->getOperand(4), N->getOperand(5), + CondTrueBlock, CondFalseBlock, Chain); - CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, N->getOperand(5), CB); + CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB); } else { // Iterate to the next basic block ilist<MachineBasicBlock>::iterator It = BB; @@ -1470,7 +1481,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { // the PowerPC Branch Selection pass to crash. if (It == BB->getParent()->end()) It = Dest; CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode, - getI32Imm(Opc), N->getOperand(4), + getI32Imm(getBCCForSetCC(CC)), N->getOperand(4), CurDAG->getBasicBlock(It), Chain); } return SDOperand(N, 0); |