[flang-dev] [RFC] Frontend driver: action vs non-action options

Andrzej Warzynski via flang-dev flang-dev at lists.llvm.org
Wed Oct 13 07:39:00 PDT 2021


Hi All,

[Flang = LLVM Flang]

I wanted to dive a bit deeper into one aspect of the design of our 
*frontend driver*, `flang-new -fc1`. It is intended as the main tool for 
Flang frontend developers and we should make sure that it meets our 
requirements. If not, perhaps we can identify how to make it work 
better? More specifically, does the current split into action and 
non-action options makes sense?

Please note - this discussion does not involve the compiler driver, 
`flang-new`.

# *Action vs non-action options*
In the frontend driver, you can split options into two groups:
     * action options (e.g. `-emit-llvm`)
     * non-action options (feature/configuration flags, e.g. `-ffixed-form`)
Action options specify "what" the compiler will do, e.g. "parse the 
input file and lower it to LLVM IR" for `-emit-llvm`. Non-action options 
allow users to configure the frontend to behave in a certain way, e.g. 
treat all input files as fixed-form, regardless of the file extension. 
Another example for the latter is `-Werror` - make all warnings into 
errors. This tells the compiler "how" the deal with certain scenarios, 
but does not specify "what" to do.

AFAIK, this design is consistent with `clang -cc1`.

# *Default action*
The frontend driver will run `-fsyntax-only` by default, i.e. the 
following two invocations are identical:

```lang=bash
$ flang-new -fc1 input.f95
$ flang-new -fc1 -fsyntax-only input.f95
```

If users want a different action to be run, they need to specify it 
explicitly, e.g.

```lang=bash
$ flang-new -fc1 -fdebug-unparse input.f95
```

This behaviour is consistent with `clang -cc1`.

# *Selected Implementation Details*
For every action flag, there's a dedicated specialisation of the 
`FrontendActions` class in FrontendActions.h [1]. Right now, the only 
way to identify which flag is an action flag, is to look up the 
implementation. For example, options decorated with `Action_Group` in 
Options.td [2] are action flags. Alternatively, you can check the switch 
statements in CompilerInvocation.cpp [3] that selects the frontend 
action based on the input flags.

# *One action at a time*
The frontend driver will only run the rightmost frontend action 
specified on the command line. This is illustrated below:

```lang=bash
# Runs -fdebug-unparse, -fdebug-pre-fir-tree is ignored
$ flang-new -fc1 -fdebug-pre-fir-tree -fdebug-unparse input.f95
# Runs -fdebug-pre-fir-tree, -fdebug-unparse is ignored
$ flang-new -fc1 -fdebug-unparse  -fdebug-pre-fir-tree input.f95
```

This approach means that the design is relatively simple. Allowing 
multiple actions per invocation would require the driver to schedule and 
to keep track of the requested actions. That would complicate the 
implementation.

`flang-new -fc1` does not warn about action flags being ignored. This is 
counter-intuitive, but I wasn't able to identify an easy fix for this. 
We've recently discussed this in Bugzilla [4].

AFAIK, this behaviour is consistent with `clang -cc1`.

# *Does this work for you*?

With the "one action at a time" rule, it is crucial to make sure that 
the split into action and non-action options is optimal. So far we have 
used a few heuristics:
* if a flag requires something unique to happen, it's an action (e.g. 
`-fdebug-unparse` requires a call to `Fortran::parser::Unparse` that's 
otherwise not required)
* if something is an action in `clang -cc1`, it should also be an action 
in `flang-new -fc1` (e.g. `-emit-llvm`)
* if a flag configures some state, it's not an action (e.g. `-ffixed-form`)

To make this a bit easier to visualise, I've compiled the list of 
options in `flang-new -fc1` in a spreadsheet [5]. I've also added 
actions options from `clang -cc1` for comparison. Note that out of ~820 
options in `clang -cc1` (extracted from `clang -cc1 -help`), only 36 are 
action options.

Note: I've tried to make my spreadsheet [5] as accurate as possible, but 
wasn't able to generate it automatically and might have missed something.

So, does the current split make sense to you? Should any of the options 
be re-implemented? I may not have the time to implement the suggested 
changes myself, but will be available to help you and to review your 
patches. And I will also be adding more documentation upstream. In fact, 
first patch is already available [6].

Thank you for taking a look!
-Andrzej


[1] 
https://github.com/llvm/llvm-project/blob/main/flang/include/flang/Frontend/FrontendActions.h
[2] 
https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Driver/Options.td
[3] 
https://github.com/llvm/llvm-project/blob/main/flang/lib/Frontend/CompilerInvocation.cpp#L111-L178
[4] https://bugs.llvm.org/show_bug.cgi?id=52095
[5] 
https://docs.google.com/spreadsheets/d/1Cbzv58m_bO439sCRa4-onhhi-3JdFnLAhhTkeCMDdD4/edit?usp=sharing
[6] https://reviews.llvm.org/D111573


More information about the flang-dev mailing list