The book is for compiler programmers who are familiar with concepts of compilers and want to indulge in understanding, exploring, and using LLVM infrastructure in a meaningful way in their work. This book is also for programmers who are not directly involved in compiler projects but are often involved in development phases where they write thousands of lines of code. With knowledge of how compilers work, they will be able to code in an optimal way and improve performance with clean code.
AI Reading Assistant
Whole-book reading guide from stratified index samples; jump to passages in the text
Tip the Site
Support this siteYour recognition and a small knowledge-service contribution help keep this technical work open source.Scan the WeChat Pay or Alipay code below. Logged-in and guest visitors can both tip.
WeChat Pay
Alipay
Open WeChat or Alipay and scan. No login required.
AI guide
【One-Line Pitch】
A practical, recipe-driven guide for compiler programmers and performance-minded developers who want to master LLVM's infrastructure—from IR generation and optimization passes to backend code generation—by building a working compiler step by step.
【Book Arc】
- **Opening (~0%–10%)**: Introduces LLVM's modular architecture and core toolchain. Readers learn to generate IR from C code using Clang, compile IR to assembly with llc, and link bitcode files with llvm-link—establishing the fundamental workflow.
- **Early (~10%–23%)**: Builds a complete TOY language frontend. This section walks through lexer/parser design, AST class hierarchies, and the grammar rules needed to handle expressions, function declarations, and calls—giving readers a hands-on compiler construction experience.
- **Early–Middle (~23%–39%)**: Focuses on IR code generation and optimization integration. Readers implement Codegen() methods for expressions and functions, then add optimization passes like instruction combining and GVN through the PassManager—showing how to improve generated code quality.
- **Middle (~39%–48%)**: Extends the TOY language with control flow (if/then/else, loops) and user-defined operators (binary/unary). This section also introduces JIT support and transitions into LLVM's optimization framework, covering pass writing, registration, and analysis passes.
- **Late (~48%–end)**: Covers backend development and practical applications. Excerpts show instruction selection, encoding, frame lowering, and subtarget support, plus real-world uses like exception handling and sanitizers—completing the journey from frontend to production-ready compiler features.
【Key Takeaways】
- **LLVM's modular design is its superpower** (Opening): The toolchain separates frontend (Clang), optimizer (opt), and backend (llc), allowing each stage to be used independently or combined. This means you can plug in custom components at any level.
- **IR is the universal intermediate representation** (Early): LLVM IR sits between source and assembly, in SSA form where each variable assignment creates a new variable. Understanding IR is essential because all optimizations and backend work operate on this representation.
- **Building a lexer/parser is systematic** (Early): The TOY language example shows a clear pattern: define token types, write recursive descent parsers for each grammar rule, and build AST nodes. This structure scales from simple expressions to full function definitions.
- **Code generation follows AST structure** (Early–Middle): Each AST node gets a Codegen() method that emits LLVM IR using the Builder API. The pattern is consistent—generate code for children, combine results, and return a Value*—making it easy to extend with new language features.
- **Optimization passes are composable** (Middle): LLVM provides a rich set of passes (instruction combining, reassociation, GVN) that can be chained in a FunctionPassManager. You control which passes run and their order, giving you fine-grained control over code quality.
- **Control flow requires basic block management** (Middle): Implementing if/then/else and loops involves creating BasicBlocks, setting insert points, and using conditional branches. This teaches the fundamental pattern for all control flow in LLVM IR.
- **Backend development is a multi-step process** (Late): From instruction selection to encoding and frame lowering, each backend component has a specific role. The recipe format makes it approachable, showing how to add a new target or extend an existing one.
【Reading Tips】
- **Skim the toolchain chapters (Opening)**: If you're already familiar with Clang and llc, quickly review the command examples and focus on the llvm-link workflow, which is less commonly covered elsewhere.
- **Deep-read the TOY language chapters (Early)**: This is the heart of the book. Follow along with the code—type out the AST classes and parser functions yourself. The pattern of "define grammar → build AST → generate IR" will stick better through hands-on practice.
- **Pay attention to Codegen() patterns (Middle)**: The way each AST node emits IR is the key transferable skill. Notice how the Builder tracks the current insert point and how values flow between expressions.
- **Use the optimization chapters as reference (Middle)**: You don't need to memorize every pass. Instead, understand the pass manager architecture and how to write a custom pass—then look up specific passes when you need them.
- **Treat backend chapters as advanced material (Late)**: These recipes are valuable but assume solid LLVM knowledge. Skim initially to understand the scope, then return when you're ready to work on a specific backend component.
【Coverage Limits】
The excerpts cover the frontend (TOY language), IR generation, optimization passes, and early backend topics well, but do not fully detail JIT implementation, exception handling internals, or sanitizer usage—these sections appear in the table of contents but lack substantive content in the available material.
Page 11
ects Introduction Exception handling in LLVM Getting ready... How to do it… How it works… See also Using sanitizers Getting ready How to do it… How it works…...
f the function definition. This is demonstrated as follows: Function* FunctionDefnAST::Codegen() { Named_Values.clear(); Function *TheFunction = Func_Dec...
evel, running once for each function in the program. Hence, we have inherited the FunctionPass function when declaring the CountOpcodes : public FunctionPass...
types, or by truncating larger data types into smaller ones. For example, suppose that a type of target architecture supports only i32 data types. In that ca...
SelectionDAG (DAG stands for Directed Acyclic Graph). Then SelectionDAG legalization occurs where illegal instructions are mapped on the legal operations per...
Support this siteYour recognition and a small knowledge-service contribution help keep this technical work open source.
Scan the WeChat Pay or Alipay code below. Logged-in and guest visitors can both tip.
WeChat PayAlipay
Open WeChat or Alipay and scan. No login required.
Loading comments...
Reply to Comment
Edit Comment