LLVM Backend
Relevant source files
The following files were used as context for generating this wiki page:
The LLVM Backend is a critical component of the Pop Lang compiler responsible for native machine-code generation. It consumes verified, backend-neutral Mid-level Intermediate Representation (MIR) and lowers it into LLVM-specific IR to produce high-performance native executables and libraries. Within the broader Compiler Architecture, the LLVM backend operates at the end of the semantic pipeline, strictly isolated from front-end concerns like parsing or type inference.
The backend is designed to support Pop Lang's primary goal of providing predictable native runtimes. It achieves this by implementing the versioned Pop Lang Runtime Interface (PLRI) for managed memory operations, such as garbage collection (GC) and stack mapping, while ensuring semantic equivalence with other execution strategies like the MIR interpreter.
Sources: architecture/11-compiler-component-architecture.md, README.md, AGENTS.md
Architectural Integration and Isolation
The LLVM backend is strictly decoupled from the front-end and mid-end stages of the compiler. It consumes a frozen, verified MIR that contains no LLVM-specific opcodes or layouts. This isolation ensures that the core language semantics remain portable across different backends.
The diagram above illustrates how the LLVM Backend consumes MIR and interacts with the Runtime Interface without reaching back into earlier compiler stages.
Sources: architecture/11-compiler-component-architecture.md:1-20, AGENTS.md
Crate Boundaries and Dependencies
The LLVM backend is implemented in Rust (edition 2024) within the pop-backend-llvm crate. To maintain architectural integrity, several rules govern its dependencies:
- Inkwell Dependency: The backend uses Inkwell (v0.9) as a safe wrapper for LLVM. This is the only approved external dependency allowed for this component.
- No Leakage: Inkwell and
llvm-systypes are forbidden from crossing the backend crate boundary into portable compiler layers like HIR or MIR. - Targeting: It is configured with only reviewed native and BPF targets enabled to prevent bloat and maintain security.
Sources: architecture/decisions/0018-rust-workspace-and-crate-boundaries.md, architecture/11-compiler-component-architecture.md:22-60
Lowering and Native Execution
The lowering process transforms MIR control-flow graphs into LLVM instructions. A key requirement is that the LLVM backend must not "rediscover" language semantics; all necessary decisions must be encoded in the MIR or PLRI operations.
Key Lowering Components
| Component | Responsibility |
|---|---|
| Control Flow | Translating MIR basic blocks into LLVM basic blocks and branches. |
| Data Layout | Mapping Pop Lang types (e.g., Int64, Float64) to LLVM primitives. |
| Function Calls | Implementing physical calling conventions and symbol mangling. |
| Generics | Executing cross-Bubble generic specialized capsules without erased fallbacks. |
Sources: architecture/11-compiler-component-architecture.md:120-130, ROADMAP.md:30-50
Native ABI and PLRI
The backend interacts with the Pop Lang Runtime through the Native ABI (v1.x for bootstrap, v2.0 for production).
- ABI 1.x: Uses stable roots where native nursery relocation is not supported.
- ABI 2.0: Supports writable roots and mandatory post-call LLVM reload aliases, enabling a relocating nursery for higher performance.
- Safe Points: The backend must emit safe points to allow the concurrent generational GC to synchronize with the mutator.
Sources: ROADMAP.md:165-185, architecture/08.1-closed-design-questions.md:250-270
Verification and Conformance
To ensure semantic consistency, the LLVM backend is subject to rigorous verification gates. "Backend Drift"—where LLVM execution diverges from the MIR interpreter or VM—is treated as a critical bug.
Verification Workflow
The sequence shows the multi-stage verification required before machine code generation.
Sources: architecture/19-architecture-conformance-and-regression-policy.md:50-70, architecture/11-compiler-component-architecture.md:155-170
Performance and Optimization
The backend provides several optimization guarantees:
- Monomorphization: Generics are specialized at the call site to avoid runtime type erasure.
- Inlining: Aggressive inlining of small block consumers (e.g., closures) to provide zero-cost abstractions.
- Barrier Elision: The backend performs verified barrier elision for managed reference stores when immutability can be proven.
Sources: assets/pop_dsl_blocks_design_prompt.md:280-320, ROADMAP.md:200-220
Summary
The LLVM Backend is the high-performance native engine of the Pop Lang toolchain. By strictly adhering to backend-neutral IRs and versioned runtime contracts, it provides a stable and efficient path from Pop source to machine code. Its integration with the PLRI ensures that sophisticated features like precise concurrent garbage collection and structured task concurrency are executed correctly across all supported architectures.
Sources: architecture/11-compiler-component-architecture.md, ROADMAP.md