diff --git a/content/posts/2024-11-05-flang-new.md b/content/posts/2024-11-05-flang-new.md new file mode 100644 index 00000000..b1c7bf89 --- /dev/null +++ b/content/posts/2024-11-05-flang-new.md @@ -0,0 +1,436 @@ +--- +author: "David Spickett" +date: "2024-11-05" +tags: ["Flang", "MLIR"] +title: "LLVM Fortran Levels Up: Goodbye flang-new, hello flang!" +--- + +LLVM has included a Fortran compiler "Flang" since LLVM 11. What you might not +know is that the name of Flang's binary was not `flang`, but `flang-new`. + +The LLVM 20 release brings an end to the era of `flang-new`. The +community has decided Flang has reached a level of quality that is worthy of a +new name. + +The "new" name? You guessed it, `flang`. + +In this article I will explain why this simple change actually represents a +major milestone for the Flang project. Covering Flang's almost 10 year journey to +into the LLVM Project and its adoption of one of LLVM's hottest new features, MLIR. + +If you want to try `flang` right now, you can download it now or try it +in your browser using Compiler Explorer. + +TODO: llvm release link + +TODO: godbolt example (hello flang, goodbye flang-new, enable execution) + +# Why Fortran? + +This article will not require any Fortran knowledge, but it is +important to know the context the language was created in, and what about it has +kept the industry investing in it for the last 70 years. + +IBM has an excellent [article](https://www.ibm.com/history/fortran) on the history +of Fortran and I encourage you to look at the +["Programmer's Primer for Fortran"](https://archive.computerhistory.org/resources/text/Fortran/102653987.05.01.acc.pdf) +if you want to know more. + +The name Fortran came from "Formula Translation" and reading the Programmer's +Primer you will see why. A focus on the mathematical use case, freeing programmers +from writing machine specific assembly code. + +Instead they could write code that looked like their formulas. Something we expect +today but at the time was a revolution. This focus led to Fortran being used +heavily in scientific computing. Weather modelling, fluid dynamics and +computational chemistry, just to name a few. + +A 2023 [study](https://arxiv.org/pdf/2308.13274) put it this way: +> Whilst many alternative programming languages have come +> and gone, it [Fortran] has regained its popularity for writing high +> performance codes. Indeed, over 80% of the applications +> running on ARCHER2, a 750,000 core Cray EX which is +> the UK national supercomputer, are written in Fortran. + +# Did We Need Another Fortran Compiler? + +There are many Fortran compilers. Some are vendor specific such as the +[Intel Fortran Compiler](https://www.intel.com/content/www/us/en/developer/tools/oneapi/fortran-compiler.html) +or NVIDIA's [HPC compilers](https://developer.nvidia.com/hpc-compilers) and +there are open source options like [gfortran](https://gcc.gnu.org/fortran/). + +So why build another one? In 2020 Gary Klimowicz (NVIDIA) +[laid out](https://www.youtube.com/watch?v=Fy68k5hHgLk) the goals for Flang, +paraphrased here: + +* Develop Flang under a permissive license like LLVM's, which is more palatable + to commercial users and contributors. +* Develop an active community of Fortran compiler developers that includes + companies and institutions. +* Support Fortran tool development by being based on existing LLVM frameworks. +* Support Fortran language experimentation for future language standards proposals. + +The last one can be explained by comparison to Clang. For C++ feature, a common +path is to implement them on top of Clang, GCC, or both, to prove the feature can work. +Implementing the feature multiple times in different compilers uncovers any +assumptions in the design that may be a problem for one compiler or another. + +In the same way, Flang and gfortran can provide that diversity. + +Finally, though Fortran is an ISO standard, standards can be ambiguous +and implementations can make mistakes. A new compiler is a chance to +rethink those decisions and find parts of the standards that have been neglected. + +Jeff Hammond (NVIDIA) had this to say on the topic: + +TODO: quote goes here + +# PGI to LLVM: the Flang Story + +Though the first glimpses of Flang as we know it do not appear until 2017, the +Portland Group's history with supercomputing and US National Labs is important +so we will start there. + +* **1989** The Portland Group, otherwise known as + [PGI](https://web.archive.org/web/19970628161656/http://www.pgroup.com/corp_home.html), + is formed. To provide C, Fortran 77 and C++ compilers for the Intel i860 market. +* **1990** Intel bundles PGI's compilers with its iPSC/860 supercomputer. +* **1996** PGI + [works with](https://web.archive.org/web/20100528051556/http://www.sandia.gov/ASCI/Red/papers/Mattson/OVERVIEW.html) + Sandia National Laboratories to provide compilers for the ASCI Option Red + supercomputer. +* **December 2000** PGI becomes a + [wholly owned subsidiary](https://www.electronicsweekly.com/news/archived/resources-archived/stmicroelectronics-to-acquire-pgi-2000-12/) of + STMicroElectronics. +* **July 2013** PGI is [sold to NVIDIA](https://www.theregister.com/2013/07/30/nvidia_buys_the_portland_group/). + +In late 2015 we saw the first signs of what would become "Classic Flang". + +* **November 2015** NVIDIA is part of the US Department of Energy + Exascale Computing Project. Including a commitment to create an open source + [Fortran compiler](https://www.llnl.gov/article/41756/nnsa-national-labs-team-nvidia-develop-open-source-fortran-compiler-technology). + + > “The U.S. Department of Energy’s National Nuclear Security Administration and its + > three national labs have reached an agreement with NVIDIA's PGI division to adapt + > and open-source PGI's Fortran frontend, and associated Fortran runtime library, + > for contribution to the LLVM project.” +* **May 2017** The first source code release of Classic Flang as a separate + respository, outside of the LLVM Project. Consisting of PGI's compiler frontend + and a new backend that generated LLVM IR. + + Other companies such as Arm and AMD got involved at this point. + +During this time, plans were being made to propose Classic Flang for inclusion +in the LLVM Project. + +* **April 2018** Steve Scalpone (NVIDIA) [announces](https://www.youtube.com/watch?v=sFVRQDgKihY) + at Euro LLVM 2018 that the frontend of Classic Flang (which was derived from PGI's frontend) + will be rewritten to address feedback from the LLVM community. This new + front end became known as "F18". + + > “We started writing this about 30 years ago, and our data structure is called integer.” + - Steve Scalpone, on the subject of the PGI frontend. + + There was also a hint at a rewrite of the backend, which will appear again later + as the `fir-dev` branch. +* **February 2019** Steve Scalpone (NVIDIA) [proposes](https://lists.llvm.org/pipermail/llvm-dev/2019-February/130497.html) + contributing F18 to the LLVM Project. +* **April 2019** F18 is [approved for migration](https://discourse.llvm.org/t/f18-is-accepted-as-part-of-llvm-project/51719) + into the LLVM Project monorepo. + + At this point F18 was only the early parts of the compiler, it could not generate + code (later `fir-dev` work addressed this). Despite that, it moved into `flang` + in the monorepo, ready for the day it was complete. +* **August 2019** The [first appearance](https://github.com/flang-compiler/f18/commit/b6c30284e7876f6ccd4bb024bd5f349128e99b7c) + of the `flang.sh` driver wrapper script, more on this later. +* **December 2019** The [plan](https://discourse.llvm.org/t/flang-landing-in-the-monorepo/54022) + for rewriting the F18 git history to fit into the LLVM project is announced. + This effort was led by Arm, with Peter Waller (Arm) going so far as to write + a [custom tool](https://github.com/llvm/llvm-project/commit/55d5e6cbe2509a24132d056e1f361dc39312929b#diff-c389405236998090c7c8b9741506f01fb28abbd7da52e9566323c585ac0eb89cL910) + to rewrite the history of F18. +* **Februrary 2020** The [plan](https://discourse.llvm.org/t/plan-for-landing-flang-in-monorepo/54546) + for improvements to F18 to meet the standards required for inclusion in the + LLVM monorepo is announced by Richard Barton (Arm). +* **April 2020** Upstreaming of F18 into the LLVM monorepo is + [completed](https://github.com/llvm/llvm-project/commit/b98ad941a40c96c841bceb171725c925500fce6c). + +At this point what was in the LLVM monorepo was F18, the rewritten frontend of +Classic Flang. Classic Flang remained unchanged, using the PGI based frontend. + +Around this time work started in the Classic Flang repo on the `fir-dev` branch +that would enable code generation when using F18. + +So for the next events remember that this whole time Classic Flang was (and still +is today) in use. Classic Flang's binary name was `flang`, just like the folder F18 now occupied +in the LLVM monorepo. + +* **October 2020** Flang is included in an LLVM release for the first time in + LLVM 11.0.0. There was an `f18` binary and the aforementioned script + `flang.sh`. +* **October 2021** First appearance of the `flang-new` binary, in the LLVM 13.0.0 + release. +* **April 2022** NVIDIA [ceases development](https://discourse.llvm.org/t/nvidia-transition-from-fir-dev/61947) + of the `fir-dev` branch in the Classic Flang project. Upstreaming of `fir-dev` + to the LLVM Project begins around this date. +* **April 2022** `flang-new` can now do code generation if an experimental flag + is used. Enabled by the code upstreamed into the LLVM Project from `fir-dev`. +* **May 2022** The `flang.sh` driver script becomes `flang-to-external-fc`. It + allows the user to use `flang-new` to process Fortran source code then send + the result to an existing Fortran compiler such as gfortran. + + (this seems strange, but it allowed users to drop in Flang as a replacement + for an existing compiler and test Flang's parsing code on their own codebases) +* **June 2022** `flang-new` was changed to do code generation + [by default](https://github.com/llvm/llvm-project/commit/0867d4157328169c570f4d1e9c01806624035873) + with no extra flags required. +* **July 2022** NVIDIA [finish](https://discourse.llvm.org/t/nvidia-transition-from-fir-dev/61947/5) + upstreaming `fir-dev`. + +At this point we had in the LLVM Project the Flang you see today. The +combination of the F18 frontend and MLIR based code generation from `fir-dev`. +As opposed to Classic Flang with its PGI based frontend and legacy backend. + +An initiative to upstream Classic Flang had effectively rewritten the entire +compiler by the time it was complete. + + + +* **April 2024** The `flang-to-external-fc` script is removed. Marking the point + where `flang-new` was mature enough to be used as a standalone compiler. + +* **October 2024** The community deems that Flang has met the criteria to not be + "new" and the name is changed. Goodbye `flang-new`, hello `flang`! + +* TODO: First release with `flang` binary goes here! + +# Flang and the Definition of New + +The renaming of Flang was a contentious +[proposal](https://discourse.llvm.org/t/proposal-rename-flang-new-to-flang/69462) +and an early use of the +[LLVM proposal process](https://github.com/llvm/llvm-www/blob/main/proposals/LP0001-LLVMDecisionMaking.md). + +The most critial point was that `flang` has meant different things to different +people over time. + +To some `flang` was the out of tree Classic Flang. To some it was the in-tree +LLVM Flang. Some were aware of both, but really wanted to move on from Classic +Flang. + +> We have a bit of an unprecedented situation where an LLVM project is taking +> the name of an already established compiler [Classic Flang]. Everyone seems to +> want the older flang [Classic Flang] to fade away, but flang-new is not as +> mature and it isn’t clear when and what the criteria should be for that. +- Chris Lattner, commenting on the [proposal](https://discourse.llvm.org/t/proposal-rename-flang-new-to-flang/69462/25). + +No single list of criteria emerged but some items came up many times: +* Known limitations and supported features should be documented. +* As much as reasonably possible, ongoing work that was expected to fix known + bugs should be completed to prevent duplicate bug reports. +* Unimplemented language features should fail with a message saying they are + unimplemented. Rather than with a nondescript crash or by producing incorrect + code. +* LLVM Flang should have a reasonable level of performance relative to its + competitors. +* Some large Fortran language test suite must be being run publicly and have + a reasonable pass rate. +* All reasonable steps should be taken to prevent anyone using a pre-packaged + Classic Flang from confusing it with LLVM Flang. + +You will see a lot of relative language in those criteria, like "reasonable". It was hard +to say exactly what that meant everyone agreed it would eventually be the case. + +Paul T Robinson summarised the dilema [early](https://discourse.llvm.org/t/proposal-rename-flang-new-to-flang/69462/15) +in the thread: +> > the plan is to replace Classic Flang with the new Flang in the future. +> +> I suppose one of the relevant questions here is: Has the future arrived? + +After which Steve Scalpone (NVIDIA) gave +[their perspective](https://discourse.llvm.org/t/proposal-rename-flang-new-to-flang/69462/16) +their perspective that now was not the time for a name change. + +We know that Flang was renamed, so what changed since then? + +* Many performance and correctness issues were addressed by the work on HLFIR. +* OpenMP support improved greatly. +* Code generation was enabled by default and building popular benchmarks like + [SPEC](https://www.spec.org/benchmarks.html) became possible. +* Several community members put together their own lists of must fix issues + and addressed them. +* The gfortran test suite was added to the [LLVM Test Suite](https://github.com/llvm/llvm-test-suite/tree/main/Fortran/gfortran), + and people judged that Flang achieved good results. +* Test suites from [Fujitsu](https://github.com/fujitsu/compiler-test-suite) and + IBM were made public and issues started to be filed for problems with those. +* Linaro [showed that](https://www.youtube.com/watch?v=Gua80XRPhyY) Flang's + performance compared favourably with Classic Flang and was not that much behind + gfortran. + +Therefore, in October of 2024 `flang-new` became `flang`. The future had arrived. + +# MLIR + +One advantage of the reworking of Flang between Classic Flang and LLVM Flang is +that it allowed Flang to adopt new features from LLVM. The most notable being MLIR. + +"Multi-Level Intermediate Representation", otherwise known as "MLIR" was first +[introduced](https://www.youtube.com/watch?v=qzljG6DKgic) to LLVM +in 2019. Around the time F18 was approved to move into the LLVM Project. + +The problem MLIR tries to solve is that it is difficult to map high level details +of programming languages into the LLVM Intermediate Representation (LLVM IR). You +either have to find a way to attach it to the IR as metadata, try to recover the +lost information later, or fight an uphill battle to add the information to +LLVM IR itself. + +These details are crucial for producing optimised code in these languages, and +Fortran array optimisations were listed in that introductory talk as one example. + +This lead languages such as Swift, Rust and Julia to create their own IRs +which include information useful for their own optimisations. +After that IR has been optimised it is lowered into LLVM IR and goes through the +normal pipeline. + +In doing so, they have to implement a lot of common things repeatedly. This is +where MLIR comes in. + +> The MLIR project aims to directly tackle these programming language design and +> implementation challenges—by making it very cheap to define and introduce new +> abstraction levels, and provide “in the box” infrastructure to solve common +> compiler engineering problems. +- ["MLIR: A Compiler Infrastructure for the End of Moore’s Law"](https://arxiv.org/abs/2002.11054) + (Chris Lattner et al., 2020) + +# Flang and MLIR + +The same year MLIR debuted, Eric Schweitz (NVIDIA) gave a talk at the later US +LLVM Developers' meeting titled +["An MLIR Dialect for High-Level Optimization of Fortran”](https://www.youtube.com/watch?v=ff3ngdvUang). + +Remember the `fir-dev` branch? The `fir` is this. +[Fortran Intermediate Representation](https://flang.llvm.org/docs/FIRLangRef.html), +better known to developers as "FIR". + +FIR did the same thing that Rust, Swift and Julia did but this time, Flang had +the benefit of basing FIR on MLIR. + +They did not stop there, later adding +["High Level Fortran Intermediate Representation"](https://flang.llvm.org/docs/HighLevelFIR.html) +(HLFIR) which works at a higher level than FIR. A big target of HLFIR +was array optimisations, which were more complex to handle using just FIR. + +## IRs All the Way Down + +We start with Fortran source code. This function assigns array `b` to array `a`. + +```fortran +subroutine foo(a, b) + real :: a(:), b(:) + a = b +end subroutine +``` + +(if you want to modify this example, you can do so on +[Compiler Explorer](https://godbolt.org/z/851qrcj6a)) + +It is tempting to think of the IRs in a "stack" where each one is converted +into the next. However, MLIR allows multiple "dialects" of MLIR to exist in the +same file. + +As you can see in this first step, Flang produces a file that uses the HLFIR +dialect where it can, and the FIR dialect for the rest. + +```mlir +module attributes {<...>} { + func.func @_QPfoo(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "b"}) { + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFfooEa"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFfooEb"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + hlfir.assign %2#0 to %1#0 : !fir.box>, !fir.box> + return + } +} +``` +For example, the parameters are declared with `hlfir.declare` but their type is +specified with `fir.array`. MLIR's flexibility means that there is no need for +HLFIR to have a `hlfir.array` which duplicates `fir.array`, unless HLFIR wanted +to add extra information. + +The next step is to convert the HLFIR parts into a combination of FIR and MLIR's +built in `arith` (arithmetic) dialect. + +```mlir +module attributes {<...>} { + func.func @_QPfoo(<...>) { + <...> + %c3_i32 = arith.constant 3 : i32 + %7 = fir.convert %0 : (!fir.ref>>) -> !fir.ref> + %8 = fir.convert %5 : (!fir.box>) -> !fir.box + %9 = fir.convert %6 : (!fir.ref>) -> !fir.ref + %10 = fir.call @_FortranAAssign(%7, %8, %9, %c3_i32) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none + return + } +<...> +} +``` +Then this bundle of MLIR dialects is converted into purely LLVM IR: +```mlir +define void @foo_(ptr %0, ptr %1) { + <...> + store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %37, ptr %3, align 8 + call void @llvm.memcpy.p0.p0.i32(ptr %5, ptr %4, i32 48, i1 false) + %38 = call {} @_FortranAAssign(ptr %5, ptr %3, ptr @_QQclX2F6170702F6578616D706C652E66393000, i32 3) + ret void +} +<...> +``` +This LLVM IR passes through the standard optimisation pipeline that LLVM IR produced +by Clang would. Eventually being converted into target specific Machine IR +(MIR) and finally machine code. + +At each of the stages, the optimisations most suited to that stage are done. +For example, while we are in HLFIR we could optimise array accesses because in +HLFIR we have information about how the Fortran language treats those. + +If we were to do this later in LLVM IR it would be much more difficult. Either +the information would be lost or incomplete, or we would be at a stage in the pipeline +where we cannot assume that we started with a specific source language. + +# Reflections on Flang + +We are almost 10 years from the first announcement of what would become LLVM +Flang. In LLVM monorepo alone there have been almost 10,000 commits +from close to 400 different contributors. Undoubtedly more in Classic Flang before +that. + +So it is time to hear from users, contributors, and supporters past and present +about their experiences with Flang. + +TODO: contributor feedback goes here + +# Getting Involved + +Flang might not be new anymore, but it is definitely still improving. If you +want to try Flang on your own projects, you can download it today. + +TODO: release link goes here + +If you want to contribute, there are many ways to do so. Bug reports, +code contributions, documentation improvements and so on. Flang follows the +[LLVM contribution process](https://llvm.org/docs/Contributing.html) and you +can find links to the mailing lists, community calls and anything else you +might need [here](https://flang.llvm.org/docs/GettingInvolved.html). + +# Credits + +TODO: everyone goes here + +Thanks to the following people for reviewing this article: +* Luis Machado (Arm) + +Thanks to the following people for providing information for this article: +* Carlos Seo (Linaro) +* Kiran Chandramohan (Arm) +* Leandro Lupori (Linaro) +* Peter Waller (Arm) \ No newline at end of file