mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-27 13:40:30 +00:00
[Hexagon] Pick the right branch opcode depending on branch probabilities
Specifically, pick the opcode with the correct branch prediction, i.e. jump:t or jump:nt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296821 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2f35f8a7a2
commit
06a22af389
@ -3470,20 +3470,75 @@ int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {
|
||||
int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const {
|
||||
// We assume that block can have at most two successors.
|
||||
bool taken = false;
|
||||
const MachineBasicBlock *Src = MI.getParent();
|
||||
const MachineOperand &BrTarget = MI.getOperand(1);
|
||||
const MachineBasicBlock *Dst = BrTarget.getMBB();
|
||||
bool Taken = false;
|
||||
const BranchProbability OneHalf(1, 2);
|
||||
|
||||
const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst);
|
||||
if (Prediction >= BranchProbability(1,2))
|
||||
taken = true;
|
||||
if (BrTarget.isMBB()) {
|
||||
const MachineBasicBlock *Dst = BrTarget.getMBB();
|
||||
Taken = MBPI->getEdgeProbability(Src, Dst) >= OneHalf;
|
||||
} else {
|
||||
// The branch target is not a basic block (most likely a function).
|
||||
// Since BPI only gives probabilities for targets that are basic blocks,
|
||||
// try to identify another target of this branch (potentially a fall-
|
||||
// -through) and check the probability of that target.
|
||||
//
|
||||
// The only handled branch combinations are:
|
||||
// - one conditional branch,
|
||||
// - one conditional branch followed by one unconditional branch.
|
||||
// Otherwise, assume not-taken.
|
||||
assert(MI.isConditionalBranch());
|
||||
const MachineBasicBlock &B = *MI.getParent();
|
||||
bool SawCond = false, Bad = false;
|
||||
for (const MachineInstr &I : B) {
|
||||
if (!I.isBranch())
|
||||
continue;
|
||||
if (I.isConditionalBranch()) {
|
||||
SawCond = true;
|
||||
if (&I != &MI) {
|
||||
Bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (I.isUnconditionalBranch() && !SawCond) {
|
||||
Bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!Bad) {
|
||||
MachineBasicBlock::const_instr_iterator It(MI);
|
||||
MachineBasicBlock::const_instr_iterator NextIt = std::next(It);
|
||||
if (NextIt == B.instr_end()) {
|
||||
// If this branch is the last, look for the fall-through block.
|
||||
for (const MachineBasicBlock *SB : B.successors()) {
|
||||
if (!B.isLayoutSuccessor(SB))
|
||||
continue;
|
||||
Taken = MBPI->getEdgeProbability(Src, SB) < OneHalf;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
assert(NextIt->isUnconditionalBranch());
|
||||
// Find the first MBB operand and assume it's the target.
|
||||
const MachineBasicBlock *BT = nullptr;
|
||||
for (const MachineOperand &Op : NextIt->operands()) {
|
||||
if (!Op.isMBB())
|
||||
continue;
|
||||
BT = Op.getMBB();
|
||||
break;
|
||||
}
|
||||
Taken = BT && MBPI->getEdgeProbability(Src, BT) < OneHalf;
|
||||
}
|
||||
} // if (!Bad)
|
||||
}
|
||||
|
||||
// The Taken flag should be set to something reasonable by this point.
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case Hexagon::J2_jumpt:
|
||||
return taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
|
||||
return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
|
||||
case Hexagon::J2_jumpf:
|
||||
return taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
|
||||
return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
|
||||
|
||||
default:
|
||||
llvm_unreachable("Unexpected jump instruction.");
|
||||
@ -3493,20 +3548,19 @@ int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
|
||||
// Return .new predicate version for an instruction.
|
||||
int HexagonInstrInfo::getDotNewPredOp(const MachineInstr &MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const {
|
||||
int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
|
||||
if (NewOpcode >= 0) // Valid predicate new instruction
|
||||
return NewOpcode;
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
// Condtional Jumps
|
||||
case Hexagon::J2_jumpt:
|
||||
case Hexagon::J2_jumpf:
|
||||
return getDotNewPredJumpOp(MI, MBPI);
|
||||
|
||||
default:
|
||||
assert(0 && "Unknown .new type");
|
||||
}
|
||||
return 0;
|
||||
|
||||
int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
|
||||
if (NewOpcode >= 0)
|
||||
return NewOpcode;
|
||||
|
||||
dbgs() << "Cannot convert to .new: " << getName(MI.getOpcode()) << '\n';
|
||||
llvm_unreachable(nullptr);
|
||||
}
|
||||
|
||||
int HexagonInstrInfo::getDotOldOp(const int opc) const {
|
||||
|
44
test/CodeGen/Hexagon/builtin-expect.ll
Normal file
44
test/CodeGen/Hexagon/builtin-expect.ll
Normal file
@ -0,0 +1,44 @@
|
||||
; RUN: llc -march=hexagon -disable-block-placement < %s | FileCheck %s
|
||||
|
||||
; Check that the branch to the block b10 is marked as taken (i.e. ":t").
|
||||
; CHECK-LABEL: foo
|
||||
; CHECK: if ({{.*}}) jump:t .LBB0_[[LAB:[0-9]+]]
|
||||
; CHECK: [[LAB]]:
|
||||
; CHECK: add({{.*}},#65)
|
||||
|
||||
target triple = "hexagon"
|
||||
|
||||
define i32 @foo(i32 %a0) local_unnamed_addr #0 {
|
||||
b1:
|
||||
%v2 = icmp eq i32 %a0, 0
|
||||
br i1 %v2, label %b3, label %b10, !prof !0
|
||||
|
||||
b3: ; preds = %b1
|
||||
br label %b4
|
||||
|
||||
b4: ; preds = %b4, %b3
|
||||
%v5 = phi i32 [ %v6, %b4 ], [ 0, %b3 ]
|
||||
%v6 = add nuw nsw i32 %v5, 1
|
||||
%v7 = mul nuw nsw i32 %v5, 67
|
||||
%v8 = tail call i32 @bar(i32 %v7) #0
|
||||
%v9 = icmp eq i32 %v6, 10
|
||||
br i1 %v9, label %b13, label %b4
|
||||
|
||||
b10: ; preds = %b1
|
||||
%v11 = add nsw i32 %a0, 65
|
||||
%v12 = tail call i32 @bar(i32 %v11) #0
|
||||
br label %b14
|
||||
|
||||
b13: ; preds = %b4
|
||||
br label %b14
|
||||
|
||||
b14: ; preds = %b13, %b10
|
||||
%v15 = phi i32 [ %v12, %b10 ], [ 0, %b13 ]
|
||||
ret i32 %v15
|
||||
}
|
||||
|
||||
declare i32 @bar(i32) local_unnamed_addr #0
|
||||
|
||||
attributes #0 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvx,-hvx-double,-long-calls" }
|
||||
|
||||
!0 = !{!"branch_weights", i32 1, i32 2000}
|
Loading…
Reference in New Issue
Block a user