Home | History | Annotate | Download | only in Instrumentation
      1 //===- OptimalEdgeProfiling.cpp - Insert counters for opt. edge profiling -===//
      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 // This pass instruments the specified program with counters for edge profiling.
     11 // Edge profiling can give a reasonable approximation of the hot paths through a
     12 // program, and is used for a wide variety of program transformations.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 #define DEBUG_TYPE "insert-optimal-edge-profiling"
     16 #include "ProfilingUtils.h"
     17 #include "llvm/Constants.h"
     18 #include "llvm/Module.h"
     19 #include "llvm/Pass.h"
     20 #include "llvm/Analysis/Passes.h"
     21 #include "llvm/Analysis/ProfileInfo.h"
     22 #include "llvm/Analysis/ProfileInfoLoader.h"
     23 #include "llvm/Support/raw_ostream.h"
     24 #include "llvm/Support/Debug.h"
     25 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
     26 #include "llvm/Transforms/Instrumentation.h"
     27 #include "llvm/ADT/DenseSet.h"
     28 #include "llvm/ADT/Statistic.h"
     29 #include "MaximumSpanningTree.h"
     30 using namespace llvm;
     31 
     32 STATISTIC(NumEdgesInserted, "The # of edges inserted.");
     33 
     34 namespace {
     35   class OptimalEdgeProfiler : public ModulePass {
     36     bool runOnModule(Module &M);
     37   public:
     38     static char ID; // Pass identification, replacement for typeid
     39     OptimalEdgeProfiler() : ModulePass(ID) {
     40       initializeOptimalEdgeProfilerPass(*PassRegistry::getPassRegistry());
     41     }
     42 
     43     void getAnalysisUsage(AnalysisUsage &AU) const {
     44       AU.addRequiredID(ProfileEstimatorPassID);
     45       AU.addRequired<ProfileInfo>();
     46     }
     47 
     48     virtual const char *getPassName() const {
     49       return "Optimal Edge Profiler";
     50     }
     51   };
     52 }
     53 
     54 char OptimalEdgeProfiler::ID = 0;
     55 INITIALIZE_PASS_BEGIN(OptimalEdgeProfiler, "insert-optimal-edge-profiling",
     56                 "Insert optimal instrumentation for edge profiling",
     57                 false, false)
     58 INITIALIZE_PASS_DEPENDENCY(ProfileEstimatorPass)
     59 INITIALIZE_AG_DEPENDENCY(ProfileInfo)
     60 INITIALIZE_PASS_END(OptimalEdgeProfiler, "insert-optimal-edge-profiling",
     61                 "Insert optimal instrumentation for edge profiling",
     62                 false, false)
     63 
     64 ModulePass *llvm::createOptimalEdgeProfilerPass() {
     65   return new OptimalEdgeProfiler();
     66 }
     67 
     68 inline static void printEdgeCounter(ProfileInfo::Edge e,
     69                                     BasicBlock* b,
     70                                     unsigned i) {
     71   DEBUG(dbgs() << "--Edge Counter for " << (e) << " in " \
     72                << ((b)?(b)->getName():"0") << " (# " << (i) << ")\n");
     73 }
     74 
     75 bool OptimalEdgeProfiler::runOnModule(Module &M) {
     76   Function *Main = M.getFunction("main");
     77   if (Main == 0) {
     78     errs() << "WARNING: cannot insert edge profiling into a module"
     79            << " with no main function!\n";
     80     return false;  // No main, no instrumentation!
     81   }
     82 
     83   // NumEdges counts all the edges that may be instrumented. Later on its
     84   // decided which edges to actually instrument, to achieve optimal profiling.
     85   // For the entry block a virtual edge (0,entry) is reserved, for each block
     86   // with no successors an edge (BB,0) is reserved. These edges are necessary
     87   // to calculate a truly optimal maximum spanning tree and thus an optimal
     88   // instrumentation.
     89   unsigned NumEdges = 0;
     90 
     91   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
     92     if (F->isDeclaration()) continue;
     93     // Reserve space for (0,entry) edge.
     94     ++NumEdges;
     95     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
     96       // Keep track of which blocks need to be instrumented.  We don't want to
     97       // instrument blocks that are added as the result of breaking critical
     98       // edges!
     99       if (BB->getTerminator()->getNumSuccessors() == 0) {
    100         // Reserve space for (BB,0) edge.
    101         ++NumEdges;
    102       } else {
    103         NumEdges += BB->getTerminator()->getNumSuccessors();
    104       }
    105     }
    106   }
    107 
    108   // In the profiling output a counter for each edge is reserved, but only few
    109   // are used. This is done to be able to read back in the profile without
    110   // calulating the maximum spanning tree again, instead each edge counter that
    111   // is not used is initialised with -1 to signal that this edge counter has to
    112   // be calculated from other edge counters on reading the profile info back
    113   // in.
    114 
    115   Type *Int32 = Type::getInt32Ty(M.getContext());
    116   ArrayType *ATy = ArrayType::get(Int32, NumEdges);
    117   GlobalVariable *Counters =
    118     new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
    119                        Constant::getNullValue(ATy), "OptEdgeProfCounters");
    120   NumEdgesInserted = 0;
    121 
    122   std::vector<Constant*> Initializer(NumEdges);
    123   Constant *Zero = ConstantInt::get(Int32, 0);
    124   Constant *Uncounted = ConstantInt::get(Int32, ProfileInfoLoader::Uncounted);
    125 
    126   // Instrument all of the edges not in MST...
    127   unsigned i = 0;
    128   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    129     if (F->isDeclaration()) continue;
    130     DEBUG(dbgs() << "Working on " << F->getName() << "\n");
    131 
    132     // Calculate a Maximum Spanning Tree with the edge weights determined by
    133     // ProfileEstimator. ProfileEstimator also assign weights to the virtual
    134     // edges (0,entry) and (BB,0) (for blocks with no successors) and this
    135     // edges also participate in the maximum spanning tree calculation.
    136     // The third parameter of MaximumSpanningTree() has the effect that not the
    137     // actual MST is returned but the edges _not_ in the MST.
    138 
    139     ProfileInfo::EdgeWeights ECs =
    140       getAnalysis<ProfileInfo>(*F).getEdgeWeights(F);
    141     std::vector<ProfileInfo::EdgeWeight> EdgeVector(ECs.begin(), ECs.end());
    142     MaximumSpanningTree<BasicBlock> MST(EdgeVector);
    143     std::stable_sort(MST.begin(), MST.end());
    144 
    145     // Check if (0,entry) not in the MST. If not, instrument edge
    146     // (IncrementCounterInBlock()) and set the counter initially to zero, if
    147     // the edge is in the MST the counter is initialised to -1.
    148 
    149     BasicBlock *entry = &(F->getEntryBlock());
    150     ProfileInfo::Edge edge = ProfileInfo::getEdge(0, entry);
    151     if (!std::binary_search(MST.begin(), MST.end(), edge)) {
    152       printEdgeCounter(edge, entry, i);
    153       IncrementCounterInBlock(entry, i, Counters); ++NumEdgesInserted;
    154       Initializer[i++] = (Zero);
    155     } else{
    156       Initializer[i++] = (Uncounted);
    157     }
    158 
    159     // InsertedBlocks contains all blocks that were inserted for splitting an
    160     // edge, this blocks do not have to be instrumented.
    161     DenseSet<BasicBlock*> InsertedBlocks;
    162     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    163       // Check if block was not inserted and thus does not have to be
    164       // instrumented.
    165       if (InsertedBlocks.count(BB)) continue;
    166 
    167       // Okay, we have to add a counter of each outgoing edge not in MST. If
    168       // the outgoing edge is not critical don't split it, just insert the
    169       // counter in the source or destination of the edge. Also, if the block
    170       // has no successors, the virtual edge (BB,0) is processed.
    171       TerminatorInst *TI = BB->getTerminator();
    172       if (TI->getNumSuccessors() == 0) {
    173         ProfileInfo::Edge edge = ProfileInfo::getEdge(BB, 0);
    174         if (!std::binary_search(MST.begin(), MST.end(), edge)) {
    175           printEdgeCounter(edge, BB, i);
    176           IncrementCounterInBlock(BB, i, Counters); ++NumEdgesInserted;
    177           Initializer[i++] = (Zero);
    178         } else{
    179           Initializer[i++] = (Uncounted);
    180         }
    181       }
    182       for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
    183         BasicBlock *Succ = TI->getSuccessor(s);
    184         ProfileInfo::Edge edge = ProfileInfo::getEdge(BB,Succ);
    185         if (!std::binary_search(MST.begin(), MST.end(), edge)) {
    186 
    187           // If the edge is critical, split it.
    188           bool wasInserted = SplitCriticalEdge(TI, s, this);
    189           Succ = TI->getSuccessor(s);
    190           if (wasInserted)
    191             InsertedBlocks.insert(Succ);
    192 
    193           // Okay, we are guaranteed that the edge is no longer critical.  If
    194           // we only have a single successor, insert the counter in this block,
    195           // otherwise insert it in the successor block.
    196           if (TI->getNumSuccessors() == 1) {
    197             // Insert counter at the start of the block
    198             printEdgeCounter(edge, BB, i);
    199             IncrementCounterInBlock(BB, i, Counters); ++NumEdgesInserted;
    200           } else {
    201             // Insert counter at the start of the block
    202             printEdgeCounter(edge, Succ, i);
    203             IncrementCounterInBlock(Succ, i, Counters); ++NumEdgesInserted;
    204           }
    205           Initializer[i++] = (Zero);
    206         } else {
    207           Initializer[i++] = (Uncounted);
    208         }
    209       }
    210     }
    211   }
    212 
    213   // Check if the number of edges counted at first was the number of edges we
    214   // considered for instrumentation.
    215   assert(i == NumEdges && "the number of edges in counting array is wrong");
    216 
    217   // Assign the now completely defined initialiser to the array.
    218   Constant *init = ConstantArray::get(ATy, Initializer);
    219   Counters->setInitializer(init);
    220 
    221   // Add the initialization call to main.
    222   InsertProfilingInitCall(Main, "llvm_start_opt_edge_profiling", Counters);
    223   return true;
    224 }
    225 
    226