<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
I like the overall approach, especially as a starting point to get flang working.
<br>
<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
I think that we should eliminate the dependence on Clang at some point by moving the driver code, and other shared parts (e.g., the OpenMP codegen), into llvm-core or a dedicated helper package. This will not only allow to build flang in a more standalone fashion
 but also to make it easier for new frontends to reuse all these parts.<br>
<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
Cheers,<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
  Johannes<br>
<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
<span id="OutlookSignature">
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
Get <a href="https://aka.ms/ghei36">Outlook for Android</a></div>
</span><br>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> cfe-dev <cfe-dev-bounces@lists.llvm.org> on behalf of Peter Waller via cfe-dev <cfe-dev@lists.llvm.org><br>
<b>Sent:</b> Monday, June 24, 2019 11:34:18 AM<br>
<b>To:</b> cfe-dev@lists.llvm.org<br>
<b>Cc:</b> nd<br>
<b>Subject:</b> [cfe-dev] RFC: Adding a fortran mode to the clang driver for flang</font>
<div> </div>
</div>
<div><span>Hi All,<br>
</span>
<div><br>
</div>
<div>I'm starting work on a driver and frontend for the new flang (the<br>
</div>
<div>recently renamed f18 - not to be confused with any previous project also<br>
</div>
<div>of the same name). This has implications for the clang subproject, which<br>
</div>
<div>I discuss below.<br>
</div>
<div><br>
</div>
<div># Preliminaries<br>
</div>
<div><br>
</div>
<div>The goal is to make the in-progress flang compiler usable as soon as<br>
</div>
<div>possible.<br>
</div>
<div><br>
</div>
<div>I am motivated to keep things simple and deliver soon, hopefully in<br>
</div>
<div>digestible chunks of work.<br>
</div>
<div><br>
</div>
<div>I have split this task into two smaller pieces in a top-down approach. First, a<br>
</div>
<div>driver needs to land which can invoke the flang compiler as part of a multi-file<br>
</div>
<div>compile+link when it is passed a Fortran input. Subsequently, the flang compiler<br>
</div>
<div>needs logic analogous to clang::CompilerInvocation, which takes a Fortran file<br>
</div>
<div>as input and produces output in the appropriate form for the command line<br>
</div>
<div>options specified.<br>
</div>
<div><br>
</div>
<div>This RFC is focused on the first part. There are implications for clang,<br>
</div>
<div>since there exists a significant body of driver code there, much of the<br>
</div>
<div>logic it would be beneficial to share and reuse. The first change will<br>
</div>
<div>be to clang. The flang changes will come in future RFCs, and I envisage<br>
</div>
<div>will be more an internal detail of the flang subproject. There will be<br>
</div>
<div>some leakage as we seek to share as much logic as makes sense to do so.<br>
</div>
<div><br>
</div>
<div># Approach<br>
</div>
<div><br>
</div>
<div>I assuming that flang intends to implement a gcc-like interface.<br>
</div>
<div><br>
</div>
<div>From https://clang.llvm.org/docs/DriverInternals.html:<br>
</div>
<div><br>
</div>
<div>> [...] most of the driver functionality is kept in a library which can<br>
</div>
<div>> be used to build other tools which want to implement or accept a gcc<br>
</div>
<div>> like interface.<br>
</div>
<div><br>
</div>
<div>libclangDriver has the goal of being a reusable and extensible driver.<br>
</div>
<div>If it gained knowledge of the flang toolchain, implementing a flang<br>
</div>
<div>driver as powerful as the clang driver in terms of libclangDriver would<br>
</div>
<div>be a relatively small task.<br>
</div>
<div><br>
</div>
<div>I propose to put together a new "bin/flang" binary which would be<br>
</div>
<div>structured and behave in a similar manner as clang. The intent is to<br>
</div>
<div>mirror clang, for both the driver and CompilerInvocation, as much as<br>
</div>
<div>makes sense to do so. The aim is to avoid re-inventing the wheel and to<br>
</div>
<div>enable people who have worked with either the clang or flang<br>
</div>
<div>entrypoints, drivers, and frontends to easily understand the other.<br>
</div>
<div><br>
</div>
<div># The user-facing result will be:<br>
</div>
<div><br>
</div>
<div>When I do `bin/flang -o foobar foobar.f90`, the driver will invoke<br>
</div>
<div>`bin/flang -fc1 foobar.f90 -o /tmp/foobar_cafe1234.o` and subsequently<br>
</div>
<div>link it.<br>
</div>
<div><br>
</div>
<div># Preliminary prototype<br>
</div>
<div></div>
<div><span><br>
</span></div>
<div><span>https://reviews.llvm.org/D63607?id=206172 introduces the above</span></div>
<div><span></span></div>
<div>behaviour, to illustrate the approach. At this point I seek advice<br>
</div>
<div>primarily on the overall approach. If acceptable, I will tidy it up and<br>
</div>
<span>submit it for review. There will be more details to get right.</span>
<div><br>
</div>
<div>The patch is it stands has a small amount of logic which makes<br>
</div>
<div>`bin/flang` a symlink to `clang`, which causes the driver to go into<br>
</div>
<div>Fortran mode and invoke `bin/flang -fc1`; at the moment this is just a<br>
</div>
<div>stub which prints the arguments. In the real implementation, `bin/flang`<br>
</div>
<div>will be a standalone binary in the flang project. This hack enables<br>
</div>
<div>playing with my proposed driver approach now. At no point will flang<br>
</div>
<div>be required to build clang.<br>
</div>
<div><br>
</div>
<div># More details<br>
</div>
<div><br>
</div>
<div>`bin/flang` will naturally support mixed C/C++/Fortran inputs, invoke<br>
</div>
<div>the relevant compilers for each input and link everything together.<br>
</div>
<div><br>
</div>
<div>libclangDriver will gain a new "Fortran" mode (--driver-mode=fortran).<br>
</div>
<div>When in this mode, when given a Fortran input, the driver will invoke<br>
</div>
<div>the flang compiler, which would live at "flang -fc1" by analogy with<br>
</div>
<div>"clang -cc1". "clang", when not in `--driver-mode=fortran`, would retain<br>
</div>
<div>its existing default behaviour of falling back to gcc (and thus<br>
</div>
<div>gfortran), for now. This means that existing build processes relying on<br>
</div>
<div>the existing behaviour will not be touched, and that the new behaviour<br>
</div>
<div>is opt-in by either using `bin/flang` or `--driver-mode=fortran`.<br>
</div>
<div><br>
</div>
<div>`bin/flang` will use clang::Driver, in Fortran mode. This seems a source<br>
</div>
<div>of potential problems since it requires a clang::DiagnosticsEngine to<br>
</div>
<div>construct, and these things seem clang-specific. However, this<br>
</div>
<div>diagnostics engine is primarily used by the driver to print warnings<br>
</div>
<div>about user errors made in the options supplied, so maybe this is not a<br>
</div>
<div>big problem. I have not investigated the full implications of this yet.<br>
</div>
<div><br>
</div>
<div>The clang driver already has an option group for gfortran options.<br>
</div>
<div>libclangDriver will need to know about all of the options that the flang<br>
</div>
<div>frontend supports. The complete set is under development and will grow<br>
</div>
<div>over time. All options in this group would be passed through to the<br>
</div>
<div>flang compiler. It's unclear to me at the moment whether the<br>
</div>
<div>gfortran-specific options will remain in their own group, or whether<br>
</div>
<div>they can be merged into a 'fortran group'. This can be decided once the<br>
</div>
<div>full flang compiler options story is better understood.<br>
</div>
<div><br>
</div>
<div>Where it makes sense to do so, the flang compiler will accept many of<br>
</div>
<div>the same options that clang does, particularly those relating to the<br>
</div>
<div>output form (e.g. -emit-llvm, -S, optimization options, etc).<br>
</div>
<div><br>
</div>
<div>I would act under the assumption that where possible, the<br>
</div>
<div>non-passthrough logic in the driver should be minimized, and the heavy<br>
</div>
<div>lifting should occur inside the flang compiler. The compiler will reuse LLVM<br>
</div>
<div>option parsing logic where it makes sense to do so.<br>
</div>
<div><br>
</div>
<div>cmake and project structure: flang at the moment is an independent<br>
</div>
<div>project. Taking the above proposed approach will "grow a dependency<br>
</div>
<div>edge" from flang onto the clang subproject. This may be undesirable in<br>
</div>
<div>the long run. It implies that building flang will require building (at<br>
</div>
<div>least part of) clang. I think this should be addressed at some point so<br>
</div>
<div>that flang can be built independently, but perhaps not initially, as<br>
</div>
<div>moving the clang driver into another top-level subproject would be<br>
</div>
<div>another significant task. The approach and value for that task may be<br>
</div>
<div>clearer once a second dependency on libclangDriver exists under the<br>
</div>
<div>llvm-project tree.<br>
</div>
<div><br>
</div>
<div>Help text contamination: I'm operating under the belief that clang<br>
</div>
<div>should not mention the Fortran language options and likewise flang<br>
</div>
<div>should not mention the C-like-language options.<br>
</div>
<div><br>
</div>
<div>When in Fortran mode, the driver will need to pass additional options to<br>
</div>
<div>the linker, in particular to link the Fortran runtime and intrinsics.<br>
</div>
<div>I have not yet considered this in detail.<br>
</div>
<div><br>
</div>
<div># Implications<br>
</div>
<div><br>
</div>
<div>Building flang will require building libclangDriver, at least.<br>
</div>
<div><br>
</div>
<div>This approach gives a future path to having clang invoke flang for<br>
</div>
<div>Fortran inputs instead of falling back to gcc as it currently does,<br>
</div>
<div>giving better gcc drop-in compatibility without depending on having gcc<br>
</div>
<div>available.<br>
</div>
<div><br>
</div>
<div>Having this arrangement does mean that some changes - for example,<br>
</div>
<div>adding a new compiler option - will require patches which touch both the<br>
</div>
<div>clang and flang subprojects. In particular, Fortran language specific<br>
</div>
<div>options will continue to reside in clang/include/clang/Driver/Options.td.<br>
</div>
<div><br>
</div>
<div># Prior art<br>
</div>
<div><br>
</div>
<div>There is a lot of prior art in this domain. While considering the<br>
</div>
<div>problem, I have looked at the following projects:<br>
</div>
<div><br>
</div>
<div>* https://github.com/flang-compiler/flang-driver<br>
</div>
<div><br>
</div>
<div>  This is a fork of clang, with the main goal of implementing the<br>
</div>
<div>  toolchains/flang tool. The implementation that I propose in this RFC<br>
</div>
<div>  is similar to that, but the tool would be simpler since the frontend<br>
</div>
<div>  is starting from fresh.<br>
</div>
<div><br>
</div>
<div>* https://github.com/apple/swift<br>
</div>
<div><br>
</div>
<div>  Swift's driver looks similar to that of clang, but is a separate<br>
</div>
<div>  implementation.<br>
</div>
<div><br>
</div>
<div>* llgo and other languages<br>
</div>
<div><br>
</div>
<div>  These are written in other languages, and do not appear to reuse the<br>
</div>
<div>  driver logic.<br>
</div>
<div><br>
</div>
<div>I observe that most prior implementations do not try to share logic with<br>
</div>
<div>clang. I surmise that the reasons for this are partly due to those<br>
</div>
<div>projects being external, and also due to those projects having quite<br>
</div>
<div>different user interfaces. Fortran on the other hand shares many<br>
</div>
<div>similarities with the C-like user interfaces, and there is a large body<br>
</div>
<div>of existing code relying on gcc-like behaviour implemented by the clang<br>
</div>
<div>driver.<br>
</div>
<div><br>
</div>
<div># Alternative approaches<br>
</div>
<div><br>
</div>
<div>The other approach I have considered is to do what Swift have done and<br>
</div>
<div>reimplement significant amounts of the driver, copying the structure<br>
</div>
<div>from clang. I don't currently see a good reason to do this at this<br>
</div>
<div>stage, since flang is joining the LLVM project and therefore should be<br>
</div>
<div>able to share the clang implementation directly.<br>
</div>
<div><br>
</div>
<div>There may be other good reasons for doing this I've missed, in which<br>
</div>
<div>case I would be interested in hearing about it.<br>
</div>
<div><br>
</div>
<div># Future work and next steps<br>
</div>
<div><br>
</div>
<div>If there are no show-stoppers in my above proposal, I will submit the<br>
</div>
<div>attached patch for review, and commence further work on proposing,<br>
</div>
<div>prototyping and implementing `bin/flang` and `bin/flang -fc1` in the<br>
</div>
<div>flang project.<br>
</div>
<div><br>
</div>
<div>All input appreciated.<br>
</div>
<div><br>
</div>
<div>Thanks for reading,<br>
</div>
<div><br>
</div>
<div>Peter Waller<br>
</div>
<div>peter.waller@arm.com<br>
</div>
<div>Arm Limited<br>
</div>
<span></span></div>
</body>
</html>