From fe292356a284996618ab83fe88e49c13a1c9a78a Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Wed, 15 Oct 2008 09:29:13 +0000 Subject: [PATCH] llvmc2: Documentation update. Describe recent work on plugins. llvm-svn: 57568 --- llvm/tools/llvmc2/doc/LLVMC-Reference.rst | 111 +++++++++++++++++----- llvm/tools/llvmc2/doc/LLVMC-Tutorial.rst | 43 +++++---- 2 files changed, 110 insertions(+), 44 deletions(-) diff --git a/llvm/tools/llvmc2/doc/LLVMC-Reference.rst b/llvm/tools/llvmc2/doc/LLVMC-Reference.rst index 9ec57dcfd394..1b7e017c4ffe 100644 --- a/llvm/tools/llvmc2/doc/LLVMC-Reference.rst +++ b/llvm/tools/llvmc2/doc/LLVMC-Reference.rst @@ -10,8 +10,10 @@ options. What makes LLVMC different is that these transformation rules are completely customizable - in fact, LLVMC knows nothing about the specifics of transformation (even the command-line options are mostly not hard-coded) and regards the transformation structure as an -abstract graph. This makes it possible to adapt LLVMC for other -purposes - for example, as a build tool for game resources. +abstract graph. The structure of this graph is completely determined +by plugins, which can be either statically or dynamically linked. This +makes it possible to easily adapt LLVMC for other purposes - for +example, as a build tool for game resources. Because LLVMC employs TableGen [1]_ as its configuration language, you need to be familiar with it to customize LLVMC. @@ -55,6 +57,7 @@ impossible for LLVMC to choose the right linker in that case:: $ ./a.out hello + Predefined options ================== @@ -66,6 +69,9 @@ configuration files: * ``-x LANGUAGE`` - Specify the language of the following input files 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. * ``--view-graph`` - Show a graphical representation of the compilation @@ -83,26 +89,76 @@ configuration files: their standard meaning. +Compiling LLVMC plugins +======================= + +It's easiest to start working on your own LLVMC plugin by copying the +skeleton project which lives under ``$LLVMC_DIR/plugins/Simple``:: + + $ cd $LLVMC_DIR/plugins + $ cp -r Simple MyPlugin + $ cd MyPlugin + $ ls + Makefile PluginMain.cpp Simple.td + +As you can see, our basic plugin consists of only two files (not +counting the build script). ``Simple.td`` contains TableGen +description of the compilation graph; its format is documented in the +following sections. ``PluginMain.cpp`` is just a helper file used to +compile the auto-generated C++ code produced from TableGen source. It +can also contain hook definitions (see `below`__). + +__ hooks_ + +The first thing that you should do is to change the ``LLVMC_PLUGIN`` +variable in the ``Makefile`` to avoid conflicts (since this variable +is used to name the resulting library):: + + LLVMC_PLUGIN=MyPlugin + +It is also a good idea to rename ``Simple.td`` to something less +generic:: + + $ mv Simple.td MyPlugin.td + +Note that the plugin source directory should be placed into +``$LLVMC_DIR/plugins`` to make use of the existing build +infrastructure. To build a version of the LLVMC executable called +``mydriver`` with your plugin compiled in, use the following command:: + + $ cd $LLVMC_DIR + $ make BUILTIN_PLUGINS=MyPlugin DRIVER_NAME=mydriver + +When linking plugins dynamically, you'll usually 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 BUILTIN_PLUGINS="" + +To build your plugin as a dynamic library, just ``cd`` to its source +directory and run ``make``. The resulting file will be called +``LLVMC$(LLVMC_PLUGIN).$(DLL_EXTENSION)`` (in our case, +``LLVMCMyPlugin.so``). This library can be then loaded in with the +``-load`` option. Example:: + + $ cd $LLVMC_DIR/plugins/Simple + $ make + $ llvmc2 -load $LLVM_DIR/Release/lib/LLVMCSimple.so + +In the future LLVMC will be able to load TableGen files directly. + + Customizing LLVMC: the compilation graph ======================================== -At the time of writing LLVMC does not support on-the-fly reloading of -configuration, so to customize LLVMC you'll have to recompile the -source code (which lives under ``$LLVM_DIR/tools/llvmc2``). The -default configuration files are ``Common.td`` (contains common -definitions, don't forget to ``include`` it in your configuration -files), ``Tools.td`` (tool descriptions) and ``Graph.td`` (compilation -graph definition). +Each TableGen configuration file should include the common +definitions:: -To compile LLVMC with your own configuration file (say,``MyGraph.td``), -run ``make`` like this:: - - $ cd $LLVM_DIR/tools/llvmc2 - $ make GRAPH=MyGraph.td TOOLNAME=my_llvmc - -This will build an executable named ``my_llvmc``. There are also -several sample configuration files in the ``llvmc2/examples`` -subdirectory that should help to get you started. + include "llvm/CompilerDriver/Common.td" + // And optionally: + // include "llvm/CompilerDriver/Tools.td" + // which contains tool definitions. Internally, LLVMC stores information about possible source transformations in form of a graph. Nodes in this graph represent @@ -111,8 +167,8 @@ special "root" node is used to mark entry points for the transformations. LLVMC also assigns a weight to each edge (more on this later) to choose between several alternative edges. -The definition of the compilation graph (see file ``Graph.td``) is -just a list of edges:: +The definition of the compilation graph (see file +``plugins/Base/Base.td`` for an example) is just a list of edges:: def CompilationGraph : CompilationGraph<[ Edge, @@ -136,8 +192,8 @@ just a list of edges:: ]>; As you can see, the edges can be either default or optional, where -optional edges are differentiated by sporting a ``case`` expression -used to calculate the edge's weight. +optional edges are differentiated by an additional ``case`` expression +used to calculate the weight of this edge. The default edges are assigned a weight of 1, and optional edges get a weight of 0 + 2*N where N is the number of tests that evaluated to @@ -162,7 +218,7 @@ Writing a tool description As was said earlier, nodes in the compilation graph represent tools, which are described separately. A tool definition looks like this -(taken from the ``Tools.td`` file):: +(taken from the ``include/llvm/CompilerDriver/Tools.td`` file):: def llvm_gcc_cpp : Tool<[ (in_language "c++"), @@ -289,7 +345,9 @@ no meaning in the context of ``OptionList``, so the only properties allowed there are ``help`` and ``required``. Option lists are used at the file scope. See file -``examples/Clang.td`` for an example of ``OptionList`` usage. +``plugins/Clang/Clang.td`` for an example of ``OptionList`` usage. + +.. _hooks: Using hooks and environment variables in the ``cmd_line`` property ================================================================== @@ -297,8 +355,9 @@ Using hooks and environment variables in the ``cmd_line`` property Normally, LLVMC executes programs from the system ``PATH``. Sometimes, this is not sufficient: for example, we may want to specify tool names in the configuration file. This can be achieved via the mechanism of -hooks - to compile LLVMC with your hooks, just drop a .cpp file into -``tools/llvmc2`` directory. Hooks should live in the ``hooks`` +hooks - to write your own hooks, just add their definitions to the +``PluginMain.cpp`` or drop a ``.cpp`` file into the +``$LLVMC_DIR/driver`` directory. Hooks should live in the ``hooks`` namespace and have the signature ``std::string hooks::MyHookName (void)``. They can be used from the ``cmd_line`` tool property:: diff --git a/llvm/tools/llvmc2/doc/LLVMC-Tutorial.rst b/llvm/tools/llvmc2/doc/LLVMC-Tutorial.rst index b13b043ac29b..ffc1de903b8b 100644 --- a/llvm/tools/llvmc2/doc/LLVMC-Tutorial.rst +++ b/llvm/tools/llvmc2/doc/LLVMC-Tutorial.rst @@ -4,8 +4,10 @@ Tutorial - Using LLVMC LLVMC is a generic compiler driver, which plays the same role for LLVM as the ``gcc`` program does for GCC - the difference being that LLVMC -is designed to be more adaptable and easier to customize. This -tutorial describes the basic usage and configuration of LLVMC. +is designed to be more adaptable and easier to customize. Most of +LLVMC functionality is implemented via plugins, which can be loaded +dynamically or compiled in. This tutorial describes the basic usage +and configuration of LLVMC. .. contents:: @@ -27,21 +29,25 @@ For further help on command-line LLVMC usage, refer to the ``llvmc Using LLVMC to generate toolchain drivers ========================================= -At the time of writing LLVMC does not support on-the-fly reloading of -configuration, so it will be necessary to recompile its source -code. LLVMC uses TableGen [1]_ as its configuration language, so -you need to be familiar with it. +LLVMC plugins are written mostly using TableGen [1]_, so you need to +be familiar with it to get anything done. -Start by compiling ``examples/Simple.td``, which is a simple wrapper -for ``gcc``:: +Start by compiling ``plugins/Simple/Simple.td``, which is a primitive +wrapper for ``gcc``:: $ cd $LLVM_DIR/tools/llvmc2 - $ make TOOLNAME=mygcc GRAPH=examples/Simple.td - $ edit hello.c + $ make DRIVER_NAME=mygcc BUILTIN_PLUGINS=Simple + $ cat > hello.c + [...] $ mygcc hello.c $ ./hello.out Hello +Here we link our plugin with the LLVMC core statically to form an +executable file called ``mygcc``. It is also possible to build our +plugin as a standalone dynamic library; this is described in the +reference manual. + Contents of the file ``Simple.td`` look like this:: // Include common definitions @@ -65,23 +71,24 @@ Contents of the file ``Simple.td`` look like this:: As you can see, this file consists of three parts: tool descriptions, language map, and the compilation graph definition. -At the heart of LLVMC is the idea of a transformation graph: vertices -in this graph are tools, and edges represent a transformation path +At the heart of LLVMC is the idea of a compilation graph: vertices in +this graph are tools, and edges represent a transformation path between two tools (for example, assembly source produced by the -compiler can be transformed into executable code by an assembler). A -special node named ``root`` is used to mark graph entry points. +compiler can be transformed into executable code by an assembler). The +compilation graph is basically a list of edges; a special node named +``root`` is used to mark graph entry points. -Tool descriptions are basically lists of properties: most properties +Tool descriptions are represented as property lists: most properties in the example above should be self-explanatory; the ``sink`` property means that all options lacking an explicit description should be forwarded to this tool. -``LanguageMap`` associates a language name with a list of suffixes and -is used for deciding which toolchain corresponds to a given input +The ``LanguageMap`` associates a language name with a list of suffixes +and is used for deciding which toolchain corresponds to a given input file. To learn more about LLVMC customization, refer to the reference -manual and sample configuration files in the ``examples`` directory. +manual and plugin source code in the ``plugins`` directory. References ==========