编译器图形学编程语言【免费下载链接】slangMaking it easier to work with shaders项目地址https://gitcode.com/GitHub_Trending/sl/slang点击查看免费下载本指南围绕 Slang 编译器的 IR 指令参考文档子树docs/generated/design/ir-reference/展开说明该子树的组织契约、十个家族页的分类逻辑、页面总览表的计数口径以及“AST origin”列opcode 生产者溯源的语义约定。读完本文你可以掌握在数百个kIROp_*指令中快速定位目标 opcode 的方法理解一个 opcode 是由 AST 降低、核心模块__intrinsic_op声明还是某个 IR pass 构造的判别依据并能顺着源码路径source/slang/slang-ir-insts.lua、source/slang/slang-lower-to-ir.cpp自行核对与扩展这套参考文档。子树的定位一份面向编译器开发者的 IR opcode 目录docs/generated/design/ir-reference/是 docs/generated/design/ir-reference/index.md 所描述的“按家族per-family的 Slang 中间表示IR参考”。其核心承诺是凡是在 slang-ir-insts.lua 中声明的每一个具体 opcode都会出现在下方某个家族页中并以表格形式列出它的 C 包装结构体IRFoo、操作数形态operand shape、操作标志位op-flagsHhoistable、Pparent、Gglobal、构造它的生产者AST origin以及一行摘要语义复杂到表格行无法承载的 opcode则在页面下方以短段落Notable opcodes单独说明。它的目标读者是已经大致知道自己要找什么的编译器开发者想查某个 opcode 是否存在、它的操作数形态是什么、它从哪里来。因此这个子树刻意保持“窄”范围——只描述形状与出处shape and provenance不描述消费 IR 的各 pass 的行为。后者分别由两份相邻文档承担约定层面schema、flag bits、hoistable/global 去重、模块版本化、新增 opcode 的工作流见 docs/generated/design/cross-cutting/ir-instructions.md时序层面AST 节点何时降低为 IR、调用了哪些 lowering 辅助函数见 docs/generated/design/pipeline/04-ast-to-ir.md后续处理IR pass 对 IR 做合法化、特化与优化见 docs/generated/design/pipeline/05-ir-passes.md。Family taxonomy十个家族页的分类逻辑整个指令集以IRInst为根先按语义分成五个大类再细分出十个家族页。分类的目的是让读者在打开ir-reference/目录的瞬间就能判断自己该进哪个页面这一分类并非随意划分而是贴合 Lua 声明文件中的嵌套分组slang-ir-insts.lua本身就是一棵以父条目包裹子条目的树父子层级同时决定了 opcode 枚举的连续区间一个asIRBasicType()式的类型判断因此退化为一次整数区间比较家族页的分类基本映射了这棵树的结构。十个家族页及其在指令集中的范围如下PageFamilyLua entry rootApprox. opcodestypes.mdType instructionsType约 line 20内含嵌套的BasicType约 line 22、TranslatedTypeBase约 line 168、WorkGraphRecordTypeBase约 line 232分组~170values.md常量、算术、转换含DescriptorHandleT转换、内存、聚合构造器、reshape/pack 辅助、constexpr 算术/转换、字符串与原生指针辅助Constant约 line 953及顶层 value opcodeconstexpr*簇始于约 line 3412~150structure.md模块结构函数、泛型、全局量、结构体、接口、witness 表GlobalValueWithCode约 line 885、module约 line 942~20control-flow.mdblock、参数、分支、函数退出、target / quad-executionRequire*标记block约 line 944、param约 line 1170、TerminatorInst约 lines 1454-1535、backend-hint 分组约 lines 1537-1547~30generics-and-existentials.mdspecialize、witness 查找、existential 打包/解包、RTTI、类型流特化sets、tagged unions、dispatchersspecialize约 line 1047、lookupWitness约 line 1048type-flowSetBase分组始于约 line 3129~50resources-and-atomics.mdimage/buffer/sampler 操作、shader IO、原子操作、barrier、fragment-shader interlocks、cooperative matrix/vector、wave intrinsics、光线追踪、descriptor-heap 加载以及 natural-layout 的getNaturalStride/getNaturalAlignment对AtomicOperation约 line 1186及顶层 resource opcode~90differentiation.md自动微分differential pairs、前向/反向 differentiate、reverse-mode 上下文、autodiff 占位符、DiffTypeInfoMakeDifferentialPairBase约 lines 1016-1046、DiffTypeInfo约 line 1124、TranslateBase约 lines 2816-2855~40decorations.mdDecoration 家族附加在指令上的元数据Decoration约 line 1756~200metadata.mdLayout、Attr、Debug*、SPIRVAsmOperandLayout约 line 2880、Attr约 line 2909、Debug*簇约 lines 2974-3009、SPIRVAsmOperand约 line 3016~60misc.md系统 opcodenop、Unrecognized、pack/expansion、类型查询、编译期 size/align/count 查询、storage 转换、无类型 descriptor-heap handle 转换、liveness 标记、tensor/runtime 辅助、kernel launch顶层杂项 opcode外加Undefined约 line 972、BindingQuery约 line 1736、CastStorageToLogicalBase约 line 2763、LiveRangeMarker约 line 2961分组~70Approx. opcodes 列的统计口径向上/向下取整到最近的十位prefix~。计数方法是统计 slang-ir-insts.lua 中落入该家族的struct_name ...条目数再加上落入该家族的裸 opcode 条目数。它还有第二个近似来源部分页面存在“交叉链接行”——同一 opcode 的规范条目在另一页本页以交叉链接形式重复出现因此底层行数会对这类双角色 opcode 重复计数。在动手翻页前还有两处所有权划分容易猜错值得先记住DescriptorHandleT的转换在 values.md无类型descriptor-heap handle 转换在 misc.md“untyped descriptor-heap handle casts”小节而 descriptor-heap 的加载在 resources-and-atomics.mdgetNaturalStride与getNaturalAlignment与其余 alignment/stride 家族一起记录在 resources-and-atomics.md“getNaturalStride and getNaturalAlignment”小节而不是放在 misc.md 的编译期sizeOf/alignOf查询里。Lua entry root 列的行号均指 slang-ir-insts.lua 而言该文件在生成导航页的提交source_commit下为 3609 行当前 HEAD 实测为 3644 行——无论计数还是行号都会随着 opcode 的增删、跨家族移动而漂移应以提交时的实际文件为准。家族页的内部契约形状 出处而非行为每个家族页如 types.md、control-flow.md遵循_common.md中定义的IR-reference family contract见 docs/generated/design/_meta/prompts/_common.md固定按以下顺序组织# Family标题如# Types、# Control Flow## Source——一段指出该家族在 Lua 文件中的条目区间、slang-ir-insts.h 中对应的IRFoo包装结构、以及 slang-lower-to-ir.cpp 中产出这些 opcode 的 visitor依赖 slang-ir.h 基础设施op flags、IRBuilder辅助时一并引入## Family hierarchy——一个 mermaidflowchart TD镜像 Lua 的嵌套结构让读者看到例如BasicType是Type的一个子区间抽象中间条目只出现在这里## Opcodes——一张或多张表格每行一个具体 opcode列固定为Opcode / C wrapper / Operands / Flags / AST origin / Summary## Notable opcodes——对表格难以承载语义的 opcode 的短段落说明## See also——链接约定页、平级家族页、lowering 页、相关 ast-reference 页与词汇表。覆盖规则是硬性的Lua 文件中属于该家族的每个具体 opcode 条目都必须出现在## Opcodes表中仅用于分组子条目的抽象父条目如BasicType、TerminatorInst只出现在## Family hierarchy图中横跨两个家族的 opcode 归入更具体的一方并从另一方交叉链接。## Opcodes表的列语义有几处容易误读逐条说明OpcodeLua 条目名反引号包裹同时也是kIROp_name枚举标签的组成部分C wrapperIRFoo结构体名必须带IR前缀。契约明确禁止在该列使用破折号——不存在没有包装结构体的 opcode。但并非全部 wrapper 都由生成器产出getAllOtherInstStructsData()slang-ir.h.lua 约 line 145 起以if not Slang[IR .. struct_name] then开头会跳过已在 slang-ir-insts.h 中手写的结构体只为其余条目生成结构手写 wrapper 在表中以脚注标记如‡区分并在正文中说明数量Operands来自 Lua 条目的操作数名如elementType, count变长操作用(variadic)无操作数用—。当 Lua 条目声明了min_operands N却没有给出操作数名时写作(N unnamed)不得自行发明名字也不得误标为(variadic)若 slang-ir-insts.h 中的 C 访问器能揭示该未命名操作数实际是什么则允许命名并加†标记与图例说明Flags单字母连接、不加分隔符——Hhoistable可提升、会去重、Pparent父容器、Gglobal恒在模块作用域但不去重均不适用时留空AST origin见下一节Summary一行短句除行内代码外不带其他标记。AST origin 列一个 opcode 究竟由谁构造AST origin 列是这套参考文档最有信息量的一列它要求写出实际的生产者producer而不是笼统的类别标签来自 AST 降低标注 AST 类 slang-lower-to-ir.cpp 中产出它的visit*成员函数。整个文件约有 230 个当前 HEAD 下 grep 到 285 处visit相关匹配数量随提交漂移visit*函数例如visitVarDecl当前 HEAD 约 line 11763发射var。AST 一侧的对应关系记录在 docs/generated/design/ast-reference/ 子树主要是 expressions.md、statements.md 与 declarations.md不要因为解析层存在某个 AST 类就假定存在对应 visitor例如并不存在visitInfixExpr——parser 为a b构建的InfixExpr在语义检查阶段已被解析成BuiltinOperatorExpr由visitBuiltinOperatorExpr处理或一个对核心模块中以__intrinsic_op声明的普通函数的InvokeExpr由visitInvokeExpr处理。导航页在源码中明确指出了这个“易错点”由 pass 引入标注 pass 或函数名例如lowerTypeLayout、前向自动微分 pass、PyTorch 绑定 pass——不再使用已退役的笼统标签(synthesized)由核心模块 intrinsic 声明__intrinsic_op声明本身没有visit*其生产者是 source/slang/core.meta.slang、source/slang/hlsl.meta.slang 或 source/slang/diff.meta.slang 中的声明没有任何source/代码构造它标注no producer at HEAD并在 Summary 中说明。旧版文档使用的兜底写法(synthesized)与裸—已被废弃因为它们掩盖了“由 pass 产生”与“完全未产生”之间的真实区别。跨主题文档IR 在更大编译流水线中的位置导航页将 IR 相关的横向文档串成一张网便于从任一入口跳到相邻主题docs/generated/design/pipeline/04-ast-to-ir.md —— AST 到 IR 的 lowering 流水线IRBuilder、IRGenContext与visit*方法如何把 AST 翻译为 IRdocs/generated/design/pipeline/05-ir-passes.md —— 对 IR 做合法化、特化与优化的各 IR passdocs/generated/design/pipeline/06-emit.md —— 各目标发射器如何消费合法化后的 IRdocs/generated/design/cross-cutting/ir-instructions.md —— IR schema、op-flag 约定、hoistable/global 去重、模块版本化、新增 opcode 的工作流docs/generated/design/cross-cutting/serialization.md —— IR 模块如何被序列化docs/generated/design/cross-cutting/diagnostics.md —— IR 指令携带SourceLoc贯穿诊断系统docs/generated/design/cross-cutting/targets.md —— 消费合法化 IR 的目标后端以及塑造“哪些 opcode 能存活到发射阶段”的按目标合法化docs/generated/design/glossary.md ——IRInst、IROp、IRBuilder、IRModule、parent instruction、terminator instruction、block parameter、decoration、hoistable instruction、target intrinsic、differential pair、witness table、existential type、specialization、single static assignment (SSA) 等术语定义。如何导航先读约定还是直接进家族页导航页给出的使用建议非常明确如果你是 IR 新手先从 docs/generated/design/cross-cutting/ir-instructions.md 开始它覆盖每个家族页都默认读者已知的 schema、op-flag 位与模块版本化如果你已有明确目标直接跳到你关心的 opcode 所在家族页每页以## Source开头链接其 Lua 条目区间并说明本页的表格约定AST origin 单元格的读法把它当作“实际构造该 opcode 的生产者名称”——一个 slang-lower-to-ir.cpp visitor、一个核心模块__intrinsic_op声明、或一个具名 IR pass当source/中没有任何代码构造它时读到的是no producer at HEAD抽象条目只在图中仅用于分组的 Lua 抽象条目永远不会作为## Opcodes行出现只出现在各页的## Family hierarchy图中。导航页背后的基础设施命名、包装与版本化索引页引用的这些机制实际上定义了整个 IR 参考子树的可信度边界值得从源码层面理解kIROp_*枚举名来自struct_name而非 Lua key。instEnums模板slang-ir.h.lua 约 line 269发射kIROp_$(value.struct_name)所以 Lua keyVec变成kIROp_VectorType、Array变成kIROp_ArrayType、TextureShapeCubeDType变成kIROp_TextureShapeCubeTypeLua key 作为-dump-ir打印的助记符保留。当struct_name省略时slang-ir-insts.lua 底部的process函数用to_pascal_case从 key 推导对应 line 3452 附近。wrapper 的生成与手写边界getAllOtherInstStructsData()只补发“未手写”的结构体手写 wrapper 通常因为需要IRUse成员、索引算术或解释性访问器如TerminatorInst家族、IRDebugFunction::getParentScope的“操作数个数 5 才读取第 6 个”写法。生成的结构体获得isaImpl、kOp常量与每个具名 Lua 操作数一个访问器IRBuilder::getStructName(...)便捷构造器则由getBasicTypesForBuilderMethodsslang-ir.h.lua 约 line 320驱动少数需要手写逻辑的类型如StructType/ClassType采用createStructType/createClassType被显式排除。序列化与模块版本化opcode 不会被序列化为其枚举值而是经由 slang-ir-insts-stable-names.lua 中的稳定名stable name按条目点路径如Type.BasicType.Int分配、永不重用转换新增指令只提升k_maxSupportedModuleVersion删除指令才同时抬高最小值当前为 4~28详见 docs/generated/design/cross-cutting/ir-instructions.md 的“Module versioning and opcode insertion”一节。新增 opcode 的完整工作流在所属家族内插入 Lua 条目、运行 extras/check-ir-stable-names.lua 的update、提升版本常量、决定 flag、必要时手写 wrapper、补充 lowering 与发射后端、加测试也在该文档中逐步列出并由 extras/check-ir-stable-names-gh-actions.sh 与 extras/check-inst-version-changes.sh 在 CI 中强制。结语索引页是入口家族页才是正文ir-reference/index.md本身刻意不描述任何 opcode 细节——它是一份导航页职责是把读者以最快路径送到正确的家族页并交代清楚统计口径、所有权划分与 AST origin 的读法。真正逐 opcode 的目录在十个家族页中合计约 7400 行当前 HEAD而支撑它们的事实基础是 slang-ir-insts.lua 这份“指令集的唯一权威声明”。无论你是要查一个 opcode 的形状、要确认它由谁构造、还是要新增一个 opcode正确的起点分别是家族页、AST origin 列与 docs/generated/design/cross-cutting/ir-instructions.md 的“Adding a new opcode”工作流。赞分享编译器图形学编程语言【免费下载链接】slangMaking it easier to work with shaders项目地址https://gitcode.com/GitHub_Trending/sl/slang点击查看免费下载相关推荐Windows热键冲突终极解决方案Hotkey Detective一键定位占用程序Windows热键冲突终极解决方案Hotkey Detective一键定位占用程序 当你在Windows系统中设置的全局快捷键突然失效却找不到哪个程序在占用编译器图形学编程语言Slang IR 指令集全解析从 slang-ir-insts.lua 到 opcode 定义、去重与版本管理Slang IR 指令集全解析从 slang ir insts.lua 到 opcode 定义、去重与版本管理 SlangGitHub 推荐项目精选 / s编译器图形学编程语言Slang 自动微分 IR Opcode 全解析Differential Pair、翻译请求与 Checkpointing 家族参考Slang 自动微分 IR Opcode 全解析Differential Pair、翻译请求与 Checkpointing 家族参考 导读 本文面向编译器工程编译器图形学编程语言上一篇ClojureScript与WebGL纹理映射技术下一篇终极命令行美化工具grc10分钟让你的终端输出变得五彩斑斓创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考