<p><br>
On Dec 26, 2011 11:40 PM, "Nick Lewycky" <<a href="mailto:nicholas@mxc.ca">nicholas@mxc.ca</a>> wrote:<br>
><br>
> Author: nicholas<br>
> Date: Mon Dec 26 22:31:52 2011<br>
> New Revision: 147286<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=147286&view=rev">http://llvm.org/viewvc/llvm-project?rev=147286&view=rev</a><br>
> Log:<br>
> Teach simplifycfg to recompute branch weights when merging some branches, and<br>
> to discard weights when appropriate. Still more to do (and a new TODO), but<br>
> it's a start!<br>
><br>
> Modified:<br>
>    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp<br>
>    llvm/trunk/test/Transforms/SimplifyCFG/preserve-branchweights.ll<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=147286&r1=147285&r2=147286&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=147286&r1=147285&r2=147286&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Dec 26 22:31:52 2011<br>
> @@ -18,6 +18,8 @@<br>
>  #include "llvm/GlobalVariable.h"<br>
>  #include "llvm/Instructions.h"<br>
>  #include "llvm/IntrinsicInst.h"<br>
> +#include "llvm/LLVMContext.h"<br>
> +#include "llvm/Metadata.h"<br>
>  #include "llvm/Type.h"<br>
>  #include "llvm/Analysis/InstructionSimplify.h"<br>
>  #include "llvm/Analysis/ValueTracking.h"<br>
> @@ -1462,6 +1464,26 @@<br>
>   return true;<br>
>  }<br>
><br>
> +/// ExtractBranchMetadata - Given a conditional BranchInstruction, retrieve the<br>
> +/// probabilities of the branch taking each edge. Fills in the two APInt<br>
> +/// parameters and return true, or returns false if no or invalid metadata was<br>
> +/// found.<br>
> +static bool ExtractBranchMetadata(BranchInst *BI,<br>
> +                                  APInt &ProbTrue, APInt &ProbFalse) {<br>
> +  assert(BI->isConditional() &&<br>
> +         "Looking for probabilities on unconditional branch?");<br>
> +  MDNode *ProfileData = BI->getMetadata(LLVMContext::MD_prof);<br>
> +  if (!ProfileData || ProfileData->getNumOperands() != 3) return 0;</p>
<p>return false;  // ?</p>
<p>> +  ConstantInt *CITrue = dyn_cast<ConstantInt>(ProfileData->getOperand(1));<br>
> +  ConstantInt *CIFalse = dyn_cast<ConstantInt>(ProfileData->getOperand(2));<br>
> +  if (!CITrue || !CIFalse) return 0;</p>
<p>return false; // ?</p>
<p>> +  ProbTrue = CITrue->getValue();<br>
> +  ProbFalse = CIFalse->getValue();<br>
> +  assert(ProbTrue.getBitWidth() == 32 && ProbFalse.getBitWidth() == 32 &&<br>
> +         "Branch probability metadata must be 32-bit integers");<br>
> +  return true;<br>
> +}<br>
> +<br>
>  /// FoldBranchToCommonDest - If this basic block is simple enough, and if a<br>
>  /// predecessor branches to us and one of our successors, fold the block into<br>
>  /// the predecessor and use logical operations to pick the right destination.<br>
> @@ -1636,6 +1658,51 @@<br>
>       PBI->setSuccessor(1, FalseDest);<br>
>     }<br>
><br>
> +    // TODO: If BB is reachable from all paths through PredBlock, then we<br>
> +    // could replace PBI's branch probabilities with BI's.<br>
> +<br>
> +    // Merge probability data into PredBlock's branch.<br>
> +    APInt A, B, C, D;<br>
> +    if (ExtractBranchMetadata(PBI, C, D) && ExtractBranchMetadata(BI, A, B)) {<br>
> +      // bbA: br bbB (a% probability), bbC (b% prob.)<br>
> +      // bbB: br bbD (c% probability), bbC (d% prob.)</p>
<p>I don't understand this comment at all... the association between letters is particularly mysterious.</p>
<p>> +      // --> bbA: br bbD ((a*c)% prob.), bbC ((b+a*d)% prob.)<br>
> +      //<br>
> +      // Probabilities aren't stored as ratios directly. Converting to<br>
> +      // probability-numerator form, we get:<br>
> +      // (a*c)% = A*C, (b+(a*d))% = A*D+B*C+B*D.</p>
<p>Why is this done with explicit math? At the least it seems like we should be able to form BranchProbability objects to represent the ratio form. Even better would be to use the BranchProbability analysis to compute the ratios from the metadata? </p>

<p>> +<br>
> +      bool Overflow1 = false, Overflow2 = false, Overflow3 = false;<br>
> +      bool Overflow4 = false, Overflow5 = false, Overflow6 = false;<br>
> +      APInt ProbTrue = A.umul_ov(C, Overflow1);<br>
> +<br>
> +      APInt Tmp1 = A.umul_ov(D, Overflow2);<br>
> +      APInt Tmp2 = B.umul_ov(C, Overflow3);<br>
> +      APInt Tmp3 = B.umul_ov(D, Overflow4);<br>
> +      APInt Tmp4 = Tmp1.uadd_ov(Tmp2, Overflow5);<br>
> +      APInt ProbFalse = Tmp4.uadd_ov(Tmp3, Overflow6);<br>
> +<br>
> +      APInt GCD = APIntOps::GreatestCommonDivisor(ProbTrue, ProbFalse);<br>
> +      ProbTrue = ProbTrue.udiv(GCD);<br>
> +      ProbFalse = ProbFalse.udiv(GCD);<br>
> +<br>
> +      if (Overflow1 || Overflow2 || Overflow3 || Overflow4 || Overflow5 ||<br>
> +          Overflow6) {<br>
> +        DEBUG(dbgs() << "Overflow recomputing branch weight on: " << *PBI<br>
> +                     << "when merging with: " << *BI);<br>
> +        PBI->setMetadata(LLVMContext::MD_prof, NULL);<br>
> +      } else {<br>
> +        LLVMContext &Context = BI->getContext();<br>
> +        Value *Ops[3];<br>
> +        Ops[0] = BI->getMetadata(LLVMContext::MD_prof)->getOperand(0);<br>
> +        Ops[1] = ConstantInt::get(Context, ProbTrue);<br>
> +        Ops[2] = ConstantInt::get(Context, ProbFalse);<br>
> +        PBI->setMetadata(LLVMContext::MD_prof, MDNode::get(Context, Ops));<br>
> +      }<br>
> +    } else {<br>
> +      PBI->setMetadata(LLVMContext::MD_prof, NULL);<br>
> +    }<br>
> +<br>
>     // Copy any debug value intrinsics into the end of PredBlock.<br>
>     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)<br>
>       if (isa<DbgInfoIntrinsic>(*I))<br>
><br>
> Modified: llvm/trunk/test/Transforms/SimplifyCFG/preserve-branchweights.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/preserve-branchweights.ll?rev=147286&r1=147285&r2=147286&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/preserve-branchweights.ll?rev=147286&r1=147285&r2=147286&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/SimplifyCFG/preserve-branchweights.ll (original)<br>
> +++ llvm/trunk/test/Transforms/SimplifyCFG/preserve-branchweights.ll Mon Dec 26 22:31:52 2011<br>
> @@ -10,6 +10,45 @@<br>
><br>
>  X:<br>
>   %c = or i1 %b, false<br>
> +  br i1 %c, label %Z, label %Y, !prof !1<br>
> +<br>
> +Y:<br>
> +  call void @helper(i32 0)<br>
> +  ret void<br>
> +<br>
> +Z:<br>
> +  call void @helper(i32 1)<br>
> +  ret void<br>
> +}<br>
> +<br>
> +define void @test2(i1 %a, i1 %b) {<br>
> +; CHECK: @test2<br>
> +entry:<br>
> +  br i1 %a, label %X, label %Y, !prof !1<br>
> +; CHECK: br i1 %or.cond, label %Z, label %Y, !prof !1<br>
> +; CHECK-NOT: !prof<br>
> +<br>
> +X:<br>
> +  %c = or i1 %b, false<br>
> +  br i1 %c, label %Z, label %Y, !prof !2<br>
> +<br>
> +Y:<br>
> +  call void @helper(i32 0)<br>
> +  ret void<br>
> +<br>
> +Z:<br>
> +  call void @helper(i32 1)<br>
> +  ret void<br>
> +}<br>
> +<br>
> +define void @test3(i1 %a, i1 %b) {<br>
> +; CHECK: @test3<br>
> +; CHECK-NOT: !prof<br>
> +entry:<br>
> +  br i1 %a, label %X, label %Y, !prof !1<br>
> +<br>
> +X:<br>
> +  %c = or i1 %b, false<br>
>   br i1 %c, label %Z, label %Y<br>
><br>
>  Y:<br>
> @@ -21,6 +60,29 @@<br>
>   ret void<br>
>  }<br>
><br>
> -!0 = metadata !{metadata !"branch_weights", i32 1, i32 2}<br>
> +define void @test4(i1 %a, i1 %b) {<br>
> +; CHECK: @test4<br>
> +; CHECK-NOT: !prof<br>
> +entry:<br>
> +  br i1 %a, label %X, label %Y<br>
> +<br>
> +X:<br>
> +  %c = or i1 %b, false<br>
> +  br i1 %c, label %Z, label %Y, !prof !1<br>
> +<br>
> +Y:<br>
> +  call void @helper(i32 0)<br>
> +  ret void<br>
> +<br>
> +Z:<br>
> +  call void @helper(i32 1)<br>
> +  ret void<br>
> +}<br>
> +<br>
> +!0 = metadata !{metadata !"branch_weights", i32 3, i32 5}<br>
> +!1 = metadata !{metadata !"branch_weights", i32 1, i32 1}<br>
> +!2 = metadata !{metadata !"branch_weights", i32 1, i32 2}<br>
><br>
> -; CHECK: !0 = metadata !{metadata !"branch_weights", i32 2, i32 1}<br>
> +; CHECK: !0 = metadata !{metadata !"branch_weights", i32 5, i32 11}<br>
> +; CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 5}<br>
> +; CHECK-NOT: !2<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</p>