Skip to content

语义保持的编译器阶段

Semantics-preserving compiler pass · Correct compiler transformation · 编译阶段语义保持

在固定观察、错误与未定义行为契约下,要求一次编译变换的目标程序不产生源程序未允许的行为。

条目类型
定义

形式陈述

设编译阶段 C 把源中间表示程序 P 成功变换为目标程序 Q=C(P)。先用小步语义为两层语言定义完整行为,包括有限可观察事件迹 t 后正常返回 v、以错误或 trap 终止、产生无限迹或静默发散。将这些行为集合记作 BehS(P)BehT(Q)。本页采用实现精化规格的方向:

BehT(C(P))BehS(P).

这正是精化关系的“目标不新增源未允许观察”口径。源语义若非确定,目标可以选择其中一种合法行为,未必保持集合相等;若源程序安全且语义确定,并另证不丢失终止或发散行为,才可能加强为相同观察。

命题还要规定未定义行为。若源一旦 UB 就允许任意后续行为,可把 UB 状态解释为行为全集的顶部,编译器在该点之后无需提供通常保证;trap 若是确定、可观察的终止事件,则不能与 UB 混同。外部调用、I/O 顺序、终止值、发散与资源耗尽是否进入观察,都属于定理参数而不是自然语言省略项。

环境也须满足共同假设。例如源、目标调用同名外部函数时,参数编码与返回关系要一致,环境不得在两层观察本应隐藏的内部临时状态。对开放程序,定理通常量化所有满足接口约束的环境;只固定测试时使用的一套库,会把链接假设误装成编译器本身的正确性。

直觉

语义保持不是要求源、目标逐条指令相同,而是要求外部观察者无法看到契约禁止的新结果。优化可以删除临时量、合并基本块或把一条指令扩成数步;状态形状和步数因此不同。证明需要一座桥,把两边状态及若干步对应起来,最终比较完整行为。

“保持”也不总是双向相等。源语言可能允许表达式求值顺序的多种结果,编译器固定其中一种,这是减少非确定性,仍满足目标行为包含于源行为。反过来,若目标新增一个崩溃结果,即使它还保留所有正常结果,也破坏上述精化方向。

例子与边界

设源 IR 的常量计算分两步:

(t:=2+3; y:=t×x,ρ)(y:=5×x,ρ[t5])(returny,ρ[y5x]).

常量折叠目标直接含 y:=5×x。若整数运算均为同一宽度的模运算且赋值无可见事件,源的第一步可由目标零步匹配,第二步由一次目标步匹配,最终返回相同位串。这里减少内部步不影响观察,但证明必须使用状态关系忽略死临时量 t

边界例取 0×load(p)0。在纯数学中等式成立;若读取 p 可能越界 trap、触发 volatile 设备或参与原子顺序,目标删除了源的可见事件或错误,便不是同一契约下的语义保持。类似地,把有符号除法替换为右移可能对负数采用不同舍入方向,几个正数测试全部通过也无法覆盖反例。

回归测试只检查有限输入和有限运行。即使一百万次测试都相等,也不能推出所有状态、路径、发散执行与环境交互上的集合包含。测试适合发现实现错误,语义定理则量化全部合法程序和执行;两者作用互补,不能互相改名。

源程序已触发 UB 与“编译器提前制造 UB”也要区分。若某输入的源执行在第十步才越界,目标不能在第一步、尚未匹配前九步可见事件时任意行动。行为顶部只从已到达 UB 的相关状态开始放宽;在此之前,模拟仍要保存事件前缀与状态不变量。

推论与应用

若每个阶段 Ci 都在相容观察下满足行为精化,则集合包含的传递性给出整条编译流水线

Beh(CnC1(P))Beh(P).

组合要求相邻 IR 对事件、返回和错误的编码一致;一层把 trap 当事件、下一层把它当 UB,会让形式上可复合的符号失去实际含义。

常用证明方法包括编译器前向模拟编译器后向模拟、逻辑关系和翻译验证。它们是建立语义保持的不同证据接口,并不等于性质本身。选择方法应由确定性、非确定性、内部停顿与阶段实现的可信边界决定。

参考资料
  • Xavier Leroy, “Formal Verification of a Realistic Compiler,” Communications of the ACM 52(7), 2009, pp. 107–115.
  • Xavier Leroy, “A Formally Verified Compiler Back-end,” Journal of Automated Reasoning 43(4), 2009, pp. 363–446.
  • John C. Reynolds, Theories of Programming Languages, Cambridge University Press, 1998, Chapters 6–8.
关系图谱14 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系