> Sure, you can do that. Just use F->getParent() to get to the Module.
D'oh. OK, so I can do what I need with a hack for now.
> We have no problem with people asking questions. The PassManager
> is actually do for a rewrite. The current implementation is a nasty
Well, I took a look at it a bit over the weekend. I am probably not the
right person to do the complete rewrite, for instance reworking the
Pass class hierarchy doesn't sound like something I'd want to do. Just
getting to this point has been a bit of an education in real C++.
Ok, fair enough. It's a pretty big piece of work. I would recommend
starting a bit smaller in the world of LLVM, then working up to the big
Here's what I see: We have a modulepass MP that needs a functionpass
FP. We need a copy of that FP (and every pass it depends on) for each
function in the module that MP is being run on.
Currently, in add() we only create one instance of FP, on which we then
call addToPassManager() so we can get the right call to addPass(FP,
...), which adds FP to a single Batcher, in this case, a
PassManagerT<FunctionPass>. In addPass(MP, ...) we see the FP in the
required set, and attempt to mark it as used by the MP. We don't find
it in markPassUsed though, because FP was never added to
CurrentAnalyses. It was just added to the Batcher.
Yeah, this is the problem.
So here's some changes that look necessary. This is likely to be an
oversimplified view, but hopefully it's a start.
1 - in add(), discover that the pass we're requiring is a subpass, and
create more of them. This is the natural place to do it, but can we do
this here, or do we not know enough about the passes?
I think this should work, the problem is that you might have to recurse
and do some other funky stuff. Imagine you have the following situation:
PM.add(functionpass B, which uses A)
PM.add(modulepass C, which uses B)
In this situation, the pass manager would have to clone not just the B
objects, but also the A objects for every function.
The other tricky thing is that we don't know how many pass objects to
create until we actuall start running the pass manager (it depends on the
module being run on).
2 - in addPass(SubPassClass, ...), add those FPs to CurrentAnalyses.
Should we have a map of BatcherClasses - (function, BatcherClass) pairs
instead of just one BatcherClass?
I'm not sure about this. At the time add is called, you don't know what
the functions are. I think that the correct solution is to just build up
more-or-less what we already have, but when a functionpass is marked used
by a pass, the funciton pass should be marked as clonable.
At function-pass-run-time, we should call clone() (a new method on
function passes), to create one copy of each marked function pass for each
non-external function in the module (only if the function pass is marked
as being used by a Pass obviously )
These clones can be stored in in a map from Function* -> FunctionPass*.
Writing the clone() method for FunctionPass objects is an annoying thing
to have to do, but is purely mechanical.
3 - Provide API for the MP to get an analysis per function. (generally,
for the PassClass to get analysis per SubPassClass):
Instead of this:
the natural thing would seem to be (for PassClass = MP and SubPassClass
Yes. This makes a lot of sense. In the future, only the "ModulePass"
class will have this new getAnalysis<T>(Function*) method, but for now it
will go into the Pass class (where everyone will get it).
This simple change does mean some big moving in the background, though,
since (for starters) the PassInfoMap can't just key on the TypeInfo
anymore. It will need to key on something like a structure with TypeInfo
and the unit of code that the pass is attached to. I have a feeling
there are similar instances where PassInfo needs code-unit info attached
I think that a lot of this can be moved to runtime. In particular, when
the PM is constructed, we only need to (and only can) create one instance
of each pass. At runtime, they need to be cloned and destroyed as