Problems with registering of ModulePass (with Dependencies)

Hello,

I have created a ModulePass, that now needs LoopInfo information.
The ModulePass registration is taken from [1]. I use clang to directly invoke
it (This is also a hard requirement, because I need the fancy output of clang
warnings/remarks).

The problem is, that the dependency to the LoopInfoWrapperPass does not seem
to work. The error is:
--- snip ---
clang-4.0: /var/tmp/portage/sys-devel/llvm-4.0.1/work/llvm-4.0.1.src/include/llvm/PassAnalysisSupport.h:236:
AnalysisType& llvm::Pass::getAnalysisID(llvm::AnalysisID) const [with AnalysisType = llvm::LoopInfoWrapperPass; llvm::AnalysisID = const void*]:
Assertion `ResultPass && "getAnalysis*() called on an analysis that was not " "'required' by pass!"' failed.
--- /snip ---

The minimal code, that triggers the error is:
--------- snip ---------
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Analysis/LoopInfo.h"

using namespace llvm;

namespace {
        struct SkeletonPass : public ModulePass {
                static char ID;
                SkeletonPass() : ModulePass(ID) { }

                virtual bool runOnModule(Module &M) override {
                        errs() << "In module called: " << M.getName() << "!\n";
                        LoopInfo& li = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
                        return false;
                }

                virtual void getAnalysisUsage(AnalysisUsage& au) const override {
                        au.setPreservesCFG();
                        au.addRequired<LoopInfoWrapperPass>();
                }
    };
}

char SkeletonPass::ID = 0;

//Automatically enable the pass.
//Adrian Sampson: Run an LLVM Pass Automatically with Clang
static void registerSkeletonPass(const PassManagerBuilder &,
                     legacy::PassManagerBase &PM) {
        PM.add(new SkeletonPass());
}

static RegisterStandardPasses
        RegisterMyPass(PassManagerBuilder::EP_ModuleOptimizerEarly, registerSkeletonPass);

static RegisterStandardPasses
        RegisterMyPass0(PassManagerBuilder::EP_EnabledOnOptLevel0, registerSkeletonPass);
-------- /snip------
Invocation per:
clang -Xclang -load -Xclang /path/to/llvm-pass-skeleton/build/skeleton/libSkeletonPass.so -g test.c
I use clang 4.0.1.

Can someone give me an advice, how to fix this and use the LoopInfo?

Gerion

[1] ModulePasses with Auto Registration · Issue #7 · sampsyo/llvm-pass-skeleton · GitHub

It’s not clear to me what the problem is, but perhaps your pass dependencies are creating circular dependencies that the PassManager cannot resolve. This could happen if LoopInfoWrappersPass, or a pass upon which LoopInfoWrappersPass depends, is not a pure analysis pass (i.e., it does not preserve the results of all other passes). To that end, you could try making your pass preserve all other passes (using addPreserveAll() in your getAnalysisUsage() method) or check that LoopInfoWrappersPass and all passes it uses do not invalidate any passes. If that doesn’t help, then you’ll need to dig deeper (using the debugger) to figure out why the PassManager is hitting the assertion. Using -debug-pass=structure may help. Tracing back through the control flow using the debugger may also provide some insight. Sorry I can’t be more helpful. Regards, John Criswell

> Hello,
>
> I have created a ModulePass, that now needs LoopInfo information.
> The ModulePass registration is taken from [1]. I use clang to directly invoke
> it (This is also a hard requirement, because I need the fancy output of clang
> warnings/remarks).

It's not clear to me what the problem is, but perhaps your pass
dependencies are creating circular dependencies that the PassManager
cannot resolve. This could happen if LoopInfoWrappersPass, or a pass
upon which LoopInfoWrappersPass depends, is not a pure analysis pass
(i.e., it does not preserve the results of all other passes).

Is there any other way to get a valid LoopInfo? In the documention the
LoopInfoWrappersPass is explicitly mentioned for that.

To that end, you could try making your pass preserve all other passes
(using addPreserveAll() in your getAnalysisUsage() method) or check that
LoopInfoWrappersPass and all passes it uses do not invalidate any passes.

addPreservesAll does not change the error.

If that doesn't help, then you'll need to dig deeper (using the
debugger) to figure out why the PassManager is hitting the assertion.
Using -debug-pass=structure may help. Tracing back through the control
flow using the debugger may also provide some insight.

Ok, I'll try.

Is this whole problem maybe dependent on the way of registration? The
standard documentation says to use RegisterPass<SkeletonPass>, what is
not done in this case. Anyway, using RegisterPass has not worked with direct
calling from clang for me.

BTW, I've subscribed the list, so you don't have to CC me.

Gerion

> > Hello,
> >
> > I have created a ModulePass, that now needs LoopInfo information.
> > The ModulePass registration is taken from [1]. I use clang to directly invoke
> > it (This is also a hard requirement, because I need the fancy output of clang
> > warnings/remarks).
>
> It's not clear to me what the problem is, but perhaps your pass
> dependencies are creating circular dependencies that the PassManager
> cannot resolve. This could happen if LoopInfoWrappersPass, or a pass
> upon which LoopInfoWrappersPass depends, is not a pure analysis pass
> (i.e., it does not preserve the results of all other passes).
Is there any other way to get a valid LoopInfo? In the documention the
LoopInfoWrappersPass is explicitly mentioned for that.

> To that end, you could try making your pass preserve all other passes
> (using addPreserveAll() in your getAnalysisUsage() method) or check that
> LoopInfoWrappersPass and all passes it uses do not invalidate any passes.
addPreservesAll does not change the error.

> If that doesn't help, then you'll need to dig deeper (using the
> debugger) to figure out why the PassManager is hitting the assertion.
> Using -debug-pass=structure may help. Tracing back through the control
> flow using the debugger may also provide some insight.
Ok, I'll try.

Is this whole problem maybe dependent on the way of registration? The
standard documentation says to use RegisterPass<SkeletonPass>, what is
not done in this case. Anyway, using RegisterPass has not worked with direct
calling from clang for me.

Found the error. The analysis has to be called per Function. The following code
fixes the pass:
                virtual bool runOnModule(Module &M) override {
                        errs() << "In module called: " << M.getName() << "!\n";
- LoopInfo& li = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ for(Function& f : M) {
+ if (!f.isIntrinsic() && !f.empty()) {
+ LoopInfo& li = getAnalysis<LoopInfoWrapperPass>(f).getLoopInfo();
+ li.print(errs());
+ }
+ }
                        return false;
                }

Reference:
LLVM unable to get a required analysis - Stack Overflow and
http://lists.llvm.org/pipermail/llvm-dev/2011-March/038496.html

Gerion