ast
無料Manual AST construction with FunctionBuilder for kernels and callables without DSL sugar.
日本語の概要は準備中です。原文の説明を表示しています。
Legacy IR and XIR compiler pipeline, AST lowering, SSA IR, and optimization passes.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Two IRs, both starting from AST (src/ast/), feeding into backend codegen:
| IR (Legacy) | XIR (Preferred) | |
|---|---|---|
| Location | src/ir/, include/luisa/ir/ | src/xir/, include/luisa/xir/ |
| Impl | Rust (src/rust/) | Pure C++ |
| Serialization | ast2json → Rust IR | xir2json/json2xir (yyjson) |
| SSA | Yes | Yes (mem2reg) |
| Status | Maintained (compat) | Active development |
| Basic Blocks | Yes | Yes |
DSL Tracing (src/dsl/) → AST (src/ast/)
│
┌─────────┴─────────┐
▼ ▼
XIR (ast2xir) IR (ast2ir → JSON → Rust FFI)
│ │
└─────────┬─────────┘
▼
Backend Codegen (src/backends/<name>/)
│
▼
GPU Execution (src/runtime/)
Rust IR path: src/rust/luisa_compute_ir/ does autodiff, DCE, SSA, vectorize.
XIR path: Pure C++ with ast2xir translator, xir2ast round-trip, and optimization passes.
File: src/ir/ast2ir.cpp
AST Function → to_json() → JSON string → Rust FFI → CArc<KernelModule/CallableModule>
FFI: luisa_compute_ir_ast_json_to_ir_kernel(), ..._callable(), ..._type().
Key IR classes (Rust, via C FFI): KernelModule, CallableModule, Node, Instruction (Local, Call, Phi, Loop, If, Switch, RayQuery, AdScope), Type, BasicBlock.
Files: src/xir/translators/ast2xir.cpp, xir2ast.cpp. AST2XIRContext maps AST variables to XIR Values, tracks break/continue targets, handles autodiff adjoints, caches constants.
| AST | XIR |
|---|---|
UnaryExpr | ArithmeticOp (UNARY_MINUS, UNARY_BIT_NOT); +x is elided |
BinaryExpr | ArithmeticOp (BINARY_ADD, etc.); matrix-aware; logic ops cast to bool |
MemberExpr | EXTRACT/SHUFFLE or GEP |
AccessExpr | GEP + LOAD |
LiteralExpr | Constant |
ConstantExpr | Constant |
RefExpr | Variable lookup or SpecialRegister |
CallExpr | CallInst, ArithmeticOp, AtomicOp, Resource*Op, ThreadGroupOp, RayQuery*Op, Assert/Assume/Unreachable/RasterDiscard |
CastExpr | CastInst (STATIC_CAST, BITWISE_CAST) |
TypeIdExpr/StringIdExpr/FuncRefExpr | Not implemented |
| AST | XIR |
|---|---|
IfStmt | IfInst + true/false/merge |
SwitchStmt | SwitchInst + case/default/merge |
ForStmt | LoopInst (prepare/body/update/merge) |
LoopStmt | SimpleLoopInst (do-while) |
BreakStmt | BreakInst |
ContinueStmt | ContinueInst |
ReturnStmt | ReturnInst |
AssignStmt | StoreInst |
ExprStmt | Expression (terminator-aware, e.g. Unreachable) |
AutoDiffStmt | AutodiffScopeInst |
RayQueryStmt | RayQueryLoopInst + RayQueryDispatchInst |
PrintStmt | PrintInst |
DebugBreakStmt | DebugBreakInst |
CommentStmt | Collected as comment metadata on following instruction |
Value
├── GlobalValue
│ ├── Function → FunctionDefinition → KernelFunction (entry+block size), CallableFunction, ExternalFunction
│ ├── Constant (literals)
│ ├── Undefined
│ └── SpecialRegister (SPR_ThreadID, SPR_BlockID, SPR_DispatchID, SPR_WarpLaneID, SPR_KernelID, SPR_BlockSize, SPR_WarpSize, SPR_DispatchSize, SPR_ObjectID, SPR_Barycentrics, ...)
├── FunctionScopeValue
│ ├── BasicBlock (instruction container)
│ └── Argument → ValueArgument / ReferenceArgument / ResourceArgument
└── BlockScopeValue → Instruction
├── TerminatorInstruction: BranchInst, ConditionalBranchInst, IfInst, SwitchInst,
│ LoopInst, SimpleLoopInst, ReturnInst, BreakInst, ContinueInst, UnreachableInst, RasterDiscardInst
└── Non-terminator instructions
include/luisa/xir/module.h): container for globals, unique constants via hashinclude/luisa/xir/function.h): ArgumentList, BasicBlockList, body_block(), traversal orders (PRE_ORDER, POST_ORDER, ...). Traversal: traverse_basic_blocks(), traverse_instructions()include/luisa/xir/argument.h): ValueArgument, ReferenceArgument, ResourceArgumentinclude/luisa/xir/basic_block.h): InstructionList, is_terminated(), terminator(), traverse_predecessors(), traverse_successors()include/luisa/xir/instruction.h): DerivedInstruction<>, is_terminator(), control_flow_merge(), clone(), intrinsic_identifier()include/luisa/xir/value.h, use.h): SSA UseList, replace_all_uses_with(), is_lvalue() for alloca/gep/reference args| Instruction | Blocks |
|---|---|
IfInst | true, false, merge |
SwitchInst | cases, default, merge |
LoopInst | prepare, body, update, merge |
SimpleLoopInst | body, merge |
BranchInst | target |
ConditionalBranchInst | true, false |
ReturnInst | — |
BreakInst / ContinueInst | target (lowered before codegen) |
UnreachableInst | — |
AllocaInst (LOCAL/SHARED), LoadInst, StoreInst, GEPInst
PhiInst — (block, value) pairs
CallInst (user/external functions), CastInst (STATIC_CAST, BITWISE_CAST)
ArithmeticOp)ResourceQueryOp, ResourceReadOp, ResourceWriteOp — buffer/texture/bindless ops, ray-tracing queries, indirect dispatch, device-address loads/stores
AtomicOp)EXCHANGE, COMPARE_EXCHANGE, FETCH_ADD/SUB/AND/OR/XOR/MIN/MAX
ThreadGroupOp (warp, sync, SER, quad derivatives), RayQueryLoopInst, RayQueryDispatchInst, RayQueryObjectReadInst, RayQueryObjectWriteInst, RayQueryPipelineInst, AutodiffScopeInst, AutodiffIntrinsicInst (requires_gradient, gradient, gradient_marker, accumulate_gradient, backward, detach)
PrintInst, ClockInst, DebugBreakInst, AssertInst, AssumeInst, OutlineInst, RasterDiscardInst
Location: src/xir/passes/ (headers in include/luisa/xir/passes/)
| Pass | File | Purpose |
|---|---|---|
| DCE | dce.cpp | Dead instructions, unreachable blocks, dead allocas, static branch eval |
| Mem2Reg | mem2reg.cpp | Alloca→SSA via dominance tree/frontiers, PHI insertion |
| Dominance Tree | dom_tree.cpp | Immediate dominators + frontiers |
| Post-Dominance Tree | post_dom_tree.cpp | Post-dominance analysis |
| Early Return Elim | early_return_elimination.cpp | Early returns → structured control flow |
| Lower Break/Continue | lower_break_continue.cpp | Lower break/continue to explicit branches |
| Lower Ray Query Loop | lower_ray_query_loop.cpp | Ray query loop lowering |
| Lower Ray Query Loop → Loop | lower_ray_query_loop_to_loop.cpp | Convert ray query loops to plain loops |
| Destructure CFG | destructure_cfg.cpp | Flatten structured CFG to basic branches |
| Restructure CFG | restructure_cfg.cpp | Recover structured control flow |
| Outline | outline.cpp | Function outlining |
| Phi Cleanup | phi_cleanup.cpp | Remove trivial/duplicate PHI nodes |
| Fix Self-Referential | fix_self_referential.cpp | Break self-referential PHI/value cycles |
| If Conversion | if_conversion.cpp | Convert simple diamonds to select/min/max |
| Pass | File | Purpose |
|---|---|---|
| Call Graph | call_graph.cpp | Call-graph construction |
| Pointer Usage | pointer_usage.cpp | Per-field kill/touch/live analysis for pointers |
| Lexical Scope | lex_scope_analysis.cpp | Scope region analysis |
| Aggregate Field Bitmask | aggregate_field_bitmask.cpp | Bitmask tracking for aggregate fields |
| Alias Analysis | alias_analysis.cpp | May-/must-alias queries for memory instructions |
| Convergence Region | convergence_region.cpp | Divergence/convergence region analysis |
| CVP | cvp.cpp | Correlated value propagation via structured branches |
| Scalar Evolution | scalar_evolution.cpp | SCEV for loop induction variables |
| Uniformity Analysis | uniformity_analysis.cpp | Uniform/divergent value analysis |
| Pass | File | Purpose |
|---|---|---|
| Algebraic Simplify | algebraic_simplify.cpp | Algebraic identities (with optional fast-math) |
| Const Fold | const_fold.cpp | Constant folding |
| Early CSE | early_cse.cpp | Early common subexpression elimination |
| GVN | gvn.cpp | Global value numbering |
| Reassociate | reassociate.cpp | Reassociate expressions for CSE/folding |
| SCCP | sccp.cpp | Sparse conditional constant propagation |
| Simplify CFG | simplify_cfg.cpp | Remove empty/trivial blocks |
| Simplify Libcalls | simplify_libcalls.cpp | Simplify known builtin calls |
| Scalarizer | scalarizer.cpp | Break vector ops into scalar ops |
| Div-Rem Pairs | div_rem_pairs.cpp | Combine division/remainder pairs |
| Dead Arg Elim | dead_arg_elim.cpp | Remove unused arguments |
| Pass | File | Purpose |
|---|---|---|
| IndVar Simplify | indvar_simplify.cpp | Simplify induction variables |
| LICM | licm.cpp | Loop-invariant code motion |
| Loop Rotation | loop_rotation.cpp | Rotate loops for simpler CFG |
| Pass | File | Purpose |
|---|---|---|
| SROA | sroa.cpp | Scalar replacement of aggregates |
| Reg2Mem | reg2mem.cpp | Register → 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 |
| Dead Store Elimination | dead_store_elimination.cpp | Remove dead stores |
| Pass | File | Purpose |
|---|---|---|
| Autodiff | autodiff.cpp | Autodiff transformations |
| Inline | inline.cpp | Function inlining |
| Unused Callable Removal | unused_callable_removal.cpp | Dead function elimination |
pass_pipeline.cpp / include/luisa/xir/passes/pass_pipeline.h provides PassPipeline, PassReport, and factory functions:
create_basic_optimization_pipeline()create_post_inline_cleanup_pipeline()create_ssa_optimization_pipeline()create_post_restructure_cleanup_pipeline()XIR uses structured control flow with explicit merge blocks:
IfInst: condition, true_block, false_block, merge_block
LoopInst: prepare_block, body_block, update_block, merge_block
Design: maintains SSA, enables structured transforms, maps well to GPU shaders,
and supports PHI nodes at merges. SwitchInst is a first-class structured
terminator. Only the explicit destructure_cfg boundary maps it to raw
IndexedBranchInst; restructure_cfg reconstructs the switch and its merge.
There is no generic switch-lowering or XIR loop-unroll pass. Autodiff's private
bounded semantic expansion and SPIRV-Tools loop unrolling are separate
mechanisms with separate contracts.
Headers: include/luisa/xir/metadata.h plus include/luisa/xir/metadata/{name,location,comment,curve_basis}.h. Types: NAME, LOCATION, COMMENT, CURVE_BASIS. Applied via MetadataListMixin.
ast2json → Rust IR, C API luisa_compute_ir_ast_json_to_ir_*src/xir/translators/xir2json.cpp, json2xir.cpp, xir2ast.cpp, xir2text.cpp — yyjson-based module serialization and AST round-tripping, useful for cross-process transport and debuggingManagedIntrusiveList for node managementDerivedValue<>, DerivedInstruction<>, DerivedFunction<>, DerivedArgument<>traverse_basic_blocks(), traverse_instructions()XIRBuilder for instruction creationMetadataListMixin, ControlFlowMergeMixin, InstructionOpMixin, PrintMessageMixinUse objects track value users for SSAsrc/xir/passes/<name>.cpp + header include/luisa/xir/passes/<name>.hsrc/xir/CMakeLists.txtModule & or Function &, return an info struct (often with *_pass_run_on_module(Module *, PassReport *report = nullptr)), use XIRBuilder, call replace_all_uses_with() for substitutionまだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Manual AST construction with FunctionBuilder for kernels and callables without DSL sugar.
日本語の概要は準備中です。原文の説明を表示しています。
Backend plugin architecture, DeviceInterface, dynamic loading, and command encoding.
日本語の概要は準備中です。原文の説明を表示しています。
CMake build options, custom functions, and backend patterns for LuisaCompute.
日本語の概要は準備中です。原文の説明を表示しています。
C++ naming, formatting, static analysis, and RTTI rules for LuisaCompute.
日本語の概要は準備中です。原文の説明を表示しています。
Debug crashes and test failures via stack-traces, host/device logging, and DSL buffer inspection.
日本語の概要は準備中です。原文の説明を表示しています。
Show uncommitted changes and commit history via git. Use when: (1) inspecting what changed in a file before committing, (2) checking diff of tracked/new/deleted files, (3) reviewing a specific commit's changes, (4) listing files changed in a commit.
日本語の概要は準備中です。原文の説明を表示しています。