How to tell clang call a custom instrumentation pass (like MemorySanitizer)

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();
}

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

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

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

  4. 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);
    }

  5. 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::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::SimpleType>, typename llvm::cast_retty<X, Y*>::ret_type>::type = llvm::PointerType*]: Assertion `isa(Val) && “cast() argument of incompatible type!”’ failed.

I greatly appreciate any help.
Best regards

Tuan