diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 84 |
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 { |