llvm passes

In the instructions for writing LLVM passes, it says "[c]urrently it is illegal for a ModulePass to require a FunctionPass. This is because there is only one instance of the FunctionPass object ever created, thus nowhere to store information for all of the functions in the program at the same time."

I'm a little confused by that. It was my understanding that if pass X required pass Y, then pass Y would have to fully run and build up its internal data structures before pass X ran. Then, when pass X was run, X would call getAnalysis<Y> and get a reference to the pass Y object, which it could query for information stored during pass Y's execution. So, I'm wondering why the types of the passes matter. The statement that there would be "nowhere to store information for all of the functions in the program," confuses me. I assumed that information for all of the functions processed by pass Y would be retained in internal data structures specific to Y.

Can someone please help me figure out where I'm going wrong?

Thanks,
Ryan

In the instructions for writing LLVM passes, it says "[c]urrently it is
illegal for a ModulePass to require a FunctionPass. This is because
there is only one instance of the FunctionPass object ever created, thus
nowhere to store information for all of the functions in the program at
the same time."

Right.

I'm a little confused by that. It was my understanding that if pass X
required pass Y, then pass Y would have to fully run and build up its
internal data structures before pass X ran. Then, when pass X was run,
X would call getAnalysis<Y> and get a reference to the pass Y object,
which it could query for information stored during pass Y's execution.
So, I'm wondering why the types of the passes matter. The statement
that there would be "nowhere to store information for all of the
functions in the program," confuses me.

Imagine you have a functionpass X, for example DominatorSet. DominatorSet runs on a function at a time and captures information about the current function's dominator information in its instance variables.

Now you have ModulePass Y that runs and requires X to be run. Because it is a functionpass, X will be run on every function in the module before Y starts. Further, because X only has one set of instance variables, Y could see, at most, information for one function.

-Chris

So, am I correct that the implication of what you're saying is that if pass X requires pass Y, then pass Y does not necessarily run to completion on every component of a program, before pass X runs. Furthermore, if those passes X and Y are both function passes, then when pass X runs on function F, the last function Y will have run on is function F.

Chris Lattner wrote:

Imagine you have a functionpass X, for example DominatorSet. DominatorSet runs on a function at a time and captures information about the current function's dominator information in its instance variables.

Now you have ModulePass Y that runs and requires X to be run. Because it is a functionpass, X will be run on every function in the module before Y starts. Further, because X only has one set of instance variables, Y could see, at most, information for one function.

I assumed that X would run to completion before pass Y ran and that pass X would have stored instance data for each function in some sort of list or map. I think my confusion must be with what type of pass to use. Am I correct that if I have a pass M that runs on each function but needs to collect data from every function before it can be used by another pass N, then M should be a ModulePass?

Regards,
Ryan

So, am I correct that the implication of what you're saying is that if
pass X requires pass Y, then pass Y does not necessarily run to
completion on every component of a program, before pass X runs.

Right.

Furthermore, if those passes X and Y are both function passes, then when
pass X runs on function F, the last function Y will have run on is
function F.

Please read:
http://llvm.org/docs/WritingAnLLVMPass.html#passmanager

-Chris

Chris Lattner wrote:

Imagine you have a functionpass X, for example DominatorSet. DominatorSet
runs on a function at a time and captures information about the current
function's dominator information in its instance variables.

Now you have ModulePass Y that runs and requires X to be run. Because it
is a functionpass, X will be run on every function in the module before Y
starts. Further, because X only has one set of instance variables, Y
could see, at most, information for one function.

I assumed that X would run to completion before pass Y ran and that pass
X would have stored instance data for each function in some sort of list
or map. I think my confusion must be with what type of pass to use. Am
I correct that if I have a pass M that runs on each function but needs
to collect data from every function before it can be used by another
pass N, then M should be a ModulePass?

Regards,
Ryan

-Chris

-Chris