1======================================== 2 Kaleidoscope: Compiling to Object Code 3======================================== 4 5.. contents:: 6 :local: 7 8Chapter 8 Introduction 9====================== 10 11Welcome to Chapter 8 of the "`Implementing a language with LLVM 12<index.html>`_" tutorial. This chapter describes how to compile our 13language down to object files. 14 15Choosing a target 16================= 17 18LLVM has native support for cross-compilation. You can compile to the 19architecture of your current machine, or just as easily compile for 20other architectures. In this tutorial, we'll target the current 21machine. 22 23To specify the architecture that you want to target, we use a string 24called a "target triple". This takes the form 25``<arch><sub>-<vendor>-<sys>-<abi>`` (see the `cross compilation docs 26<https://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_). 27 28As an example, we can see what clang thinks is our current target 29triple: 30 31:: 32 33 $ clang --version | grep Target 34 Target: x86_64-unknown-linux-gnu 35 36Running this command may show something different on your machine as 37you 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 the 40current machine. LLVM provides ``sys::getDefaultTargetTriple``, which 41returns 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 target 48functionality. For example, if we're just using the JIT, we don't need 49the assembly printers. Similarly, if we're only targeting certain 50architectures, we can only link in the functionality for those 51architectures. 52 53For this example, we'll initialize all the targets for emitting object 54code. 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 the 73 // TargetRegistry or we have a bogus target triple. 74 if (!Target) { 75 errs() << Error; 76 return 1; 77 } 78 79Target Machine 80============== 81 82We will also need a ``TargetMachine``. This class provides a complete 83machine description of the machine we're targeting. If we want to 84target a specific feature (such as SSE) or a specific CPU (such as 85Intel's Sandylake), we do so now. 86 87To 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 108For our example, we'll use the generic CPU without any additional feature or 109target 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 Module 121====================== 122 123We're now ready to configure our module, to specify the target and 124data layout. This isn't strictly necessary, but the `frontend 125performance guide <../../Frontend/PerformanceTips.html>`_ recommends 126this. Optimizations benefit from knowing about the target and data 127layout. 128 129.. code-block:: c++ 130 131 TheModule->setDataLayout(TargetMachine->createDataLayout()); 132 TheModule->setTargetTriple(TargetTriple); 133 134Emit Object Code 135================ 136 137We're ready to emit object code! Let's define where we want to write 138our 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 that 152pass: 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 Together 168======================= 169 170Does it work? Let's give it a try. We need to compile our code, but 171note 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 toy 176 177Let's run it, and define a simple ``average`` function. Press Ctrl-D 178when you're done. 179 180:: 181 182 $ ./toy 183 ready> def average(x y) (x + y) * 0.5; 184 ^D 185 Wrote output.o 186 187We have an object file! To test it, let's write a simple program and 188link 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 we 203expected: 204 205:: 206 207 $ clang++ main.cpp output.o -o main 208 $ ./main 209 average of 3.0 and 4.0: 3.5 210 211Full Code Listing 212================= 213 214.. literalinclude:: ../../../examples/Kaleidoscope/Chapter8/toy.cpp 215 :language: c++ 216 217`Next: Adding Debug Information <LangImpl09.html>`_ 218