brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · 2e3d4ed Raw
218 lines · plain
1========================================2 Kaleidoscope: Compiling to Object Code3========================================4 5.. contents::6   :local:7 8Chapter 8 Introduction9======================10 11Welcome to Chapter 8 of the "`Implementing a language with LLVM12<index.html>`_" tutorial. This chapter describes how to compile our13language down to object files.14 15Choosing a target16=================17 18LLVM has native support for cross-compilation. You can compile to the19architecture of your current machine, or just as easily compile for20other architectures. In this tutorial, we'll target the current21machine.22 23To specify the architecture that you want to target, we use a string24called a "target triple". This takes the form25``<arch><sub>-<vendor>-<sys>-<abi>`` (see the `cross compilation docs26<https://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_).27 28As an example, we can see what clang thinks is our current target29triple:30 31::32 33    $ clang --version | grep Target34    Target: x86_64-unknown-linux-gnu35 36Running this command may show something different on your machine as37you might be using a different architecture or operating system to me.38 39Fortunately, we don't need to hard-code a target triple to target the40current machine. LLVM provides ``sys::getDefaultTargetTriple``, which41returns the target triple of the current machine.42 43.. code-block:: c++44 45    auto TargetTriple = sys::getDefaultTargetTriple();46 47LLVM doesn't require us to link in all the target48functionality. For example, if we're just using the JIT, we don't need49the assembly printers. Similarly, if we're only targeting certain50architectures, we can only link in the functionality for those51architectures.52 53For this example, we'll initialize all the targets for emitting object54code.55 56.. code-block:: c++57 58    InitializeAllTargetInfos();59    InitializeAllTargets();60    InitializeAllTargetMCs();61    InitializeAllAsmParsers();62    InitializeAllAsmPrinters();63 64We 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 the73  // TargetRegistry or we have a bogus target triple.74  if (!Target) {75    errs() << Error;76    return 1;77  }78 79Target Machine80==============81 82We will also need a ``TargetMachine``. This class provides a complete83machine description of the machine we're targeting. If we want to84target a specific feature (such as SSE) or a specific CPU (such as85Intel's Sandylake), we do so now.86 87To see which features and CPUs that LLVM knows about, we can use88``llc``. For example, let's look at x86:89 90::91 92    $ llvm-as < /dev/null | llc -march=x86 -mattr=help93    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 108For our example, we'll use the generic CPU without any additional feature or109target option.110 111.. code-block:: c++112 113  auto CPU = "generic";114  auto Features = "";115 116  TargetOptions opt;117  auto TargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, Reloc::PIC_);118 119 120Configuring the Module121======================122 123We're now ready to configure our module, to specify the target and124data layout. This isn't strictly necessary, but the `frontend125performance guide <../../Frontend/PerformanceTips.html>`_ recommends126this. Optimizations benefit from knowing about the target and data127layout.128 129.. code-block:: c++130 131  TheModule->setDataLayout(TargetMachine->createDataLayout());132  TheModule->setTargetTriple(TargetTriple);133 134Emit Object Code135================136 137We're ready to emit object code! Let's define where we want to write138our file to:139 140.. code-block:: c++141 142  auto Filename = "output.o";143  std::error_code EC;144  raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);145 146  if (EC) {147    errs() << "Could not open file: " << EC.message();148    return 1;149  }150 151Finally, we define a pass that emits object code, then we run that152pass:153 154.. code-block:: c++155 156  legacy::PassManager pass;157  auto FileType = CodeGenFileType::ObjectFile;158 159  if (TargetMachine->addPassesToEmitFile(pass, dest, nullptr, FileType)) {160    errs() << "TargetMachine can't emit a file of this type";161    return 1;162  }163 164  pass.run(*TheModule);165  dest.flush();166 167Putting It All Together168=======================169 170Does it work? Let's give it a try. We need to compile our code, but171note that the arguments to ``llvm-config`` are different to the previous chapters.172 173::174 175    $ clang++ -g -O3 toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs all` -o toy176 177Let's run it, and define a simple ``average`` function. Press Ctrl-D178when you're done.179 180::181 182    $ ./toy183    ready> def average(x y) (x + y) * 0.5;184    ^D185    Wrote output.o186 187We have an object file! To test it, let's write a simple program and188link it with our output. Here's the source code:189 190.. code-block:: c++191 192    #include <iostream>193 194    extern "C" {195        double average(double, double);196    }197 198    int main() {199        std::cout << "average of 3.0 and 4.0: " << average(3.0, 4.0) << std::endl;200    }201 202We link our program to output.o and check the result is what we203expected:204 205::206 207    $ clang++ main.cpp output.o -o main208    $ ./main209    average of 3.0 and 4.0: 3.5210 211Full Code Listing212=================213 214.. literalinclude:: ../../../examples/Kaleidoscope/Chapter8/toy.cpp215   :language: c++216 217`Next: Adding Debug Information <LangImpl09.html>`_218