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