xref: /llvm-project/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst (revision dad614cc606333fa614e696dbdd22263096dadb7)
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