作者业余为 Common Lisp 编译器 Cleavir 写代码,这次实现了 G. A. Kildall 1973 年《A Unified Approach to Global Program Optimization》里的通用算法:定义一个由「池」构成的有界半格、一个「给定指令节点与池、返回新池」的优化函数,然后用工作表在指令图上迭代到不动点。所有控制流——分支、循环——由算法统一处理,业务代码只剩半格定义与规则,五十来行就完成了闭包逃逸分析。
🔑 核心要点
Cleavir 用 HIR/MIR 图表示程序,图结构本来就适合这类数据流分析。
逃逸分析只需跟踪「变量是否逃逸」:返回算逃逸、加法不算,meet 是取并集,上界是「全部逃逸」。
规则保守到近乎粗暴:FUNCALL 的第一个输入(被调函数)不逃逸,其余参数一律视为逃逸。
得到「GETX 不逃逸」后,闭包就能按栈纪律分配,少一次堆分配和 GC 压力。
闭包里的 cell(可变捕获)要难得多:必须处理嵌套函数,而 Kildall 原论文没考虑这一点。
💡 金句
The beautiful thing here is that all we actually need to have in the code are the definition of the semilattice and the optimization function rules, and the algorithm handles all the control flow.