--- local: ---
The Flang compiler transforms Fortran source code into an executable file. This transformation proceeds in three high level phases -- analysis, lowering, and code generation/linking.
The first high level phase (analysis) transforms Fortran source code into a decorated parse tree and a symbol table. During this phase, all user related errors are detected and reported.
The second high level phase (lowering), changes the decorated parse tree and symbol table into the Fortran Intermediate Representation (FIR), which is a dialect of LLVM‘s Multi-Level Intermediate Representation or MLIR. It then runs a series of passes on the FIR code which verify its validity, perform a series of optimizations, and finally transform it into LLVM’s Intermediate Representation, or LLVM IR
The third high level phase generates machine code and invokes a linker to produce an executable file.
This document describes the first two high level phases. Each of these is described in more detailed phases.
Each detailed phase is described -- its inputs and outputs along with how to produce a readable version of the outputs.
Each detailed phase produces either correct output or fatal errors.
This high level phase validates that the program is correct and creates all of the information needed for lowering.
See Preprocessing.md.
Input: Fortran source and header files, command line macro definitions, set of enabled compiler directives (to be treated as directives rather than comments).
Output:
Entry point: parser::Parsing::Prescan
Commands:
flang -fc1 -E src.f90
dumps the cooked character streamflang -fc1 -fdebug-dump-provenance src.f90
dumps provenance informationInput: Cooked character stream
Output: A parse tree for each Fortran program unit in the source code representing a syntactically correct program, rooted at the program unit. See: Parsing.md and ParserCombinators.md.
Entry point: parser::Parsing::Parse
Commands:
flang -fc1 -fdebug-dump-parse-tree-no-sema src.f90
dumps the parse treeflang -fc1 -fdebug-unparse src.f90
converts the parse tree to normalized Fortranflang -fc1 -fdebug-dump-parsing-log src.f90
runs an instrumented parse and dumps the logflang -fc1 -fdebug-measure-parse-tree src.f90
measures the parse treeInput: the parse tree, the cooked character stream, and provenance information
Output:
Entry point: semantics::Semantics::Perform
For more detail on semantic analysis, see: Semantics.md. Semantic processing performs several tasks:
In the course of semantic analysis, the compiler:
At the end of semantic processing, all validation of the user's program is complete. This is the last detailed phase of analysis processing.
Commands:
flang -fc1 -fdebug-dump-parse-tree src.f90
dumps the parse tree after semantic analysisflang -fc1 -fdebug-dump-symbols src.f90
dumps the symbol tableflang -fc1 -fdebug-dump-all src.f90
dumps both the parse tree and the symbol tableLowering takes the parse tree and symbol table produced by analysis and produces LLVM IR.
Inputs:
The lowering bridge is a container that holds all of the information needed for lowering.
Output: A container with all of the information needed for lowering
Entry point: lower::LoweringBridge::create
Input: the lowering bridge
Output: A Fortran IR (FIR) representation of the program.
Entry point: lower::LoweringBridge::lower
The compiler then takes the information in the lowering bridge and creates a pre-FIR tree or PFT. The PFT is a list of programs and modules. The programs and modules contain lists of function-like units. The function-like units contain a list of evaluations. All of these contain pointers back into the parse tree. The compiler walks the PFT generating FIR.
Commands:
flang -fc1 -fdebug-dump-pft src.f90
dumps the pre-FIR treeflang -fc1 -emit-mlir src.f90
dumps the FIR to the files src.mlirInput: initial version of the FIR code
Output: An LLVM IR representation of the program
Entry point: mlir::PassManager::run
The compiler then runs a series of passes over the FIR code. The first is a verification pass. It's followed by a series of transformation passes that perform various optimizations and transformations. The final pass creates an LLVM IR representation of the program.
Commands:
flang -mmlir --mlir-print-ir-after-all -S src.f90
dumps the FIR code after each pass to standard errorflang -fc1 -emit-llvm src.f90
dumps the LLVM IR to src.llAfter the LLVM IR is created, the flang driver invokes LLVM's existing infrastructure to generate object code and invoke a linker to create the executable file.