Home | History | Annotate | Download | only in tutorial
      1 ========================================
      2  Kaleidoscope: Compiling to Object Code
      3 ========================================
      4 
      5 .. contents::
      6    :local:
      7 
      8 Chapter 8 Introduction
      9 ======================
     10 
     11 Welcome to Chapter 8 of the "`Implementing a language with LLVM
     12 <index.html>`_" tutorial. This chapter describes how to compile our
     13 language down to object files.
     14 
     15 Choosing a target
     16 =================
     17 
     18 LLVM has native support for cross-compilation. You can compile to the
     19 architecture of your current machine, or just as easily compile for
     20 other architectures. In this tutorial, we'll target the current
     21 machine.
     22 
     23 To specify the architecture that you want to target, we use a string
     24 called a "target triple". This takes the form
     25 ``<arch><sub>-<vendor>-<sys>-<abi>`` (see the `cross compilation docs
     26 <http://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_).
     27 
     28 As an example, we can see what clang thinks is our current target
     29 triple:
     30 
     31 ::
     32 
     33     $ clang --version | grep Target
     34     Target: x86_64-unknown-linux-gnu
     35 
     36 Running this command may show something different on your machine as
     37 you might be using a different architecture or operating system to me.
     38 
     39 Fortunately, we don't need to hard-code a target triple to target the
     40 current machine. LLVM provides ``sys::getDefaultTargetTriple``, which
     41 returns the target triple of the current machine.
     42 
     43 .. code-block:: c++
     44 
     45     auto TargetTriple = sys::getDefaultTargetTriple();
     46 
     47 LLVM doesn't require us to to link in all the target
     48 functionality. For example, if we're just using the JIT, we don't need
     49 the assembly printers. Similarly, if we're only targeting certain
     50 architectures, we can only link in the functionality for those
     51 architectures.
     52 
     53 For this example, we'll initialize all the targets for emitting object
     54 code.
     55 
     56 .. code-block:: c++
     57 
     58     InitializeAllTargetInfos();
     59     InitializeAllTargets();
     60     InitializeAllTargetMCs();
     61     InitializeAllAsmParsers();
     62     InitializeAllAsmPrinters();
     63 
     64 We can now use our target triple to get a ``Target``:
     65 
     66 .. code-block:: c++
     67 
     68   std::string Error;
     69   auto Target = TargetRegistry::lookupTarget(TargetTriple, Error);
     70 
     71   // Print an error and exit if we couldn't find the requested target.
     72   // This generally occurs if we've forgotten to initialise the
     73   // TargetRegistry or we have a bogus target triple.
     74   if (!Target) {
     75     errs() << Error;
     76     return 1;
     77   }
     78 
     79 Target Machine
     80 ==============
     81 
     82 We will also need a ``TargetMachine``. This class provides a complete
     83 machine description of the machine we're targeting. If we want to
     84 target a specific feature (such as SSE) or a specific CPU (such as
     85 Intel's Sandylake), we do so now.
     86 
     87 To see which features and CPUs that LLVM knows about, we can use
     88 ``llc``. For example, let's look at x86:
     89 
     90 ::
     91 
     92     $ llvm-as < /dev/null | llc -march=x86 -mattr=help
     93     Available CPUs for this target:
     94 
     95       amdfam10      - Select the amdfam10 processor.
     96       athlon        - Select the athlon processor.
     97       athlon-4      - Select the athlon-4 processor.
     98       ...
     99 
    100     Available features for this target:
    101 
    102       16bit-mode            - 16-bit mode (i8086).
    103       32bit-mode            - 32-bit mode (80386).
    104       3dnow                 - Enable 3DNow! instructions.
    105       3dnowa                - Enable 3DNow! Athlon instructions.
    106       ...
    107 
    108 For our example, we'll use the generic CPU without any additional
    109 features, options or relocation model.
    110 
    111 .. code-block:: c++
    112 
    113   auto CPU = "generic";
    114   auto Features = "";
    115 
    116   TargetOptions opt;
    117   auto RM = Optional<Reloc::Model>();
    118   auto TargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
    119 
    120 
    121 Configuring the Module
    122 ======================
    123 
    124 We're now ready to configure our module, to specify the target and
    125 data layout. This isn't strictly necessary, but the `frontend
    126 performance guide <../Frontend/PerformanceTips.html>`_ recommends
    127 this. Optimizations benefit from knowing about the target and data
    128 layout.
    129 
    130 .. code-block:: c++
    131 
    132   TheModule->setDataLayout(TargetMachine->createDataLayout());
    133   TheModule->setTargetTriple(TargetTriple);   
    134   
    135 Emit Object Code
    136 ================
    137 
    138 We're ready to emit object code! Let's define where we want to write
    139 our file to:
    140 
    141 .. code-block:: c++
    142 
    143   auto Filename = "output.o";
    144   std::error_code EC;
    145   raw_fd_ostream dest(Filename, EC, sys::fs::F_None);
    146 
    147   if (EC) {
    148     errs() << "Could not open file: " << EC.message();
    149     return 1;
    150   }
    151 
    152 Finally, we define a pass that emits object code, then we run that
    153 pass:
    154 
    155 .. code-block:: c++
    156 
    157   legacy::PassManager pass;
    158   auto FileType = TargetMachine::CGFT_ObjectFile;
    159 
    160   if (TargetMachine->addPassesToEmitFile(pass, dest, FileType)) {
    161     errs() << "TargetMachine can't emit a file of this type";
    162     return 1;
    163   }
    164 
    165   pass.run(*TheModule);
    166   dest.flush();
    167 
    168 Putting It All Together
    169 =======================
    170 
    171 Does it work? Let's give it a try. We need to compile our code, but
    172 note that the arguments to ``llvm-config`` are different to the previous chapters.
    173 
    174 ::
    175 
    176     $ clang++ -g -O3 toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs all` -o toy
    177 
    178 Let's run it, and define a simple ``average`` function. Press Ctrl-D
    179 when you're done.
    180 
    181 ::
    182    
    183     $ ./toy
    184     ready> def average(x y) (x + y) * 0.5;
    185     ^D
    186     Wrote output.o
    187 
    188 We have an object file! To test it, let's write a simple program and
    189 link it with our output. Here's the source code:
    190 
    191 .. code-block:: c++
    192 
    193     #include <iostream>
    194 
    195     extern "C" {
    196         double average(double, double);
    197     }
    198 
    199     int main() {
    200         std::cout << "average of 3.0 and 4.0: " << average(3.0, 4.0) << std::endl;
    201     }
    202 
    203 We link our program to output.o and check the result is what we
    204 expected:
    205 
    206 ::
    207 
    208     $ clang++ main.cpp output.o -o main
    209     $ ./main
    210     average of 3.0 and 4.0: 3.5
    211 
    212 Full Code Listing
    213 =================
    214 
    215 .. literalinclude:: ../../examples/Kaleidoscope/Chapter8/toy.cpp
    216    :language: c++
    217 
    218 `Next: Adding Debug Information <LangImpl09.html>`_
    219