1 <!--===- docs/FlangDriver.md
3 Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 See https://llvm.org/LICENSE.txt for license information.
5 SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
17 There are two main drivers in Flang:
18 * the compiler driver, `flang-new`
19 * the frontend driver, `flang-new -fc1`
21 > **_NOTE:_** The diagrams in this document refer to `flang` as opposed to
22 > `flang-new`. Eventually, `flang-new` will be renamed as `flang` and the
23 > diagrams reflect the final design that we are still working towards.
25 The **compiler driver** will allow you to control all compilation phases (e.g.
26 preprocessing, semantic checks, code-generation, code-optimisation, lowering
27 and linking). For frontend specific tasks, the compiler driver creates a
28 Fortran compilation job and delegates it to `flang-new -fc1`, the frontend
29 driver. For linking, it creates a linker job and calls an external linker (e.g.
30 LLVM's [`lld`](https://lld.llvm.org/)). It can also call other tools such as
31 external assemblers (e.g. [`as`](https://www.gnu.org/software/binutils/)). In
32 Clang, the compiler driver can also link the generated binaries with LLVM's
33 static analysis/sanitizer libraries (e.g.
34 [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html)). This is
35 not yet available in Flang, but will be relatively easy to support once such
36 libraries become available. Flang's compiler driver is intended for Flang's
37 end-users - its interface needs to remain stable. Otherwise, Flang's users will
38 have to adjust their build scripts every time a compiler flag is changed.
40 | ![Compiler Driver](compiler_driver.png) |
42 | *Flang’s compiler driver and the **tools** that it runs* |
44 The **frontend driver** glues together and drives all of the Flang's frontend
45 libraries. As such, it provides an easy-to-use and intuitive interface to the
46 frontend. It uses MLIR and LLVM for code-generation and can be viewed as a
47 driver for Flang, LLVM and MLIR libraries. Contrary to the compiler driver, it
48 is not capable of calling any external tools (including linkers). It is aware
49 of all the frontend internals that are "hidden" from the compiler driver. It
50 accepts many frontend-specific options not available in `flang-new` and as such
51 it provides a finer control over the frontend. Note that this tool is mostly
52 intended for Flang developers. In particular, there are no guarantees about the
53 stability of its interface and compiler developers can use it to experiment
56 | ![Frontend Driver](frontend_driver.png) |
58 | *Flang's frontend driver and the **libraries** that it drives* |
60 Note that similarly to `-Xclang` in `clang`, you can use `-Xflang` to forward a
61 frontend specific flag from the _compiler_ directly to the _frontend_ driver,
65 flang-new -Xflang -fdebug-dump-parse-tree input.f95
68 In the invocation above, `-fdebug-dump-parse-tree` is forwarded to `flang-new
69 -fc1`. Without the forwarding flag, `-Xflang`, you would see the following
73 flang-new: warning: argument unused during compilation:
76 As `-fdebug-dump-parse-tree` is only supported by `flang-new -fc1`, `flang-new`
77 will ignore it when used without `Xflang`.
79 ## Why Do We Need Two Drivers?
80 As hinted above, `flang-new` and `flang-new -fc1` are two separate tools. The
81 fact that these tools are accessed through one binary, `flang-new`, is just an
82 implementation detail. Each tool has a separate list of options, albeit defined
83 in the same file: `clang/include/clang/Driver/Options.td`.
85 The separation helps us split various tasks and allows us to implement more
86 specialised tools. In particular, `flang-new` is not aware of various
87 compilation phases within the frontend (e.g. scanning, parsing or semantic
88 checks). It does not have to be. Conversely, the frontend driver, `flang-new
89 -fc1`, needs not to be concerned with linkers or other external tools like
90 assemblers. Nor does it need to know where to look for various systems
91 libraries, which is usually OS and platform specific.
93 One helpful way of differentiating these tools is to keep in mind that:
95 * the compiler driver is an end-user tool
96 * frontend driver is a compiler developer tool with many additional options,
98 Also, Since the compiler driver can call external tools, e.g. linkers, it can
99 be used to generate **executables**. The frontend driver cannot call external
100 tools and hence can only generate **object files**. A similar model is
101 implemented in Clang (`clang` vs `clang -cc1` vs `clang -cc1as`), which is
102 based on the [architecture of
103 GCC](https://en.wikibooks.org/wiki/GNU_C_Compiler_Internals/GNU_C_Compiler_Architecture).
104 In fact, Flang needs to adhere to this model in order to be able to re-use
105 Clang's driver library. If you are more familiar with the [architecture of
106 GFortran](https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gfortran/About-GNU-Fortran.html)
107 than Clang, then `flang-new` corresponds to `gfortran` and `flang-new -fc1` to
111 The main entry point for Flang's compiler driver is implemented in
112 `flang/tools/flang-driver/driver.cpp`. Flang's compiler driver is implemented
113 in terms of Clang's driver library, `clangDriver`. This approach allows us to:
114 * benefit from Clang's support for various targets, platforms and operating systems
115 * leverage Clang's ability to drive various backends available in LLVM, as well
116 as linkers and assemblers.
117 One implication of this dependency on Clang is that all of Flang's compiler
118 options are defined alongside Clang's options in
119 `clang/include/clang/Driver/Options.td`. For options that are common for both
120 Flang and Clang, the corresponding definitions are shared.
122 Internally, a `clangDriver` based compiler driver works by creating actions
123 that correspond to various compilation phases, e.g. `PreprocessJobClass`,
124 `CompileJobClass`, `BackendJobClass` or `LinkJobClass` from the
125 `clang::driver::Action::ActionClass` enum. There are also other, more
126 specialised actions, e.g. `MigrateJobClass` or `InputClass`, that do not map
127 directly to common compilation steps. The actions to run are determined from
128 the supplied compiler flags, e.g.
130 * `-E` for `PreprocessJobClass`,
131 * `-c` for `CompileJobClass`.
133 In most cases, the driver creates a chain of actions/jobs/phases where the
134 output from one action is the input for the subsequent one. You can use the
135 `-ccc-print-phases` flag to see the sequence of actions that the driver will
136 create for your compiler invocation:
138 flang-new -ccc-print-phases -E file.f
139 +- 0: input, "file.f", f95-cpp-input
140 1: preprocessor, {0}, f95
142 As you can see, for `-E` the driver creates only two jobs and stops immediately
143 after preprocessing. The first job simply prepares the input. For `-c`, the
144 pipeline of the created jobs is more complex:
146 flang-new -ccc-print-phases -c file.f
147 +- 0: input, "file.f", f95-cpp-input
148 +- 1: preprocessor, {0}, f95
149 +- 2: compiler, {1}, ir
150 +- 3: backend, {2}, assembler
151 4: assembler, {3}, object
153 The other phases are printed nonetheless when using `-ccc-print-phases`, as
154 that reflects what `clangDriver`, the library, will try to create and run.
156 For actions specific to the frontend (e.g. preprocessing or code generation), a
157 command to call the frontend driver is generated (more specifically, an
158 instance of `clang::driver::Command`). Every command is bound to an instance of
159 `clang::driver::Tool`. For Flang we introduced a specialisation of this class:
160 `clang::driver::Flang`. This class implements the logic to either translate or
161 forward compiler options to the frontend driver, `flang-new -fc1`.
163 You can read more on the design of `clangDriver` in Clang's [Driver Design &
164 Internals](https://clang.llvm.org/docs/DriverInternals.html).
167 Flang's frontend driver is the main interface between compiler developers and
168 the Flang frontend. The high-level design is similar to Clang's frontend
169 driver, `clang -cc1` and consists of the following classes:
170 * `CompilerInstance`, which is a helper class that encapsulates and manages
171 various objects that are always required by the frontend (e.g. `AllSources`,
172 `AllCookedSources, `Parsing`, `CompilerInvocation`, etc.). In most cases
173 `CompilerInstance` owns these objects, but it also can share them with its
174 clients when required. It also implements utility methods to construct and
176 * `CompilerInvocation` encapsulates the configuration of the current
177 invocation of the compiler as derived from the command-line options and the
178 input files (in particular, file extensions). Among other things, it holds an
179 instance of `FrontendOptions`. Like `CompilerInstance`, it owns the objects
180 that it manages. It can share them with its clients that want to access them
181 even after the corresponding `CompilerInvocation` has been destructed.
182 * `FrontendOptions` holds options that control the behaviour of the frontend,
183 as well as e.g. the list of the input files. These options come either
184 directly from the users (through command-line flags) or are derived from
185 e.g. the host system configuration.
186 * `FrontendAction` and `FrontendActions` (the former being the base class for
187 the latter) implement the actual actions to perform by the frontend. Usually
188 there is one specialisation of `FrontendActions` for every compiler action flag
189 (e.g. `-E`, `-fdebug-unparse`). These classes also contain various hooks that
190 allow you to e.g. fine-tune the configuration of the frontend based on the
193 This list is not exhaustive and only covers the main classes that implement the
194 driver. The main entry point for the frontend driver, `fc1_main`, is
195 implemented in `flang/tools/flang-driver/driver.cpp`. It can be accessed by
196 invoking the compiler driver, `flang-new`, with the `-fc1` flag.
198 The frontend driver will only run one action at a time. If you specify multiple
199 action flags, only the last one will be taken into account. The default action
200 is `ParseSyntaxOnlyAction`, which corresponds to `-fsyntax-only`. In other
201 words, `flang-new -fc1 <input-file>` is equivalent to `flang-new -fc1 -fsyntax-only
204 ## The `flang-to-external-fc` script
205 The `flang-to-external-fc` wrapper script for `flang-new` was introduced as a
206 development tool and to facilitate testing. The `flang-to-external-fc` wrapper
208 * use `flang-new` to unparse the input source file (i.e. it will run `flang-new
209 -fc1 -fdebug-unparse <input-file>`), and then
210 * call a host Fortran compiler, e.g. `gfortran`, to compile the unparsed file.
212 Here's a basic breakdown of what happens inside `flang-to-external-fc` when you
213 run `flang-to-external-fc file.f90`:
215 flang-new -fc1 -fdebug-unparse file.f90 -o file-unparsed.f90
216 gfortran file-unparsed.f90
218 This is a simplified version for illustration purposes only. In practice,
219 `flang-to-external-fc` adds a few more frontend options and it also supports
220 various other use cases (e.g. compiling C files, linking existing object
221 files). `gfortran` is the default host compiler used by `flang-to-external-fc`.
222 You can change it by setting the `FLANG_FC` environment variable.
224 ## Adding new Compiler Options
225 Adding a new compiler option in Flang consists of two steps:
226 * define the new option in a dedicated TableGen file,
227 * parse and implement the option in the relevant drivers that support it.
229 ### Option Definition
230 All of Flang's compiler and frontend driver options are defined in
231 `clang/include/clang/Driver/Options.td` in Clang. When adding a new option to
232 Flang, you will either:
233 * extend the existing definition for an option that is already available
234 in one of Clang's drivers (e.g. `clang`), but not yet available in Flang, or
235 * add a completely new definition if the option that you are adding has not
238 There are many predefined TableGen classes and records that you can use to fine
239 tune your new option. The list of available configurations can be overwhelming
240 at times. Sometimes the easiest approach is to find an existing option that has
241 similar semantics to your new option and start by copying that.
243 For every new option, you will also have to define the visibility of the new
244 option. This is controlled through the `Visibility` field. You can use the
245 following Flang specific visibility flags to control this:
246 * `FlangOption` - this option will be available in the `flang-new` compiler driver,
247 * `FC1Option` - this option will be available in the `flang-new -fc1` frontend driver,
249 Options that are supported by clang should explicitly specify `ClangOption` in
250 `Visibility`, and options that are only supported in Flang should not specify
253 When deciding what `OptionGroup` to use when defining a new option in the
254 `Options.td` file, many new options fall into one of the following two
256 * `Action_Group` - options that define an action to run (e.g.
257 `-fsyntax-only`, `-E`)
258 * `f_Group` - target independent compiler flags (e.g. `-ffixed-form`,
260 There are also other groups and occasionally you will use them instead of the
263 ### Option Implementation
264 First, every option needs to be parsed. Flang compiler options are parsed in
265 two different places, depending on which driver they belong to:
267 * frontend driver: `flang/lib/Frontend/CompilerInvocation.cpp`,
268 * compiler driver: `clang/lib/Driver/ToolChains/Flang.cpp`.
270 The parsing will depend on the semantics encoded in the TableGen definition.
272 When adding a compiler driver option (i.e. an option that contains
273 `FlangOption` among in it's `Visibility`) that you also intend to be understood
274 by the frontend, make sure that it is either forwarded to `flang-new -fc1` or
275 translated into some other option that is accepted by the frontend driver. In
276 the case of options that contain both `FlangOption` and `FC1Option` among its
277 flags, we usually just forward from `flang-new` to `flang-new -fc1`. This is
278 then tested in `flang/test/Driver/frontend-forward.F90`.
280 What follows is usually very dependant on the meaning of the corresponding
281 option. In general, regular compiler flags (e.g. `-ffree-form`) are mapped to
282 some state within the driver. A lot of this state is stored within an instance
283 of `FrontendOptions`, but there are other more specialised classes too. Action
284 flags (e.g. `-fsyntax-only`) are usually more complex overall, but also more
285 structured in terms of the implementation.
288 For options that correspond to an action (i.e. marked as `Action_Group`), you
289 will have to define a dedicated instance of `FrontendActions` in
290 `flang/include/flang/Frontend/FrontendOptions.h`. For example, for
291 `-fsyntax-only` we defined:
293 class ParseSyntaxOnlyAction : public PrescanAndSemaAction {
294 void ExecuteAction() override;
297 Command line options are mapped to frontend actions through the
298 `Fortran::frontend::ActionKind` enum. For every new action option that you
299 add, you will have to add a dedicated entry in that enum (e.g.
300 `ParseSyntaxOnly` for `-fsyntax-only`) and a corresponding `case` in
301 `ParseFrontendArgs` function in the `CompilerInvocation.cpp` file, e.g.:
303 case clang::driver::options::OPT_fsyntax_only:
304 opts.programAction = ParseSyntaxOnly;
307 Note that this simply sets the program/frontend action within the frontend
308 driver. You still have make sure that the corresponding frontend action class
309 is instantiated when your new action option is used. The relevant `switch`
310 statement is implemented in `Fortran::frontend::CreatedFrontendBaseAction` in
311 the `ExecuteCompilerInvocation.cpp` file. Here's an example for
314 case ParseSyntaxOnly:
315 return std::make_unique<ParseSyntaxOnlyAction>();
317 At this point you should be able to trigger that frontend action that you have
318 just added using your new frontend option.
322 As of [#7246](https://gitlab.kitware.com/cmake/cmake/-/merge_requests/7246)
323 (and soon to be released CMake 3.24.0), `cmake` can detect `flang-new` as a
324 supported Fortran compiler. You can configure your CMake projects to use
325 `flang-new` as follows:
327 cmake -DCMAKE_Fortran_COMPILER=<path/to/flang-new> <src/dir>
329 You should see the following in the output:
331 -- The Fortran compiler identification is LLVMFlang <version>
333 where `<version>` corresponds to the LLVM Flang version.
336 In LIT, we define two variables that you can use to invoke Flang's drivers:
337 * `%flang` is expanded as `flang-new` (i.e. the compiler driver)
338 * `%flang_fc1` is expanded as `flang-new -fc1` (i.e. the frontend driver)
340 For most regression tests for the frontend, you will want to use `%flang_fc1`.
341 In some cases, the observable behaviour will be identical regardless of whether
342 `%flang` or `%flang_fc1` is used. However, when you are using `%flang` instead
343 of `%flang_fc1`, the compiler driver will add extra flags to the frontend
344 driver invocation (i.e. `flang-new -fc1 -<extra-flags>`). In some cases that might
345 be exactly what you want to test. In fact, you can check these additional
346 flags by using the `-###` compiler driver command line option.
348 Lastly, you can use `! REQUIRES: <feature>` for tests that will only work when
349 `<feature>` is available. For example, you can use`! REQUIRES: shell` to mark a
350 test as only available on Unix-like systems (i.e. systems that contain a Unix
351 shell). In practice this means that the corresponding test is skipped on
354 # Frontend Driver Plugins
355 Plugins are an extension to the frontend driver that make it possible to run
356 extra user defined frontend actions, in the form of a specialization of a
357 `PluginParseTreeAction`. These actions are run during compilation, after
358 semantic checks. Similarly to Clang, Flang leverages `LoadLibraryPermanently`
359 from LLVM's `llvm::sys::DynamicLibrary` to load dynamic objects that implement
360 plugins. The process for using plugins includes:
361 * [Creating a plugin](#creating-a-plugin)
362 * [Loading and running a plugin](#loading-and-running-a-plugin)
364 Flang plugins are limited to `flang-new -fc1` and are currently only available /
365 been tested on Linux.
368 There are three parts required for plugins to work:
369 1. [`PluginParseTreeAction` subclass](#a-pluginparsetreeaction-subclass)
370 1. [Implementation of `ExecuteAction`](#implementation-of-executeaction)
371 1. [Plugin registration](#plugin-registration)
373 There is an example plugin located in `flang/example/PrintFlangFunctionNames`
374 that demonstrates these points by using the `ParseTree` API to print out
375 function and subroutine names declared in the input file.
377 ### A `PluginParseTreeAction` Subclass
378 This subclass will wrap everything together and represent the `FrontendAction`
379 corresponding to your plugin. It will need to inherit from
380 `PluginParseTreeAction` (defined in `flang/include/flang/FrontendActions.h`), in
381 order to have access to the parse tree post semantic checks, and also so that it
382 can be registered, e.g.
384 class PrintFunctionNamesAction : public PluginParseTreeAction
387 ### Implementation of `ExecuteAction`
388 Like in other frontend actions, the driver looks for an `ExecuteAction` function
389 to run, so in order for your plugin to do something, you will need to implement
390 the `ExecuteAction` method in your plugin class. This method will contain the
391 implementation of what the plugin actually does, for example:
393 // Forward declaration
394 struct ParseTreeVisitor;
396 void ExecuteAction() override {
397 ParseTreeVisitor visitor;
398 Fortran::parser::Walk(getParsing().parseTree(), visitor);
401 In the example plugin, the `ExecuteAction` method first creates an instance of
402 `visitor` struct, before passing it together with the parse tree to the
403 `Fortran::parser::Walk` function that will traverse the parse tree. The parse
404 tree will normally be generated by the frontend driver and can be retrieved in
405 your plugin through the `getParsing()` member method. Implementation and
406 details of the `Walk` function can be found in
407 `flang/include/flang/Parser/parse-tree-visitor.h`.
409 You will have to define your own `visitor` struct. It should define different
410 `Pre` and `Post` functions that take the type of a specific `ParseTree` node as
411 an argument. When the `Walk` function is traversing the parse tree, these
412 functions will be run before/after a node of that type is visited. Template
413 functions for `Pre`/`Post` are defined so that when a node is visited that you
414 have not defined a function for, it will still be able to continue. `Pre`
415 returns a `bool` indicating whether to visit that node's children or not. For
418 struct ParseTreeVisitor {
419 template <typename A> bool Pre(const A&) { return true; }
420 template <typename A> void Post(const A&) {}
421 void Post(const Fortran::parser::FunctionStmt &f) {
422 llvm::outs() << std::get<Fortran::parser::Name>(f.t).ToString() << "\n" ;
426 The different types of nodes and also what each node structure contains are
427 defined in `flang/include/flang/Parser/parse-tree.h`. In the example, there is a
428 `Post` function, with a line that gets the `Name` element from a tuple `t` in
429 the `FunctionStmt` struct and prints it. This function will be run after every
430 `FunctionStmt` node is visited in the parse tree.
432 ### Plugin Registration
433 A plugin registry is used to store names and descriptions of a collection of
434 plugins. The Flang plugin registry, defined in
435 `flang/include/flang/Frontend/FrontendPluginRegistry.h`, is an alias of
436 `llvm::Registry` of type `PluginParseTreeAction`.
438 The plugin will need to be registered, which will add the Plugin to the registry
439 and allow it to be used. The format is as follows, with `print-fns` being the
440 plugin name that is used later to call the plugin and `Print Function names`
441 being the description:
443 static FrontendPluginRegistry::Add<PrintFunctionNamesAction> X(
444 "print-fns", "Print Function names");
447 ## Loading and Running a Plugin
448 In order to use plugins, there are 2 command line options made available to the
449 frontend driver, `flang-new -fc1`:
450 * [`-load <dsopath>`](#the--load-dsopath-option) for loading the dynamic shared
452 * [`-plugin <name>`](#the--plugin-name-option) for calling the registered plugin
454 Invocation of the example plugin is done through:
456 flang-new -fc1 -load flangPrintFunctionNames.so -plugin print-fns file.f90
459 Both these options are parsed in `flang/lib/Frontend/CompilerInvocation.cpp` and
460 fulfil their actions in
461 `flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp`
463 ### The `-load <dsopath>` option
464 This loads the plugin shared object library, with the path given at `<dsopath>`,
465 using `LoadLibraryPermantly` from LLVM's `llvm::sys::DynamicLibrary`, which
466 itself uses `dlopen`. During this stage, the plugin is registered with the
467 registration line from the plugin, storing the name and description.
469 ### The `-plugin <name>` option
470 This sets `frontend::ActionKind programAction` in `FrontendOptions` to
471 `PluginAction`, through which it searches the plugin registry for the plugin
472 name from `<name>`. If found, it returns the instantiated plugin, otherwise it
473 reports an error diagnostic and returns `nullptr`.
475 ## Enabling In-Tree Plugins
476 For in-tree plugins, there is the CMake flag `FLANG_PLUGIN_SUPPORT`, enabled by
477 default, that controls the exporting of executable symbols from `flang-new`,
478 which plugins need access to. Additionally, there is the CMake flag
479 `LLVM_BUILD_EXAMPLES`, turned off by default, that is used to control if the
480 example programs are built. This includes plugins that are in the
481 `flang/example` directory and added as a `sub_directory` to the
482 `flang/examples/CMakeLists.txt`, for example, the `PrintFlangFunctionNames`
483 plugin. It is also possible to develop plugins out-of-tree.
486 Note that the traversal API presented here is under active development and
487 might change in the future. We expect it to evolve as support for new
488 language features are added. This document and the examples will be updated
491 The current `ParseTree` structure is not suitable for modifications. The
492 copy constructors are not available and hence duplicating code might not be
493 trivial. Please take this into consideration when designing your plugin. In
494 particular, creating a transformation plugin will be noticeably harder than
495 analysis plugins that just consume (rather than edit) `ParseTree`.
497 Lastly, if `ParseTree` modifications are performed, then it might be necessary
498 to re-analyze expressions and modify scope or symbols. You can check
499 [Semantics.md](Semantics.md) for more details on how `ParseTree` is edited
500 e.g. during the semantic checks.
504 Pass plugins are dynamic shared objects that consist of one or more LLVM IR
505 passes. The `-fpass-plugin` option enables these passes to be passed to the
506 middle-end where they are added to the optimization pass pipeline and run after
507 lowering to LLVM IR.The exact position of the pass in the pipeline will depend
508 on how it has been registered with the `llvm::PassBuilder`. See the
510 [`llvm::PassBuilder`](https://llvm.org/doxygen/classllvm_1_1PassBuilder.html)
513 The framework to enable pass plugins in `flang-new` uses the exact same
514 machinery as that used by `clang` and thus has the same capabilities and
517 In order to use a pass plugin, the pass(es) must be compiled into a dynamic
518 shared object which is then loaded using the `-fpass-plugin` option.
521 flang-new -fpass-plugin=/path/to/plugin.so <file.f90>
524 This option is available in both the compiler driver and the frontend driver.
525 Note that LLVM plugins are not officially supported on Windows.
527 ## LLVM Pass Extensions
529 Pass extensions are similar to plugins, except that they can also be linked
530 statically. Setting `-DLLVM_${NAME}_LINK_INTO_TOOLS` to `ON` in the cmake
531 command turns the project into a statically linked extension. An example would
532 be Polly, e.g., using `-DLLVM_POLLY_LINK_INTO_TOOLS=ON` would link Polly passes
533 into `flang-new` as built-in middle-end passes.
536 [`WritingAnLLVMNewPMPass`](https://llvm.org/docs/WritingAnLLVMNewPMPass.html#id9)
537 documentation for more details.
539 ## Ofast and Fast Math
540 `-Ofast` in Flang means `-O3 -ffast-math -fstack-arrays`.
542 `-ffast-math` means the following:
543 - `-fno-honor-infinities`
545 - `-fassociative-math`
546 - `-freciprocal-math`
548 - `-fno-signed-zeros`
549 - `-ffp-contract=fast`
551 These correspond to LLVM IR Fast Math attributes:
552 https://llvm.org/docs/LangRef.html#fast-math-flags
554 When `-ffast-math` is specified, any linker steps generated by the compiler
555 driver will also link to `crtfastmath.o`, which adds a static constructor
556 that sets the FTZ/DAZ bits in MXCSR, affecting not only the current only the
557 current compilation unit but all static and shared libraries included in the
558 program. Setting these bits causes denormal floating point numbers to be flushed
561 ### Comparison with GCC/GFortran
562 GCC/GFortran translate `-Ofast` to
563 `-O3 -ffast-math -fstack-arrays -fno-semantic-interposition`.
564 `-fno-semantic-interposition` is not used because Clang does not enable this as
565 part of `-Ofast` as the default behaviour is similar.
567 GCC/GFortran has a wider definition of `-ffast-math`: also including
568 `-fno-trapping-math`, `-fno-rounding-math`, and `-fsignaling-nans`; these
569 aren't included in Flang because Flang currently has no support for strict
570 floating point and so always acts as though these flags were specified.
572 GCC/GFortran will also set flush-to-zero mode: linking `crtfastmath.o`, the same
575 The only GCC/GFortran warning option currently supported is `-Werror`. Passing
576 any unsupported GCC/GFortran warning flags into Flang's compiler driver will
577 result in warnings being emitted.
579 ### Comparison with nvfortran
580 nvfortran defines `-fast` as
581 `-O2 -Munroll=c:1 -Mnoframe -Mlre -Mpre -Mvect=simd -Mcache_align -Mflushz -Mvect`.
582 - `-O2 -Munroll=c:1 -Mlre -Mautoinline -Mpre -Mvect-simd` affect code
583 optimization. `flang -O3` should enable all optimizations for execution time,
584 similarly to `clang -O3`. The `-O3` pipeline has passes that perform
585 transformations like inlining, vectorisation, unrolling, etc. Additionally,
586 the GVN and LICM passes perform redundancy elimination like `Mpre` and `Mlre`
587 - `-Mnoframe`: the equivalent flag would be `-fomit-frame-pointer`. This flag
588 is not yet supported in Flang and so Flang follows GFortran in not including
589 this in `-Ofast`. There is no plan to include this flag as part of `-Ofast`.
590 - `-Mcache_align`: there is no equivalent flag in Flang or Clang.
591 - `-Mflushz`: flush-to-zero mode - when `-ffast-math` is specified, Flang will
592 link to `crtfastmath.o` to ensure denormal numbers are flushed to zero.