打开文档导航

为什么纯 AST 优化现在真的是 Pass

一句话

以前分散的 source/AST 优化现在先登记为带身份和执行阶段的 pass;纯 AST rewrite 也能作为 plugin 运行。Semantic pre-dispatch 已有 common-outcome adapter 和单测,但当前没有 production caller 自动调用它。

先看一个例子

这里先把两个前置概念说成人话。Semantic pre-dispatch 是“代码还没生成完时,先准备一个受限 read”;prepared pure-region 是“完整代码到达后,为一段纯计算生成执行 patch”。两者都必须绑定 exact source identity(这份代码的唯一身份),过去却各自描述“成功、丢弃、拒绝”和资源用量。

若以后再加一个纯 AST constant-fold pass,继续复制这些记账和绑定检查会让每条路径产生自己的术语。更糟的是,开发者可能把“生成了 derived AST”误当成“已经执行优化程序”,或把 prefix overlay 错送到 whole-program patch consumer。

真实机制

passregistration.Definition 现在把一个 pass 的稳定合同拆成五部分:name、version、stage、consumer 和 required bindings。绑定 analyzer/config 后得到 immutable Registration 与 identity digest。新增 pass 可以用 Define(...).Register(...) 注册,不需要修改旧的 central name switch。

当前 source-bound pass 有四个 registration:

PassStageConsumer谁拥有真实机制
semantic_pre_dispatchprefix_overlayoverlay_only既有 semantic/streaming lifecycle
prepared_pure_regionwhole_program_patchexecution_patch既有 prepared-region lifecycle
pure_scalar_csewhole_program_patchexecution_patchgeneric source-patch plugin
pure_scalar_foldwhole_program_patchexecution_patchgeneric source-patch plugin

passpipeline 是 Host-owned outcome shell(只检查和记录 pass 结果的外壳)。它提供四个有类型的记录入口,校验 stage、registration、binding、outcome、resource bound 和 deterministic order,再追加 immutable record。当前 registration 使用 prefix-overlay 与 whole-program-patch stage;另外两个入口不表示已经存在对应 optimizer。

Outcome 只能是 applieddiscardedprepared_awaiting_finalrejected,而且字段必须与处置一致。例如 rejected record 不能带 result、derived identity、logical/physical work 或 preparation bytes;discarded work 不能声称 logical event。一个 bound occurrence/region 最多投影一个 terminal outcome。

Pipeline record 只含 identity、计数、disposition 和 bounded resource use,不保存 source、result、workspace 或 prepared body。RecordSemanticPreDispatchPassOutcomes adapter 可以把已有 observation terminal state 投影成 prefix outcome;unit tests 覆盖该映射,但当前 production code 没有调用点。Adapter 本身不重新 dispatch、claim 或 cancel physical work。

其余接线要分开看。prepared_pure_region 有 immutable registration 和 static adapter,但仍完全走原本的 final-source sealing、target-Guest compile/execute 和 cleanup owner。两个 scalar pass 是真正可执行的 SourcePatchPlugin,由 passplugin.Registry dispatch;当前 registry 执行并不会自动调用 passpipeline.RecordWholeProgramPatch。因此统一的是 pass identity/stage 和可用的 outcome contract,不是所有 live path 已汇入同一个 ledger。

Pipeline 与 plugin registry 都默认 all-off,但处置不同:zero-enabled pipeline 的任何 record attempt 都返回 ErrAllOff 且不追加 record;mixed pipeline 中对 disabled pass 的 attempt 才产生 typed rejected/pass_disabled。Plugin registry 遇到 disabled pass 时直接执行 unchanged original request,当前不会自动追加 pipeline record。V0 outcome shell 还限制最多 16 个 pass、1 MiB source growth、8192 AST node growth、8 MiB preparation 和 16 次 reanalysis,caller 只能收紧,不能放宽。

为什么重要

技术上: “这是哪个 pass、在哪个 stage、需要哪些 binding”有了共同合同;Host 也有可复用的 terminal outcome schema。原有机制不用为了叫 pass 就把 authority/lifecycle 强行合并成一个执行器。

产品和业务上: Host 可以逐 pass 开关、记录拒绝和资源消耗,并在没有适用优化时保留原始执行路径。添加一个窄 pass 不再自动扩大 Broker、workspace 或调度系统。

不能推出什么

  • passpipeline 不执行 Agent Python、不调用 transform,也不选择 effect 发生后的 fallback。
  • 四个 stage 名称不是四类 optimizer 都已实现;当前没有 multi-program pass 或 generic hybrid optimizer。
  • 统一 outcome 不表示 semantic pre-dispatch、prepared region 和 source rewrite 共用同一个 runtime lifecycle。
  • 当前不能声称所有 registered pass 都自动向同一个 runtime outcome ledger 写记录。
  • 当前没有自动 pass ordering、冲突解决、fixed-point、generic IR 或 cost-based planner。

术语卡

  • Source-bound pass:结果与 exact source/AST 及所需 Host bindings 绑定的优化 pass。
  • Registration:冻结 pass 名称、版本、stage、consumer、analyzer/config 和 required bindings 的身份。
  • Stage:pass 产物进入执行前后的哪类 typed seam。
  • Outcome shell:只验证和记录 terminal metadata、不执行 transform 的 Host 组件。
  • Adapter:把既有机制接到共同 registration 或 outcome contract,而不复制其 owner。

继续阅读