title: Basic Block instrumentation
body: <p>I want to insert a counter to record how many times the basic block executed. </p>
  
  <p>The steps I took:</p>
  
  <ol>
  <li><p>I write an LLVM instrumentation pass named <code>BlockProfiling.cpp</code></p></li>
  <li><p>I compile it with:</p>
  
  <pre><code>$ g++ -c BlockProfiling.cpp _i/usr/local/include `llvm-config --cxxflag`
  </code></pre>
  
  <p>it generates a file named <code>BlockPrpfiling.o</code></p></li>
  <li><p>I run:</p>
  
  <pre><code>$ g++ -shared -o BlockProfiling.so BlockProfiling.o -L/usr/local/lib `llvm-config --ldflags -libs`
  </code></pre>
  
  <p>it generates a shared library named <code>BlockProfiling.so</code></p></li>
  <li><p>I use it to instrument my file <code>test.bc</code> and generate <code>test.bb.bc</code>:</p>
  
  <pre><code>$opt -load=./BlockProfiling.so -insert-bb-profling test.bc -o test.bb.bc
  </code></pre></li>
  <li><p>I use llvm-diff to confirm it's done. </p></li>
  </ol>
  
  <p>But when I use lli to execute test.bb.bc, there comes an error said:</p>
  
  <blockquote>
    <p>LLVM ERROR: Program used external function 'llvm_start_func_profiling' which could not be resolved!</p>
  </blockquote>
  
  <p>Any solutions? </p>
  
  <p>The llvm version is 3.3 and here is my code:</p>
  
  <pre><code>namespace{
  struct BlockProfiler: public ModulePass{
      static char ID;
      BlockProfiler():ModulePass(ID) {
          initializeBlock ProfilerPass(*Registry::getPassRegistry());
      }
  
      virtual bool runOnModule(Module &amp;M);
  };  //end of function profiling pass
  
  }  //end of namespace
  
  char BlockProfiler::ID = 0 ;
  INITIALIZE_PASS(BlockProfiler, "insert-block-profiling",
      "Insert instrumentation for profiling", false, false )
  
  ModulePass *llvm::createBlockProfilerPass() {return new BlockProfiler() ;  }
  
  
  //static RegisterPass&lt;BlockProfilerPass&gt; Y("insert-block-profiling", 
                                             "Insert instrumentation for block profiling");
  
  bool BlockProfiler::runOnModule(Module &amp;M){
  Function *Main = M.getFunction("main") ;
  if(Main == 0)
  {
      errs()&lt;&lt;" WARING: cannot insert block profiling into a module"
          &lt;&lt;" with no main function. \n" ;
      return false ; // no main, no instrumentation, and no modify
  }
  
  unsigned NumBlocks = 0;
  for(Module::iterator I = M.begin(), E = M.end(); I != E ; ++I)
      NumBlocks += I-&gt;size(); 
  
  Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), NumBlocks) ;
  GlobalVariable *Counters = 
      new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
          Constant::getNullValue(ATy), "BlockProCounters") ;
  
  //Instrument all of the blocks
      unsigned i = 0;
      for(Module::iterator I = M.begin(), E = M.end(); I != E; ++I){
          for(Function::iterator BB = I-&gt;begin(), E = I-&gt;end() ; BB != E; ++BB )
              //Insert counter at the start of the block
              IncrementCounterInBlock(BB, i++, Counters);
      }
  
      //add the initialization call to main
      InsertProfilingInitCall(Main, "llvm_start_block_profiling", Counters); 
      return true;
  }
  </code></pre>