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