Home | History | Annotate | Download | only in Analysis
      1 //===-- IndirectCallPromotionAnalysis.cpp - Find promotion candidates ===//
      2 //
      3 //                      The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Helper methods for identifying profitable indirect call promotion
     11 // candidates for an instruction when the indirect-call value profile metadata
     12 // is available.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
     17 #include "llvm/ADT/STLExtras.h"
     18 #include "llvm/Analysis/IndirectCallSiteVisitor.h"
     19 #include "llvm/IR/CallSite.h"
     20 #include "llvm/IR/DiagnosticInfo.h"
     21 #include "llvm/IR/InstIterator.h"
     22 #include "llvm/IR/InstVisitor.h"
     23 #include "llvm/IR/Instructions.h"
     24 #include "llvm/IR/IntrinsicInst.h"
     25 #include "llvm/ProfileData/InstrProf.h"
     26 #include "llvm/Support/Debug.h"
     27 #include <string>
     28 #include <utility>
     29 #include <vector>
     30 
     31 using namespace llvm;
     32 
     33 #define DEBUG_TYPE "pgo-icall-prom-analysis"
     34 
     35 // The minimum call count for the direct-call target to be considered as the
     36 // promotion candidate.
     37 static cl::opt<unsigned>
     38     ICPCountThreshold("icp-count-threshold", cl::Hidden, cl::ZeroOrMore,
     39                       cl::init(1000),
     40                       cl::desc("The minimum count to the direct call target "
     41                                "for the promotion"));
     42 
     43 // The percent threshold for the direct-call target (this call site vs the
     44 // total call count) for it to be considered as the promotion target.
     45 static cl::opt<unsigned>
     46     ICPPercentThreshold("icp-percent-threshold", cl::init(33), cl::Hidden,
     47                         cl::ZeroOrMore,
     48                         cl::desc("The percentage threshold for the promotion"));
     49 
     50 // Set the maximum number of targets to promote for a single indirect-call
     51 // callsite.
     52 static cl::opt<unsigned>
     53     MaxNumPromotions("icp-max-prom", cl::init(2), cl::Hidden, cl::ZeroOrMore,
     54                      cl::desc("Max number of promotions for a single indirect "
     55                               "call callsite"));
     56 
     57 ICallPromotionAnalysis::ICallPromotionAnalysis() {
     58   ValueDataArray = llvm::make_unique<InstrProfValueData[]>(MaxNumPromotions);
     59 }
     60 
     61 bool ICallPromotionAnalysis::isPromotionProfitable(uint64_t Count,
     62                                                    uint64_t TotalCount) {
     63   if (Count < ICPCountThreshold)
     64     return false;
     65 
     66   unsigned Percentage = (Count * 100) / TotalCount;
     67   return (Percentage >= ICPPercentThreshold);
     68 }
     69 
     70 // Indirect-call promotion heuristic. The direct targets are sorted based on
     71 // the count. Stop at the first target that is not promoted. Returns the
     72 // number of candidates deemed profitable.
     73 uint32_t ICallPromotionAnalysis::getProfitablePromotionCandidates(
     74     const Instruction *Inst, uint32_t NumVals, uint64_t TotalCount) {
     75   ArrayRef<InstrProfValueData> ValueDataRef(ValueDataArray.get(), NumVals);
     76 
     77   DEBUG(dbgs() << " \nWork on callsite " << *Inst << " Num_targets: " << NumVals
     78                << "\n");
     79 
     80   uint32_t I = 0;
     81   for (; I < MaxNumPromotions && I < NumVals; I++) {
     82     uint64_t Count = ValueDataRef[I].Count;
     83     assert(Count <= TotalCount);
     84     DEBUG(dbgs() << " Candidate " << I << " Count=" << Count
     85                  << "  Target_func: " << ValueDataRef[I].Value << "\n");
     86 
     87     if (!isPromotionProfitable(Count, TotalCount)) {
     88       DEBUG(dbgs() << " Not promote: Cold target.\n");
     89       return I;
     90     }
     91     TotalCount -= Count;
     92   }
     93   return I;
     94 }
     95 
     96 ArrayRef<InstrProfValueData>
     97 ICallPromotionAnalysis::getPromotionCandidatesForInstruction(
     98     const Instruction *I, uint32_t &NumVals, uint64_t &TotalCount,
     99     uint32_t &NumCandidates) {
    100   bool Res =
    101       getValueProfDataFromInst(*I, IPVK_IndirectCallTarget, MaxNumPromotions,
    102                                ValueDataArray.get(), NumVals, TotalCount);
    103   if (!Res) {
    104     NumCandidates = 0;
    105     return ArrayRef<InstrProfValueData>();
    106   }
    107   NumCandidates = getProfitablePromotionCandidates(I, NumVals, TotalCount);
    108   return ArrayRef<InstrProfValueData>(ValueDataArray.get(), NumVals);
    109 }
    110