diff options
Diffstat (limited to 'lib/Transforms/Instrumentation/PGOInstrumentation.cpp')
| -rw-r--r-- | lib/Transforms/Instrumentation/PGOInstrumentation.cpp | 64 | 
1 files changed, 64 insertions, 0 deletions
diff --git a/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index 1e30dbf6b55a..b2d95271479c 100644 --- a/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -182,6 +182,14 @@ static cl::opt<bool>                    cl::desc("Use this option to turn on/off "                             "memory intrinsic size profiling.")); +// Emit branch probability as optimization remarks. +static cl::opt<bool> +    EmitBranchProbability("pgo-emit-branch-prob", cl::init(false), cl::Hidden, +                          cl::desc("When this option is on, the annotated " +                                   "branch probability will be emitted as " +                                   " optimization remarks: -Rpass-analysis=" +                                   "pgo-instr-use")); +  // Command line option to turn on CFG dot dump after profile annotation.  // Defined in Analysis/BlockFrequencyInfo.cpp:  -pgo-view-counts  extern cl::opt<bool> PGOViewCounts; @@ -192,6 +200,39 @@ extern cl::opt<std::string> ViewBlockFreqFuncName;  namespace { +// Return a string describing the branch condition that can be +// used in static branch probability heuristics: +std::string getBranchCondString(Instruction *TI) { +  BranchInst *BI = dyn_cast<BranchInst>(TI); +  if (!BI || !BI->isConditional()) +    return std::string(); + +  Value *Cond = BI->getCondition(); +  ICmpInst *CI = dyn_cast<ICmpInst>(Cond); +  if (!CI) +    return std::string(); + +  std::string result; +  raw_string_ostream OS(result); +  OS << CmpInst::getPredicateName(CI->getPredicate()) << "_"; +  CI->getOperand(0)->getType()->print(OS, true); + +  Value *RHS = CI->getOperand(1); +  ConstantInt *CV = dyn_cast<ConstantInt>(RHS); +  if (CV) { +    if (CV->isZero()) +      OS << "_Zero"; +    else if (CV->isOne()) +      OS << "_One"; +    else if (CV->isAllOnesValue()) +      OS << "_MinusOne"; +    else +      OS << "_Const"; +  } +  OS.flush(); +  return result; +} +  /// The select instruction visitor plays three roles specified  /// by the mode. In \c VM_counting mode, it simply counts the number of  /// select instructions. In \c VM_instrument mode, it inserts code to count @@ -1424,6 +1465,29 @@ void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts,          for (const auto &W : Weights) { dbgs() << W << " "; }          dbgs() << "\n";);    TI->setMetadata(llvm::LLVMContext::MD_prof, MDB.createBranchWeights(Weights)); +  if (EmitBranchProbability) { +    std::string BrCondStr = getBranchCondString(TI); +    if (BrCondStr.empty()) +      return; + +    unsigned WSum = +        std::accumulate(Weights.begin(), Weights.end(), 0, +                        [](unsigned w1, unsigned w2) { return w1 + w2; }); +    uint64_t TotalCount = +        std::accumulate(EdgeCounts.begin(), EdgeCounts.end(), 0, +                        [](uint64_t c1, uint64_t c2) { return c1 + c2; }); +    BranchProbability BP(Weights[0], WSum); +    std::string BranchProbStr; +    raw_string_ostream OS(BranchProbStr); +    OS << BP; +    OS << " (total count : " << TotalCount << ")"; +    OS.flush(); +    Function *F = TI->getParent()->getParent(); +    emitOptimizationRemarkAnalysis( +        F->getContext(), "pgo-use-annot", *F, TI->getDebugLoc(), +        Twine(BrCondStr) + +            " is true with probability : " + Twine(BranchProbStr)); +  }  }  template <> struct GraphTraits<PGOUseFunc *> {  | 
