ModulePass cannot be registered as EarlyAsPossible

Hello all,

I’ve followed the example in in order to create a custom pass.

The pass needs to be added before any transformation, so I used EP_EarlyAsPossible extension point to register it. Furthermore, I need to access to every GlobalVariable in the IR, so my pass has to be a ModulePass, like this:

struct MyPass : public ModulePass {
static char ID;

MyPass(): ModulePass(ID) {}

virtual bool runOnModule(Module &M) {…}


However, every time I try to access to the Module object M inside runOnModule(), clang just crashes. Even a debug message like outs() << M.getName() << ‘\n’; would cause a segfault. So am I doing something wrong, like EP_EarlyAsPossible is really not to be used with ModulePasses, or is this rather a bug?

In case this is not a bug, what would be the best way to manipulate an IR Module as it is coming right out of the frontend?

Thanks for your help,

Yes, sorry that I wasn’t very clear about that, but the hack in opt.cpp only works when using opt. We are doing the “early rewrites” when using another frontend than clang, and in that case we are running the opt/llc binaries standalone after the frontend.

I’m not sure, but maybe it is possible to do something similar in EmitAssemblyHelper::CreatePasses (in clang/lib/CodeGen/BackendUtil.cpp), if you want to do it in clang.



EP_EarlyAsPossible only works with FunctionPasses, yes. If you look at how it’s used in PassManagerBuilder, it is only invoked from populateFunctionPassManager.

The earliest you can add ModulePasses is with EP_ModuleOptimizerEarly. However, those passes are not added on O0. If the OptLevel is 0, you can instead add the passes to EP_EnabledOnOptLevel0.

This might not be early enough for you, but those are the points that are available for module passes as far as I know.


Hi Bevin,

Thank you for your reply. Unfortunately, I was using EP_ModuleOptimizerEarly and I just realized that it is not early enough, since the FunctionPassManager does apply some basic optimization on the functions before any Module optimizations…

So there’s no way to insert a Module pass earlier than ModuleOptimizerEarly? I will try to hack it as Björn pointed out then.

Thanks for your help,