Remove all references to plugins from the LLVMC docs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130090 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Mikhail Glushenkov 2011-04-24 14:17:32 +00:00
parent 685501836b
commit 834b93b51d
2 changed files with 221 additions and 318 deletions

View File

@ -18,17 +18,16 @@ Introduction
============ ============
LLVMC is a generic compiler driver, designed to be customizable and LLVMC is a generic compiler driver, designed to be customizable and
extensible. It plays the same role for LLVM as the ``gcc`` program extensible. It plays the same role for LLVM as the ``gcc`` program does for
does for GCC - LLVMC's job is essentially to transform a set of input GCC - LLVMC's job is essentially to transform a set of input files into a set of
files into a set of targets depending on configuration rules and user targets depending on configuration rules and user options. What makes LLVMC
options. What makes LLVMC different is that these transformation rules different is that these transformation rules are completely customizable - in
are completely customizable - in fact, LLVMC knows nothing about the fact, LLVMC knows nothing about the specifics of transformation (even the
specifics of transformation (even the command-line options are mostly command-line options are mostly not hard-coded) and regards the transformation
not hard-coded) and regards the transformation structure as an structure as an abstract graph. The structure of this graph is described in
abstract graph. The structure of this graph is completely determined high-level TableGen code, from which an efficient C++ representation is
by plugins, which can be either statically or dynamically linked. This automatically derived. This makes it possible to adapt LLVMC for other
makes it possible to easily adapt LLVMC for other purposes - for purposes - for example, as a build tool for game resources.
example, as a build tool for game resources.
Because LLVMC employs TableGen_ as its configuration language, you Because LLVMC employs TableGen_ as its configuration language, you
need to be familiar with it to customize LLVMC. need to be familiar with it to customize LLVMC.
@ -36,8 +35,8 @@ need to be familiar with it to customize LLVMC.
.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html .. _TableGen: http://llvm.org/docs/TableGenFundamentals.html
Compiling with LLVMC Compiling with ``llvmc``
==================== ========================
LLVMC tries hard to be as compatible with ``gcc`` as possible, LLVMC tries hard to be as compatible with ``gcc`` as possible,
although there are some small differences. Most of the time, however, although there are some small differences. Most of the time, however,
@ -78,17 +77,13 @@ possible to choose the ``clang`` compiler with the ``-clang`` option.
Predefined options Predefined options
================== ==================
LLVMC has some built-in options that can't be overridden in the LLVMC has some built-in options that can't be overridden in the TableGen code:
configuration libraries:
* ``-o FILE`` - Output file name. * ``-o FILE`` - Output file name.
* ``-x LANGUAGE`` - Specify the language of the following input files * ``-x LANGUAGE`` - Specify the language of the following input files
until the next -x option. until the next -x option.
* ``-load PLUGIN_NAME`` - Load the specified plugin DLL. Example:
``-load $LLVM_DIR/Release/lib/LLVMCSimple.so``.
* ``-v`` - Enable verbose mode, i.e. print out all executed commands. * ``-v`` - Enable verbose mode, i.e. print out all executed commands.
* ``--save-temps`` - Write temporary files to the current directory and do not * ``--save-temps`` - Write temporary files to the current directory and do not
@ -103,124 +98,90 @@ configuration libraries:
precedence. precedence.
* ``--check-graph`` - Check the compilation for common errors like mismatched * ``--check-graph`` - Check the compilation for common errors like mismatched
output/input language names, multiple default edges and cycles. Because of output/input language names, multiple default edges and cycles. Exit with code
plugins, these checks can't be performed at compile-time. Exit with code zero zero if no errors were found, and return the number of found errors
if no errors were found, and return the number of found errors otherwise. Hidden option, useful for debugging.
otherwise. Hidden option, useful for debugging LLVMC plugins.
* ``--view-graph`` - Show a graphical representation of the compilation graph * ``--view-graph`` - Show a graphical representation of the compilation graph
and exit. Requires that you have ``dot`` and ``gv`` programs installed. Hidden and exit. Requires that you have ``dot`` and ``gv`` programs installed. Hidden
option, useful for debugging LLVMC plugins. option, useful for debugging.
* ``--write-graph`` - Write a ``compilation-graph.dot`` file in the current * ``--write-graph`` - Write a ``compilation-graph.dot`` file in the current
directory with the compilation graph description in Graphviz format (identical directory with the compilation graph description in Graphviz format (identical
to the file used by the ``--view-graph`` option). The ``-o`` option can be to the file used by the ``--view-graph`` option). The ``-o`` option can be
used to set the output file name. Hidden option, useful for debugging LLVMC used to set the output file name. Hidden option, useful for debugging.
plugins.
* ``--help``, ``--help-hidden``, ``--version`` - These options have * ``--help``, ``--help-hidden``, ``--version`` - These options have
their standard meaning. their standard meaning.
Compiling LLVMC plugins Compiling LLVMC-based drivers
======================= =============================
It's easiest to start working on your own LLVMC plugin by copying the It's easiest to start working on your own LLVMC driver by copying the skeleton
skeleton project which lives under ``$LLVMC_DIR/plugins/Simple``:: project which lives under ``$LLVMC_DIR/examples/Skeleton``::
$ cd $LLVMC_DIR/plugins $ cd $LLVMC_DIR/examples
$ cp -r Simple MyPlugin $ cp -r Skeleton MyDriver
$ cd MyPlugin $ cd MyDriver
$ ls $ ls
Makefile PluginMain.cpp Simple.td AutoGenerated.td Hooks.cpp Main.cpp Makefile
As you can see, our basic plugin consists of only two files (not As you can see, our basic driver consists of only three files (not counting the
counting the build script). ``Simple.td`` contains TableGen build script). ``AutoGenerated.td`` contains TableGen description of the
description of the compilation graph; its format is documented in the compilation graph; its format is documented in the following
following sections. ``PluginMain.cpp`` is just a helper file used to sections. ``Hooks.cpp`` is an empty file that should be used for hook
compile the auto-generated C++ code produced from TableGen source. It definitions (see `below`__). ``Main.cpp`` is just a helper used to compile the
can also contain hook definitions (see `below`__). auto-generated C++ code produced from TableGen source.
__ hooks_ __ hooks_
The first thing that you should do is to change the ``LLVMC_PLUGIN`` The first thing that you should do is to change the ``LLVMC_BASED_DRIVER``
variable in the ``Makefile`` to avoid conflicts (since this variable variable in the ``Makefile``::
is used to name the resulting library)::
LLVMC_PLUGIN=MyPlugin LLVMC_BASED_DRIVER=MyDriver
It is also a good idea to rename ``Simple.td`` to something less It can also be a good idea to put your TableGen code into a file with a less
generic:: generic name::
$ mv Simple.td MyPlugin.td $ touch MyDriver.td
$ vim AutoGenerated.td
To build your plugin as a dynamic library, just ``cd`` to its source
directory and run ``make``. The resulting file will be called
``plugin_llvmc_$(LLVMC_PLUGIN).$(DLL_EXTENSION)`` (in our case,
``plugin_llvmc_MyPlugin.so``). This library can be then loaded in with the
``-load`` option. Example::
$ cd $LLVMC_DIR/plugins/Simple
$ make
$ llvmc -load $LLVM_DIR/Release/lib/plugin_llvmc_Simple.so
Compiling standalone LLVMC-based drivers
========================================
By default, the ``llvmc`` executable consists of a driver core plus several
statically linked plugins (``Base`` and ``Clang`` at the moment). You can
produce a standalone LLVMC-based driver executable by linking the core with your
own plugins. The recommended way to do this is by starting with the provided
``Skeleton`` example (``$LLVMC_DIR/example/Skeleton``)::
$ cd $LLVMC_DIR/example/
$ cp -r Skeleton mydriver
$ cd mydriver
$ vim Makefile
[...] [...]
$ make include "MyDriver.td"
If you have more than one TableGen source file, they all should be included from
``AutoGenerated.td``, since this file is used by the build system to generate
C++ code.
To build your driver, just ``cd`` to its source directory and run ``make``. The
resulting executable will be put into ``$LLVM_OBJ_DIR/$(BuildMode)/bin``.
If you're compiling LLVM with different source and object directories, then you If you're compiling LLVM with different source and object directories, then you
must perform the following additional steps before running ``make``:: must perform the following additional steps before running ``make``::
# LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/ # LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/
# LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/ # LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/
$ cp $LLVMC_SRC_DIR/example/mydriver/Makefile \ $ mkdir $LLVMC_OBJ_DIR/examples/MyDriver/
$LLVMC_OBJ_DIR/example/mydriver/ $ cp $LLVMC_SRC_DIR/examples/MyDriver/Makefile \
$ cd $LLVMC_OBJ_DIR/example/mydriver $LLVMC_OBJ_DIR/examples/MyDriver/
$ cd $LLVMC_OBJ_DIR/examples/MyDriver
$ make $ make
Another way to do the same thing is by using the following command::
$ cd $LLVMC_DIR
$ make LLVMC_BUILTIN_PLUGINS=MyPlugin LLVMC_BASED_DRIVER_NAME=mydriver
This works with both srcdir == objdir and srcdir != objdir, but assumes that the
plugin source directory was placed under ``$LLVMC_DIR/plugins``.
Sometimes, you will want a 'bare-bones' version of LLVMC that has no
built-in plugins. It can be compiled with the following command::
$ cd $LLVMC_DIR
$ make LLVMC_BUILTIN_PLUGINS=""
Customizing LLVMC: the compilation graph Customizing LLVMC: the compilation graph
======================================== ========================================
Each TableGen configuration file should include the common Each TableGen configuration file should include the common definitions::
definitions::
include "llvm/CompilerDriver/Common.td" include "llvm/CompilerDriver/Common.td"
Internally, LLVMC stores information about possible source Internally, LLVMC stores information about possible source transformations in
transformations in form of a graph. Nodes in this graph represent form of a graph. Nodes in this graph represent tools, and edges between two
tools, and edges between two nodes represent a transformation path. A nodes represent a transformation path. A special "root" node is used to mark
special "root" node is used to mark entry points for the entry points for the transformations. LLVMC also assigns a weight to each edge
transformations. LLVMC also assigns a weight to each edge (more on (more on this later) to choose between several alternative edges.
this later) to choose between several alternative edges.
The definition of the compilation graph (see file The definition of the compilation graph (see file ``llvmc/src/Base.td`` for an
``plugins/Base/Base.td`` for an example) is just a list of edges:: example) is just a list of edges::
def CompilationGraph : CompilationGraph<[ def CompilationGraph : CompilationGraph<[
Edge<"root", "llvm_gcc_c">, Edge<"root", "llvm_gcc_c">,
@ -245,43 +206,37 @@ The definition of the compilation graph (see file
]>; ]>;
As you can see, the edges can be either default or optional, where As you can see, the edges can be either default or optional, where optional
optional edges are differentiated by an additional ``case`` expression edges are differentiated by an additional ``case`` expression used to calculate
used to calculate the weight of this edge. Notice also that we refer the weight of this edge. Notice also that we refer to tools via their names (as
to tools via their names (as strings). This makes it possible to add strings). This makes it possible to add edges to an existing compilation graph
edges to an existing compilation graph in plugins without having to without having to know about all tool definitions used in the graph.
know about all tool definitions used in the graph.
The default edges are assigned a weight of 1, and optional edges get a The default edges are assigned a weight of 1, and optional edges get a weight of
weight of 0 + 2*N where N is the number of tests that evaluated to 0 + 2*N where N is the number of tests that evaluated to true in the ``case``
true in the ``case`` expression. It is also possible to provide an expression. It is also possible to provide an integer parameter to
integer parameter to ``inc_weight`` and ``dec_weight`` - in this case, ``inc_weight`` and ``dec_weight`` - in this case, the weight is increased (or
the weight is increased (or decreased) by the provided value instead decreased) by the provided value instead of the default 2. Default weight of an
of the default 2. It is also possible to change the default weight of optional edge can be changed by using the ``default`` clause of the ``case``
an optional edge by using the ``default`` clause of the ``case``
construct. construct.
When passing an input file through the graph, LLVMC picks the edge When passing an input file through the graph, LLVMC picks the edge with the
with the maximum weight. To avoid ambiguity, there should be only one maximum weight. To avoid ambiguity, there should be only one default edge
default edge between two nodes (with the exception of the root node, between two nodes (with the exception of the root node, which gets a special
which gets a special treatment - there you are allowed to specify one treatment - there you are allowed to specify one default edge *per language*).
default edge *per language*).
When multiple plugins are loaded, their compilation graphs are merged When multiple compilation graphs are defined, they are merged together. Multiple
together. Since multiple edges that have the same end nodes are not edges with the same end nodes are not allowed (i.e. the graph is not a
allowed (i.e. the graph is not a multigraph), an edge defined in multigraph), and will lead to a compile-time error.
several plugins will be replaced by the definition from the plugin
that was loaded last. Plugin load order can be controlled by using the
plugin priority feature described above.
To get a visual representation of the compilation graph (useful for To get a visual representation of the compilation graph (useful for debugging),
debugging), run ``llvmc --view-graph``. You will need ``dot`` and run ``llvmc --view-graph``. You will need ``dot`` and ``gsview`` installed for
``gsview`` installed for this to work properly. this to work properly.
Describing options Describing options
================== ==================
Command-line options that the plugin supports are defined by using an Command-line options supported by the driver are defined by using an
``OptionList``:: ``OptionList``::
def Options : OptionList<[ def Options : OptionList<[
@ -290,11 +245,10 @@ Command-line options that the plugin supports are defined by using an
... ...
]>; ]>;
As you can see, the option list is just a list of DAGs, where each DAG As you can see, the option list is just a list of DAGs, where each DAG is an
is an option description consisting of the option name and some option description consisting of the option name and some properties. More than
properties. A plugin can define more than one option list (they are one option list can be defined (they are all merged together in the end), which
all merged together in the end), which can be handy if one wants to can be handy if one wants to separate option groups syntactically.
separate option groups syntactically.
* Possible option types: * Possible option types:
@ -380,42 +334,17 @@ separate option groups syntactically.
Usage examples: ``(switch_option "foo", (init true))``; ``(prefix_option Usage examples: ``(switch_option "foo", (init true))``; ``(prefix_option
"bar", (init "baz"))``. "bar", (init "baz"))``.
- ``extern`` - this option is defined in some other plugin, see `below`__.
__ extern_
.. _extern:
External options
----------------
Sometimes, when linking several plugins together, one plugin needs to
access options defined in some other plugin. Because of the way
options are implemented, such options must be marked as
``extern``. This is what the ``extern`` option property is
for. Example::
...
(switch_option "E", (extern))
...
If an external option has additional attributes besides 'extern', they are
ignored. See also the section on plugin `priorities`__.
__ priorities_
.. _case: .. _case:
Conditional evaluation Conditional evaluation
====================== ======================
The 'case' construct is the main means by which programmability is The 'case' construct is the main means by which programmability is achieved in
achieved in LLVMC. It can be used to calculate edge weights, program LLVMC. It can be used to calculate edge weights, program actions and modify the
actions and modify the shell commands to be executed. The 'case' shell commands to be executed. The 'case' expression is designed after the
expression is designed after the similarly-named construct in similarly-named construct in functional languages and takes the form ``(case
functional languages and takes the form ``(case (test_1), statement_1, (test_1), statement_1, (test_2), statement_2, ... (test_N), statement_N)``. The
(test_2), statement_2, ... (test_N), statement_N)``. The statements statements are evaluated only if the corresponding tests evaluate to true.
are evaluated only if the corresponding tests evaluate to true.
Examples:: Examples::
@ -439,20 +368,19 @@ Examples::
(switch_on "B"), "cmdline2", (switch_on "B"), "cmdline2",
(default), "cmdline3") (default), "cmdline3")
Note the slight difference in 'case' expression handling in contexts Note the slight difference in 'case' expression handling in contexts of edge
of edge weights and command line specification - in the second example weights and command line specification - in the second example the value of the
the value of the ``"B"`` switch is never checked when switch ``"A"`` is ``"B"`` switch is never checked when switch ``"A"`` is enabled, and the whole
enabled, and the whole expression always evaluates to ``"cmdline1"`` in expression always evaluates to ``"cmdline1"`` in that case.
that case.
Case expressions can also be nested, i.e. the following is legal:: Case expressions can also be nested, i.e. the following is legal::
(case (switch_on "E"), (case (switch_on "o"), ..., (default), ...) (case (switch_on "E"), (case (switch_on "o"), ..., (default), ...)
(default), ...) (default), ...)
You should, however, try to avoid doing that because it hurts You should, however, try to avoid doing that because it hurts readability. It is
readability. It is usually better to split tool descriptions and/or usually better to split tool descriptions and/or use TableGen inheritance
use TableGen inheritance instead. instead.
* Possible tests are: * Possible tests are:
@ -526,72 +454,75 @@ use TableGen inheritance instead.
Example: ``(not (or (test1), (test2), ... (testN)))``. Example: ``(not (or (test1), (test2), ... (testN)))``.
Writing a tool description Writing a tool description
========================== ==========================
As was said earlier, nodes in the compilation graph represent tools, As was said earlier, nodes in the compilation graph represent tools, which are
which are described separately. A tool definition looks like this described separately. A tool definition looks like this (taken from the
(taken from the ``include/llvm/CompilerDriver/Tools.td`` file):: ``llvmc/src/Base.td`` file)::
def llvm_gcc_cpp : Tool<[ def llvm_gcc_cpp : Tool<[
(in_language "c++"), (in_language "c++"),
(out_language "llvm-assembler"), (out_language "llvm-assembler"),
(output_suffix "bc"), (output_suffix "bc"),
(cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"), (command "llvm-g++ -c -emit-llvm"),
(sink) (sink)
]>; ]>;
This defines a new tool called ``llvm_gcc_cpp``, which is an alias for This defines a new tool called ``llvm_gcc_cpp``, which is an alias for
``llvm-g++``. As you can see, a tool definition is just a list of ``llvm-g++``. As you can see, a tool definition is just a list of properties;
properties; most of them should be self-explanatory. The ``sink`` most of them should be self-explanatory. The ``sink`` property means that this
property means that this tool should be passed all command-line tool should be passed all command-line options that aren't mentioned in the
options that aren't mentioned in the option list. option list.
The complete list of all currently implemented tool properties follows. The complete list of all currently implemented tool properties follows.
* Possible tool properties: * Possible tool properties:
- ``in_language`` - input language name. Can be given multiple arguments, in - ``in_language`` - input language name. Can be given multiple arguments, in
case the tool supports multiple input languages. case the tool supports multiple input languages. Used for typechecking and
mapping file extensions to tools.
- ``out_language`` - output language name. Multiple output languages are - ``out_language`` - output language name. Multiple output languages are
allowed. allowed. Used for typechecking the compilation graph.
- ``output_suffix`` - output file suffix. Can also be changed - ``output_suffix`` - output file suffix. Can also be changed dynamically, see
dynamically, see documentation on actions. documentation on `actions`__.
- ``cmd_line`` - the actual command used to run the tool. You can
use ``$INFILE`` and ``$OUTFILE`` variables, output redirection
with ``>``, hook invocations (``$CALL``), environment variables
(via ``$ENV``) and the ``case`` construct.
- ``join`` - this tool is a "join node" in the graph, i.e. it gets a
list of input files and joins them together. Used for linkers.
- ``sink`` - all command-line options that are not handled by other
tools are passed to this tool.
- ``actions`` - A single big ``case`` expression that specifies how
this tool reacts on command-line options (described in more detail
`below`__).
__ actions_ __ actions_
- ``command`` - the actual command used to run the tool. You can use output
redirection with ``>``, hook invocations (``$CALL``), environment variables
(via ``$ENV``) and the ``case`` construct.
- ``join`` - this tool is a "join node" in the graph, i.e. it gets a list of
input files and joins them together. Used for linkers.
- ``sink`` - all command-line options that are not handled by other tools are
passed to this tool.
- ``actions`` - A single big ``case`` expression that specifies how this tool
reacts on command-line options (described in more detail `below`__).
__ actions_
- ``out_file_option``, ``in_file_option`` - Options appended to the
``command`` string to designate output and input files. Default values are
``"-o"`` and ``""``, respectively.
.. _actions: .. _actions:
Actions Actions
------- -------
A tool often needs to react to command-line options, and this is A tool often needs to react to command-line options, and this is precisely what
precisely what the ``actions`` property is for. The next example the ``actions`` property is for. The next example illustrates this feature::
illustrates this feature::
def llvm_gcc_linker : Tool<[ def llvm_gcc_linker : Tool<[
(in_language "object-code"), (in_language "object-code"),
(out_language "executable"), (out_language "executable"),
(output_suffix "out"), (output_suffix "out"),
(cmd_line "llvm-gcc $INFILE -o $OUTFILE"), (command "llvm-gcc"),
(join), (join),
(actions (case (not_empty "L"), (forward "L"), (actions (case (not_empty "L"), (forward "L"),
(not_empty "l"), (forward "l"), (not_empty "l"), (forward "l"),
@ -599,18 +530,17 @@ illustrates this feature::
[(append_cmd "-dummy1"), (append_cmd "-dummy2")]) [(append_cmd "-dummy1"), (append_cmd "-dummy2")])
]>; ]>;
The ``actions`` tool property is implemented on top of the omnipresent The ``actions`` tool property is implemented on top of the omnipresent ``case``
``case`` expression. It associates one or more different *actions* expression. It associates one or more different *actions* with given
with given conditions - in the example, the actions are ``forward``, conditions - in the example, the actions are ``forward``, which forwards a given
which forwards a given option unchanged, and ``append_cmd``, which option unchanged, and ``append_cmd``, which appends a given string to the tool
appends a given string to the tool execution command. Multiple actions execution command. Multiple actions can be associated with a single condition by
can be associated with a single condition by using a list of actions using a list of actions (used in the example to append some dummy options). The
(used in the example to append some dummy options). The same ``case`` same ``case`` construct can also be used in the ``cmd_line`` property to modify
construct can also be used in the ``cmd_line`` property to modify the the tool command line.
tool command line.
The "join" property used in the example means that this tool behaves The "join" property used in the example means that this tool behaves like a
like a linker. linker.
The list of all possible actions follows. The list of all possible actions follows.
@ -656,10 +586,10 @@ The list of all possible actions follows.
Language map Language map
============ ============
If you are adding support for a new language to LLVMC, you'll need to If you are adding support for a new language to LLVMC, you'll need to modify the
modify the language map, which defines mappings from file extensions language map, which defines mappings from file extensions to language names. It
to language names. It is used to choose the proper toolchain(s) for a is used to choose the proper toolchain(s) for a given input file set. Language
given input file set. Language map definition looks like this:: map definition looks like this::
def LanguageMap : LanguageMap< def LanguageMap : LanguageMap<
[LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
@ -673,9 +603,7 @@ For example, without those definitions the following command wouldn't work::
llvmc: Unknown suffix: cpp llvmc: Unknown suffix: cpp
The language map entries are needed only for the tools that are linked from the The language map entries are needed only for the tools that are linked from the
root node. Since a tool can't have multiple output languages, for inner nodes of root node. A tool can have multiple output languages.
the graph the input and output languages should match. This is enforced at
compile-time.
Option preprocessor Option preprocessor
=================== ===================
@ -686,7 +614,7 @@ implemented as switches, we might want to output a warning if the user invokes
the driver with both of these options enabled. the driver with both of these options enabled.
The ``OptionPreprocessor`` feature is reserved specially for these The ``OptionPreprocessor`` feature is reserved specially for these
occasions. Example (adapted from the built-in Base plugin):: occasions. Example (adapted from ``llvm/src/Base.td.in``)::
def Preprocess : OptionPreprocessor< def Preprocess : OptionPreprocessor<
@ -705,7 +633,7 @@ that they are not forwarded to the compiler. If no optimization options are
specified, ``-O2`` is enabled. specified, ``-O2`` is enabled.
``OptionPreprocessor`` is basically a single big ``case`` expression, which is ``OptionPreprocessor`` is basically a single big ``case`` expression, which is
evaluated only once right after the plugin is loaded. The only allowed actions evaluated only once right after the driver is started. The only allowed actions
in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions: in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions:
``unset_option`` and ``set_option``. As their names suggest, they can be used to ``unset_option`` and ``set_option``. As their names suggest, they can be used to
set or unset a given option. To set an option with ``set_option``, use the set or unset a given option. To set an option with ``set_option``, use the
@ -726,30 +654,28 @@ More advanced topics
Hooks and environment variables Hooks and environment variables
------------------------------- -------------------------------
Normally, LLVMC executes programs from the system ``PATH``. Sometimes, Normally, LLVMC searches for programs in the system ``PATH``. Sometimes, this is
this is not sufficient: for example, we may want to specify tool paths not sufficient: for example, we may want to specify tool paths or names in the
or names in the configuration file. This can be easily achieved via configuration file. This can be achieved via the hooks mechanism. To write your
the hooks mechanism. To write your own hooks, just add their own hooks, add their definitions to the ``Hooks.cpp`` or drop a ``.cpp`` file
definitions to the ``PluginMain.cpp`` or drop a ``.cpp`` file into the into your driver directory. Hooks should live in the ``hooks`` namespace and
your plugin directory. Hooks should live in the ``hooks`` namespace have the signature ``std::string hooks::MyHookName ([const char* Arg0 [ const
and have the signature ``std::string hooks::MyHookName ([const char* char* Arg2 [, ...]]])``. They can be used from the ``command`` tool property::
Arg0 [ const char* Arg2 [, ...]]])``. They can be used from the
``cmd_line`` tool property::
(cmd_line "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)") (command "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)")
To pass arguments to hooks, use the following syntax:: To pass arguments to hooks, use the following syntax::
(cmd_line "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2") (command "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2")
It is also possible to use environment variables in the same manner:: It is also possible to use environment variables in the same manner::
(cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)") (command "$ENV(VAR1)/path/to/file -o $ENV(VAR2)")
To change the command line string based on user-provided options use To change the command line string based on user-provided options use
the ``case`` expression (documented `above`__):: the ``case`` expression (documented `above`__)::
(cmd_line (command
(case (case
(switch_on "E"), (switch_on "E"),
"llvm-g++ -E -x c $INFILE -o $OUTFILE", "llvm-g++ -E -x c $INFILE -o $OUTFILE",
@ -758,42 +684,21 @@ the ``case`` expression (documented `above`__)::
__ case_ __ case_
.. _priorities:
How plugins are loaded
----------------------
It is possible for LLVMC plugins to depend on each other. For example,
one can create edges between nodes defined in some other plugin. To
make this work, however, that plugin should be loaded first. To
achieve this, the concept of plugin priority was introduced. By
default, every plugin has priority zero; to specify the priority
explicitly, put the following line in your plugin's TableGen file::
def Priority : PluginPriority<$PRIORITY_VALUE>;
# Where PRIORITY_VALUE is some integer > 0
Plugins are loaded in order of their (increasing) priority, starting
with 0. Therefore, the plugin with the highest priority value will be
loaded last.
Debugging Debugging
--------- ---------
When writing LLVMC plugins, it can be useful to get a visual view of When writing LLVMC-based drivers, it can be useful to get a visual view of the
the resulting compilation graph. This can be achieved via the command resulting compilation graph. This can be achieved via the command line option
line option ``--view-graph``. This command assumes that Graphviz_ and ``--view-graph`` (which assumes that Graphviz_ and Ghostview_ are
Ghostview_ are installed. There is also a ``--write-graph`` option that installed). There is also a ``--write-graph`` option that creates a Graphviz
creates a Graphviz source file (``compilation-graph.dot``) in the source file (``compilation-graph.dot``) in the current directory.
current directory.
Another useful ``llvmc`` option is ``--check-graph``. It checks the Another useful ``llvmc`` option is ``--check-graph``. It checks the compilation
compilation graph for common errors like mismatched output/input graph for common errors like mismatched output/input language names, multiple
language names, multiple default edges and cycles. These checks can't default edges and cycles. When invoked with ``--check-graph``, ``llvmc`` doesn't
be performed at compile-time because the plugins can load code perform any compilation tasks and returns the number of encountered errors as
dynamically. When invoked with ``--check-graph``, ``llvmc`` doesn't its status code. In the future, these checks will be performed at compile-time
perform any compilation tasks and returns the number of encountered and this option will disappear.
errors as its status code.
.. _Graphviz: http://www.graphviz.org/ .. _Graphviz: http://www.graphviz.org/
.. _Ghostview: http://pages.cs.wisc.edu/~ghost/ .. _Ghostview: http://pages.cs.wisc.edu/~ghost/
@ -821,7 +726,7 @@ accessible only in the C++ code (i.e. hooks). Use the following code::
In general, you're encouraged not to make the behaviour dependent on the In general, you're encouraged not to make the behaviour dependent on the
executable file name, and use command-line switches instead. See for example how executable file name, and use command-line switches instead. See for example how
the ``Base`` plugin behaves when it needs to choose the correct linker options the ``llvmc`` program behaves when it needs to choose the correct linker options
(think ``g++`` vs. ``gcc``). (think ``g++`` vs. ``gcc``).
.. raw:: html .. raw:: html

View File

@ -17,59 +17,54 @@ Tutorial - Using LLVMC
Introduction Introduction
============ ============
LLVMC is a generic compiler driver, which plays the same role for LLVM LLVMC is a generic compiler driver, which plays the same role for LLVM as the
as the ``gcc`` program does for GCC - the difference being that LLVMC ``gcc`` program does for GCC - the difference being that LLVMC is designed to be
is designed to be more adaptable and easier to customize. Most of more adaptable and easier to customize. Most of LLVMC functionality is
LLVMC functionality is implemented via plugins, which can be loaded implemented via high-level TableGen code, from which a corresponding C++ source
dynamically or compiled in. This tutorial describes the basic usage file is automatically generated. This tutorial describes the basic usage and
and configuration of LLVMC. configuration of LLVMC.
Compiling with LLVMC Using the ``llvmc`` program
==================== ===========================
In general, LLVMC tries to be command-line compatible with ``gcc`` as In general, ``llvmc`` tries to be command-line compatible with ``gcc`` as much
much as possible, so most of the familiar options work:: as possible, so most of the familiar options work::
$ llvmc -O3 -Wall hello.cpp $ llvmc -O3 -Wall hello.cpp
$ ./a.out $ ./a.out
hello hello
This will invoke ``llvm-g++`` under the hood (you can see which This will invoke ``llvm-g++`` under the hood (you can see which commands are
commands are executed by using the ``-v`` option). For further help on executed by using the ``-v`` option). For further help on command-line LLVMC
command-line LLVMC usage, refer to the ``llvmc --help`` output. usage, refer to the ``llvmc --help`` output.
Using LLVMC to generate toolchain drivers Using LLVMC to generate toolchain drivers
========================================= =========================================
LLVMC plugins are written mostly using TableGen_, so you need to LLVMC-based drivers are written mostly using TableGen_, so you need to be
be familiar with it to get anything done. familiar with it to get anything done.
.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html .. _TableGen: http://llvm.org/docs/TableGenFundamentals.html
Start by compiling ``example/Simple``, which is a primitive wrapper for Start by compiling ``example/Simple``, which is a primitive wrapper for
``gcc``:: ``gcc``::
$ cd $LLVM_DIR/tools/llvmc $ cd $LLVM_OBJ_DIR/tools/examples/Simple
$ cp -r example/Simple plugins/Simple $ make
# NB: A less verbose way to compile standalone LLVMC-based drivers is
# described in the reference manual.
$ make LLVMC_BASED_DRIVER_NAME=mygcc LLVMC_BUILTIN_PLUGINS=Simple
$ cat > hello.c $ cat > hello.c
[...] #include <stdio.h>
$ mygcc hello.c int main() { printf("Hello\n"); }
$ $LLVM_BIN_DIR/Simple -v hello.c
gcc hello.c -o hello.out
$ ./hello.out $ ./hello.out
Hello Hello
Here we link our plugin with the LLVMC core statically to form an executable We have thus produced a simple driver called, appropriately, ``Simple``, from
file called ``mygcc``. It is also possible to build our plugin as a dynamic the input TableGen file ``Simple.td``. The ``llvmc`` program itself is generated
library to be loaded by the ``llvmc`` executable (or any other LLVMC-based using a similar process (see ``llvmc/src``). Contents of the file ``Simple.td``
standalone driver); this is described in the reference manual. look like this::
Contents of the file ``Simple.td`` look like this::
// Include common definitions // Include common definitions
include "llvm/CompilerDriver/Common.td" include "llvm/CompilerDriver/Common.td"
@ -79,37 +74,40 @@ Contents of the file ``Simple.td`` look like this::
[(in_language "c"), [(in_language "c"),
(out_language "executable"), (out_language "executable"),
(output_suffix "out"), (output_suffix "out"),
(cmd_line "gcc $INFILE -o $OUTFILE"), (command "gcc"),
(sink) (sink),
// -o is what is used by default, out_file_option here is included for
// instructive purposes.
(out_file_option "-o")
]>; ]>;
// Language map // Language map
def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>; def LanguageMap : LanguageMap<[(lang_to_suffixes "c", "c")]>;
// Compilation graph // Compilation graph
def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>; def CompilationGraph : CompilationGraph<[(edge "root", "gcc")]>;
As you can see, this file consists of three parts: tool descriptions, As you can see, this file consists of three parts: tool descriptions, language
language map, and the compilation graph definition. map, and the compilation graph definition.
At the heart of LLVMC is the idea of a compilation graph: vertices in At the heart of LLVMC is the idea of a compilation graph: vertices in this graph
this graph are tools, and edges represent a transformation path are tools, and edges represent a transformation path between two tools (for
between two tools (for example, assembly source produced by the example, assembly source produced by the compiler can be transformed into
compiler can be transformed into executable code by an assembler). The executable code by an assembler). The compilation graph is basically a list of
compilation graph is basically a list of edges; a special node named edges; a special node named ``root`` is used to mark graph entry points.
``root`` is used to mark graph entry points.
Tool descriptions are represented as property lists: most properties Tool descriptions are represented as property lists: most properties in the
in the example above should be self-explanatory; the ``sink`` property example above should be self-explanatory; the ``sink`` property means that all
means that all options lacking an explicit description should be options lacking an explicit description should be forwarded to this tool.
forwarded to this tool.
The ``LanguageMap`` associates a language name with a list of suffixes The ``LanguageMap`` associates a language name with a list of suffixes and is
and is used for deciding which toolchain corresponds to a given input used for deciding which toolchain corresponds to a given input file.
file.
To learn more about LLVMC customization, refer to the reference To learn more about writing your own drivers with LLVMC, refer to the reference
manual and plugin source code in the ``plugins`` directory. manual and examples in the ``examples`` directory. Of a particular interest is
the ``Skeleton`` example, which can serve as a template for your LLVMC-based
drivers.
.. raw:: html .. raw:: html