How can I use llvm::LoopInfo in the runOnModule method?

Hi all,

I tried to have a LoopInfo object in a function pass, and add addRequired in getAnalysisUsage, and then use getAnalysis in runOnFunction(). It worked OK.
Now I want to have a module pass to traverse the functions, and similarly, I want to have to loop information of the functions.
When I did the above in runOnModule, and build the module pass, the following error popped out, and the compile did not succeed:

[ 50%] Building CXX object src/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.o
/home/**/Desktop/skeleton/src/Skeleton.cpp: In member function ‘virtual bool llvm::SkeletonPass::runOnModule(llvm::Module&)’:
/home/**/Desktop/skeleton/src/Skeleton.cpp:47:43: error: no matching function for call to ‘llvm::SkeletonPass::getAnalysis(llvm::Function*&)’
     LoopInfo &LI = getAnalysis<LoopInfo>(F);

...
home/**/Work/llvm-6.0.1.src/include/llvm/PassAnalysisSupport.h: In instantiation of ‘llvm::AnalysisUsage& llvm::AnalysisUsage::addRequired() [with PassClass = llvm::LoopInfo]’:
/home/**/Desktop/skeleton/src/Skeleton.cpp:24:38:   required from here
/home/**/Work/llvm-6.0.1.src/include/llvm/PassAnalysisSupport.h:67:39: error: ‘ID’ is not a member of ‘llvm::LoopInfo’
     return addRequiredID(PassClass::ID);
                                       ^

Here is my source code:

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Analysis/LoopInfo.h"

namespace llvm
{
    class SkeletonPass : public ModulePass
    {
    public:
        static char ID;
        SkeletonPass() : ModulePass(ID) {}
        bool runOnModule(Module &M) override;
        virtual StringRef getPassName() const override
        {
            return "Skeleton";
        }
        virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
            errs() << "get analysis usage method.\n";
            AU.addRequired<LoopInfo>();
        }
    };

    Pass *createSkeletonPass()
    {
        return new SkeletonPass();
    }

    char SkeletonPass::ID = 0;
    Pass *createSkeletonPass();
    void initializeSkeletonPass(PassRegistry &Registry);

} // namespace llvm

using namespace llvm;
using namespace std;

bool SkeletonPass::runOnModule(llvm::Module &M){
    errs() << "=============start=============\n";
    auto F = M.getFunction("main");
    LoopInfo &LI = getAnalysis<LoopInfo>(F);

    LI.print(errs());
    errs() << "==========================\n";
}

static RegisterPass<SkeletonPass> X("run", "Hello world pass", false, false);

The version of LLVM is 6.0.1, can anyone tell me the correct way to handle this in a module pass? Thanks a lot!

Best,
Liu

It should be `LoopInfoWrapperPass` instead of just `LoopInfo`, but you
can also get the same information if you manually construct a
dominator tree and target info first and pass those to the LoopInfo
constructor.

Interesting that we're getting a relative flood of these recently.

See here:

http://lists.llvm.org/pipermail/llvm-dev/2019-March/131346.html

I don't think one can reliably get a Function analysis pass from within
a ModulePass using the legacy pass manager. You have to manually
construct the pass yourself.

                    -David

Jonathan Smith via llvm-dev <llvm-dev@lists.llvm.org> writes:

I saw this (or perhaps an earlier, similar message) before and that
was enough for me to avoid trying it.

The good thing is it's easy enough to get a LoopInfo manually without
constructing a pass at all:

  llvm::DominatorTree domTree{&func, func};
  llvm::LoopInfo loopInfo{&func, domTree};

That’s strange. AFAIK IPSCCP does exactly that for the DT analysis, see getAnalysis in
https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/IPO/SCCP.cpp#L53

Which is called for each function in the module:
https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/Scalar/SCCP.cpp#L1960

It does not seem like the legacy pass manager is able to preserve Function analyses from Module passes, whereas the new pass manager can, however.

Cheers,
Florian

Florian Hahn <florian_hahn@apple.com> writes:

I don't think one can reliably get a Function analysis pass from within
a ModulePass using the legacy pass manager. You have to manually
construct the pass yourself.

That’s strange. AFAIK IPSCCP does exactly that for the DT analysis, see getAnalysis in
   https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/IPO/SCCP.cpp#L53

Yes, I know. That's what I modeled my solution after. And it worked
for a bunch of codes I ran it on. Until it didn't.

I think IPSCCP is broken because the on-the-fly pass manager stuff is
broken.

It does not seem like the legacy pass manager is able to preserve
Function analyses from Module passes, whereas the new pass manager
can, however.

It's not about preserving analyses. The analyses are not safely
available within the ModulePass itself. They get deleted sometime
during the sequence of calls to getAnalysis.

                      -David