Pass Added as Required fails assert

Hey all,

We have been working on a pass that uses another pass to count loads and stores prior to performing its own instrumentation. The second pass adds the first as required via the usual getAnalysisUsage function. On one machine, it has been tested and proven to function correctly. On another machine, whenever the second pass is run, it consistently fails the assertion:

opt: /home/tmason/llvm/llvm/include/llvm/PassAnalysisSupport.h:193: AnalysisType& llvm::Pass::getAnalysisID(const llvm::PassInfo*) const [with AnalysisType = ::LdStCallCounter]: Assertion `ResultPass && "getAnalysis*() called on an analysis that was not " “‘required’ by pass!”’ failed.

We have modified opt.cpp with the following lines:
addPass(PM, createLdStCallCounter()); // tmason
addPass(PM, createLAMPProfilerPass()); // tmason

We have modified Instrumentation.h with the following lines:
ModulePass* createLdStCallCounter();
BasicBlockPass *createLAMPProfilerPass();

The .cpp file generating the error is attached.

Both machines run Ubuntu 8.0.4 with gcc 4.2.3. Does anyone know what could be causing this error to occur on one machine but not another?

Thanks,
Thomas

LAMPProfiling.cpp (6.54 KB)

We have discovered the issue with our code. It seems that when the first call to doInitilization utilized one of the specified analyses, that analysis had never been properly added as required. Using gdb, we can see that addRequired is getting called (seen below) but when doInitalization is finally called, it still responds as if the analysis was not required.

Is this a bug or is doInitialization not permitted to access other analyses?

Our code functions correctly as a function pass as well as on any program that has other functions prior to the main function. It only fails in this manner when main is the first (or only) function in the source file.

Debugging information:

Breakpoint 2, getAnalysisUsage (this=0x88072c8, AU=@0xbfa352f8) at /home/pprabhu/llvm/llvm/lib/Transforms/Instrumentation/LAMPProfiling.cpp:93
93 AU.addRequired();
(gdb) c
Continuing.

Breakpoint 2, getAnalysisUsage (this=0x88072c8, AU=@0xbfa350b4) at /home/pprabhu/llvm/llvm/lib/Transforms/Instrumentation/LAMPProfiling.cpp:93
93 AU.addRequired();
(gdb) c
Continuing.

Breakpoint 2, getAnalysisUsage (this=0x88072c8, AU=@0xbfa35088) at /home/pprabhu/llvm/llvm/lib/Transforms/Instrumentation/LAMPProfiling.cpp:93
93 AU.addRequired();
(gdb) c
Continuing.
32 30 5

Breakpoint 3, doInitialization (this=0x88072c8, F=@0x8807d90) at /home/pprabhu/llvm/llvm/lib/Transforms/Instrumentation/LAMPProfiling.cpp:135
135 const char* FnName = “LAMP_init”;
(gdb) n
137 if (lampFuncs[0] == NULL)
(gdb) n
139 Module* M = F.getParent();
(gdb) n
140 createLampDeclarations(M);
(gdb) n
143 if (F.getName() == “main”) {
(gdb) n
145 Module* M = F.getParent();
(gdb) n
146 LdStCallCounter& lscnts = getAnalysis();
(gdb) n
opt: /home/pprabhu/llvm/llvm/include/llvm/PassAnalysisSupport.h:193: AnalysisType& llvm::Pass::getAnalysisID(const llvm::PassInfo*) const [with AnalysisType = ::LdStCallCounter]: Assertion `ResultPass && "getAnalysis*() called on an analysis that was not " “‘required’ by pass!”’ failed.

Yes this is true. doInitialization() is used to prepare the stage and it is executed before any other pass is run by the pass manager.

If pass B requires pass A then usual sequence is

Run PassA doInitialization()
Run PassB doInitialization() <--- Here PassA is not run so the analysis info. provided by A is not available.

Run PassA
Run PassB

Run PassA doFinalization()
Run PassB doFinalization()