[llvm] r296821 - [Hexagon] Pick the right branch opcode depending on branch probabilities

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 2 13:49:49 PST 2017


Author: kparzysz
Date: Thu Mar  2 15:49:49 2017
New Revision: 296821

URL: http://llvm.org/viewvc/llvm-project?rev=296821&view=rev
Log:
[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.

Added:
    llvm/trunk/test/CodeGen/Hexagon/builtin-expect.ll
Modified:
    llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp

Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=296821&r1=296820&r2=296821&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Thu Mar  2 15:49:49 2017
@@ -3470,20 +3470,75 @@ int HexagonInstrInfo::getDotNewOp(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::getDotNewPredJumpO
 // 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 {

Added: llvm/trunk/test/CodeGen/Hexagon/builtin-expect.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/builtin-expect.ll?rev=296821&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/builtin-expect.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/builtin-expect.ll Thu Mar  2 15:49:49 2017
@@ -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}




More information about the llvm-commits mailing list