summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-03-02 21:49:49 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-03-02 21:49:49 +0000
commite720feb1c612654c90a8b476778d89dbf3eb2e41 (patch)
tree604931ba12648cef71002469e1a1c34247929b5b /llvm/lib
parent02d86b80ece595495e69ba386548949d84fcee03 (diff)
downloadbcm5719-llvm-e720feb1c612654c90a8b476778d89dbf3eb2e41.tar.gz
bcm5719-llvm-e720feb1c612654c90a8b476778d89dbf3eb2e41.zip
[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. llvm-svn: 296821
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp84
1 files changed, 69 insertions, 15 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 6b74c2fd618..509d838ad11 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -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 {
OpenPOWER on IntegriCloud