banach-space / llvm-tutor

A collection of out-of-tree LLVM passes for teaching and learning
MIT License
3k stars 397 forks source link

Calling pass from Clang #36

Closed palmerc closed 4 months ago

palmerc commented 3 years ago

When you call opt directly you use --passes and the list of desired passes, but in some older code I've seen you could call from clang with -mllvm followed by some additional options added directly to PassManagerBuilder in the form of cl::opt items. This was also how you could then pass along additional options to the pass. This code was using the legacy pass manager. What is the current way to specify the passes and options when using clang?

banach-space commented 3 years ago

Hello @palmerc ,

Thank you for stopping by! :) Unfortunately, the short answer is that I don't know.

Running plugins from clang It's a very important use-case and I am curious myself. I've labeled this as an enhancement and will try to produce some examples and/or docs (or at least get a better understanding of the available options). I can't commit to any timelines and volunteers are always very welcome :)

Passing command line options to plugins with clang All of llvm-tutor relies on opt to load and run the plugins. clang is a completely different driver, so the underlying logic around command-line options is also very different. I haven't really looked into it yet.

In opt, AFAIK, it is not possible to pass command line options to plugins when using the new PM. This was brought up in the past:

This might have changed since I looked into it originally (LLVM ~9).

-Andrzej

palmerc commented 3 years ago

Cool! I’m looking into this and I will report my findings.

On 17 Jul 2021, at 17:34, Andrzej Warzyński @.***> wrote:

 Hello @palmerc ,

Thank you for stopping by! :) Unfortunately, the short answer is that I don't know.

Running plugins from clang It's a very important use-case and I am curious myself. I've labeled this as an enhancement and will try to produce some examples and/or docs (or at least get a better understanding of the available options). I can't commit to any timelines and volunteers are always very welcome :)

Passing command line options to plugins with clang All of llvm-tutor relies on opt to load and run the plugins. clang is a completely different driver, so the underlying logic around command-line options is also very different. I haven't really looked into it yet.

In opt, AFAIK, it is not possible to pass command line options to plugins when using the new PM. This was brought up in the past:

https://lists.llvm.org/pipermail/llvm-dev/2019-September/134973.html (slightly different question, but the answer applies here as well) https://www.reddit.com/r/LLVM/comments/eh6m1t/new_pass_manager_new_interesting_behavior_with/ This might have changed since I looked into it originally (LLVM ~9).

-Andrzej

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

palmerc commented 3 years ago

Initial look. You can get options back to LLVM by calling clang with -mllvm followed by the option. You would then need to add your pass into PassManagerBuilder by specifying an option cl::opt and then in void PassManagerBuilder::populateModulePassManager(legacy::PassManagerBase &MPM) you would call MPM.add() there is a function pass analogue named populateFunctionPassManager

banach-space commented 3 years ago

Thanks for the update! Do you know where are options for LLVM defined? (e.g. -load). And who is responsible for calling populateModulePassManager? Is that supposed to happen in a plugin?

banach-space commented 3 years ago

FYI: https://lists.llvm.org/pipermail/cfe-dev/2020-November/067166.html

KuanKuanQAQ commented 4 months ago

Sorry to bother you both. Recently, I've been trying to use LLVM to compile the Linux kernel and integrate my LLVM pass into some kernel modules to enhance security. As far as I know, it's not feasible to use opt when compiling the kernel, so I specifically need a method to invoke the LLVM pass via clang. I noticed that this issue has been around for a few years and was wondering if there have been any updates.

KuanKuanQAQ commented 4 months ago

In fact, I have already made some attempts. For example, using HelloWorld.cpp and the registerVectorizerStartEPCallback function, it is possible to invoke this LLVM pass with clang.

llvm::PassPluginLibraryInfo getHelloWorldPluginInfo() {
  return {LLVM_PLUGIN_API_VERSION, "HelloWorld", LLVM_VERSION_STRING,
          [](PassBuilder &PB) {
            PB.registerVectorizerStartEPCallback(
                [](FunctionPassManager &PM, OptimizationLevel Level) {
                  PM.addPass(HelloWorld());
                });
          }};
}

We can compile like this: clang -fpass-plugin=libHelloWorld.so input_for_hello.c

banach-space commented 4 months ago

Sounds like you have a solution?

KuanKuanQAQ commented 4 months ago

I’m not sure if this is an official method, as it only allows the use of register*EPCallback and not registerAnalysisRegistrationCallback or registerPipelineParsingCallback. This means that only transform passes can be registered, and not analysis passes. I believe there should be an official method to pass arguments to opt, but when I tested it, neither -mllvm nor -Xclang worked.

banach-space commented 4 months ago

This is more of a question for https://discourse.llvm.org/ ;-) Please post there.