“一种小可信基架构让外部 allocator 产生位置映射与重写程序,再以翻译验证检查:所有干涉边颜色不同、预着色与类别正确、spill 槽分离、每条重写指令满足局部状态关系。只要 check…”
形式陈述 ​
翻译验证把编译器或优化器视作可能不受信任的产生器。给定源程序
关键定理不是“编译器总正确”,而是验证器的可靠性:
右侧采用语义保持阶段的行为精化契约。验证器可以不完备,即对某些其实正确的输出拒绝;流水线此时应回退、重编译或报告失败,绝不能把 reject 当作“可能也没问题”继续发布。若用小步语义检查局部模拟,证书通常给出控制点映射、状态关系、数据流事实或每条目标边的源路径见证。
验证器本身的可信边界必须明示。可在证明助理中证明
为了让这条蕴含可部署,
直觉
与其证明一座巨大工厂永远不会装错零件,翻译验证在每件成品出厂时核对它与订单。优化器可以使用复杂启发式甚至外部求解器,只要每次输出都附带足够证据,简单检查器就能确认这一个源—目标对没有新增行为。
这种分工把“找到优化”和“检查优化”分开。前者可不完备、依赖性能技巧,后者力求小、确定且有可靠性证明。它特别适合搜索算法复杂、但候选结果的验证条件清晰的阶段,例如寄存器着色、指令调度或局部等价检查。
例子与边界
源块先执行
若优化器误产出
边界还包括算法覆盖率。一个只理解常量折叠的验证器可能拒绝完全正确的循环展开,这是只影响完备性的假阴性。真正危险的是破坏 soundness 的假阳性:checker 接受错误翻译。随机测试源、目标在若干输入相等可以协助筛错,却没有给出对所有输入和路径的可靠性定理。
推论与应用
翻译验证不等于验证整个编译器。它证明的是“每个被接受的输出正确”;若构建脚本允许绕过 validator、证书与二进制配错,或拒绝后仍使用目标,端到端保证就断裂。部署流程必须把 accept 绑定到确切的源、目标、配置与语义版本。
验证器可采用前向模拟证书、后向模拟证书、SMT 可证等价或专用校验条件。不同方法仍要落到同一观察契约。验证多个阶段时,可以逐阶段检查并组合精化,也可对源与最终目标做全局验证;前者定位清楚,后者可能发现跨阶段对应,但证书更难生成。
逐阶段组合还要求阶段一的目标语义与阶段二当作源语义的版本完全一致,包括整数宽度、外部事件、调用约定和 UB 解释。两个 checker 即使各自可靠,若通过不同解析器理解同一中间文件,集合包含也无法首尾相接。验证器的完备性仍非安全要求:正确优化被拒绝只影响可用性;但拒绝路径必须真的停止或回退到已验证结果。
参考资料
- Amir Pnueli, Michael Siegel, and Eli Singerman, “Translation Validation,” in TACAS 1998, LNCS 1384, Springer, pp. 151–166.
- George C. Necula, “Translation Validation for an Optimizing Compiler,” PLDI, 2000, pp. 83–94.
- Jean-Baptiste Tristan and Xavier Leroy, “Formal Verification of Translation Validators: A Case Study on Instruction Scheduling Optimizations,” POPL, 2008, pp. 17–27.