seqc/codegen/mod.rs
1//! LLVM IR Code Generation
2//!
3//! This module generates LLVM IR as text (.ll files) for Seq programs.
4//! The code generation is split into focused submodules for maintainability.
5//!
6//! # Key Concepts
7//!
8//! ## Value Representation
9//!
10//! All Seq values use the `%Value` type, an 8-byte tagged pointer (i64).
11//! Int and Bool are encoded inline; heap types (Float, String, Variant, etc.)
12//! are stored as Arc<Value> pointers.
13//!
14//! ## Calling Conventions
15//!
16//! - **User-defined words**: Use `tailcc` (tail call convention) to enable TCO.
17//! Each word has two functions: a C-convention wrapper (`seq_word_*`) for
18//! external calls and a `tailcc` implementation (`seq_word_*_impl`) for
19//! internal calls that can use `musttail`.
20//!
21//! - **Runtime functions**: Use C convention (`ccc`). Declared in `runtime.rs`.
22//!
23//! - **Quotations**: Use C convention. Quotations are first-class functions that
24//! capture their environment. They have wrapper/impl pairs but currently don't
25//! support TCO due to closure complexity.
26//!
27//! ## Virtual Stack Optimization
28//!
29//! The top N values (default 4) are kept in SSA virtual registers instead of
30//! memory. This avoids store/load overhead for common patterns like `2 3 i.+`.
31//! Values are "spilled" to the memory stack at control flow points (if/else,
32//! loops) and function calls. See `virtual_stack.rs` and `VirtualValue` in
33//! `state.rs`.
34//!
35//! ## Tail Call Optimization (TCO)
36//!
37//! Word calls in tail position use LLVM's `musttail` for guaranteed TCO.
38//! A call is in tail position when it's the last operation before return.
39//! TCO is disabled in these contexts:
40//! - Inside `main` (uses C convention for entry point)
41//! - Inside quotations (closure semantics require stack frames)
42//! - Inside closures that capture variables
43//!
44//! ## Quotations and Closures
45//!
46//! Quotations (`[ ... ]`) compile to function pointers pushed onto the stack.
47//! - **Pure quotations**: No captured variables, just a function pointer.
48//! - **Closures**: Capture variables from enclosing scope. The runtime allocates
49//! a closure struct containing the function pointer and captured values.
50//!
51//! Each quotation generates a wrapper function (C convention, for `call` builtin)
52//! and an impl function. Closure captures are analyzed at compile time by
53//! `capture_analysis.rs`.
54//!
55//! # Module Structure
56//!
57//! - `state.rs`: Core types (CodeGen, VirtualValue, TailPosition)
58//! - `program.rs`: Main entry points (codegen_program*)
59//! - `words.rs`: Word and quotation code generation
60//! - `statements.rs`: Statement dispatch and main function
61//! - `inline/`: Inline operation code generation (no runtime calls)
62//! - `dispatch.rs`: Main inline dispatch logic
63//! - `ops.rs`: Individual inline operations
64//! - `shuffle.rs`: Stack shuffle + pick/roll helpers
65//! - `control_flow.rs`: If/else, match statements
66//! - `virtual_stack.rs`: Virtual register optimization
67//! - `types.rs`: Type helpers and exhaustiveness checking
68//! - `globals.rs`: String and symbol constants
69//! - `runtime/`: Runtime function declarations (split by category)
70//! - `specialization/`: Register-based specialization for primitive-typed words
71//! - `ffi_wrappers.rs`: FFI wrapper generation
72//! - `platform.rs`: Platform detection
73//! - `error.rs`: Error types
74//! - `tests.rs`: End-to-end codegen tests (pipeline-level)
75
76// Submodules
77mod control_flow;
78mod error;
79mod ffi_wrappers;
80mod globals;
81mod inline;
82mod layout;
83mod platform;
84mod program;
85mod runtime;
86mod specialization;
87mod state;
88mod statements;
89mod types;
90mod virtual_stack;
91mod words;
92
93// Public re-exports
94pub use error::CodeGenError;
95pub use platform::{ffi_c_args, ffi_return_type, get_target_triple};
96pub use runtime::{BUILTIN_SYMBOLS, RUNTIME_DECLARATIONS, emit_runtime_decls};
97pub use state::CodeGen;
98
99// Internal re-exports for submodules
100use state::{
101 BranchResult, MAX_VIRTUAL_STACK, QuotationFunctions, QuotationScope, TailPosition,
102 UNREACHABLE_PREDECESSOR, VirtualValue, mangle_name,
103};
104
105#[cfg(test)]
106mod tests;