[llvm-commits] [llvm] r129340 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Instrumentation.h lib/Transforms/Instrumentation/Instrumentation.cpp lib/Transforms/Instrumentation/LineProfiling

Nick Lewycky nlewycky at google.com
Tue Apr 12 12:41:27 PDT 2011


On 12 April 2011 08:55, Jim Grosbach <grosbach at apple.com> wrote:

> Hi Nick,
>
> clang is issuing a warning for this. Mind having a look?
>

Sorry! I meant for counter to be a uint64_t, and updated that. Neither gcc
nor clang warned when I built it this time, but I could imagine that it
still might on a different platform. Let me know if it's not fixed past
r129380.

Nick


>
> llvm[2]: Compiling LineProfiling.c for Debug+Asserts build (PIC)
> /Volumes/Home/grosbaj/sources/llvm/runtime/libprofile/LineProfiling.c:32:25:
> warning:
>      conversion specifies type 'unsigned long' but the argument has type
>      'int64_t' (aka 'long long') [-Wformat]
>   printf("%s/%s:%u:%u %lu\n", dir, file, line, column, *counter);
>                       ~~^                              ~~~~~~~~
>                      %lld
> 1 warning generated.
>
> (highlighting points to the "%lu" and "*counter" inputs)
>
> -Jim
>
> On Apr 11, 2011, at 6:06 PM, Nick Lewycky wrote:
>
> > Author: nicholas
> > Date: Mon Apr 11 20:06:09 2011
> > New Revision: 129340
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=129340&view=rev
> > Log:
> > Add support for line profiling. Very work-in-progress.
> >
> > Use debug info in the IR to find the directory/file:line:col. Each time
> that location changes, bump a counter.
> >
> > Unlike the existing profiling system, we don't try to look at argv[], and
> thusly don't require main() to be present in the IR. This matches GCC's
> technique where you specify the profiling flag when producing each .o file.
> >
> > The runtime library is minimal, currently just calling printf at program
> shutdown time. The API is designed to make it possible to emit GCOV data
> later on.
> >
> > Added:
> >    llvm/trunk/lib/Transforms/Instrumentation/LineProfiling.cpp
> >    llvm/trunk/runtime/libprofile/LineProfiling.c
> > Modified:
> >    llvm/trunk/include/llvm/InitializePasses.h
> >    llvm/trunk/include/llvm/LinkAllPasses.h
> >    llvm/trunk/include/llvm/Transforms/Instrumentation.h
> >    llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> >    llvm/trunk/runtime/libprofile/libprofile.exports
> >
> > Modified: llvm/trunk/include/llvm/InitializePasses.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=129340&r1=129339&r2=129340&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/InitializePasses.h (original)
> > +++ llvm/trunk/include/llvm/InitializePasses.h Mon Apr 11 20:06:09 2011
> > @@ -94,6 +94,7 @@
> > void initializeEdgeBundlesPass(PassRegistry&);
> > void initializeEdgeProfilerPass(PassRegistry&);
> > void initializePathProfilerPass(PassRegistry&);
> > +void initializeLineProfilerPass(PassRegistry&);
> > void initializeEarlyCSEPass(PassRegistry&);
> > void initializeExpandISelPseudosPass(PassRegistry&);
> > void initializeFindUsedTypesPass(PassRegistry&);
> >
> > Modified: llvm/trunk/include/llvm/LinkAllPasses.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=129340&r1=129339&r2=129340&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
> > +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Apr 11 20:06:09 2011
> > @@ -70,6 +70,7 @@
> >       (void) llvm::createEdgeProfilerPass();
> >       (void) llvm::createOptimalEdgeProfilerPass();
> >       (void) llvm::createPathProfilerPass();
> > +      (void) llvm::createLineProfilerPass();
> >       (void) llvm::createFunctionInliningPass();
> >       (void) llvm::createAlwaysInlinerPass();
> >       (void) llvm::createGlobalDCEPass();
> >
> > Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=129340&r1=129339&r2=129340&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)
> > +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Mon Apr 11
> 20:06:09 2011
> > @@ -17,7 +17,6 @@
> > namespace llvm {
> >
> > class ModulePass;
> > -class FunctionPass;
> >
> > // Insert edge profiling instrumentation
> > ModulePass *createEdgeProfilerPass();
> > @@ -28,6 +27,9 @@
> > // Insert path profiling instrumentation
> > ModulePass *createPathProfilerPass();
> >
> > +// Insert line profiling instrumentation
> > +ModulePass *createLineProfilerPass();
> > +
> > } // End llvm namespace
> >
> > #endif
> >
> > Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=129340&r1=129339&r2=129340&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> (original)
> > +++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Mon Apr
> 11 20:06:09 2011
> > @@ -23,6 +23,7 @@
> >   initializeEdgeProfilerPass(Registry);
> >   initializeOptimalEdgeProfilerPass(Registry);
> >   initializePathProfilerPass(Registry);
> > +  initializeLineProfilerPass(Registry);
> > }
> >
> > /// LLVMInitializeInstrumentation - C binding for
> >
> > Added: llvm/trunk/lib/Transforms/Instrumentation/LineProfiling.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/LineProfiling.cpp?rev=129340&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Instrumentation/LineProfiling.cpp (added)
> > +++ llvm/trunk/lib/Transforms/Instrumentation/LineProfiling.cpp Mon Apr
> 11 20:06:09 2011
> > @@ -0,0 +1,217 @@
> > +//===- LineProfiling.cpp - Insert counters for line profiling
> -------------===//
> > +//
> > +//                      The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +//
> > +// This pass creates counters for the number of times that the original
> source
> > +// lines of code were executed.
> > +//
> > +// The lines are found from existing debug info in the LLVM IR.
> Iterating
> > +// through LLVM instructions, every time the debug location changes we
> insert a
> > +// new counter and instructions to increment the counter there. A global
> > +// destructor runs to dump the counters out to a file.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#define DEBUG_TYPE "insert-line-profiling"
> > +
> > +#include "ProfilingUtils.h"
> > +#include "llvm/Transforms/Instrumentation.h"
> > +#include "llvm/Analysis/DebugInfo.h"
> > +#include "llvm/Module.h"
> > +#include "llvm/Pass.h"
> > +#include "llvm/Instructions.h"
> > +#include "llvm/Support/raw_ostream.h"
> > +#include "llvm/Support/Debug.h"
> > +#include "llvm/Support/DebugLoc.h"
> > +#include "llvm/Support/InstIterator.h"
> > +#include "llvm/Support/IRBuilder.h"
> > +#include "llvm/ADT/DenseMap.h"
> > +#include "llvm/ADT/Statistic.h"
> > +#include "llvm/ADT/StringExtras.h"
> > +#include <set>
> > +#include <string>
> > +using namespace llvm;
> > +
> > +STATISTIC(NumUpdatesInserted, "The # of counter increments inserted.");
> > +
> > +namespace {
> > +  class LineProfiler : public ModulePass {
> > +    bool runOnModule(Module &M);
> > +  public:
> > +    static char ID;
> > +    LineProfiler() : ModulePass(ID) {
> > +      initializeLineProfilerPass(*PassRegistry::getPassRegistry());
> > +    }
> > +    virtual const char *getPassName() const {
> > +      return "Line Profiler";
> > +    }
> > +
> > +  private:
> > +    // Get pointers to the functions in the runtime library.
> > +    Constant *getStartFileFunc();
> > +    Constant *getCounterFunc();
> > +    Constant *getEndFileFunc();
> > +
> > +    // Insert an increment of the counter before instruction I.
> > +    void InsertCounterUpdateBefore(Instruction *I);
> > +
> > +    // Add the function to write out all our counters to the global
> destructor
> > +    // list.
> > +    void InsertCounterWriteout();
> > +
> > +    // Mapping from the source location to the counter tracking that
> location.
> > +    DenseMap<DebugLoc, GlobalVariable *> counters;
> > +
> > +    Module *Mod;
> > +    LLVMContext *Ctx;
> > +  };
> > +}
> > +
> > +char LineProfiler::ID = 0;
> > +INITIALIZE_PASS(LineProfiler, "insert-line-profiling",
> > +                "Insert instrumentation for line profiling", false,
> false)
> > +
> > +ModulePass *llvm::createLineProfilerPass() { return new LineProfiler();
> }
> > +
> > +bool LineProfiler::runOnModule(Module &M) {
> > +  Mod = &M;
> > +  Ctx = &M.getContext();
> > +
> > +  DebugLoc last_line;  // initializes to unknown
> > +  bool Changed = false;
> > +  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
> > +    for (inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE;
> ++II) {
> > +      const DebugLoc &loc = II->getDebugLoc();
> > +      if (loc.isUnknown()) continue;
> > +      if (loc == last_line) continue;
> > +      last_line = loc;
> > +
> > +      InsertCounterUpdateBefore(&*II);
> > +      ++NumUpdatesInserted;
> > +      Changed = true;
> > +    }
> > +  }
> > +
> > +  if (Changed) {
> > +    InsertCounterWriteout();
> > +  }
> > +
> > +  return Changed;
> > +}
> > +
> > +void LineProfiler::InsertCounterUpdateBefore(Instruction *I) {
> > +  const DebugLoc &loc = I->getDebugLoc();
> > +  GlobalVariable *&counter = counters[loc];
> > +  const Type *Int64Ty = Type::getInt64Ty(*Ctx);
> > +  if (!counter) {
> > +    counter = new GlobalVariable(*Mod, Int64Ty, false,
> > +                                 GlobalValue::InternalLinkage,
> > +                                 Constant::getNullValue(Int64Ty),
> > +                                 "__llvm_prof_linecov_ctr", 0, false,
> 0);
> > +    counter->setVisibility(GlobalVariable::HiddenVisibility);
> > +    counter->setUnnamedAddr(true);
> > +  }
> > +
> > +  if (isa<PHINode>(I)) {
> > +    // We may not error out or crash in this case, because a module
> could put
> > +    // changing line numbers on phi nodes and still pass the verifier.
> > +    dbgs() << "Refusing to insert code before phi: " << *I << "\n";
> > +    I = I->getParent()->getFirstNonPHI();
> > +  }
> > +
> > +  IRBuilder<> builder(I);
> > +  Value *ctr = builder.CreateLoad(counter);
> > +  ctr = builder.CreateAdd(ctr, ConstantInt::get(Int64Ty, 1));
> > +  builder.CreateStore(ctr, counter);
> > +}
> > +
> > +static DISubprogram FindSubprogram(DIScope scope) {
> > +  while (!scope.isSubprogram()) {
> > +    assert(scope.isLexicalBlock() &&
> > +           "Debug location not lexical block or subprogram");
> > +    scope = DILexicalBlock(scope).getContext();
> > +  }
> > +  return DISubprogram(scope);
> > +}
> > +
> > +Constant *LineProfiler::getStartFileFunc() {
> > +  const Type *Args[1] = { Type::getInt8PtrTy(*Ctx) };
> > +  const FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
> > +                                              Args, false);
> > +  return Mod->getOrInsertFunction("llvm_prof_linectr_start_file", FTy);
> > +}
> > +
> > +Constant *LineProfiler::getCounterFunc() {
> > +  const Type *Args[] = {
> > +    Type::getInt8PtrTy(*Ctx),   // const char *dir
> > +    Type::getInt8PtrTy(*Ctx),   // const char *file
> > +    Type::getInt32Ty(*Ctx),     // uint32_t line
> > +    Type::getInt32Ty(*Ctx),     // uint32_t column
> > +    Type::getInt64PtrTy(*Ctx),  // int64_t *counter
> > +  };
> > +  const FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
> > +                                              Args, false);
> > +  return Mod->getOrInsertFunction("llvm_prof_linectr_emit_counter",
> FTy);
> > +}
> > +
> > +Constant *LineProfiler::getEndFileFunc() {
> > +  const FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
> false);
> > +  return Mod->getOrInsertFunction("llvm_prof_linectr_end_file", FTy);
> > +}
> > +
> > +void LineProfiler::InsertCounterWriteout() {
> > +  std::set<std::string> compile_units;
> > +  for (DenseMap<DebugLoc, GlobalVariable *>::iterator I =
> counters.begin(),
> > +           E = counters.end(); I != E; ++I) {
> > +    const DebugLoc &loc = I->first;
> > +    DISubprogram
> subprogram(FindSubprogram(DIScope(loc.getScope(*Ctx))));
> > +
>  compile_units.insert(subprogram.getCompileUnit().getFilename().str());
> > +  }
> > +
> > +  const FunctionType *WriteoutFTy =
> > +      FunctionType::get(Type::getVoidTy(*Ctx), false);
> > +  Function *WriteoutF = Function::Create(WriteoutFTy,
> > +                                         GlobalValue::InternalLinkage,
> > +                                         "__llvm_prof_linecov_dtor",
> > +                                         Mod);
> > +  WriteoutF->setUnnamedAddr(true);
> > +  BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF);
> > +  IRBuilder<> builder(BB);
> > +
> > +  Constant *StartFile = getStartFileFunc();
> > +  Constant *EmitCounter = getCounterFunc();
> > +  Constant *EndFile = getEndFileFunc();
> > +
> > +  for (std::set<std::string>::const_iterator CUI =
> compile_units.begin(),
> > +           CUE = compile_units.end(); CUI != CUE; ++CUI) {
> > +    builder.CreateCall(StartFile,
> > +                       builder.CreateGlobalStringPtr(*CUI));
> > +    for (DenseMap<DebugLoc, GlobalVariable *>::iterator I =
> counters.begin(),
> > +             E = counters.end(); I != E; ++I) {
> > +      const DebugLoc &loc = I->first;
> > +      DISubprogram
> subprogram(FindSubprogram(DIScope(loc.getScope(*Ctx))));
> > +      DICompileUnit compileunit(subprogram.getCompileUnit());
> > +
> > +      if (compileunit.getFilename() != *CUI)
> > +        continue;
> > +
> > +      Value *Args[] = {
> > +        builder.CreateGlobalStringPtr(subprogram.getDirectory()),
> > +        builder.CreateGlobalStringPtr(subprogram.getFilename()),
> > +        ConstantInt::get(Type::getInt32Ty(*Ctx), loc.getLine()),
> > +        ConstantInt::get(Type::getInt32Ty(*Ctx), loc.getCol()),
> > +        I->second
> > +      };
> > +      builder.CreateCall(EmitCounter, Args);
> > +    }
> > +    builder.CreateCall(EndFile);
> > +  }
> > +  builder.CreateRetVoid();
> > +
> > +  InsertProfilingShutdownCall(WriteoutF, Mod);
> > +}
> >
> > Added: llvm/trunk/runtime/libprofile/LineProfiling.c
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/runtime/libprofile/LineProfiling.c?rev=129340&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/runtime/libprofile/LineProfiling.c (added)
> > +++ llvm/trunk/runtime/libprofile/LineProfiling.c Mon Apr 11 20:06:09
> 2011
> > @@ -0,0 +1,37 @@
> > +/*===- LineProfiling.c - Support library for line profiling
> ---------------===*\
> > +|*
> > +|*                     The LLVM Compiler Infrastructure
> > +|*
> > +|* This file is distributed under the University of Illinois Open Source
> > +|* License. See LICENSE.TXT for details.
> > +|*
> >
> +|*===----------------------------------------------------------------------===*|
> > +|*
> > +|* This file implements the call back routines for the line profiling
> > +|* instrumentation pass. Link against this library when running code
> through
> > +|* the -insert-line-profiling LLVM pass.
> > +|*
> >
> +\*===----------------------------------------------------------------------===*/
> > +
> > +#include <stdlib.h>
> > +#include <stdio.h>
> > +#include <stdint.h>
> > +
> > +/* A file in this case is a translation unit. Each .o file built with
> line
> > + * profiling enabled will emit to a different file. Only one file may be
> > + * started at a time.
> > + */
> > +void llvm_prof_linectr_start_file(const char *orig_filename) {
> > +  printf("[%s]\n", orig_filename);
> > +}
> > +
> > +/* Emit data about a counter to the data file. */
> > +void llvm_prof_linectr_emit_counter(const char *dir, const char *file,
> > +                                    uint32_t line, uint32_t column,
> > +                                    int64_t *counter) {
> > +  printf("%s/%s:%u:%u %lu\n", dir, file, line, column, *counter);
> > +}
> > +
> > +void llvm_prof_linectr_end_file() {
> > +  printf("-----\n");
> > +}
> >
> > Modified: llvm/trunk/runtime/libprofile/libprofile.exports
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/runtime/libprofile/libprofile.exports?rev=129340&r1=129339&r2=129340&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/runtime/libprofile/libprofile.exports (original)
> > +++ llvm/trunk/runtime/libprofile/libprofile.exports Mon Apr 11 20:06:09
> 2011
> > @@ -5,3 +5,6 @@
> > llvm_trace_basic_block
> > llvm_increment_path_count
> > llvm_decrement_path_count
> > +llvm_prof_linectr_start_file
> > +llvm_prof_linectr_emit_counter
> > +llvm_prof_linectr_end_file
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110412/d0385ec8/attachment.html>


More information about the llvm-commits mailing list