mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
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
This commit is contained in:
@@ -1445,20 +1445,31 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock();
|
cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock();
|
||||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||||
SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC);
|
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
|
// 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
|
// argument and build a PowerPC branch pseudo-op, suitable for long branch
|
||||||
// conversion if necessary by the branch selection pass. Otherwise, emit a
|
// conversion if necessary by the branch selection pass. Otherwise, emit a
|
||||||
// standard conditional branch.
|
// standard conditional branch.
|
||||||
if (N->getOpcode() == ISD::BRTWOWAY_CC) {
|
if (N->getOpcode() == ISD::BRTWOWAY_CC) {
|
||||||
MachineBasicBlock *Fallthrough =
|
SDOperand CondTrueBlock = N->getOperand(4);
|
||||||
cast<BasicBlockSDNode>(N->getOperand(5))->getBasicBlock();
|
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,
|
SDOperand CB = CurDAG->getTargetNode(PPC::COND_BRANCH, MVT::Other,
|
||||||
CondCode, getI32Imm(Opc),
|
CondCode, getI32Imm(Opc),
|
||||||
N->getOperand(4), N->getOperand(5),
|
CondTrueBlock, CondFalseBlock,
|
||||||
Chain);
|
Chain);
|
||||||
CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, N->getOperand(5), CB);
|
CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB);
|
||||||
} else {
|
} else {
|
||||||
// Iterate to the next basic block
|
// Iterate to the next basic block
|
||||||
ilist<MachineBasicBlock>::iterator It = BB;
|
ilist<MachineBasicBlock>::iterator It = BB;
|
||||||
@@ -1470,7 +1481,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
// the PowerPC Branch Selection pass to crash.
|
// the PowerPC Branch Selection pass to crash.
|
||||||
if (It == BB->getParent()->end()) It = Dest;
|
if (It == BB->getParent()->end()) It = Dest;
|
||||||
CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode,
|
CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode,
|
||||||
getI32Imm(Opc), N->getOperand(4),
|
getI32Imm(getBCCForSetCC(CC)), N->getOperand(4),
|
||||||
CurDAG->getBasicBlock(It), Chain);
|
CurDAG->getBasicBlock(It), Chain);
|
||||||
}
|
}
|
||||||
return SDOperand(N, 0);
|
return SDOperand(N, 0);
|
||||||
|
Reference in New Issue
Block a user