PassManager Mysteries

I've never been able to figure this one out:

llvm/lib/VMCore/PassManager.cpp:938: virtual void
llvm::PMDataManager::addLowerLevelRequiredPass(llvm::Pass*, llvm::Pass*):
Assertion `0 && "Unable to handle Pass that requires lower level Analysis
pass"' failed.

In the past, I've resolved this by disabling random addRequired calls in the
offending Pass, even when those dependencies are real.

So what does this assert mean, exactly? How do I find out just what is wrong
with the Pass dependencies?

                                             -Dave

I've never been able to figure this one out:

llvm/lib/VMCore/PassManager.cpp:938: virtual void
llvm::PMDataManager::addLowerLevelRequiredPass(llvm::Pass*, llvm::Pass*):
Assertion `0 && "Unable to handle Pass that requires lower level Analysis
pass"' failed.

In the past, I've resolved this by disabling random addRequired calls in the
offending Pass, even when those dependencies are real.

If those dependencies were real then I expect that you won't be able to disable it because otherwise your pass won't work because of lack of required information :wink:

So what does this assert mean, exactly?

In simple word, pass manager is unable to fulfill your request.

How do I find out just what is wrong
with the Pass dependencies?

Use -debug-pass=Details and find out which pass dependency is not handled.

Can you explain this one in complex words then? :^) I’ve encountered the same problem.

–Vikram

From experience, an important point that is often forgotten is that the order of declaration of dependencies matter. If you declare that you require pass A, and then pass B, and B doesn’t preserve A, you’ll get an error like this.

Just some advice from having had similar problems in the past.

–Owen

Not true. If the information happens to be current (in my case it
always is), everyone's happy.

                                       -Dave

I'll have to double-check my code, but I don't think I have this particular
problem.

But in any case, isn't the whole point of PassManager that it can handle
situations like this? Why wouldn't it just run Pass A twice, or run it
in the correct order (after Pass B)?

This strikes me as rather fragile. And my experience has been that
that is in fact exactly the case.

                                          -Dave

Dear All,

I had a similar error back in December; there are a number of email exchanges about it on llvmdev in December 2007; a search through the archives might shed some light on my PassManager does this.

If you're updating a pass from pre-LLVM 2.0 to post-LLVM 2.0, you should be aware that the pass manager in LLVM 2.x is used only for scheduling dependent *analysis* passes. If you need to ensure that transform passes are run in a certain order or before an analysis pass, you need to order that explicitly by adding the passes to the PassManager object in the correct order.

In my case, SAFECode used the PassManager's dependency checking to ensure that the Automatic Pool Allocation transform was run before the SAFECode analysis and transform passes. This worked in LLVM 1.9; it doesn't work in LLVM 2.x.

-- John T.

Vikram S. Adve wrote:

I assume there are situations in which a pass cannot be recomputed, but we really need Devang for that. All I know is that, most of the times I've encountered this problem, it was fixable just by reordering the declarations.

--Owen

Well, I was wrong. I found the missing addPreserved and everything's
hunky-dorey.

BTW, -debug-pass=Details wasn't all that helpful. An excerpt:

    Live Interval Analysis
    MachineDominator Tree Construction
    Machine Natural Loop Construction
    Iterated Register Coalescing
llvm/lib/VMCore/PassManager.cpp:938: virtual void
llvm::PMDataManager::addLowerLevelRequiredPass(llvm::Pass*, llvm::Pass*):
Assertion `0 && "Unable to handle Pass that requires lower level Analysis
pass"' failed.
ftn-2116 ftn: INTERNAL

That doesn't say anything about which pass triggered the error or which
dependency was unavailable. PassManager should be able to dump
this information.

                                          -Dave

If you're updating a pass from pre-LLVM 2.0 to post-LLVM 2.0, you should
be aware that the pass manager in LLVM 2.x is used only for scheduling
dependent *analysis* passes.

I believe that was the intention from day one otherwise original author would not have used term "analysis" everywhere in code and interface that deals with pass dependencies.

If you need to ensure that transform
passes are run in a certain order or before an analysis pass, you need
to order that explicitly by adding the passes to the PassManager object
in the correct order.

In my case, SAFECode used the PassManager's dependency checking to
ensure that the Automatic Pool Allocation transform was run before the
SAFECode analysis and transform passes. This worked in LLVM 1.9; it
doesn't work in LLVM 2.x.

On the other side, LLVM 2.x PassManager add much needed flexibility and new features.

If you realize that function level analysis pass only preserves and servers analysis info for one function at a time then current pass manager behavior is obvious. If you insert a module level pass between two function level passes then these two function level passes can not share analysis information.

Let's develop one example step by step to understand this.

Ok, thanks! I'm copying llvmdev again because others had asked about this as well.

--Vikram
http://www.cs.uiuc.edu/~vadve
http://llvm.org/