[cfe-dev] How to tell clang call a custom instrumentation pass (like MemorySanitizer)

Nguyen, Tuan Dung Dung.Nguyen at rwth-aachen.de
Thu Feb 6 04:25:52 PST 2014


hi,

i have an instrumentation pass which uses an instrumentation library (like the MemorySanitizer).  And i want to call this pass through my own flag '-dp'.  In order to achive it, i performed the following main steps:

1. llvm-3.3.src/include/llvm/Transforms/Instrumentation.h
    added a new function declaration:  FunctionPass *createDiscoPoPPass();

2. llvm-3.3.src/lib/Transforms/Instrumentation.cpp:
   added initializeDiscoPoPPass  at the end of function initializeInstrumentation(PassRegistry &Registry)

3. copied my instrumentation library to llvm-3.3.src/projects/compiler-rt/lib and modified the Makefile.mk, CMakeLists.txt respectively (in the same way for MemorySanitizer)

4. copied the source file of my pass 'DiscoPoP.cpp' to llvm-3.3.src/lib/Transforms/Instrumentation and added the following code
                  INITIALIZE_PASS(DiscoPoP, "discoPoP", "analyze dependences", false, false)

                  FunctionPass *llvm::createDiscoPoPPass() {
                     return new DiscoPoP();
                  }

5. Added my new flag:
     Options.td:  def discoPoP : Flag<["-"], "dp">, Group<d_clang_Group>, Flags<[CC1Option]>, HelpText....
     LangOptions.def: LANGOPT(UseDiscoPoP, 1, 0, ".........")

6. llvm-3.3.src/tools/clang/lib/Frontend/CompilerInvocation.cpp:
      modified the function ParseLangArgs to save my option just like other options.

7. llvm-3.3.src/tools/clang/lib/Driver/Toolsc.pp: just forwared my option in function Clang::ConstructJob

8. llvm-3.3.src/tools/clang/lib/CodeGen/BackendUtil.cpp:
    added new function:  static void addDiscoPopPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {  // add a new instance of DiscoPoP to PM .....}
    added the following code to function EmitAssemblyHelper::CreatePasses(TargetMachine *TM):
          if (LangOpts.UseDiscoPoP)
          {
               PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addDiscoPopPass);
               PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addDiscoPopPass);
          }

9. llvm-3.3.src/tools/clang/lib/Driver/Driver.cpp: added the following functions to tell clang how to locate the runtime library for my pass
         static void addDiscoPoPRTLinkFlagsLinux( // do the same step as for runtime lib of MemorySanitizer .... }
         static void addDiscoPoPRTLinux(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs)

After performing all those steps, i'm able to call my pass with opt and it works fine
            clang -S -g -emit-llvm test.cc -o test.ll
            opt -S -discoPoP --debug-pass=Structure < test.ll > test_ins.ll

However if i call my pass with -O0 from clang directly then i got the following error :
   ./clang++ -g -dp -std=c++11 -O0 test.cc

   Pass 'DiscoPoP' is not initialized.
   Verify if there is a pass dependency cycle.
   Required Passes:
   clang: PassManager.cpp:646: void llvm::PMTopLevelManager::schedulePass(llvm::Pass*): Assertion `PI && "Expected required passes to be initialized"' failed.

I tried to figure out what is the difference between my pass and memory sanitizer. But i was not successful. Actually i did the same steps as for MemorySanitizer .
Besides, if i call mypass with -O1 or -O2 then my pass is initialized :-). But i got another error which i could not figure out.

   .... other passes
   Dominator Tree Construction 0
   Natural Loop Information 1
   DiscoPoP 2
   Preliminary module verification 0
   Dominator Tree Construction 1
   Function Pass: Module Verifier 2
clang: /home/maus/Desktop/Thesis/llvm-3.3.src/include/llvm/Support/Casting.h:237: typename llvm::enable_if<llvm::is_same<Y, typename llvm::simplify_type<From>::SimpleType>, typename llvm::cast_retty<X, Y*>::ret_type>::type llvm::cast(Y*) [with X = llvm::PointerType; Y = llvm::Type; typename llvm::enable_if<llvm::is_same<Y, typename llvm::simplify_type<From>::SimpleType>, typename llvm::cast_retty<X, Y*>::ret_type>::type = llvm::PointerType*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

I greatly appreciate any help.
Best regards

Tuan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140206/2dea9b61/attachment.html>


More information about the cfe-dev mailing list