一键导入
ir-pipeline
// IR and XIR compiler pipeline, AST translation, SSA-based IR, instruction set, optimization passes, and control flow representation in LuisaCompute
// IR and XIR compiler pipeline, AST translation, SSA-based IR, instruction set, optimization passes, and control flow representation in LuisaCompute
Backend plugin architecture, DeviceInterface API, dynamic loading, command encoding, and backend registration patterns in LuisaCompute
Comprehensive project structure and architecture reference for the LuisaCompute codebase
Rust workspace architecture, IR data structures, compiler transforms, CPU backend, FFI integration with C++, and crate dependencies in LuisaCompute
Manual AST construction API for building kernels and callables without DSL syntax sugar
| name | ir_pipeline |
| description | IR and XIR compiler pipeline, AST translation, SSA-based IR, instruction set, optimization passes, and control flow representation in LuisaCompute |
LuisaCompute has two intermediate representations:
| Aspect | IR (Legacy) | XIR (New/Preferred) |
|---|---|---|
| Location | src/ir/, include/luisa/ir/ | src/xir/, include/luisa/xir/ |
| Implementation | Rust-based (via src/rust/) | Pure C++ |
| JSON Serialization | ast2json → Rust IR | Native xir2json/json2xir |
| Status | Maintained for compatibility | Active development |
| SSA Form | Yes | Yes (with mem2reg pass) |
| Basic Blocks | Yes | Yes |
Both paths start from the same AST (src/ast/) and feed into backend codegen.
User C++ DSL / Python
│
▼
┌─────────────────┐
│ DSL Tracing │ src/dsl/ — captures C++ lambdas into AST
└────────┬────────┘
│
▼
┌─────────────────┐
│ AST │ src/ast/ — expression/statement tree
└────────┬────────┘
│
┌────┴────┐
▼ ▼
┌────────┐ ┌──────────┐
│ XIR │ │ IR │ src/xir/ (new) / src/ir/ (legacy)
│transl. │ │transl. │
└───┬────┘ └────┬─────┘
│ │
▼ ▼
┌─────────────────┐
│ Backend Codegen│ src/backends/<name>/
│ + Compilation │
└────────┬────────┘
│
▼
┌─────────────────┐
│ GPU Execution │ src/runtime/
└─────────────────┘
Rust IR path: src/rust/luisa_compute_ir/ performs additional transforms (autodiff, DCE, SSA, vectorize) before backend codegen.
XIR path: Pure C++ pipeline with ast2xir translator and XIR optimization passes.
File: src/ir/ast2ir.cpp
to_json(function) to serialize AST to JSONir::luisa_compute_ir_ast_json_to_ir_kernel() for kernelsir::luisa_compute_ir_ast_json_to_ir_callable() for callablesir::luisa_compute_ir_ast_json_to_ir_type() for typesAST Function → JSON String → Rust IR Module → CArc<KernelModule/CallableModule>
Key legacy IR classes (defined in Rust, used via C FFI):
ir::KernelModule / ir::CallableModuleir::Node — IR nodes (intrusive linked list)ir::Instruction — Local, Call, Phi, Loop, If, Switch, RayQuery, AdScope, etc.ir::Type — Type representationir::BasicBlock — Basic block structureFile: src/xir/translators/ast2xir.cpp
Direct C++ implementation using XIRBuilder API.
AST2XIRContext)| AST Expression | XIR Instruction |
|---|---|
UnaryExpr | ArithmeticOp (UNARY_MINUS, UNARY_BIT_NOT) |
BinaryExpr | ArithmeticOp (BINARY_ADD, etc.) |
MemberExpr | EXTRACT/SHUFFLE or GEP |
AccessExpr | GEP + LOAD |
LiteralExpr | Constant |
RefExpr | Variable lookup or SpecialRegister |
CallExpr | Various opcodes based on CallOp |
CastExpr | CastInst (STATIC_CAST, BITWISE_CAST) |
| AST Statement | XIR Control Flow |
|---|---|
IfStmt | IfInst + true/false/merge blocks |
SwitchStmt | SwitchInst + case/default/merge blocks |
ForStmt | LoopInst (prepare/body/update/merge) |
LoopStmt | SimpleLoopInst (do-while style) |
BreakStmt | BreakInst |
ContinueStmt | ContinueInst |
ReturnStmt | ReturnInst |
AutoDiffStmt | AutodiffScopeInst |
Value (base class)
├── GlobalValue (module-scoped)
│ ├── Function
│ │ ├── KernelFunction (entry point with block size)
│ │ ├── CallableFunction (user-defined functions)
│ │ └── ExternalFunction (external linkage)
│ ├── Constant (literal values)
│ ├── Undefined (placeholder for undef)
│ └── SpecialRegister (builtin variables)
│ ├── SPR_ThreadID, SPR_BlockID, SPR_DispatchID, etc.
├── FunctionScopeValue (function-scoped)
│ └── BasicBlock (container for instructions)
└── BlockScopeValue (block-scoped)
└── Instruction (computation)
├── TerminatorInstruction (control flow)
│ ├── BranchInst
│ ├── ConditionalBranchInst
│ ├── IfInst, SwitchInst, LoopInst, etc.
│ └── ReturnInst
└── Non-terminator instructions
include/luisa/xir/module.h)include/luisa/xir/function.h)ArgumentList — function parametersBasicBlockList — CFG nodesFunctionDefinition — for kernels/callables with body blockstraverse_basic_blocks(), traverse_instructions()include/luisa/xir/basic_block.h)InstructionList — sequential instructionsis_terminated(), terminator() — control flow queriestraverse_predecessors(), traverse_successors() — CFG navigationinclude/luisa/xir/instruction.h)DerivedInstruction<> templateis_terminator() — ends basic blockcontrol_flow_merge() — for structured control flowclone() — for pass transformationsinclude/luisa/xir/value.h, use.h)UseList tracking all usersreplace_all_uses_with() — for substitutionis_lvalue() — for memory operations (alloca, gep results)| Instruction | Purpose | Blocks |
|---|---|---|
IfInst | Conditional branch | true, false, merge |
SwitchInst | Multi-way branch | cases, default, merge |
LoopInst | For/while loops | prepare, body, update, merge |
SimpleLoopInst | Do-while loops | body, merge |
BranchInst | Unconditional jump | target |
ConditionalBranchInst | Branches on condition | true, false |
ReturnInst | Function return | — |
BreakInst / ContinueInst | Loop control | target |
UnreachableInst | Unreachable code | — |
| Instruction | Purpose |
|---|---|
AllocaInst | Stack allocation (LOCAL/SHARED) |
LoadInst | Read from memory |
StoreInst | Write to memory |
GEPInst | Get element pointer (indexing) |
| Instruction | Purpose |
|---|---|
PhiInst | Phi node for SSA (block, value) pairs |
ArithmeticOp)Unary: UNARY_MINUS, UNARY_BIT_NOT
Binary: BINARY_ADD, SUB, MUL, DIV, MOD, BIT_AND, BIT_OR, BIT_XOR, SHIFT_LEFT, SHIFT_RIGHT, ROTATE_LEFT, ROTATE_RIGHT, comparison ops
Math: ABS, MIN, MAX, CLAMP, SATURATE, LERP, SMOOTHSTEP, trigonometric, exponential, logarithmic
Vector/Matrix: DOT, CROSS, NORMALIZE, MATRIX_COMP_MUL, MATRIX_LINALG_MUL, MATRIX_DETERMINANT, MATRIX_TRANSPOSE, MATRIX_INVERSE
Aggregate: AGGREGATE, SHUFFLE, EXTRACT, INSERT
| Category | Operations |
|---|---|
ResourceQueryOp | Buffer/texture size, bindless queries, ray tracing queries |
ResourceReadOp | Buffer read, texture read, bindless read |
ResourceWriteOp | Buffer write, texture write, ray tracing updates |
AtomicOp)EXCHANGE, COMPARE_EXCHANGE, FETCH_ADD, FETCH_SUB, FETCH_AND, FETCH_OR, FETCH_XOR, FETCH_MIN, FETCH_MAX
ThreadGroupOp)Warp operations, block synchronization, shader execution reordering, raster quad derivatives
RayQueryLoopInst, RayQueryDispatchInst, RayQueryObjectReadInst, RayQueryObjectWriteInst, RayQueryPipelineInst
AutodiffScopeInst, AutodiffIntrinsicInst (requires_gradient, gradient, accumulate_gradient, backward, detach)
Location: src/xir/passes/
| Pass | File | Purpose |
|---|---|---|
| DCE | dce.cpp | Removes unused instructions, unreachable blocks, dead allocas; evaluates static branches |
| Mem2Reg | mem2reg.cpp | Promotes allocas to SSA registers using dominance tree and frontiers; inserts PHI nodes |
| Dominance Tree | dom_tree.cpp | Cooper et al. 2001 algorithm; computes immediate dominators and dominance frontiers |
| Early Return Elimination | early_return_elimination.cpp | Converts early returns to structured control flow |
| Pass | File | Purpose |
|---|---|---|
| Call Graph | call_graph.cpp | Call graph analysis |
| Pointer Usage | pointer_usage.cpp | Pointer usage analysis |
| Lexical Scope | lex_scope_analysis.cpp | Lexical scope analysis |
| Aggregate Field Bitmask | aggregate_field_bitmask.cpp | Aggregate field usage analysis |
| Pass | File | Purpose |
|---|---|---|
| SROA | sroa.cpp | Scalar replacement of aggregates |
| Outline | outline.cpp | Function outlining |
| Autodiff | autodiff.cpp | Autodiff transformations |
| Lower Ray Query | lower_ray_query_loop.cpp | Ray query lowering |
| Reg2Mem | reg2mem.cpp | Register to memory conversion |
| Promote Ref Arg | promote_ref_arg.cpp | Reference argument promotion |
| Transpose GEP | transpose_gep.cpp | Transpose GEP through loads/stores |
| Trace GEP | trace_gep.cpp | GEP analysis/tracing |
| Local Load Elimination | local_load_elimination.cpp | Redundant load elimination |
| Local Store Forward | local_store_forward.cpp | Store-to-load forwarding |
| Unused Callable Removal | unused_callable_removal.cpp | Dead function elimination |
XIR uses structured control flow with explicit merge blocks:
IfInst:
- condition: Value*
- true_block: BasicBlock*
- false_block: BasicBlock*
- merge_block: BasicBlock*
LoopInst:
- prepare_block: BasicBlock*
- body_block: BasicBlock*
- update_block: BasicBlock*
- merge_block: BasicBlock*
This design:
File: include/luisa/xir/metadata.h
Metadata types (DerivedMetadataTag):
NAME — Symbol namesLOCATION — Source file/line informationCOMMENT — Debug commentsCURVE_BASIS — Ray tracing curve basisApplied via MetadataListMixin to Values and Instructions.
ast2json for AST serializationluisa_compute_ir_ast_json_to_ir_*Files: src/xir/translators/xir2json.cpp, json2xir.cpp
Uses yyjson library for module serialization, cross-process communication, and debugging.
ManagedIntrusiveList for efficient node managementDerivedValue<>, DerivedInstruction<>, DerivedFunction<>traverse_basic_blocks(), traverse_instructions()XIRBuilder for instruction creationMetadataListMixin, ControlFlowMergeMixin, InstructionOpMixinUse objects track value users for SSAsrc/xir/passes/<name>.cppinclude/luisa/xir/passes/<name>.hsrc/xir/CMakeLists.txtModule & or Function &bool indicating whether changes were madeXIRBuilder for instruction insertionreplace_all_uses_with() for value substitution