Can anyone explain what this means?
llvm/include/llvm/PassManagers.h:232: virtual void
llvm::PMDataManager::addLowerLevelRequiredPass(llvm::Pass*, llvm::Pass*):
Assertion `0 && "Unable to handle Pass that requires lower level Analysis
pass"' failed.
-Dave
In simple words, pass manager is not able to schedule passes in requested order.
Pass manager is not able to find required pass at the same level (module, function,
loop etc..) or higher level compared current pass.
What is Pass and RequiredPass when this assertion hits ?
In simple words, pass manager is not able to schedule passes in
requested order. Pass manager is not able to find required pass at the same
level (module, function, loop etc..) or higher level compared current pass.
Ok, that gives me some ideas. I didn't understand what "level" means.
What is Pass and RequiredPass when this assertion hits ?
I haven't had a chance to explore too deeply yet (the stack trace doesn't give
any useful information) but I suspect Pass is the register allocator and
RequiredPass is the coalescer. I say that because the coalescer is an
ImmutablePass (since it shouldn't be run by PassManager) and ImmutablePass
derives from ModulePass, which would trigger the error. The register
allocator does a getAnalysis<RegisterCoalescer> to talk to the coalescer.
So now the question is, what kind of Pass should the coalescer be? It should
not be run by PassManager but PassManager still needs to know about its
analysis requirements. Do we need a new kind of Pass, like
ImmutableFunctionPass, or in this specific case, ImmutableMachineFunctionPass?
I hate this kind of multiple-cross-product-derivation-categorization. :-/
How does this work for AliasAnalysis, which is also an ImmutablePass (or, at
least some of them are)? How do FunctionPasses query the analysis?
-Dave
Turns out I was wrong. Pass is the register allocator but RequiredPass is
LiveVariableAnalysis. Any idea why this would cause a problem?
-Dave
If in register allocator you have requested another higher level pass after LiveVariableAnalysis pass then this may happen.
Can you explain why this is so? I would assume that I could declare Pass
dependencies in any order. The manual certainly doesn't say anything about
restricions like this. Shouldn't a Pass just be a Pass that can be run?
-Dave
A pass is not just a pass. It depends on the the level it operates on. A function level pass operates on all functions and a module level pass works on entire module. For example,
If pass sequence is - ModuleLevelPass A, FunctionLevelPass B, FunctionLevelPass C, ModuleLevelPass D then
For each Module
run ModuleLevelPass A
for each function in this module
run FunctionLevelPass B
run FunctionLevelPass C
run ModuleLevelPass D
Now, if pass sequence is - ModuleLevelPass A, FunctionLevelPass B, ModuleLevelPass D, FunctionLevelPass C then
For each Module
run ModuleLevelPass A
for each function in this module
run FunctionLevelPass B
run ModuleLevelPass D
for each function in this module
run FunctionLevelPass C
In this situation, while processing 'foo' FunctionLevelPass C can not use analysis info generated by FunctionLevelPass B for 'foo'.
So if FunctionLevelPass C is requiring FunctionLevelPass B and ModuleLevelPass D in that order then you may see mentioned assertions. I just checked in patch to help investigate such failures. Add --debug-pass=Structure on the 'opt' command line to understand what is going on.
I welcome patches to update manual to explain this clearly.
Why? I expect the answer is something like, "because B doesn't exist
anymore," or, "because you processed function 'bar' with B after 'foo.'"
But why? B doesn't _have_ to exist and it shouldn't necessarily matter
in what order PassManager processes functions. Only the information
that pass B generates for foo need exist.
If you're running module-level passes anyway, you're probably burning a bit
of memory to hold state, so maybe keeping around information for all functions
is feasible. I don't know.
Yes, I understand that these questions imply rethinking how PassManager
works. That's why I'm asking them. I reordered my code and got things to
work but it's always good to take a step back from time-to-time and ask
fundamental questions. Even if no changes are immediately forthcoming,
it at least helps to identify areas of potential future work.
-Dave
Now, if pass sequence is - ModuleLevelPass A, FunctionLevelPass B,
ModuleLevelPass D, FunctionLevelPass C then
For each Module
run ModuleLevelPass A
for each function in this module
run FunctionLevelPass B
run ModuleLevelPass D
for each function in this module
run FunctionLevelPass C
In this situation, while processing 'foo' FunctionLevelPass C can not
use analysis info generated by FunctionLevelPass B for 'foo'.
Why? I expect the answer is something like, "because B doesn't exist
anymore," or, "because you processed function 'bar' with B after 'foo.'"
But why? B doesn't _have_ to exist and it shouldn't necessarily matter
in what order PassManager processes functions. Only the information
that pass B generates for foo need exist.
That is not true in LLVM. For example, DominatorTree pass maintains Dominator
info.
If you're running module-level passes anyway, you're probably burning a bit
of memory to hold state, so maybe keeping around information for all functions
is feasible. I don't know.
In general, it is not a good idea to keep info for all components around all time for many reasons. Too many to list here.
Yes, I understand that these questions imply rethinking how PassManager
works. That's why I'm asking them. I reordered my code and got things to
work but it's always good to take a step back from time-to-time and ask
fundamental questions. Even if no changes are immediately forthcoming,
it at least helps to identify areas of potential future work.
It is not just pass manager, you're asking question regarding LLVM's core design.
> Why? I expect the answer is something like, "because B doesn't exist
> anymore," or, "because you processed function 'bar' with B after
> 'foo.'"
> But why? B doesn't _have_ to exist and it shouldn't necessarily
> matter
> in what order PassManager processes functions. Only the information
> that pass B generates for foo need exist.
That is not true in LLVM. For example, DominatorTree pass maintains
Dominator
info.
Only because the information is embedded into the Pass. There's no reason
it has to be.
> If you're running module-level passes anyway, you're probably
> burning a bit
> of memory to hold state, so maybe keeping around information for
> all functions
> is feasible. I don't know.
In general, it is not a good idea to keep info for all components
around all time for many reasons. Too many to list here.
Probably not everything, but if PassManager is sorting out dependencies, it
should have knowledge of exactly what to keep around when.
It is not just pass manager, you're asking question regarding LLVM's
core design.
Yep.
-Dave