<div dir="ltr">Thanks for the writeup, this seems like a good direction to me. Do you have a concrete proposal for where in the LLVM project the Driver will move to?<div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 31 Jul 2020 at 06:24, Andrzej Warzynski via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
This is a refined design of how the new Flang driver will re-use the <br>
code currently available in Clang without depending on Clang (long-term <br>
goal). This was initially discussed in [1]. Based on the feedback and <br>
after a few weeks of prototyping [2] we are proposing a much smaller set <br>
of changes. Below is detailed summary of the design and how it will <br>
affect Clang. Your input is much appreciated!<br>
<br>
# *SUMMARY OF CHANGES FOR CLANG*:<br>
* Make libclangDriver independent of Clang by:<br>
** Creating a higher-level, reduced interface over DiagnosticEngine <br>
for compiler drivers to use that does not require Clang's SourceManager<br>
** Lifting the TableGen backend for DiagnosticDriverKinds<br>
* Move libclangDriver (together with the TableGen backend for <br>
DiagnosticDriverKinds) out of Clang<br>
<br>
# *THINGS TO RE-USE*: libclangDriver<br>
The Flang driver (i.e. "flang"), like Clang driver (i.e. "clang"), will <br>
be implemented in terms of libclangDriver. libclangDriver can already <br>
distinguish between various driver modes [3], including a dedicated mode <br>
for flang: clang::driver::Driver::FlangMode. We already use this <br>
mechanism (via ParsedClangName [4]) to start the driver in <br>
Driver::FlangMode (this is done inside "flang").<br>
<br>
One of the key tasks of the driver is to parse the command line options <br>
and translate them into Actions. This part seems re-usable as is.<br>
<br>
Next, based on the generated Actions the driver creates jobs (i.e. <br>
instances of clang::driver::Command). At this point (assuming that the <br>
driver is in<br>
Driver::FlangMode):<br>
* a particular ToolChain/Tool is selected (for the preprocess phase [5], <br>
the ToolChain is implemented in Flang.cpp [6] and the selected tool is <br>
simply "flang -fc1")<br>
* compiler driver options (e.g. options for "flang") are translated into <br>
options for the selected tool (e.g. options for "flang -fc1" in the <br>
preprocess phase)<br>
<br>
The required top-level logic for this is already available in <br>
libclangDriver [6]. Any new logic that will apply only to Flang will be <br>
implemented in clang::driver::tools::Flang.<br>
<br>
# *THINGS NOT TO RE-USE*: libclangFrontend<br>
Once a job representing a call to the Flang frontend driver is <br>
constructed and a dedicate subprocesses is created, the Flang frontend <br>
driver (i.e. "flang -fc1") takes care of the rest. "flang -fc1" will be:<br>
* a seperate entity (akin "clang -cc1" [7])<br>
* independent of libclangFrontend (and "clang -cc1")<br>
* implemented in terms of libflangFrontend (this library will be part of <br>
the Flang subproject)<br>
<br>
So far the implementation of "flang -fc1" and libflangFrontend <br>
(available in our fork [2]) have been heavily inspired by "clang -cc1" <br>
and libclangFrontend, but otherwise are written from scratch. The Flang <br>
frontend driver is unlikely to re-use any code from Clang's frontend <br>
driver at this stage. This seems consistent with what people suggested <br>
in the past (in particular, see this reply from Richard Smith [8]).<br>
<br>
Clang's SourceManager is only really needed by DiagnosticsEngine, but <br>
with libclangDriver limited usage of DiagnosticsEngine, we should be <br>
able to remove the dependency on SourceManager completely. From what we <br>
can see, libclangDriver doesn't really need it.<br>
<br>
# *DEPENDENCIES ON CLANG*<br>
The end goal is to have a Flang compiler driver implemented in terms of <br>
libclangDriver that does not depend on Clang. This means extracting <br>
libclangDriver from Clang and moving it to a separate sub-project. To <br>
this end we have to make sure that libclangDriver no longer depends on <br>
Clang. This is the list of dependencies that we have identified:<br>
* DiagnosticsEngine (+DiagnotsicOptions + DiagnosticIDs + <br>
DiagnosticConsumer)<br>
* TableGen backend for generating error/warning definitions for <br>
DiagnosticsEngine<br>
<br>
Although this list is short (perhaps we missed something?), it contains <br>
some rather complex and pervasive Clang classes that belong in <br>
libclangBasic. Fortunately, libclangDriver uses these classes to a <br>
rather limited extent.<br>
<br>
DiagnosticsEngine is used by the driver to print warnings about user <br>
errors made in the options supplied. This is rather basic usage compared <br>
to reporting errors/warning generating by the parser or semantic <br>
analysis (e.g. we don't care about specific locations in files, macro <br>
expansions, etc). We propose creating a thin layer above <br>
DiagnosticsEngine to satisfy the dependencies of libclangDriver. This <br>
seems feasible and shouldn't be too disruptive.<br>
<br>
The TableGen backend is required to generate DiagnosticDriverKinds.inc, <br>
i.e. the libclangDriver specific errors/warnings. Moving the <br>
corresponding TableGen backend out of Clang (together with <br>
libclangDriver) seems like the most straightforward approach to this. <br>
Any frontend specific diagnostic definitions should remain in Clang. Any <br>
use of these within libclangDriver can be dealt with on a case-by-case <br>
basis.<br>
<br>
# *COMPILER DRIVER OPTIONS*<br>
To handle Flang options we propose to:<br>
* Use ClangFlags [9] to identify Flang options (we will add a dedicated <br>
enum for Flang, e.g. FlangOption)<br>
* Tweak Driver::PrintHelp [10] to only display the appropriate options <br>
depending on the driver mode<br>
* Add new Flang options for libClangDriver to the main DriverOptTable <br>
[11] table, perhaps via a separate *.td file<br>
<br>
We think this has the benefit of being simple and extending existing <br>
interfaces. It may be worth investigating a way to make this scale out a <br>
bit more - cf. [12] - and we propose that as a future enhancement. We <br>
should emphasise that currently libclangDriver creates only one instance <br>
of DriverOptTable [11] that holds all available options. In our design <br>
this table will hold options for both Clang and Flang.<br>
<br>
Flang will re-use many of the options already available via <br>
libclangDriver. C and C++ specific options are also relevant. A common <br>
pattern in HPC apps is mixed C++ and Fortran use in the same source <br>
base. In such mixed-source cases, it is useful for the compiler driver <br>
to be able to handle both at the same time. We will also add some new <br>
options, but it's unlikely to be a long list. Taking gfortran as a <br>
reference, the new options would be a very small fraction of what <br>
libclangDriver already supports.<br>
<br>
# *NEXT STEPS*<br>
The proposed changes (summarized at the top) are relatively small and <br>
will only affect libclangDriver. We would like to start upstreaming our <br>
patches into Flang at the same as lifting libclangDriver out of Clang <br>
into a separate project. This means submitting some patches into Clang <br>
while libclangDriver is still part of Clang. If the overall plan sounds <br>
sensible then shortly we'll prepare a separate, more detailed RFC that <br>
focuses on the usage of DiagnosticsEngine in libclangDriver.<br>
<br>
All input appreciated.<br>
<br>
Thanks for reading.<br>
<br>
Andrzej Warzynski<br>
On behalf on the Arm Fortran Team<br>
<br>
<br>
[1] <a href="http://lists.llvm.org/pipermail/llvm-dev/2020-June/141994.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/llvm-dev/2020-June/141994.html</a><br>
[2] <a href="https://github.com/banach-space/llvm-project" rel="noreferrer" target="_blank">https://github.com/banach-space/llvm-project</a><br>
[3] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/Driver.h#L64" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/Driver.h#L64</a><br>
[4] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/ToolChain.h#L63" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/ToolChain.h#L63</a><br>
[5] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/Phases.h#L14" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/Phases.h#L14</a><br>
[6] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/lib/Driver/ToolChains/Flang.cpp" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/lib/Driver/ToolChains/Flang.cpp</a><br>
[7] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/tools/driver/cc1_main.cpp#L184" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/tools/driver/cc1_main.cpp#L184</a><br>
[8] <a href="http://lists.llvm.org/pipermail/llvm-dev/2020-June/142024.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/llvm-dev/2020-June/142024.html</a><br>
[9] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/Options.h#L26" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/include/clang/Driver/Options.h#L26</a><br>
[10] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/lib/Driver/Driver.cpp#L1559" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/lib/Driver/Driver.cpp#L1559</a><br>
[11] <br>
<a href="https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/lib/Driver/DriverOptions.cpp#L43" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/cbb3571b0df5a0948602aa4d2b913b64270143ff/clang/lib/Driver/DriverOptions.cpp#L43</a><br>
[12] <a href="http://lists.llvm.org/pipermail/llvm-dev/2020-July/143745.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/llvm-dev/2020-July/143745.html</a><br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>