Skip to content

LLVM

Build LLVM Toolchain from Source

Generate build files.

cmake -S llvm -B build -G 'Unix Makefiles' -DLLVM_ENABLE_PROJECTS='clang;lld' -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_LINKER=gold

Compile:

cmake --build ./build --parallel $(nproc)

(Optional) Build MLIR Support

Following the official document, add mlir into LLVM_ENABLE_PROJECTS options.

Error When Building Old Version's LLVM

When building LLVM versioned lower than 11, compilers may complain about ‘numeric_limits’ is not a member of ‘std’ when compiling llvm/utils/benchmark/src/benchmark_register.

To fix it, add <limits> header to llvm/utils/benchmark/src/benchmark_register.h:

#ifndef BENCHMARK_REGISTER_H
#define BENCHMARK_REGISTER_H

+#include <limits>
#include <vector>

#include "check.h"

Reference: [nfc] Fix missing include

Clang Cannot Find C++ Std Library

The root cause is that gcc-12 was included in ubuntu 22.04 and created some mess with clang, according to this post.

To solve the issue:

sudo apt install g++-12

Add LLVM APT Source

Add LLVM key ring

wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -

gold Internal Error at Descriptors

Once I built llvm-project on a server with 192 cores, gold complains about ambiguous error prompt:

/usr/bin/ld.gold: internal error in open, at ../../gold/descriptors.cc:99
collect2: error: ld returned 1 exit status

It turns out that the process runs out of the maximum file descriptors. Check the maximum file descriptors:

$ ulimit -n
1024
Set to a larger value:

ulimit -n <larger value>

Alias Analysis

LLVM provides an alias(...) method to determine if two pointers are alias to each other.

Custom Alias Analysis in LLVM

Keep Value Names

LLVM provides an option -fno-discard-value-names to not drop variable names.

Debug Info

LLVM's debug info identify each specific type with tags. For example:

  • DW_TAG_compile_unit: Represents the compilation unit.
  • DW_TAG_subprogram: Represents a function or method.
  • DW_TAG_variable: Represents a variable.
  • DW_TAG_structure_type: Represents a structure.
  • DW_TAG_class_type: Represents a class.
  • DW_TAG_member: Represents a member of a class, structure, or union.

Full definitation can be found here, inside HANDLE_DW_TAG.

LLVM uses several intrinsic functions (name prefixed with “llvm.dbg”) to track source local variables through optimization and code generation.

  • @llvm.dbg.declare
  • @llvm.dbg.value
  • @llvm.dbg.assign
  • @llvm.dbg.label

References

LLVM-Tutor

A collection of out-of-tree LLVM passes for teaching and learning

Mapping High Level Constructs to LLVM IR

Source Level Debugging with LLVM

MLIR

MLIR For Beginners

Compilers and IRs: LLVM IR, SPIR-V, and MLIR

VAST

Prepare Necessary Dependencies

$ sudo apt install build-essential cmake ninja-build libstdc++-12-dev llvm-17 libmlir-17 libmlir-17-dev mlir-17-tools libclang-17-dev libpolly-17-dev libzstd-dev

Note that the two extra dependencies are required: libpolly-17-dev and libzstd-dev.

Generate Build Config

Generate building config. According to README, use clang and clang++ as the compiler.

$ cmake --preset ninja-multi-default \
    --toolchain ./cmake/lld.toolchain.cmake \
    -DCMAKE_PREFIX_PATH=/usr/lib/llvm-17/ \
    -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

Build

$ cmake --build --preset ninja-rel