// Start from the bottom of the block and work up, examining the
// terminator instructions.
MachineBasicBlock::iterator I = MBB.end();
- MachineBasicBlock::iterator UnCondBrIter = MBB.end();
while (I != MBB.begin()) {
--I;
if (I->isDebugValue())
// Handle unconditional branches.
if (I->getOpcode() == X86::JMP_4) {
- UnCondBrIter = I;
-
if (!AllowModify) {
TBB = I->getOperand(0).getMBB();
continue;
TBB = 0;
I->eraseFromParent();
I = MBB.end();
- UnCondBrIter = MBB.end();
continue;
}
- // TBB is used to indicate the unconditional destination.
+ // TBB is used to indicate the unconditinal destination.
TBB = I->getOperand(0).getMBB();
continue;
}
// Working from the bottom, handle the first conditional branch.
if (Cond.empty()) {
- MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
- if (AllowModify && UnCondBrIter != MBB.end() &&
- MBB.isLayoutSuccessor(TargetBB)) {
- // If we can modify the code and it ends in something like:
- //
- // jCC L1
- // jmp L2
- // L1:
- // ...
- // L2:
- //
- // Then we can change this to:
- //
- // jnCC L2
- // L1:
- // ...
- // L2:
- //
- // Which is a bit more efficient.
- // We conditionally jump to the fall-through block.
- BranchCode = GetOppositeBranchCondition(BranchCode);
- unsigned JNCC = GetCondBranchFromCond(BranchCode);
- MachineBasicBlock::iterator OldInst = I;
- --I;
-
- BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC))
- .addMBB(UnCondBrIter->getOperand(0).getMBB());
- BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(X86::JMP_4))
- .addMBB(TargetBB);
- MBB.addSuccessor(TargetBB);
-
- OldInst->eraseFromParent();
- UnCondBrIter->eraseFromParent();
-
- // Restart the analysis.
- UnCondBrIter = MBB.end();
- I = MBB.end();
- continue;
- }
-
FBB = TBB;
- TBB = TargetBB;
TBB = I->getOperand(0).getMBB();
Cond.push_back(MachineOperand::CreateImm(BranchCode));
continue;
; CHECK-NEXT: orl 8(%esp), %eax
; CHECK-NEXT: je LBB3_2
}
-
-; <rdar://problem/7598384>:
-;
-; jCC L1
-; jmp L2
-; L1:
-; ...
-; L2:
-; ...
-;
-; to:
-;
-; jnCC L2
-; L1:
-; ...
-; L2:
-; ...
-define float @test4(float %x, float %y) nounwind readnone optsize ssp {
-entry:
- %0 = fpext float %x to double ; <double> [#uses=1]
- %1 = fpext float %y to double ; <double> [#uses=1]
- %2 = fmul double %0, %1 ; <double> [#uses=3]
- %3 = fcmp oeq double %2, 0.000000e+00 ; <i1> [#uses=1]
- br i1 %3, label %bb2, label %bb1
-
-; CHECK: jne
-; CHECK-NEXT: jnp
-; CHECK-NOT: jmp
-; CHECK: LBB
-
-bb1: ; preds = %entry
- %4 = fadd double %2, -1.000000e+00 ; <double> [#uses=1]
- br label %bb2
-
-bb2: ; preds = %entry, %bb1
- %.0.in = phi double [ %4, %bb1 ], [ %2, %entry ] ; <double> [#uses=1]
- %.0 = fptrunc double %.0.in to float ; <float> [#uses=1]
- ret float %.0
-}