4.8 KiB
001 — Architecture
- Status: Draft
- Normative language:
MUST,MUST NOT,SHOULD,SHOULD NOT, andMAYare to be interpreted as described in RFC 2119.
1. Overview
libVCT is decomposed into modules with explicit responsibilities and boundaries. This file defines the module map, the data flow between stages, the three public interfaces, and the boundaries that carry the design's weight.
2. Modules
| Module | Responsibility | Allocation | Visibility |
|---|---|---|---|
vct.ir.hir |
HIR AST node types, the trait attachment point, builder/emitter API | arena | public |
vct.ir.vir |
VIR SSA/CFG types, VIR type system, instruction set | arena | internal |
vct.traits |
Attribute / Request / Relationship definitions and queries | arena | public |
vct.comptime |
Comptime evaluator / constant-folding engine | arena | internal |
vct.hir.opt |
HIR pass framework and passes, parallel cascade | arena | internal |
vct.lower |
HIR → VIR lowering and SSA construction | arena | internal |
vct.vir.opt |
VIR pass framework and heavy passes | arena | internal |
vct.backend.c |
VIR → C17 emitter (out-of-SSA, compiler-friendly C) | arena + GC | public entry |
vct.backend.llvm |
VIR → textual LLVM IR emitter | arena + GC | public entry |
vct.driver |
C compiler invocation, flag assembly, .o emission, LTO, cosmopolitan |
GC | public |
vct.cli |
Thin command-line wrapper | GC | public |
vct.diag |
Diagnostics, source maps, error reporting | GC | public |
vct.context |
Context and arena ownership, Config |
GC + arena | public |
vct.test.hirbuild |
Fluent HIR test-builder harness | arena | public |
3. Data flow
The default pipeline is:
frontend --build--> HIR
--hir.opt (parallel, cascading)--> annotated HIR
--lower--> VIR (SSA/CFG)
--vir.opt--> optimized VIR
--backend.c--> C17 source --driver--> .o (default path)
optimized VIR --backend.llvm--> textual LLVM IR (caller links LLVM)
Each stage consumes the previous stage's output and is specified independently: 003 — HIR, 004 — HIR Optimizer, 005 — Lowering, 006 — VIR, 007 — VIR Optimizer, 008 — C Backend, and 009 — LLVM Backend.
4. Public interfaces
libVCT exposes exactly three interfaces to embedders:
- HIR builder (frontend-facing). Construct nodes, set types and values, attach
frontend-supplied traits (such as
is_staticand optimization hints), and finish a module. See 003 — HIR. - Trait query (VIR-facing). Read attributes and walk relationships. This is the only channel through which VIR obtains facts. See 002 — Traits.
- Backend (driver-facing). Consume optimized VIR and emit C or textual LLVM IR. See 008 — C Backend and 009 — LLVM Backend.
The native D API is the full-feature surface. A thin extern(C) C API (opaque handles for
Context/Module/Builder/Config) is the primary v1 public surface and is a shim over the D
API; no logic lives in the shim. See 013 — Build & Packaging.
5. Load-bearing boundaries
vct.traitsis the contract. Both HIR and VIR depend on it. VIR depends on nothing else from HIR except node identity. A change to the trait vocabulary is a cross-cutting change and is versioned accordingly (see 013 — Build & Packaging).vct.loweris the SSA construction site. Phi-nodes, dominance, and the memory model all land there; it is the most algorithmically dense module. Its correctness invariants are specified in 005 — Lowering and 006 — VIR.
6. Memory and ownership model
- A
Contextowns one or more arenas. An arena is the unit of reclamation; the default is one arena perModule, freed wholesale. - All IR and optimizer objects are arena-owned and non-GC. Passes mutate in place under epoch guards (see 002 — Traits).
- GC is permitted only on cold paths: the driver, diagnostics, and CLI.
- The arena interface is exposed so embedders can supply their own backing memory; a default bump allocator ships in-tree.
Full lifecycle, ownership, and threading rules are specified in 013 — Build & Packaging.
7. Threading
libVCT is thread-safe when each compilation unit has its own Context and arenas. There is no
shared mutable global state. Intra-module parallelism is internal and bounded by the -j setting.
The determinism guarantee in 000 — Overview applies regardless of thread count.