Slang 编译器编译管线全解析:从源码字节流到目标产物的六阶段架构与驱动入口 编译器图形学编程语言【免费下载链接】slangMaking it easier to work with shaders项目地址https://gitcode.com/GitHub_Trending/sl/slang点击查看免费下载本篇技术指南以 Slang 开源着色器语言的编译管线为主线系统梳理从源码缓冲source buffer到最终目标产物target artefact的完整数据流词法分析/预处理、AST 解析、语义检查、AST→IR 降级、IR 变换流水线、代码发射六大阶段并结合仓库源码讲清每一阶段的驱动文件、关键数据结构与目标敏感target-sensitive的分支逻辑。读完本文你将掌握 Slang 编译器的整体架构图景能够对照源码逐阶段定位实现文件理解slangc一次调用背后CompileRequestBase/EndToEndCompileRequest/Module/CodeGenContext等高层对象的协作方式并为深入阅读各分阶段文档docs/generated/design/pipeline/下的 01–06建立索引。该管线索引文档为 overview.md对应的架构级总览见 architecture/overview.md。端到端数据流从源码到目标产物Slang 编译器把一次编译建模为一条清晰的管线。下图来自索引文档展示的是概念性的数据交接顺序需要特别说明的是这张图是概念性的实际控制流远比图更交织解析与语义检查并非严格先后——Slang 采用两阶段解析详见 02-parse-ast.md函数体在声明解析阶段被暂存为原始 token真正解析发生在语义检查按需触发时IR 变换阶段的 pass 列表是目标敏感的不同后端、不同优化等级执行的 pass 序列各不相同详见 05-ir-passes.md。因此上图反映的是主导性的数据交接而非严格的时间先后。阶段一词法分析与预处理Lex / Preprocess本阶段读取源码缓冲产出可供解析器直接消费的扁平Token数组。关键事实是词法、预处理与#include解析全部在解析开始之前完成预处理并不向解析器流式推送 token——第一阶段跑完得到完整 token 列表后第二阶段解析才开始这种解耦让解析器可以使用任意长度的前瞻lookahead。驱动文件source/compiler-core/slang-lexer.cpp——词法分析器Lexer结构体及其initialize/ 词法驱动source/slang/slang-preprocessor.cpp——预处理器与#include展开source/compiler-core/slang-include-system.cpp——路径解析IncludeSystem依据Linkage的搜索路径解析#include。更深一层的设计细节值得注意详见 01-lex-preprocess.mdToken 数据模型每个 token 携带一个单字节TokenType通过 slang-token-defs.h 中的 X-macro 声明、原始文本charsCount加指向原始字符或驻留Name*的联合、一个 32 位SourceLoc以及一个小的TokenFlags字节AtStartOfLine、AfterWhitespace、ScrubbingNeeded、Name。源码位置编码SourceLoc是单个uint32_t由SourceManagerslang-source-loc.h / slang-source-loc.cpp按需解码回文件/行/列——每个 token 只需携带一个廉价字段而非三个。SourceLoc的拷贝构造函数显式 default保证类型可平凡拷贝以嵌入联合。字面量扫描与取值分离词法器只负责扫描字面量的范围记录原始 token 文本解码其值延迟到辅助函数getIntegerLiteralValue、getFloatingPointLiteralValue、getStringLiteralTokenValue、getCharLiteralValue。例如浮点后缀分类决定可表示性1e300lf是Double保持有限而1e300是Float越界解码为INFINITY。不区分标识符与关键字所有关键字 token 都以TokenType::Identifier到达解析器关键字状态由解析器通过查表确定。预处理器的输入流栈原始源文件在栈底#include的文件与宏展开压入栈顶每个#include的文件有自己的InputFile、自己的词法器与自己的Conditional状态栈条件跳过与指令诊断按文件隔离。指令回调表指令按名字在回调表中查找新增指令#pragma、自定义扩展只需在 slang-preprocessor.cpp 中注册新回调。kDirectives表覆盖 C/HLSL 风格指令#if族、#include、#define、#undef、#warning、#error、#line、#pragma外加 Slang 语言选择指令#language/#lang与 GLSL 指令#version/#extension。阶段二解析为 ASTParse to AST递归下降解析器把扁平 token 流变成强类型 AST。由于 token 预先收集为扁平列表解析器可以做任意前瞻虽然实践中很少超过一个 token。驱动文件source/slang/slang-parser.cpp——解析器主体slang-ast-*.h头文件族source/slang——AST 数据模型。两阶段解析Two-stage parsingSlang 最独特的设计之一是两阶段解析策略由ParsingStageDecl或Body选择声明解析阶段Decl顶层声明正常解析但当解析器遇到{ ... }函数体时并不递归进入而是由parseOptBody跟踪花括号嵌套、把封闭的 token 复制进一个UnparsedStmtAST 节点同时记录该函数体书写时的作用域currentScope、outerScope。函数体解析阶段Body语义检查遇到UnparsedStmt时以 Body 模式初始化一个新Parser在语义检查器SemanticsVisitor*的监督下延迟重新解析这些 token。这样做的主要动机是消解的二义性——它既可能是泛型实参列表fooT的开始也可能是小于号比较foo bar。在函数体解析阶段tryParseGenericApp可以把之前的表达式交给检查器的CheckTerm依据其解析出的名字类型做出判断解析为GenericDecl、FunctionDeclBase或AggTypeDeclBase的都采用泛型读法只有解析为普通变量等其它东西时才采用比较读法。语法即声明Syntax-as-declarationSlang 把大多数关键字不作为词法层的保留字而是作为绑定到当前环境语法上的标识符。解析器维护一个SyntaxParseInfo表把关键字名字映射到解析回调当解析器看到一个标识符时先在活动作用域链中查找SyntaxDecltryLookUpSyntaxDecl命中则调用关联回调。其实际后果是在 Slang 中新增一个修饰符关键字通常只需在语法表中注册它而不必改动词法器或解析器核心。错误恢复解析器遇到意外 token 时Unexpected通过DiagnosticSink发出诊断并设置Parser::isRecovering标志该标志抑制后续的级联unexpected token诊断同步resynchronization由TryRecover完成它接受 recover-before 集合停在其前、不消费的 token与 recover-after 集合消费后继续的 token。块内默认策略是 recover-before}、recover-after;跳过一个平衡组bracketed/braced region整体而非逐 token。即使出错后 AST 仍以尽力而为best-effort方式构建以便下游工具可操作部分树。AST 数据模型AST 是根植于NodeBase的强类型 C 类层次slang-ast-base.h。FIDDLE(...)宏由构建期工具slang-fiddle处理生成访问者分发表、供asT转换使用的SyntaxClass反射元数据与序列化支持——切勿编辑生成文件应编辑 FIDDLE 标记的源文件。主要节点家族包括Decl——声明ContainerDecl、FunctionDeclBase、VarDecl、AggTypeDecl、GenericDecl、ExtensionDecl、InterfaceDecl、SyntaxDecl等见 slang-ast-decl.hExpr——表达式slang-ast-expr.hStmt——语句slang-ast-stmt.h含用于延迟函数体场景的UnparsedStmtType——类型注意Type派生自Val所以类型本身就是编译期值Modifier——附加到 decl 上的限定符/属性Val——泛型使用的编译期值vectorfloat, 3中的3、int a[4]中的4。刚解析完的 AST 中类型与表达式都用Expr表示因为解析期A(B)既可能是函数调用也可能是类型构造由语义检查器重新分类。阶段三语义检查Semantic check语义检查把原始 AST 变成完全解析、类型检查过的 AST为降级到 IR 做好准备。检查器实现为一系列共享SemanticsContext状态的SemanticsVisitor子类家族分布于slang-check-*.cpp文件中负责名字解析、类型附着、修饰符校验、重载决议与一致性conformance检查以及合成默认一致性见证default conformance witnesses和生成成员generated members。驱动文件source/slang/slang-check.cpp——入口与编排按关注点拆分的文件族slang-check-decl.cpp、slang-check-expr.cpp、slang-check-stmt.cpp、slang-check-type.cpp、slang-check-overload.cpp、slang-check-conformance.cpp、slang-check-conversion.cpp、slang-check-inheritance.cpp、slang-check-modifier.cpp、slang-check-constraint.cpp、slang-check-resolve-val.cpp、slang-check-shader.cpp。以一个示例说明本阶段产出详见 03-semantic-check.mdinterface IFoo { int base(); int twice() { return base() * 2; } } struct S : IFoo { int base() { return 6; } static const int tag 1; } int callT : IFoo(T v) { return v.twice(); }解析器交出的S其基类列表仍是未检查的Exprcall的函数体仍是UnparsedStmt没有任何Expr携带类型。检查后IFoo在基类列表与T的约束中被解析到同一 decl名字解析v.twice()获得类型int类型附着记录S : IFoo的见证表一致性记录用接口默认实现的见证填满表中twice槽位默认一致性见证合成UnparsedStmt变成检查过的Stmt树函数体完整解析并检查。值得注意的实现要点可微性即接口一致性[Differentiable]函数通过合成extension __func_as_type(f) : IForwardDifferentiable__func_as_type(f)来表达fwd_diff成员以kIROp_ForwardDifferentiate为实现。因此该调用目标是否可微是一个子类型查询isFuncForwardDifferentiable返回SubtypeWitness*而非修饰符查找。修饰符互斥组getModifierConflictGroupKind把修饰符映射到竞争组out/inout/ref/borrow共享一组static/uniform一组nointerpolation/noperspective/linear/sample/centroid一组。可见性作用域private是类型作用域而非文件作用域——同一文件中的自由函数不能读取struct的private成员E30600。与解析器的双程交互检查器遇到UnparsedStmt时调用parseUnparsedStmt并传入SemanticsVisitor*让解析器在解析期回调查找器消解。因此函数体内部不存在干净的解析/检查分界——两者按需交织进行。阶段四AST→IR 降级AST to IR lowering检查过的 AST 由降级访问者遍历通过IRBuilder发射 Slang IR声明Decl变成IRGlobalVar/IRFunc/IRStructType/IRGeneric控制流语句创建基本块与分支普通语句在当前块内发射指令表达式变成 SSA 值指令块参数block parameters跨控制流边携带值。驱动文件source/slang/slang-lower-to-ir.cpp——降级主体source/slang/slang-ir.cpp——IRBuilder、可提升/全局值去重。入口是 slang-lower-to-ir.h 中的generateIRForTranslationUnit(ASTBuilder*, TranslationUnitRequest*)返回一个新鲜的IRModule。该阶段不会整体链接import的模块——那是后续 IR pass 的工作唯一的例外是针对性预链接[unsafeForceInlineEarly]函数被克隆进本模块externalSymbolsToPrelink/prelinkIR使强制优化 pass 可见。SSA 形式的块参数phi 形式块参数是 IR 的 phi 形式。降级在表达式自身分叉控制流的地方直接发射它们——?:与短路求值的/||分支进入一个以结果为参数的汇合块而普通局部变量变成带 store 的var由generateIRForTranslationUnit末尾的constructSSA调用提升为同一形式该调用位于强制 pass 块中、在每个优化等级都运行。不过这一形式不会到达后端slang-emit.cpp中的eliminatePhis把 IR 移出 SSA 形式用显式临时变量替换块参数。因此发射的 SPIR-V 中出现的OpPhi是下游 SPIR-V 优化器的产物——它仅在优化等级高于None时运行——而不是贯穿到发射端的块参数。主要映射表节选AST 构造产生的 IRModuleDeclIRModule顶层容器FuncDecl含一个或多个IRBlock的IRFuncVarDecl全局IRGlobalVarVarDecl局部块内分配的IRVarStructDecl带IRStructField子节点的IRStructTypeGenericDeclIRGeneric函数形状、函数体在 IR 期计算类型级值ReturnStmtIRReturn终止符InvokeExprIRCallBuiltinOperatorExpr单个纯值指令kIROp_Add、kIROp_Mul、kIROp_Eql、kIROp_BitAnd、kIROp_Neg等LiteralExpr常量指令IRIntLit、IRFloatLit等泛型在降级中作为普通 IR 存续IRGeneric的函数体在 IR 期运行以计算特化的内部指令。特化本身不在降级期执行而是由 IR passslang-ir-specialize、slang-ir-bind-existentials、slang-ir-defunctionalization等处理这种分离让降级后的 IR 保持目标无关。一个易踩的坑-dump-ir输出中的名字经过scrubName处理——下划线打印为x5F如IFoo_zero显示为IFoox5Fzero所以在 dump 中搜索时应使用 mangled 形式而非源码形式。阶段五IR 变换流水线IR passeslinkAndOptimizeIRsource/slang/slang-emit.cpp 第 1000 行起驱动降级与发射之间的一长串、目标敏感的 IR 变换序列。source/slang/目录下包含163 个slang-ir-*.cpp文件实现分析、验证、特化、合法化与目标特定降级。所谓目标敏感指的是 pass 列表本身会分支而不仅是发射端把同一中性形状拼写不同整个 pass 被linkAndOptimizeIR内部的目标谓词守卫——走 GLSL 文本的 Khronos 目标运行legalizeModesOfNonCopyableOpaqueTypedParamsForGLSL直接 SPIR-V 路径运行其它目标见不到的 pass 集PyTorch 绑定目标运行generatePyTorchCppBinding。仅仅拼写不同的问题留到发射端解决同一个[numthreads(16, 1, 1)]入口点在 HLSL 上是numthreads(16, 1, 1)GLSL 上是local_size_x 16, ...SPIR-V 上是OpExecutionMode ... LocalSize 16 1 1WGSL 上是workgroup_size(16, 1, 1)而 Metal 与 CUDA 完全不打印组大小。驱动文件source/slang/slang-emit.cpp——编排器linkAndOptimizeIR内部约 180 处SLANG_PASS(...)调用点宏包装wrapPass使 IR dump 与剖析统一应用于每个 passslang-ir-*家族——单个 pass。阶段骨架节选linkAndOptimizeIR的相位骨架行号对应索引文档记录的source_commit行范围相位代表性 pass1005–1049链接与扫描linkIR、validateAndRemoveAssumeAddress、calcRequiredLoweringPassSet1053–1064早期剥离与借用stripDebugInfo-g0、translateEntryPointInParamToBorrow、replaceGlobalConstants1383–1466特化与自动微分收尾generateDerivativeWrappers、specializeModule、finalizeAutoDiffPass、eliminateDeadCode、finalizeSpecialization1676–1735阶段切换与强制内联specializeStageSwitch、performForceInlining、simplifyIR1755–1941类型合法化lowerCombinedTextureSamplers、legalizeVectorTypes、legalizeResourceTypes、legalizeMatrixTypes2365–2620晚期清理与出 SSAeliminateDeadCode、lowerBitCast、specializeAddressSpace*、eliminatePhis、simplifyNonSSAIRSPIR-V 是例外其主合法化legalizeIRForSPIRV不在linkAndOptimizeIR内部而是由 SPIR-V 发射后端在linkAndOptimizeIR返回后调用以便在地址空间特化之后运行。因此-dump-ir流中不会出现BEFORE legalizeSPIRV/AFTER legalizeSPIRV头。该流水线不是固定列表——不同目标、不同优化等级以及是否存在微分或覆盖率插桩都会改变序列。多数可选 pass 由RequiredLoweringPassSet标志守卫该集合由calcRequiredLoweringPassSet计算链接后与特化后各一次标志累积不重置。pass 分类一览链接与验证slang-ir-link、slang-ir-validate、slang-ir-check-recursion、slang-ir-check-unsupported-inst、slang-ir-mesh-output-reads等SSA 构造与基础清理slang-ir-ssa、slang-ir-ssa-simplificationsimplifyIR不动点SSA/SCCP/SimplifyCFG/peephole/DCE、slang-ir-eliminate-phis、slang-ir-dce、slang-ir-sccp、slang-ir-peephole、slang-ir-simplify-cfg等特化与泛型slang-ir-specialize、slang-ir-specialize-function-call、slang-ir-bind-existentials、slang-ir-defunctionalization、slang-ir-any-value-inference、slang-ir-typeflow-specialize等微分自动微分slang-ir-autodiff驱动finalizeAutoDiffPass、slang-ir-autodiff-fwd、slang-ir-autodiff-rev、slang-ir-autodiff-transpose、slang-ir-autodiff-unzip等。前向模式生成的名字提示是s_fwd_original反向模式生成s_bwdProp_original与s_bwdCallableCtx_original类型与值合法化slang-ir-legalize-types、slang-ir-legalize-array-return-type、slang-ir-lower-optional-type、slang-ir-lower-result-type、slang-ir-lower-tuple-types、slang-ir-lower-error-handling、slang-ir-lower-copy-logical仅在 SPIR-V 合法化内等内联与调用图slang-ir-inline、slang-ir-call-graph、slang-ir-reachability、slang-ir-defer-buffer-load等入口点与参数处理slang-ir-entry-point-uniforms、slang-ir-fix-entrypoint-callsite、slang-ir-transform-params-to-constref等布局与绑定slang-ir-layout、slang-ir-collect-global-uniforms、slang-ir-translate-global-varying-var、slang-ir-metadata等循环变换slang-ir-loop-unroll、slang-ir-restructure构建RegionTree给源发射器以语句形状读取 CFG等目标特定降级slang-ir-glsl-legalizeGLSL/SPIR-V、slang-ir-hlsl-legalizeHLSL/D3D、slang-ir-metal-legalize、slang-ir-spirv-legalize、slang-ir-wgsl-legalize、slang-ir-cuda-immutable-load、slang-ir-pytorch-cpp-bindingTorch、slang-ir-com-interfaceCPU/COM插桩slang-ir-coverage-instrument-trace-coverage、slang-ir-insert-debug-value-store、slang-ir-obfuscate-loc。如何新增一个 pass在 source/slang 下创建slang-ir-name.{h,cpp}对使用 slang-ir.h 及slang-ir-clone.cpp/slang-ir-dominators.cpp/slang-ir-call-graph.cpp中的辅助设施遵守 design/ir.md 描述的可提升/全局值规则在归属该变换的阶段插入调用点链接后 pass 加入linkAndOptimizeIR使用局部SLANG_PASS宏以参与 IR dump 与剖析链接前 pass 放入generateIRForTranslationUnit后端归属的 pass 放入该后端的合法化编排器如直接 SPIR-V pass 进legalizeIRForSPIRV若 pass 目标特定则用TargetRequest门控若仅在特定构造出现时需要则给RequiredLoweringPassSet加标志并在calcRequiredLoweringPassSet中设置在 tests 下添加测试——通常是COMPARE_COMPUTE或INTERPRET测试若 pass 报错则加DIAGNOSTIC_TEST提交前运行./extras/formatting.sh。阶段六代码发射EmitCodeGenContext::emitEntryPoints按TargetRequest为每个目标选择分发路径。文本类目标走emitEntryPointsSourceFromIRsource/slang/slang-emit.cpp 第 2889 行起它挑选一个 C 风格源发射器——HLSL、GLSL、Metal、WGSL、C、CUDA 或 Torch 胶水。Torch 胶水是列表中的例外PyTorch 绑定目标只为标记了[TorchEntryPoint]或由[AutoPyBindCUDA]合成的函数生成 C 包装所以对普通计算入口点-target torch没有任何可绑定的内容。二进制与非源目标直接 SPIR-V、下游编译的 DXIL/DXBC/metallib/PTX、经slang-llvm的 LLVM IR/原生、以及 VM 字节码分别分发。驱动文件source/slang/slang-code-gen.cpp——每目标分发器定义CodeGenContext::emitEntryPoints与_emitEntryPointssource/slang/slang-emit.cpp——链接 IR 与 pass 编排以及emitEntryPointsSourceFromIR中的 C 风格源发射器选择source/slang下每个后端一个slang-emit-target.cpp。后端一览后端文件关键特性HLSLslang-emit-hlsl.cpp命名常量绝不作为裸整数发射工作图属性从 IR decoration 读符号值barrier 标志集展开为 DXC 的 flag tokenGLSLslang-emit-glsl.cpp输出经source/slang-glslang/由 Khronos glslang 产生 SPIR-VSPIR-V直接slang-emit-spirv.cpp直接从SPIRVEmitContext发射 SPIR-V 二进制createArtifactFromIR预先判断是否需要下游slang-glslang/ SPIRV-Tools——普通单模块-O0 -target spirv编译完全不触碰slang-glslangMetalslang-emit-metal.cpp内联内建片段经ensurePrelude注入kMetalBuiltinPrelude*字符串WGSLslang-emit-wgsl.cpp唯一把supportsSwitchFallThrough与shouldEmitSwitchCaseTerminatingBreak都覆写为false的后端WGSLcase体不落穿尾部break冗余且老naga校验器拒绝循环外的breakCslang-emit-cpp.cpp计算入口点不作为单个函数发射IRFunc本身变成_main_N内部工作函数模块体后发射三个SLANG_PRELUDE_EXPORTshimmain_N_Thread/main_N_Group/main_N签名均为(varyingInput, void* entryPointParams, void* globalParams)这是宿主运行时调用的表面CUDAslang-emit-cuda.cpp模块作用域着色器参数不存为 CUDA 全局先收集进单个GlobalParams结构发射为extern C __constant__ GlobalParams_N SLANG_globalParams;加#define重定向Torchslang-emit-torch.cpp生成 PyTorch C 绑定胶水LLVMslang-emit-llvm.cpp交给 source/slang-llvm 的 JIT/原生编译路径HostLLVMIR/ShaderLLVMIR出文本 LLVM 汇编HostObjectCode/ShaderObjectCode出目标代码HostHostCallable/ShaderHostCallable出 JIT 库VMslang-emit-vm.cpp从链接 IR 构建VMByteCodeBuilder——Slang 的解释器字节码用于slangi工具与INTERPRET测试引用IRGlobalParam的函数触发GlobalParamNotSupportedByInterpreter共享的 C 风格基类文本后端HLSL、GLSL、Metal、WGSL、C、CUDA、Torch共享大部分机制slang-emit-c-like.h / slang-emit-c-like.cpp——基类CLikeSourceEmitter遍历 IR声明供每目标子类覆写的虚接口emitDeclarator、emitType、emitOperand等实现所有目标共享的部分slang-emit-base.h / slang-emit-base.cpp——SourceEmitterBase最低公共接口也是SPIRVEmitContext与 SPIR-V 合法化上下文的基类。类层次并非扁平CUDASourceEmitter与TorchCppSourceEmitter都直接派生自CPPSourceEmitter而非CLikeSourceEmitter。新文本后端通常子类化CLikeSourceEmitter只覆写与 C 风格默认不同的操作。运算符优先级与括号化slang-emit-precedence.h / slang-emit-precedence.cpp 为文本目标编码运算符优先级使发射代码优先级感知而非最小括号化。maybeEmitParens从优先级比较出发然后故意在位运算、逻辑、关系、相等与移位组合外加括号——即使语言自身的优先级已保持语义——因为下游编译器会对这些组合告警。例如a | b c发射为a | (b c)a b c发射为a (b c)a b c d发射为(a b) (c d)。Preludesprelude 下的 per-language prelude 头使发射的源码自包含目标Prelude 头HLSLprelude/slang-hlsl-prelude.hCUDAprelude/slang-cuda-prelude.hC 着色器prelude/slang-cpp-prelude.h、prelude/slang-cpp-types-core.h、prelude/slang-cpp-types.h、prelude/slang-cpp-scalar-intrinsics.hC 宿主prelude/slang-cpp-host-prelude.hTorchprelude/slang-torch-prelude.hLLVMprelude/slang-llvm.hGLSL、Metal、WGSL 与 SPIR-V 没有prelude/头其依赖的内建词汇由各自后端文件发射。依赖文件输出slang-emit-dependency-file.cpp 的writeDependencyFile生成 Make 风格依赖文件每个编译产物一行output-file: dep dep ...输出到 stdout 时以-为目标按 make 要求转义路径未请求输出路径时为空操作。构建系统用它跟踪头文件/模块依赖。驱动入口高层编排对象编排上述各阶段的高层对象位于 source/slangslang-compile-request.h 声明FrontEndCompileRequest/CompileRequestBase。CompileRequestBase持有拥有会话的Linkage提供整个解析与检查过程中使用的源管理器source manager、名字池name pool与文件系统slang-compile-request.cpp 实现它们并编排每翻译单元per-translation-unit的前端工作。其checkAllTranslationUnits对每个未检查的翻译单元调用一次checkTranslationUnit把每个检查过的模块加入LoadedModuleDictionary以便后续importdecl 找到它并在降级前以checkEntryPoints()收尾。一个单元只在检查完成后才注册因此同一请求中import只对排在其前的兄弟翻译单元可见之后加入的单元对它不可见。slang-end-to-end-request.h 声明EndToEndCompileRequest——一次slangc调用或slang::ICompileRequest即变成它实现在 slang-end-to-end-request.cpp。slang-module.h 声明Module——前端产出的结果对象AST IR也是 include/slang.h 中IModule的实现。slang-code-gen.cpp 是后端目标分发器在前端为待生成目标产出复合IComponentType后被调用slang-emit.cpp 是它调用的链接 IR 与 IR-pass 编排器并为文本目标选择 C 风格源发射器。这些对象的架构级介绍见 docs/generated/design/architecture/overview.md。横切关注点Cross-cutting concerns若干关注点触及每个阶段集中在 docs/generated/design/cross-cutting 下而非任一阶段文档内诊断Diagnostics——每个阶段都通过DiagnosticSink报告。见 docs/generated/design/cross-cutting/diagnostics.md。IR 指令IR instructions——操作码目录docs/generated/design/cross-cutting/ir-instructions.md被降级、每个 IR pass 与发射共享。目标与能力Targets and capabilities——目标/profile 形状的选择塑造后端阶段的行为。见 docs/generated/design/cross-cutting/targets.md。核心模块 / Preludes——为前端提供内建类型与内建函数并把文本注入发射代码。见 docs/generated/design/cross-cutting/core-module.md。序列化Serialization——AST 与 IR 都可跨管线阶段保存/加载。见 docs/generated/design/cross-cutting/serialization.md。如何继续深入本文是各阶段文档的索引。按需深入时逐阶段阅读 01-lex-preprocess.md词法/预处理细节token 模型、源位置编码、字面量扫描与取值分离、宏展开、#include解析、#pragma warning状态、02-parse-ast.md两阶段解析、泛型消歧、AST 数据模型与ASTBuilder的 arena 分配与类型 hash-consing、03-semantic-check.mdSemanticsVisitor家族分工、泛型特化失败诊断、可微性即一致性、04-ast-to-ir.mdLoweredValInfo复合形态、IRBuilder、见证表降级、可微性一致性的三处消费、05-ir-passes.mdpass 全目录与相位骨架、06-emit.md发射分发器、各后端、SourceWriter 抽象、preludes、新增后端步骤。链接前与布局相关的两个相邻管线见 04b-pre-link-passes.md翻译单元内、目标无关的强制 pass 序列与 04c-layout-ir.mdTargetProgram::createIRModuleForLayout构建的独立布局 IR 模块。按目标查看已解析的 pass 顺序图见 docs/generated/design/target-pipelines 下的五页spirv、hlsl、metal、wgsl、cuda。赞分享编译器图形学编程语言【免费下载链接】slangMaking it easier to work with shaders项目地址https://gitcode.com/GitHub_Trending/sl/slang点击查看免费下载相关推荐Slang 编译器编译管线全景从源码缓冲到目标产物的六阶段流程与驱动实现Slang 编译器编译管线全景从源码缓冲到目标产物的六阶段流程与驱动实现 本篇技术指南以 SlangShader Language开源编译器仓库中的 pi编译器图形学编程语言Slang 翻译流水线全解析从源码到目标代码的三阶段编译框架Slang 翻译流水线全解析从源码到目标代码的三阶段编译框架 本文以 Slang 编译器的翻译总览Translation Overview为核心系统讲解编译器图形学编程语言MicroPython 编译器源码解析从语法规则到字节码与本地代码的四阶段编译流水线MicroPython 编译器源码解析从语法规则到字节码与本地代码的四阶段编译流水线 本文基于 MicroPython 官方开发者文档 docs/develo嵌入式语言运行时编程语言解释器编译器物联网系统编程上一篇5分钟上手LovyanGFX从安装到点亮屏幕的快速入门教程下一篇cool-admin(midway版)前端权限管理高级实践指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考