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