This guide is the deep reference for the people who build, package, integrate, and extend the LLVM Project: distribution maintainers, toolchain engineers, release managers, CI operators, and contributors. Where the User Guide shows how to use the tools, this guide explains how the monorepo is architected, how to configure and produce a toolchain from it, and how its internals fit together.
It is written against the source tree at commit 53cbf88b6. Every build fact is
grounded in llvm/CMakeLists.txt and the repository layout.
Table of Contents
- Executive Summary
- Architecture Overview
- Repository Structure
- System Requirements
- Build Configuration Mastery
- Producing & Distributing a Toolchain
- Operations: Testing, CI, and Releases
- Security Analysis
- Internals & Module Reference
- Code Patterns & Conventions
- Testing Strategy
- Potential Improvements & Technical Debt
- Contributing
- Quick Reference
1. Executive Summary
The LLVM Project is a monorepo that produces a complete, modular compiler toolchain. It is one of the largest open-source codebases in existence — this checkout contains 176,510 files. Its defining architectural idea is a target-independent intermediate representation (LLVM IR) that decouples language frontends from optimizations and from machine-specific backends, so each layer can be reused independently.
What an administrator needs to know up front:
- There is no server to deploy. "Operating" LLVM means building it, testing it, packaging it, and shipping a toolchain to users. Your "configuration surface" is CMake.
- The repo is split into projects (built by the host compiler via
LLVM_ENABLE_PROJECTS) and runtimes (built by the freshly-built compiler viaLLVM_ENABLE_RUNTIMES). This split is the single most important concept for building correctly. - Builds are resource-intensive: a full debug build needs tens of GB of RAM
for linking and 100+ GB of disk. Production packaging almost always uses
multi-stage (bootstrap)
Releasebuilds. - The codebase is C++17 and uses CMake ≥ 3.20.0, Ninja, TableGen, and lit/FileCheck for tests.
| Property | Value |
|---|---|
| Repository | github.com/llvm/llvm-project |
| License | Apache-2.0 WITH LLVM-exception |
| Documented commit | 53cbf88b6 |
| Total files (this checkout) | 176,510 |
| Primary language | C++ (C++17) |
| Build system | CMake (≥ 3.20.0) + Ninja/Make + TableGen |
| Test infrastructure | lit + FileCheck + GoogleTest unit tests |
2. Architecture Overview
The three-phase compiler model
LLVM's architecture is the classic frontend → optimizer → backend pipeline, made reusable by a shared IR in the middle.
┌───────────────────────────────────────────────────────────────────────┐
│ THE LLVM PROJECT │
│ │
│ FRONTENDS MIDDLE-END BACKENDS │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Clang │──┐ │ │ │ 20 target codegen│ │
│ │ (C/C++/ │ │ │ LLVM IR │ │ AArch64, X86, │ │
│ │ ObjC) │ ├──IR──▶ │ + Pass │──IR──────▶│ RISCV, ARM, ... │ │
│ ├──────────┤ │ │ Manager │ │ │ │
│ │ Flang │──┤ │ (opt) │ │ → .o / .s │ │
│ │ (Fortran)│ │ │ │ └──────────────────┘ │
│ ├──────────┤ │ │ + Polly │ │ │
│ │ MLIR │──┘ │ (polyhedral)│ ▼ │
│ │ frontends│ └──────────────┘ ┌──────────────┐ │
│ └──────────┘ │ LLD │ │
│ │ (linker) │ │
│ └──────┬───────┘ │
│ ▼ │
│ RUNTIMES linked into the final program: executable / │
│ libc++, libc++abi, libunwind, compiler-rt, shared library │
│ OpenMP, libc, ... │
│ │
│ DIAGNOSTICS / DEBUG: LLDB (debugger), sanitizers (compiler-rt) │
└───────────────────────────────────────────────────────────────────────┘
The key consequence: a new language only needs a frontend that emits LLVM IR to inherit all optimizations and all 20 backends. A new CPU only needs a backend to be reachable from every frontend.
MLIR — the second IR
MLIR (Multi-Level Intermediate Representation) generalizes the idea of an IR. Where LLVM IR is a single, relatively low-level representation, MLIR is a framework for defining many coexisting IRs ("dialects") at different abstraction levels, with infrastructure to progressively lower between them — frequently ending at the LLVM IR dialect, which then feeds LLVM Core. MLIR is the foundation for modern ML compilers, Flang's lowering, and domain-specific compilers.
Library-first design
Every capability is exposed as a library first and a tool second. clang
the binary is a thin driver over libraries like clangFrontend, clangSema,
clangCodeGen; opt is a thin driver over the LLVM pass libraries. This is why
the ecosystem (clang-tidy, clangd, IDE integrations, custom compilers) can be
built without forking — they link the same libraries.
TableGen — the metacompiler
Large amounts of LLVM (instruction definitions, register files, intrinsics,
clang diagnostics and driver options, attributes) are described declaratively in
.td files and compiled by TableGen into C++ at build time. This is why
TableGen build performance matters (LLVM_OPTIMIZED_TABLEGEN) and why the actual
command-line option sets of clang/llc/opt live in TableGen and cl::opt
definitions rather than in plain argument-parsing code.
Note
Because options are defined via TableGen/
cl::opt, the authoritative, version-accurate flag list for each tool is obtained from the tool itself (<tool> --help) and from the generated docs atllvm.org/docs— not from a single hand-maintained file.
3. Repository Structure
Top-level directories correspond to the projects and runtimes:
| Path | Component | Role |
|---|---|---|
llvm/ |
LLVM Core | IR, optimizer, codegen, ~80 tools, the root CMakeLists.txt |
clang/ |
Clang | C/C++/ObjC frontend, driver, Static Analyzer |
clang-tools-extra/ |
Clang Tools Extra | clang-tidy, clangd, clang-doc, etc. |
lld/ |
LLD | ELF/COFF/Mach-O/wasm linker |
lldb/ |
LLDB | Debugger, lldb-dap, lldb-server |
mlir/ |
MLIR | Multi-level IR framework and dialects |
flang/ |
Flang | Fortran frontend |
flang-rt/ |
Flang runtime | Fortran runtime library |
bolt/ |
BOLT | Post-link binary optimizer |
polly/ |
Polly | Polyhedral loop optimizer |
libcxx/ |
libc++ | C++ standard library |
libcxxabi/ |
libc++abi | C++ ABI support |
libunwind/ |
libunwind | Stack unwinder |
compiler-rt/ |
compiler-rt | Builtins, profiling, sanitizers |
openmp/ |
OpenMP | OpenMP runtime |
offload/ |
offload | GPU/accelerator offload runtime |
libc/ |
libc | C standard library |
libclc/ |
libclc | OpenCL C library |
libsycl/ |
libsycl | SYCL support |
orc-rt/ |
orc-rt | ORC JIT runtime |
llvm-libgcc/ |
llvm-libgcc | libgcc-compatible runtime |
cross-project-tests/ |
cross-project-tests | Tests that span multiple components (e.g. debuginfo) |
cmake/ |
Shared CMake | Cross-project CMake modules |
utils/ |
Repo utilities | Bazel overlay, release scripts, shared helpers |
Important
The CMake entry point is
llvm/CMakeLists.txt, not the repo root. Allcmake -Sinvocations target thellvmsubdirectory; other components are pulled in throughLLVM_ENABLE_PROJECTS/LLVM_ENABLE_RUNTIMES.
Notable subtrees within llvm/
| Path | Contents |
|---|---|
llvm/lib/ |
The core libraries (IR, Analysis, Transforms, Target, CodeGen, MC, …) |
llvm/include/llvm/ |
Public headers |
llvm/tools/ |
~80 standalone tools (opt, llc, lli, llvm-*) |
llvm/utils/ |
Build/test tooling: lit, FileCheck, update_*_test_checks.py, TableGen helpers |
llvm/lib/Target/<Arch>/ |
Per-architecture backends |
llvm/test/ |
The lit-driven regression test suite |
4. System Requirements
| Requirement | Detail | Source |
|---|---|---|
| CMake | ≥ 3.20.0 |
cmake_minimum_required(VERSION 3.20.0) in llvm/CMakeLists.txt |
| C++ standard | C++17 (host compiler) | LLVM_REQUIRED_CXX_STANDARD = 17; configure aborts if forced lower |
| Generator | Ninja (recommended) or Unix Makefiles | Ninja yields the best incremental performance |
| Python | 3.x | Drives lit, FileCheck orchestration, and helper scripts |
| RAM | 16 GB minimum; 32–64 GB for full/debug builds | Linking is the memory bottleneck |
| Disk | 20 GB (Clang only) to 100+ GB (full debug) | Debug info dominates |
| Host toolchain | A recent GCC, Clang, or MSVC that supports C++17 | Bootstrap builds use a prior Clang |
Caution
The most common build failure on constrained machines is the linker running out of memory, not compilation. Plan link parallelism (
LLVM_PARALLEL_LINK_JOBS) against available RAM, and preferlldfor linking LLVM itself.
5. Build Configuration Mastery
CMake is the configuration interface for LLVM. This section is the complete, grounded reference for the options that matter most to packagers and integrators.
Component selection
| Option | Default | Meaning |
|---|---|---|
LLVM_ENABLE_PROJECTS |
"" |
Semicolon-separated projects, or "all" |
LLVM_ENABLE_RUNTIMES |
"" |
Semicolon-separated runtimes, or "all" |
LLVM_TARGETS_TO_BUILD |
"all" |
Backends to build; "host" for the current machine only |
LLVM_EXPERIMENTAL_TARGETS_TO_BUILD |
"" |
Add experimental backends |
Known projects ("all" = bolt;clang;clang-tools-extra;cross-project-tests;lld;lldb;mlir;polly),
plus extra projects flang, libc, compiler-rt.
Runtimes:
- Default set:
libcxx;libcxxabi;libunwind;libclc;compiler-rt;openmp - Supported set:
libc;libunwind;libcxxabi;libcxx;compiler-rt;openmp;llvm-libgcc;offload;flang-rt;libclc;libsycl;orc-rt
Warning
Three guardrails are enforced at configure time:
openmpas a project is removed — use it as a runtime (fatal error otherwise).- An unknown name in
LLVM_ENABLE_PROJECTSaborts with "isn't a known project".- An unsupported runtime aborts with "is not a supported runtime". Building
flangas a project additionally requiresmlir.
Targets
Stable (LLVM_ALL_TARGETS): AArch64, AMDGPU, ARM, AVR, BPF,
Hexagon, Lanai, LoongArch, Mips, MSP430, NVPTX, PowerPC, RISCV,
Sparc, SPIRV, SystemZ, VE, WebAssembly, X86, XCore.
Experimental (LLVM_ALL_EXPERIMENTAL_TARGETS): ARC, CSKY, DirectX,
M68k, Xtensa.
JIT-capable (LLVM_TARGETS_WITH_JIT): X86, PowerPC, AArch64, ARM,
Mips, SystemZ.
Build-type and correctness options
| Option | Default | Purpose |
|---|---|---|
CMAKE_BUILD_TYPE |
(none) | Release / Debug / RelWithDebInfo / MinSizeRel |
LLVM_ENABLE_ASSERTIONS |
ON (Debug) / OFF (Release) |
Internal invariant checks |
LLVM_ENABLE_PIC |
ON |
Position-independent code |
LLVM_ENABLE_PEDANTIC |
ON |
Compile LLVM with pedantic warnings |
LLVM_USE_SANITIZER |
"" |
Build LLVM itself under a sanitizer (e.g. Address, Undefined) |
LLVM_APPEND_VC_REV |
ON |
Embed the VCS revision into version strings |
Performance and packaging options
| Option | Default | Purpose |
|---|---|---|
LLVM_CCACHE_BUILD |
OFF |
Wrap compiles with ccache |
LLVM_OPTIMIZED_TABLEGEN |
OFF |
Build TableGen optimized even in Debug |
LLVM_ENABLE_LLD |
OFF |
Use lld to link LLVM itself |
LLVM_USE_LINKER |
(system) | Select linker by name (e.g. lld, gold) |
LLVM_PARALLEL_LINK_JOBS |
(unbounded) | Cap concurrent link jobs (RAM control) |
LLVM_PARALLEL_COMPILE_JOBS |
(unbounded) | Cap concurrent compile jobs |
BUILD_SHARED_LIBS |
OFF |
Build each component as a shared lib (dev convenience, not for distribution) |
LLVM_LINK_LLVM_DYLIB |
OFF |
Link tools against a single libLLVM dylib |
LLVM_BUILD_LLVM_DYLIB |
OFF |
Build the aggregate libLLVM shared library |
LLVM_BUILD_TESTS |
OFF |
Build unit tests |
LLVM_INCLUDE_TESTS |
ON |
Generate (but not necessarily build) test targets |
LLVM_BUILD_EXAMPLES |
OFF |
Build example programs |
LLVM_INCLUDE_BENCHMARKS |
ON |
Generate benchmark targets |
LLVM_ENABLE_SPHINX |
OFF |
Build HTML docs with Sphinx |
CMAKE_INSTALL_PREFIX |
(platform) | Install destination |
Tip
For redistribution, prefer static component libraries (
BUILD_SHARED_LIBS=OFF) and optionally a single aggregatelibLLVMviaLLVM_BUILD_LLVM_DYLIB=ON+LLVM_LINK_LLVM_DYLIB=ONto shrink tool binaries.BUILD_SHARED_LIBS=ONis a developer-iteration convenience, not a packaging mode.
Reference build recipes
Minimal C/C++ compiler (fast)
cmake -S llvm -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_TARGETS_TO_BUILD="host" \
-DCMAKE_INSTALL_PREFIX=/opt/llvm
ninja -C build install
Full self-hosting toolchain
cmake -S llvm -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;lld;clang-tools-extra" \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;compiler-rt" \
-DLLVM_TARGETS_TO_BUILD="all" \
-DLLVM_ENABLE_LLD=ON \
-DCMAKE_INSTALL_PREFIX=/opt/llvm
ninja -C build install
LLVM developer config
cmake -S llvm -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_TARGETS_TO_BUILD="host" \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DLLVM_OPTIMIZED_TABLEGEN=ON \
-DLLVM_CCACHE_BUILD=ON \
-DLLVM_USE_LINKER=lld \
-DLLVM_PARALLEL_LINK_JOBS=2
6. Producing & Distributing a Toolchain
Multi-stage (bootstrap) builds
Production toolchains are usually built in stages: a stage-1 compiler builds a stage-2 compiler (and often a stage-3 for verification). This produces a toolchain that compiles itself identically and benefits from Clang/LTO/PGO.
host compiler ──▶ stage-1 clang ──▶ stage-2 clang ──▶ (stage-3 verify)
(GCC/MSVC) (Release) (LTO/PGO) (bit-identical)
Tip
The repository ships a PGO bootstrap helper at
llvm/utils/collect_and_build_with_pgo.py. It runs an instrumented stage, collects profiles, and produces a final PGO-optimized build. Key flags:--llvm-dir,--out-dir,--cmake-extra-arg,--no-optimized-build,--use-make,--dry-run.
Installation layout
ninja install (or cmake --install build) populates CMAKE_INSTALL_PREFIX
with the standard bin/, lib/, include/, and share/ layout. llvm-config
in bin/ is how downstream consumers discover include/library/flag paths.
cmake --install build --prefix /opt/llvm
/opt/llvm/bin/llvm-config --version
/opt/llvm/bin/llvm-config --includedir --libdir
Packaging guidance
- Build
Releasewith assertions off for shipped toolchains; keep an assertions-on build for internal triage. - Use
LLVM_TARGETS_TO_BUILD="all"only if your users cross-compile; otherwise shiphostplus any targets you support to keep size down. - Strip or split debug info for the binaries you ship; the unstripped artifacts are enormous.
- The Bazel build overlay lives under
utils/bazel/for organizations that build LLVM with Bazel instead of CMake.
Note
The project also publishes official prebuilt binaries per release on GitHub. Most end users should consume those rather than building; build-from-source is for distributors, integrators, and developers.
7. Operations: Testing, CI, and Releases
Running the test suites
Each project exposes a check-<project> Ninja target that runs its lit suite.
ninja -C build check-llvm # LLVM Core regression tests
ninja -C build check-clang # Clang tests
ninja -C build check-lld # LLD tests
ninja -C build check-mlir # MLIR tests
ninja -C build check-all # Everything that is enabled
The lit + FileCheck model
LLVM's regression tests are lit test files containing RUN: lines that
invoke tools and pipe output into FileCheck, which verifies the output
against CHECK: patterns embedded in the same file. This is the dominant test
style across llvm/test/, clang/test/, etc.
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
; CHECK: ret i32 42
Tip
Regenerate the
CHECKlines of codegen/IR tests with thellvm/utils/update_*_test_checks.pyfamily (e.g.update_test_checks.py,update_llc_test_checks.py,update_cc_test_checks.py). Never hand-edit large auto-generated check blocks — re-run the updater.
Unit tests
In addition to lit tests, components ship GoogleTest unit tests under
*/unittests/. They are built when LLVM_BUILD_TESTS=ON and run via the same
check-* targets.
Continuous integration & developer hygiene
The repo carries CI configuration and a set of maintenance scripts under
llvm/utils/ and per-project ci/ folders, including:
| Script | Purpose |
|---|---|
llvm/utils/revert_checker.py |
Detect reverts around a commit range |
llvm/utils/check_ninja_deps.py |
Validate Ninja dependency correctness |
bolt/utils/nfc-check-setup.py |
Set up no-functional-change checks for BOLT |
clang-tools-extra/clang-tidy/add_new_check.py |
Scaffold a new clang-tidy check |
clang-tidy/rename_check.py |
Rename an existing clang-tidy check |
Release process
LLVM follows a time-based major-release cadence with release branches cut from
main, stabilized through release candidates, and shipped with prebuilt
binaries. LLVM_APPEND_VC_REV=ON embeds the source revision into version
strings so a binary can be traced back to a commit.
8. Security Analysis
LLVM is a compiler toolchain, so its security posture is different from a networked service. The relevant concerns are supply-chain integrity, the trust boundary of compiling untrusted input, and the security tooling LLVM itself provides.
Trust model
| Surface | Consideration |
|---|---|
| Compiling untrusted source | A compiler is a complex parser; malformed input can trigger crashes. Treat compilation of untrusted code as you would any untrusted parser — sandbox CI builders. |
| Untrusted IR/bitcode | opt, llc, lli consume IR directly; do not run untrusted bitcode through lli (it JITs/executes). |
| Build provenance | The project carries OpenSSF Scorecard and Best Practices badges (see README.md); releases are signed/published through the official channels. |
| Helper scripts | Numerous Python utilities under */utils/ shell out to tools; run them only on trusted inputs and paths. |
Security features LLVM provides to its users
- Sanitizers (compiler-rt): AddressSanitizer, ThreadSanitizer,
MemorySanitizer, UndefinedBehaviorSanitizer — runtime detectors enabled via
-fsanitize=. - Hardening flags in Clang (stack protectors, CFI, fortify) for producing hardened binaries.
- Clang Static Analyzer (
clang/lib/StaticAnalyzer/, driven byscan-build) for path-sensitive bug finding at build time. - clang-tidy
bugprone-*,cert-*, andsecurity-oriented checks.
Important
Do not execute
lli(the IR interpreter/JIT) on untrusted.ll/.bcfiles — it runs the code. Likewise, the*-fuzzertools and fuzzing engines build and execute generated inputs and must run only in sandboxed environments.
Caution
The fatal-error guardrails in the CMake configure step (unknown project/runtime, removed
openmpproject mode) are correctness checks, not security boundaries. Never feed attacker-controlled values into your CMake invocation.
9. Internals & Module Reference
This section summarizes the major components an integrator or contributor must understand. Depths reflect each component's role in the pipeline.
LLVM Core (llvm/)
The heart of the project. Important library areas under llvm/lib/:
| Area | Responsibility |
|---|---|
IR/ |
The in-memory LLVM IR (Module, Function, BasicBlock, Instruction, types, the cl::opt machinery) |
Analysis/ |
Analyses consumed by transforms (dominators, alias analysis, loop info, the ML-driven models under Analysis/models/) |
Transforms/ |
Optimization passes (Utils/, InstCombine, scalar, IPO, vectorization) |
Target/<Arch>/ |
Per-architecture backends (instruction selection, register allocation, emission) |
CodeGen/ |
Target-independent code generation framework |
MC/ |
Machine code layer: assembling, disassembling, object-file emission |
TableGen/ |
The TableGen language implementation that drives codegen of definitions |
DebugInfo/ |
DWARF/CodeView debug-info handling (incl. LogicalView/) |
Clang (clang/) & Clang Tools Extra (clang-tools-extra/)
clang/lib/— the frontend: lexer, parser,Sema(semantic analysis),CodeGen(IR emission),Driver(the command-line driver),Tooling/(LibTooling, the basis for standalone tools), andStaticAnalyzer/.clang-tools-extra/—clang-tidy(and its many check modules),clangd(the LSP server and its index),clang-doc,include-cleaner,clang-include-fixer,clang-move,clang-query,pp-trace.
LLD (lld/)
Per-format linker front-ends: ELF/, COFF/, MachO/, wasm/, with shared
infrastructure in Common/ and MinGW support in MinGW/.
LLDB (lldb/)
A large debugger with a plugin-based architecture: source/Core/,
source/Commands/ (the command interpreter), source/Plugins/ (process,
platform, language, and trace plugins), source/API/ + include/lldb/API/
(the public SB* C++/Python API), and tools/lldb-dap/ (the Debug Adapter
Protocol implementation for editors).
MLIR (mlir/)
Dialect-based IR framework: include/mlir/Dialect/* and lib/Dialect/* define
dialects (Affine, Arith, Linalg, Vector, SCF, GPU, SPIR-V, Tosa, SparseTensor,
Transform, …); lib/Transforms/ and the Transform dialect drive rewriting;
CAPI/Python bindings expose MLIR to other languages.
Runtimes
compiler-rt/ (builtins, profile, sanitizers), libcxx/ + libcxxabi/ +
libunwind/ (the C++ runtime stack), openmp/ and offload/ (parallel and
accelerator runtimes), libc/ (C library), flang-rt/ (Fortran runtime),
plus libclc/, libsycl/, orc-rt/, llvm-libgcc/.
Note
This checkout also contains some newer/incubating subtrees visible in the tool list (e.g. ClangIR
cir-*tools and a scalable-static-analysis tree). Their APIs may be less stable than the mature components above; verify behavior against the source for your specific revision before depending on them.
10. Code Patterns & Conventions
| Convention | Detail |
|---|---|
| Language | C++17; the build refuses a lower standard |
| License header | Every source file carries the Apache-2.0-WITH-LLVM-exception header and SPDX identifier |
| Coding style | The LLVM Coding Standards (RTTI via isa<>/dyn_cast<>, llvm:: ADT containers like SmallVector/StringRef, no exceptions/RTTI in core libs by default) |
| Declarative definitions | Instructions, intrinsics, diagnostics, and driver options are TableGen (.td) rather than hand-written |
| Error handling | llvm::Expected<T> / llvm::Error for recoverable errors (see e.g. LLDB's request handlers) instead of exceptions |
| Formatting | Enforced by clang-format; checks via the project's CI |
| Testing | lit + FileCheck for behavior, GoogleTest for units; check lines auto-generated by update_*_test_checks.py |
Tip
When adding a clang-tidy check, use
add_new_check.pyto scaffold the check, tests, and documentation consistently rather than copying an existing check by hand.
11. Testing Strategy
| Layer | Tooling | Location | Run with |
|---|---|---|---|
| Regression / behavior | lit + FileCheck |
*/test/ |
ninja check-<project> |
| Unit | GoogleTest | */unittests/ |
ninja check-<project> (with LLVM_BUILD_TESTS=ON) |
| Cross-component | lit |
cross-project-tests/ |
ninja check-cross-project |
| Performance | benchmarks, llvm-exegesis, llvm-mca |
*/benchmarks/, tools |
manual |
| External | llvm-test-suite (separate repo) |
external | manual |
Best practices for maintainers:
- Add a
lit/FileChecktest for every functional change; LLVM is strict about test coverage in review. - Use
llvm-reduceto minimize reproducers attached to bug reports. - For no-functional-change (NFC) refactors in BOLT, use the NFC check tooling
(
bolt/utils/nfc-check-setup.py).
Warning
Auto-generated
CHECKblocks must be regenerated with the matchingupdate_*_test_checks.pyscript, not edited by hand. Hand edits drift from the tool output and fail review.
12. Potential Improvements & Technical Debt
These are observations about consuming and operating the toolchain, framed for administrators and integrators. They are not defects in LLVM.
- Build resource ceiling. The default
LLVM_TARGETS_TO_BUILD="all"plus aDebugbuild is a frequent cause of OOM/disk-exhaustion on CI runners. Standardize onhosttargets +Release/RelWithDebInfoand explicitLLVM_PARALLEL_LINK_JOBSin shared CI to avoid flaky, resource-driven failures. - Project-vs-runtime confusion. The most common misconfiguration is putting
compiler-rt/libc/openmpinLLVM_ENABLE_PROJECTS. Encode the correct split in your build scripts and lint for it. - Per-tool flag drift across releases. Because options are TableGen/
cl::optgenerated, pin the LLVM version your downstream scripts target and validate flags against--helpin CI rather than assuming stability across majors. - Incubating subtrees. Newer trees (ClangIR
cir-*, scalable static analysis) appear in the tool set; if you ship them, document their stability caveats to your users explicitly. - Known upstream issue to watch: LLDB issue #206508 — a misleading error message when re-importing a command script. Cosmetic but user-facing; track for the fix.
13. Contributing
| Step | How |
|---|---|
| Read the guides | Contributing to LLVM and the LLVM Coding Standards |
| Build with assertions | -DLLVM_ENABLE_ASSERTIONS=ON to catch invariant violations early |
| Add tests | lit/FileCheck for behavior; regenerate checks with update_*_test_checks.py |
| Format | Run clang-format on your diff before submitting |
| Submit | Open a pull request on the GitHub repository; respond to review |
| Communicate | LLVM Discourse, Discord, office hours |
| Conduct | The project enforces a Code of Conduct |
Tip
New backend or pass work should start from the existing
Target/andTransforms/patterns and TableGen definitions — the codebase is highly pattern-consistent, and matching existing structure speeds up review.
14. Quick Reference
Configure entry point
cmake -S llvm -B build -G Ninja [options] # NOTE: -S llvm, not the repo root
ninja -C build [target]
ninja -C build install
Component lists
- Projects (
all):bolt,clang,clang-tools-extra,cross-project-tests,lld,lldb,mlir,polly(+flang,libc,compiler-rt) - Runtimes (default):
libcxx,libcxxabi,libunwind,libclc,compiler-rt,openmp - Runtimes (supported):
libc,libunwind,libcxxabi,libcxx,compiler-rt,openmp,llvm-libgcc,offload,flang-rt,libclc,libsycl,orc-rt
Targets
- Stable:
AArch64,AMDGPU,ARM,AVR,BPF,Hexagon,Lanai,LoongArch,Mips,MSP430,NVPTX,PowerPC,RISCV,Sparc,SPIRV,SystemZ,VE,WebAssembly,X86,XCore - Experimental:
ARC,CSKY,DirectX,M68k,Xtensa - JIT:
X86,PowerPC,AArch64,ARM,Mips,SystemZ
Most-used CMake options
| Option | Default |
|---|---|
CMAKE_BUILD_TYPE |
(none) |
LLVM_ENABLE_PROJECTS |
"" |
LLVM_ENABLE_RUNTIMES |
"" |
LLVM_TARGETS_TO_BUILD |
"all" |
LLVM_ENABLE_ASSERTIONS |
ON (Debug) / OFF (Release) |
LLVM_CCACHE_BUILD |
OFF |
LLVM_OPTIMIZED_TABLEGEN |
OFF |
LLVM_USE_LINKER |
(system) |
LLVM_PARALLEL_LINK_JOBS |
(unbounded) |
BUILD_SHARED_LIBS |
OFF |
CMAKE_INSTALL_PREFIX |
(platform) |
Test targets
ninja -C build check-llvm # core
ninja -C build check-clang # clang
ninja -C build check-all # everything enabled
Documentation
| Resource | URL |
|---|---|
| Getting Started / Building | https://llvm.org/docs/GettingStarted.html |
| Contributing | https://llvm.org/docs/Contributing.html |
| Clang | https://clang.llvm.org |
| LLD | https://lld.llvm.org |
| libc++ | https://libcxx.llvm.org |
| Forums | https://discourse.llvm.org |