|
| 1 | +========================= |
| 2 | +Driver Design & Internals |
| 3 | +========================= |
| 4 | + |
| 5 | +.. contents:: |
| 6 | + :local: |
| 7 | + |
| 8 | +Introduction |
| 9 | +============ |
| 10 | + |
| 11 | +This document serves to describe the high-level design of the Swift 1.0 compiler |
| 12 | +driver (which includes what the driver is intended to do, and the approach it |
| 13 | +takes to do that), as well as the internals of the driver (which is meant to |
| 14 | +provide a brief overview of and rationale for how the high-level design is |
| 15 | +implemented). |
| 16 | + |
| 17 | +The Swift 1.0 driver is not intended to be GCC/Clang compatible, as it does not |
| 18 | +need to serve as a drop-in replacement for either driver. However, the design |
| 19 | +of the driver is inspired by Clang's design (though it is "smarter" than Clang, |
| 20 | +since it performs some limited dependency analysis), and will only diverge if it |
| 21 | +produces a better design, or if it needs to implement something which Clang |
| 22 | +does not. |
| 23 | + |
| 24 | +High-Level Driver Design |
| 25 | +======================== |
| 26 | + |
| 27 | +The compiler driver for Swift will roughly follow the same design as Clang's |
| 28 | +compiler driver: it will parse command-line arguments into Arg objects; use |
| 29 | +those to generate a pipeline of Actions; bind Tools to each Action, which will |
| 30 | +then translate an Action into a Job; execute Jobs; and return a result code. |
| 31 | +However, since Swift source files must be compiled on a per-module basis, |
| 32 | +external build systems cannot easily detect while files in a module must be |
| 33 | +recompiled to accurately produce an executable. As a result, the Swift compiler |
| 34 | +driver must perform dependency tracking on its own, which means that all Jobs |
| 35 | +will not be executed. Instead, Jobs will be logically grouped, and each |
| 36 | +Job will have the opportunity to influence whether other Jobs in the same |
| 37 | +logical group will be executed. |
| 38 | + |
| 39 | +.. contents:: |
| 40 | + :local: |
| 41 | + |
| 42 | +Overview |
| 43 | +-------- |
| 44 | + |
| 45 | +The diagram below, taken from Clang's "Driver Design & Internals" document, |
| 46 | +shows the high-level design of the Swift compiler driver. |
| 47 | + |
| 48 | +.. admonition:: TODO |
| 49 | + |
| 50 | + Update diagram to show conditional Job execution |
| 51 | + |
| 52 | +.. image:: DriverDesign.png |
| 53 | + :align: center |
| 54 | + :alt: Driver Design Diagram |
| 55 | + |
| 56 | +1. Parse input strings into an ArgList of Args. |
| 57 | + |
| 58 | +2. Establish a pipeline of Action groups, such as the following: |
| 59 | + |
| 60 | + - A0: Input, "a.swift" |
| 61 | + |
| 62 | + - A1: Input, "b.swift" |
| 63 | + |
| 64 | + - B0: Compile, {A0}, "a.o" |
| 65 | + |
| 66 | + - B1: Compile, {A1}, "b.o" |
| 67 | + |
| 68 | + - C0: Link, {B0, B1}, "a.out" |
| 69 | + |
| 70 | +4. Bind the appropriate Tool to each Action. |
| 71 | + |
| 72 | +5. Using the bound Tools, translate each Action into a Job, creating a graph. |
| 73 | + |
| 74 | +6. Execute each top-level Job by performing the following: |
| 75 | + |
| 76 | + 1. Ask each Job which is an input to the current Job if it needs to |
| 77 | + execute. This will have the side-effect of loading dependency |
| 78 | + information from the last build (if present). If a Job already |
| 79 | + knows that it needs to execute, schedule it for execution. |
| 80 | + |
| 81 | + 2. Execute each Job which is scheduled for execution. This will have the |
| 82 | + side-effect of creating new dependency information for that Job. |
| 83 | + |
| 84 | + 3. After each Job finishes execution, load the new dependency information |
| 85 | + and reevaluate every Job which is a peer to that Job. |
| 86 | + |
| 87 | +7. After all top-level Jobs been processed, the build artifacts should be |
| 88 | + present on disk, either from a new execution or from a previous execution. |
| 89 | + Return a result code. |
| 90 | + |
| 91 | +Driver Stages |
| 92 | +------------- |
| 93 | + |
| 94 | +The Swift compiler driver is conceptually broken into five stages: Parse |
| 95 | +(transforming input strings to ArgList/Args), Pipeline (transforming Args into |
| 96 | +groups of Actions), Bind (assigning Tools and other build information to |
| 97 | +Actions), Translate (using Tools to translate Actions into Jobs), and Execute. |
| 98 | +From a high level, these look like Clang's driver stages, and functionally |
| 99 | +they're similar. However, unlike Clang, Translate and Execute will, optimally, |
| 100 | +only be performed on a subset of Actions, and the execution of one Action will |
| 101 | +influence whether or not another Action is executed. |
| 102 | + |
| 103 | +Parse: Option parsing |
| 104 | +^^^^^^^^^^^^^^^^^^^^^ |
| 105 | + |
| 106 | +This is a fairly straightforward port of the Clang driver's Parse stage. The |
| 107 | +command line arguments are parsed as options and inputs into Arg instances. |
| 108 | + |
| 109 | +Pipeline: Converting Args into Actions |
| 110 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 111 | + |
| 112 | +This is also a fairly straightforward port of the Clang driver's Pipeline stage. |
| 113 | +At this stage, the driver will take the input Args and input files and establish |
| 114 | +a graph of Actions. |
| 115 | + |
| 116 | +Bind: Tool and Filename Selection |
| 117 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 118 | + |
| 119 | +This stage, like the Clang driver's Bind stage, selects an appropriate Tool to |
| 120 | +use for each Action in a pipeline. This is achieved by asking the Toolchain for |
| 121 | +the right Tool for a given Action. Once every Action in the pipeline has a Tool, |
| 122 | +this stage will determine how to pass output from one Action to the next. |
| 123 | + |
| 124 | +For Actions which do not already have output filenames but require one, this |
| 125 | +stage will also assign unique output filenames. |
| 126 | + |
| 127 | +Translate: Translating Actions into Jobs using Tools |
| 128 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 129 | + |
| 130 | +This stage, like the Clang driver's Translate stage, uses the Tool bound to each |
| 131 | +Action to translate the Args in ArgList into tool-specific arguments. Unlike |
| 132 | +Clang's Translate stage, though, the Swift driver will translate the graph of |
| 133 | +Actions into a graph of Jobs, instead of putting it into a serial queue. |
| 134 | + |
| 135 | +This stage must result in a graph of Jobs instead of a queue of Jobs so that |
| 136 | +Jobs can remain logically grouped. All Jobs which are an input to a particular |
| 137 | +Job will be given the opportunity to impact whether other Jobs in that logical |
| 138 | +group need to be executed; this permits us to perform partial rebuilds when |
| 139 | +safe. |
| 140 | + |
| 141 | +Execute |
| 142 | +^^^^^^^ |
| 143 | + |
| 144 | +This stage, like the Clang driver's Execute stage, executes the Jobs which are |
| 145 | +created by Translate. Unlike Clang's Execute stage, Swift's will support |
| 146 | +concurrency: at the most basic level, this will be something like ``make -jn``, |
| 147 | +where the compiler executes up to n Jobs concurrently. This could be enhanced to |
| 148 | +include things like intelligently scaling back the number of Jobs if the system |
| 149 | +is under pressure, but that may not be necessary for Swift 1.0. (Another |
| 150 | +possible enhancement would be to let an external build system update the value |
| 151 | +of n as the build continues, but that will definitely not be necessary for 1.0.) |
| 152 | + |
| 153 | +Jobs will be scheduled onto a single work queue. Multiple Jobs may execute |
| 154 | +simultaneously, but Job termination will be handled on a single thread. When a |
| 155 | +Job terminates, the driver will evaluate the other Jobs in that Job's group |
| 156 | +to determine if any additional Jobs need to be scheduled. Once all outstanding |
| 157 | +Jobs in the same group have terminated, any unprocessed Jobs will be evaluated |
| 158 | +before executing the downstream Job for which all of the Jobs in that group are |
| 159 | +an input. |
| 160 | + |
| 161 | +Driver Internals |
| 162 | +================ |
| 163 | + |
| 164 | +TBD |
0 commit comments