Guidelines for pass initialization?

Does anyone know what the guidelines are supposed to be for properly initializing a pass? Looking around, we seem to have three styles of pass registration in use.

INITIALIZE_PASS(...)

INITIALIZE_PASS_BEGIN(...)
INITIALIZE_PASS_DEPENDENCY(...)
...
INITIALIZE_PASS_END(...)

static RegisterPass<FooPass> X(...);
(This is the one encouraged in the docs, but seemingly the least widely used in tree?)

As far as I can tell, these often appear to work interchangeably. (At least for passes with only "well known" dependencies.) Can anyone expose a set of guidelines as to when one should use each?

Philip

The macro versions should be preferred, as they reduce static initializaters.

INITIALIZE_PASS is used for a pass that is a leaf in the dependency graph, whereas INITIALIZE_PASS_BEGIN is used for interior nodes.

—Owen

Let me rephrase to make sure I understand. Once we have this settled, I'll update the comments in the file to summarize and possibly update the docs.

The macro versions should be preferred, as they reduce static initializaters.

Makes sense. But the tradeoff is that they need to be baked into the list of known passes so that someone knows to call them? So, if you have a pass which isn't part of LLVM itself, you should prefer RegisterPass? Seems to make sense. Is there also an implicit assumption here that any RegisterPass pass is a leaf in the dependency graph? i.e. you couldn't use this to define your own Analysis?

INITIALIZE_PASS is used for a pass that is a leaf in the dependency graph, whereas INITIALIZE_PASS_BEGIN is used for interior nodes.

Almost all transform passes - with the exception of LoopSimplify and the like - do not have passes which require them. As a result, most transform passes are leaves in the dependency graph and should use the INITIALIZE_PASS mechanism. All Analysis passes are expected to have consumers, so they are obvious not leaf and should use the INITIALIZE_PASS_BEGIN mechanism. Is that a reasonable summary?

No, you have the edge directions backwards. A pass that depends on something else (a Transform that depends on an Analysis) needs to specify that dependency. The Analysis pass itself does not need to specify the reverse dependency.

—Owen

I realized I had that backwards not long after sending it. :slight_smile: So, to rephrase one more time:
1) Analysis without dependencies are leaf and thus INITIALIZE_PASS eligible. Most Analysis passes do not have dependencies.
2) Transforms without dependencies are leaf and thus INITIALIZE_PASS eligible. Very few Transform passes have no dependencies!
3) Passes (Transform or Analysis) with dependencies are not leaf and must use INITIALIZE_PASS_BEGIN.
4) An INITIALIZE_PASS_BEGIN without a dependency is equivalent to INITIALIZE_PASS.

It would seem this makes the RegisterPass template essentially useless. It provides no way to register dependencies so any transform pass register through it is essentially relying on all Analysis passes it uses being previously registered. Yuck.

Philip