[llvm-dev] ModulePass cannot be registered as EarlyAsPossible

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] ModulePass cannot be registered as EarlyAsPossible

Adam Nemet via llvm-dev
Hello all,

I've followed the example in https://github.com/CompilerTeaching/SimplePass/blob/master/SimplePass.cc 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,

Son Tuan Vu

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] ModulePass cannot be registered as EarlyAsPossible

Adam Nemet via llvm-dev

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.

 

/Björn

 

From: Son Tuan VU <[hidden email]>
Sent: den 12 juni 2018 19:54
To: Björn Pettersson A <[hidden email]>
Subject: Re: [llvm-dev] ModulePass cannot be registered as EarlyAsPossible

 

Thanks Björn for your answer.

So your way of doing this implies that we have to use opt, what if we want to use clang instead? I mean, instead of
clang -O0 -emit-llvm -S foo.c -o foo.ll

opt -O1 -S foo.ll -o foo_opt.ll

we would have

clang -O1 -emit-llvm -S foo.c -o foo_opt.ll

I guess this requires me to find the right place in clang to add the same code as yours in opt?


Son Tuan Vu

 

On Tue, Jun 12, 2018 at 6:11 PM, Björn Pettersson A <[hidden email]> wrote:

I let someone else answer about if it is a bug or not.

 

Anyway, in our out-of-tree-target we have some module passes that we want to run early in opt.

Our way of doing it is to use a hack in tools/opt/opt.cpp like this:

 

diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp

index 43771d5d75b..2a08ce1a448 100644

--- a/tools/opt/opt.cpp

+++ b/tools/opt/opt.cpp

@@ -608,6 +608,16 @@ int main(int argc, char **argv) {

   OptCustomPassManager Passes;

   bool AddOneTimeDebugifyPasses = EnableDebugify && !DebugifyEach;

+  // EarlyRewriter must run very early. Since we made it a

+  // ModulePass, there is no standard way to make this happen (the standard ways

+  // only work for FunctionPasses). Run the pass in a separate Passmanager

+  // before any other pass.

+  if (TM && TM->runEarlyModulePasses()) {

+    legacy::PassManager FirstPasses;

+    addPass(FirstPasses, static_cast<ModulePass*>(createEarlyRewriterPass()));

+    FirstPasses.run(*M);

+  }

+

   // Add an appropriate TargetLibraryInfo pass for the module's triple.

   TargetLibraryInfoImpl TLII(ModuleTriple);

 

 

Note the FirstPasses.run(*M), which means that those first passes are run directly.

And then we have added the runEarlyModulePasses() hook in TargetMachine that will make sure we add and run the FirstPasses pass manager when compiling for our target.

 

Regards,

Björn

 

From: llvm-dev <[hidden email]> On Behalf Of Son Tuan VU via llvm-dev
Sent: den 12 juni 2018 15:46
To: llvm-dev <[hidden email]>
Subject: [llvm-dev] ModulePass cannot be registered as EarlyAsPossible

 

Hello all,

 

I've followed the example in https://github.com/CompilerTeaching/SimplePass/blob/master/SimplePass.cc 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,

 

Son Tuan Vu

 


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] ModulePass cannot be registered as EarlyAsPossible

Adam Nemet via llvm-dev
In reply to this post by Adam Nemet via llvm-dev

Hi,

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.

Regards,
Bevin


On 2018-06-12 15:46, Son Tuan VU via llvm-dev wrote:
Hello all,

I've followed the example in https://github.com/CompilerTeaching/SimplePass/blob/master/SimplePass.cc 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,

Son Tuan Vu


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] ModulePass cannot be registered as EarlyAsPossible

Adam Nemet via llvm-dev
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,


Son Tuan Vu

On Wed, Jun 13, 2018 at 4:01 PM, Bevin Hansson via llvm-dev <[hidden email]> wrote:

Hi,

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.

Regards,
Bevin


On 2018-06-12 15:46, Son Tuan VU via llvm-dev wrote:
Hello all,

I've followed the example in https://github.com/CompilerTeaching/SimplePass/blob/master/SimplePass.cc 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,

Son Tuan Vu


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev