Book Image

Learn LLVM 12

By : Kai Nacke
Book Image

Learn LLVM 12

By: Kai Nacke

Overview of this book

LLVM was built to bridge the gap between compiler textbooks and actual compiler development. It provides a modular codebase and advanced tools which help developers to build compilers easily. This book provides a practical introduction to LLVM, gradually helping you navigate through complex scenarios with ease when it comes to building and working with compilers. You’ll start by configuring, building, and installing LLVM libraries, tools, and external projects. Next, the book will introduce you to LLVM design and how it works in practice during each LLVM compiler stage: frontend, optimizer, and backend. Using a subset of a real programming language as an example, you will then learn how to develop a frontend and generate LLVM IR, hand it over to the optimization pipeline, and generate machine code from it. Later chapters will show you how to extend LLVM with a new pass and how instruction selection in LLVM works. You’ll also focus on Just-in-Time compilation issues and the current state of JIT-compilation support that LLVM provides, before finally going on to understand how to develop a new backend for LLVM. By the end of this LLVM book, you will have gained real-world experience in working with the LLVM compiler development framework with the help of hands-on examples and source code snippets.
Table of Contents (17 chapters)
1
Section 1 – The Basics of Compiler Construction with LLVM
5
Section 2 – From Source to Machine Code Generation
11
Section 3 –Taking LLVM to the Next Level

Building with CMake

With the build tools ready, you can now check out all the LLVM projects from GitHub. The command for doing this is essentially the same on all platforms. However, on Windows, it is recommended to turn off auto-translation for line endings.

Let's review this process in three parts: cloning the repository, creating a build directory, and generating the build system files.

Cloning the repository

On all non-Windows platforms, type in the following command to clone the repository:

$ git clone https://github.com/llvm/llvm-project.git

On Windows, you must add the option to disable line endings from being auto-translated. Here, type the following:

$ git clone --config core.autocrlf=false\  https://github.com/llvm/llvm-project.git

This git command clones the latest source code from GitHub into a local directory named llvm-project. Now, change the current directory to the new llvm-project directory with the following command:

$ cd llvm-project

Inside the directory is all the LLVM projects, each in its own directory. Most notably, the LLVM core libraries are in the llvm subdirectory. The LLVM project uses branches for subsequent release development ("release/12.x") and tags ("llvmorg-12.0.0") to mark a certain release. With the preceding clone command, you get the current development state. This book uses LLVM 12. To check out the first release of LLVM 12, type the following:

$ git checkout -b llvmorg-12.0.0

With this, you have cloned the whole repository and checked out a tag. This is the most flexible approach.

Git also allows you to clone only a branch or a tag (including history). With git clone --branch llvmorg-12.0.0 https://github.com/llvm/llvm-project, you check out the same label, as we did previously, but only the history for this tag is cloned. With the additional–-depth=1 option, you prevent the history from being cloned too. This saves time and space but obviously limits what you can do locally.

The next step is to create a build directory.

Creating a build directory

Unlike many other projects, LLVM does not support inline builds and requires a separate build directory. This can easily be created inside the llvm-project directory. Change into this directory with the following command:

$ cd llvm-project

Then, create a build directory called build for simplicity. Here, the commands for Unix and Windows systems differ. On Unix-likes system, you should use the following command:

$ mkdir build

On Windows, you should use the following command:

$ md build

Then, change into the build directory:

$ cd build

Now, you are ready to create the build system files with the CMake tool inside this directory.

Generating the build system files

To generate the build system files that will compile LLVM and Clang using Ninja, run the following command:

$ cmake –G Ninja -DLLVM_ENABLE_PROJECTS=clang ../llvm

Tip

On Windows, the backslash character, \, is the directory name separator. On Windows, CMake automatically translates the Unix separator, /, into the Windows one.

The -G option tells CMake which system to generate build files for. The most often used options are as follows:

  • Ninja: For the Ninja build system
  • Unix Makefiles: For GNU Make
  • Visual Studio 15 VS2017 and Visual Studio 16 VS2019: For Visual Studio and MS Build
  • Xcode: For XCode projects

The generation process can be influenced by setting various variables with the –D option. Usually, they are prefixed with CMAKE_ (if defined by CMake) or LLVM_ (if defined by LLVM). With the LLVM_ENABLE_PROJECTS=clang variable setting, CMake generates build files for Clang in addition to LLVM. The last part of the command tells CMake where to find the LLVM core library source. More on that in the next section.

Once the build files have been generated, LLVM and Clang can be compiled with the following command:

$ ninja

Depending on the hardware resources, this command takes between 15 minutes (a server with lots of CPU cores and memory and fast storage) and several hours (dual-core Windows notebook with limited memory) to run. By default, Ninja utilizes all available CPU cores. This is good for compilation speed but may prevent other tasks from running. For example, on a Windows-based notebook, it is almost impossible to surf the internet while Ninja is running. Fortunately, you can limit resource usage with the –j option.

Let's assume you have four CPU cores available and that Ninja should only use two (because you have parallel tasks to run). Here, you should use the following command for compilation:

$ ninja –j2

Once compilation is finished, a best practice is to run the test suite to check if everything works as expected:

$ ninja check-all

Again, the runtime of this command varies widely due to the available hardware resources. The Ninja check-all target runs all test cases. Targets are generated for each directory containing test cases. Using check-llvm, instead of check-all runs the LLVM tests but not the Clang tests; check-llvm-codegen only runs the tests in the CodeGen directory from LLVM (that is, the llvm/test/CodeGen directory).

You can also do a quick manual check. One of the LLVM applications you will be using is llc, the LLVM compiler. If you run it with the -version option, it shows the LLVM version of it, its host CPU, and all its supported architectures:

$ bin/llc -version

If you have trouble getting LLVM compiled, then you should consult the Common Problems section of the Getting Started with the LLVM System documentation (https://llvm.org/docs/GettingStarted.html#common-problems) for solutions to typical problems.

Finally, install the binaries:

$ ninja install

On a Unix-like system, the install directory is /usr/local. On Windows, C:\Program Files\LLVM is used. This can be changed, of course. The next section explains how.