:orphan:

========================================
 Kaleidoscope: Compiling to Object Code
========================================

.. contents::
   :local:

Chapter 8 Introduction
======================

Welcome to Chapter 8 of the "`Implementing a language with LLVM
<index.html>`_" tutorial. This chapter describes how to compile our
language down to object files.

Choosing a target
=================

LLVM has native support for cross-compilation. You can compile to the
architecture of your current machine, or just as easily compile for
other architectures. In this tutorial, we'll target the current
machine.

To specify the architecture that you want to target, we use a string
called a "target triple". This takes the form
``<arch><sub>-<vendor>-<sys>-<abi>`` (see the `cross compilation docs
<http://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_).

As an example, we can see what clang thinks is our current target
triple:

::

    $ clang --version | grep Target
    Target: x86_64-unknown-linux-gnu

Running this command may show something different on your machine as
you might be using a different architecture or operating system to me.

Fortunately, we don't need to hard-code a target triple to target the
current machine. LLVM provides ``sys::getDefaultTargetTriple``, which
returns the target triple of the current machine.

.. code-block:: c++

    auto TargetTriple = sys::getDefaultTargetTriple();

LLVM doesn't require us to link in all the target
functionality. For example, if we're just using the JIT, we don't need
the assembly printers. Similarly, if we're only targeting certain
architectures, we can only link in the functionality for those
architectures.

For this example, we'll initialize all the targets for emitting object
code.

.. code-block:: c++

    InitializeAllTargetInfos();
    InitializeAllTargets();
    InitializeAllTargetMCs();
    InitializeAllAsmParsers();
    InitializeAllAsmPrinters();

We can now use our target triple to get a ``Target``:

.. code-block:: c++

  std::string Error;
  auto Target = TargetRegistry::lookupTarget(TargetTriple, Error);

  // Print an error and exit if we couldn't find the requested target.
  // This generally occurs if we've forgotten to initialise the
  // TargetRegistry or we have a bogus target triple.
  if (!Target) {
    errs() << Error;
    return 1;
  }

Target Machine
==============

We will also need a ``TargetMachine``. This class provides a complete
machine description of the machine we're targeting. If we want to
target a specific feature (such as SSE) or a specific CPU (such as
Intel's Sandylake), we do so now.

To see which features and CPUs that LLVM knows about, we can use
``llc``. For example, let's look at x86:

::

    $ llvm-as < /dev/null | llc -march=x86 -mattr=help
    Available CPUs for this target:

      amdfam10      - Select the amdfam10 processor.
      athlon        - Select the athlon processor.
      athlon-4      - Select the athlon-4 processor.
      ...

    Available features for this target:

      16bit-mode            - 16-bit mode (i8086).
      32bit-mode            - 32-bit mode (80386).
      3dnow                 - Enable 3DNow! instructions.
      3dnowa                - Enable 3DNow! Athlon instructions.
      ...

For our example, we'll use the generic CPU without any additional
features, options or relocation model.

.. code-block:: c++

  auto CPU = "generic";
  auto Features = "";

  TargetOptions opt;
  auto RM = Optional<Reloc::Model>();
  auto TargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);


Configuring the Module
======================

We're now ready to configure our module, to specify the target and
data layout. This isn't strictly necessary, but the `frontend
performance guide <../Frontend/PerformanceTips.html>`_ recommends
this. Optimizations benefit from knowing about the target and data
layout.

.. code-block:: c++

  TheModule->setDataLayout(TargetMachine->createDataLayout());
  TheModule->setTargetTriple(TargetTriple);   
  
Emit Object Code
================

We're ready to emit object code! Let's define where we want to write
our file to:

.. code-block:: c++

  auto Filename = "output.o";
  std::error_code EC;
  raw_fd_ostream dest(Filename, EC, sys::fs::F_None);

  if (EC) {
    errs() << "Could not open file: " << EC.message();
    return 1;
  }

Finally, we define a pass that emits object code, then we run that
pass:

.. code-block:: c++

  legacy::PassManager pass;
  auto FileType = TargetMachine::CGFT_ObjectFile;

  if (TargetMachine->addPassesToEmitFile(pass, dest, FileType)) {
    errs() << "TargetMachine can't emit a file of this type";
    return 1;
  }

  pass.run(*TheModule);
  dest.flush();

Putting It All Together
=======================

Does it work? Let's give it a try. We need to compile our code, but
note that the arguments to ``llvm-config`` are different to the previous chapters.

::

    $ clang++ -g -O3 toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs all` -o toy

Let's run it, and define a simple ``average`` function. Press Ctrl-D
when you're done.

::
   
    $ ./toy
    ready> def average(x y) (x + y) * 0.5;
    ^D
    Wrote output.o

We have an object file! To test it, let's write a simple program and
link it with our output. Here's the source code:

.. code-block:: c++

    #include <iostream>

    extern "C" {
        double average(double, double);
    }

    int main() {
        std::cout << "average of 3.0 and 4.0: " << average(3.0, 4.0) << std::endl;
    }

We link our program to output.o and check the result is what we
expected:

::

    $ clang++ main.cpp output.o -o main
    $ ./main
    average of 3.0 and 4.0: 3.5

Full Code Listing
=================

.. literalinclude:: ../../../examples/Kaleidoscope/Chapter8/toy.cpp
   :language: c++

`Next: Adding Debug Information <LangImpl09.html>`_
