Multiple Flang frontend actions

Currently, one can only have a single frontend action. For instance, this does not work:

$ flang-new -S -emit-llvm -load plugin.so -plugin plugin-name file.f90

But something like this is possible in Clang. Are there any plans to allow multiple frontend actions in Flang? If so, is anyone working on it? If not, I would be willing to do so.

Hi @tarunprabhu !

For instance, this does not work:

What error do you see?

But something like this is possible in Clang.

Hm, is it? Also, have you checked ⚙ D111781 [flang] Make the frontend driver error out when requesting multiple actions - it might help understand the current behavior in LLVM Flang.

-Andrzej

Hi @banach-space

This is the error

flang-new -fc1 -S -emit-llvm -load ./plugin.so -plugin myplugin file.f90
error: Only one action option is allowed

IIUC, in clang, there is only one “main” action permitted (this is usually Codegen i.e. LLVM-IR generation, but it could be something else like ASM generation too). The PluginASTAction’s - those that walk the AST - are not considered main actions and are treated differently. I have been able to run multiple PluginASTAction’s in the same clang invocation.

Thanks, I hadn’t seen that. It would be nice to allow AST traversals in addition to codegen in Flang too. One potential use (albeit an extremely narrow one) is to allow annotation languages to be built using structured comments. These annotations can then be associated with AST nodes and translated into LLVM-IR without having to go through an intermediate source-to-source transformation step.

Tarun

FWIW, flang does not have ASTs.

Thanks for the reply Tarun!

OK, just to clarify - both Clang and Flang run only one //main// frontend action. In Flang, we decided to generate an error when users request multiple //main// actions. That was implemented in D111781 and is one area in which flang-new -fc1 diverges from clang -cc1 (note that clang -cc1 will also run only one action - the “righmost” one in the driver invocation).

Indeed, Clang’s PluginASTAction is a bit special and can be run //alongside// (i.e. before or after) the main frontend action (e.g. -emit-obj or -fsyntax-only). In Flang we don’t have that flexibility (i.e. plugin actions are consider as any other //main// action).

It would be great to have a specific use case first :slight_smile: I guess that this would require something akin Clang’s ActionType? This shouldn’t be too difficult to implement, but it will make the frontend driver a bit more complex. That’s fine as long as the additional complexity enables some desired functionality. But are we confident that we’ll be able to leverage the extra complexity? It would be great if we had a specific example to refer to and that would clearly benefit from this. So, before modifying the driver, would you be able to implement such example?

This is an important point to keep in mind. Plugins in Flang operate on the parse tree instead. Would that be sufficient for you? If not, it would be good to extend the parse tree API first. We did discuss the existing API briefly in ⚙ D106137 [flang][driver] Add support for Frontend Plugins and @klausler hinted that long term it would be good to move away from Pre()/Post() paradigm. That might be something to look into too.

No plans and nobody is working on this ATM (afaik) :slight_smile:

-Andrzej

Clang’s ActionType largely controls when a PluginASTAction is run (or if it replaces the main action). I think allowing actions to at least read the parse tree while also allowing the main action to proceed may be useful.

Something you can do with clang plugins is to have an AST plugin collect high-level information and have it around for an LLVM-IR pass to use. It is helpful in inferring the type of an object created by malloc, for instance. I think something like this may be of use in Fortran as well, especially for people like me who need shape information to perform static analysis. Of course, there is no AST in Flang, but the principle is similar.

I think something like this would be of interest to tool developers that may prefer to operate on the high-level source rather than on FIR or LLVM-IR. An example that immediately comes to mind would be a linter that requires the use of “implicit none” (Disclaimer: I don’t program in Fortran, so I don’t know if this can be done some other way). Would you consider this to be beneficial?

Yes, it would do. I think it would be nice to have hooks to allow passes on all of the parse tree, FIR and LLVM-IR via plugins. I think it might encourage tool developers to support Fortran.

On that somewhat related note, is there an equivalent of clang’s -fpass-plugin option that allows a plugin with LLVM-IR passes to be dynamically loaded and run? If not, and you think this is desirable, I would be willing to look into it.

Thanks for your reply!

I think that this effort should be driven by specific applications that would be enabled here rather than a desire to align with Clang. Plugins in Clang are used by some big Clang clients like libreOffice, Chromium or Mozilla. Obviously LLVM Flang is a very different project. My point is that the evolution of the plugin API in Clang was informed by users that had a specific problem to solve. Why not try similar approach here? For example, why not prototype a static analysis tool first and use that to demonstrate the limitations in the current approach?

I agree that expanding the framework and enabling more use cases would be good. My main reservation is that there doesn’t seem to be that many users of the plugin API at the moment (are there any?) and this will introduce extra complexity. It is important that the documentation and the current examples are expanded accordingly as part of this effort. Mostly to keep the barrier of entry low.

Yes, provided that we can demonstrate that it’s useful :slight_smile: When we worked on the current plugin API, we used FlangOmpReport to showcase it. It was something that we initially developed downstream as a standalone tool (i.e. a separate driver for LLVM Flang). IMHO, FlangOmpReport makes much more sense as a plugin. It would be great if you could include some new examples as part of this effort that would showcase the new functionality. This could be something fairly basic.

Not yet. And if it’s introduced, it would good to make sure that Flang and Clang behave consistently here :slight_smile:

Thanks for volunteering! I can’t think of a specific use case today, but this would be far less intrusive than the other things mentioned here. And it’s probably just a matter of time before people start asking for this, so why not?

Btw, one thing that is currently missing in Flang is something similar to Clang’s LibTooling. More specifically, there’s no mechanism to build Flang based tools other than through plugins. Have you considered that?

Just to clarify, I’m not opposing any of this. I would just appreciate more motivating examples to guide this. Or perhaps there are other folks that would like something like this in Flang (and that could help reviewing the design)?

-Andrzej

Hi Andrzej,

I am still not clear what would be considered “useful”. But I’ll try to come up with an example and we can take it from there.

I am happy help in keeping the documentation and examples up-to-date.