4 Disclaimer: this document is currently somewhat out-of-date and is
5 retained for reference; for more recent documentation please refer to
8 A complete rewrite of the LLVMC compiler driver is proposed, aimed at
9 making it more configurable and useful.
14 As it stands, the current version of LLVMC does not meet its stated goals
15 of configurability and extensibility, and is therefore not used
16 much. The need for enhancements to LLVMC is also reflected in [1]_. The
17 proposed rewrite will fix the aforementioned deficiences and provide
18 an extensible, future-proof solution.
23 A compiler driver's job is essentially to find a way to transform a set
24 of input files into a set of targets, depending on the user-provided
25 options. Since several methods of transformation can potentially exist,
26 it's natural to use a directed graph to represent all of them. In this
27 graph, nodes are tools -- e.g., ``gcc -S`` is a tool that generates
28 assembly from C language files -- and edges between the nodes indicate
29 that the output of one tool can be given as input to another -- i.e.,
30 ``gcc -S -o - file.c | as``. We'll call this graph the compilation graph.
32 The proposed design revolves around the compilation graph and the
33 following core abstractions:
35 - Target - An (intermediate) compilation target.
37 - Action - A shell command template that represents a basic compilation
38 transformation -- example: ``gcc -S $INPUT_FILE -o $OUTPUT_FILE``.
40 - Tool - Encapsulates information about a concrete tool used in the
41 compilation process, produces Actions. Its operation depends on
42 command-line options provided by the user.
44 - GraphBuilder - Constructs the compilation graph. Its operation
45 depends on command-line options.
47 - GraphTraverser - Traverses the compilation graph and constructs a
48 sequence of Actions needed to build the target file. Its operation
49 depends on command-line options.
51 A high-level view of the compilation process:
53 1. Configuration libraries (see below) are loaded in and the
54 compilation graph is constructed from the tool descriptions.
56 2. Information about possible options is gathered from (the nodes of)
57 the compilation graph.
59 3. Options are parsed based on data gathered in step 2.
61 4. A sequence of Actions needed to build the target is constructed
62 using the compilation graph and provided options.
64 5. The resulting action sequence is executed.
69 To make this design extensible, TableGen [2]_ will be used for
70 automatic generation of the Tool classes. Users wanting to customize
71 LLVMC need to write a configuration library consisting of a set of
72 TableGen descriptions of compilation tools plus a number of hooks
73 that influence compilation graph construction and traversal. LLVMC
74 will have the ability to load user configuration libraries at runtime;
75 in fact, its own basic functionality will be implemented as a
76 configuration library.
78 TableGen specification example
79 ------------------------------
81 This small example specifies a Tool that converts C source to object
82 files. Note that it is only a mock-up of intended functionality, not a
86 GCCProperties, // Properties of this tool
87 GCCOptions // Options description for this tool
90 def GCCProperties : ToolProperties<[
92 InputLanguageName<"C">,
93 OutputLanguageName<"Object-Code">
94 InputFileExtension<"c">,
95 OutputFileExtension<"o">,
96 CommandFormat<"gcc -c $OPTIONS $FILES">
99 def GCCOptions : ToolOptions<[
101 "-Wall", // Option name
102 [None], // Allowed values
103 [AddOption<"-Wall">]>, // Action
106 "-Wextra", // Option name
107 [None], // Allowed values
108 [AddOption<"-Wextra">]>, // Action
112 [None], // Allowed values
113 [AddOption<"-W">]>, // Action
117 [AnyString], // Allowed values
119 [AddOptionWithArgument<"-D",GetOptionArgument<"-D">>]
121 // If the driver was given option "-D<argument>", add
122 // option "-D" with the same argument to the invocation string of
128 Example of generated code
129 -------------------------
131 The specification above compiles to the following code (again, it's a
134 class GCC : public Tool {
142 static const char* ToolName = "GCC";
143 static const char* InputLanguageName = "C";
144 static const char* OutputLanguageName = "Object-Code";
145 static const char* InputFileExtension = "c";
146 static const char* OutputFileExtension = "o";
147 static const char* CommandFormat = "gcc -c $OPTIONS $FILES";
151 OptionsDescription SupportedOptions() {
152 OptionsDescription supportedOptions;
154 supportedOptions.Add(Option("-Wall"));
155 supportedOptions.Add(Option("-Wextra"));
156 supportedOptions.Add(Option("-W"));
157 supportedOptions.Add(Option("-D", AllowedArgs::ANY_STRING));
159 return supportedOptions;
162 Action GenerateAction(Options providedOptions) {
163 Action generatedAction(CommandFormat); Option curOpt;
165 curOpt = providedOptions.Get("-D");
167 assert(curOpt.HasArgument());
168 generatedAction.AddOption(Option("-D", curOpt.GetArgument()));
171 curOpt = providedOptions.Get("-Wall");
173 generatedAction.AddOption(Option("-Wall"));
175 curOpt = providedOptions.Get("-Wextra");
177 generatedAction.AddOption(Option("-Wall"));
179 curOpt = providedOptions.Get("-W");
181 generatedAction.AddOption(Option("-Wall")); }
183 return generatedAction;
188 // defined somewhere...
190 class Action { public: void AddOption(const Option& opt) {...}
191 int Run(const Filenames& fnms) {...}
198 Because one of the main tasks of the compiler driver is to correctly
199 handle user-provided options, it is important to define this process
200 in an exact way. The intent of the proposed scheme is to function as
201 a drop-in replacement for GCC.
206 The option syntax is specified by the following formal grammar::
208 <command-line> ::= <option>*
209 <option> ::= <positional-option> | <named-option>
210 <named-option> ::= -[-]<option-name>[<delimeter><option-argument>]
211 <delimeter> ::= ',' | '=' | ' '
212 <positional-option> ::= <string>
213 <option-name> ::= <string>
214 <option-argument> ::= <string>
216 This roughly corresponds to the GCC option syntax. Note that grouping
217 of short options (as in ``ls -la``) is forbidden.
221 llvmc -O3 -Wa,-foo,-bar -pedantic -std=c++0x a.c b.c c.c
223 Option arguments can also have special forms. For example, an argument
224 can be a comma-separated list (like in -Wa,-foo,-bar). In such cases,
225 it's up to the option handler to parse the argument.
230 According to their meaning, options are classified into the following
233 - Global options - Options that influence compilation graph
234 construction/traversal. Example: -E (stop after preprocessing).
236 - Local options - Options that influence one or several Actions in
237 the generated action sequence. Example: -O3 (turn on optimization).
239 - Prefix options - Options that influence the meaning of the following
240 command-line arguments. Example: -x language (specify language for
241 the input files explicitly). Prefix options can be local or global.
243 - Built-in options - Options that are hard-coded into the
244 driver. Examples: --help, -o file/-pipe (redirect output). Can be
250 1. Should global-options-influencing hooks be written by hand or
251 auto-generated from TableGen specifications?
260 http://llvm.org/bugs/show_bug.cgi?id=686
262 .. [2] TableGen Fundamentals
264 http://llvm.org/docs/TableGenFundamentals.html