无用代码删除
复习
- 常量传播:把确定是常量的变量替换为常量
- 数据流分析:活跃变量分析
- 控制流图:判断可达性
TL;DR
- 无用代码指永远不会执行、或结果没人使用的代码
- 分为不可达代码与死代码两类
- 它们依赖可达性分析和活跃变量分析来发现
- 删除它们能减小体积、提升速度
正文
常量传播常常会“算死”一些分支,从而暴露出那些永远不会执行的代码。把这些没用的代码删掉,就是无用代码删除(dead code elimination)。
两类“没用”
“没用”分两种:
- 不可达代码:根本执行不到。比如某个条件在编译期就能判定恒假,它包住的那段代码永远不会运行
- 死代码:会执行,但结果没有人用。比如算出一个值,却从来没有被读取过
前者是“走不到”,后者是“白算了”。
靠分析来发现
怎么知道哪些代码没用?还是靠前面的分析:
- 用可达性分析:从入口出发,哪些块根本到不了,就是不可达代码
- 用活跃变量分析:某个变量算出来之后,后面还有没有人用;没人用,那段计算就是死代码
举个小例子:
x = 1
x = 2
用 x
第一次给 x 赋的 1,立刻被 2 覆盖了,从没被读过——这就是死代码,可以删掉。
小心副作用
但删“结果没人用”的代码时,必须格外小心一件事:它有没有副作用?
如果那行代码虽然结果没人用,却会打印、写文件、修改共享状态,那它就不能被当成“没用”删掉——因为它对外的影响是有人“用”的。只有真正“纯”的计算,才允许因为结果没人用而被删除。
这也再次呼应了优化的第一原则:删可以,但行为不能变。
思考题 1
“不可达代码”和“死代码”,有什么区别?
思考题 2
删除“结果没人用”的代码时,为什么还要小心?
小结
知识点
- 无用代码分为不可达代码与死代码
- 可达性分析发现不可达代码
- 活跃变量分析发现死代码
- 有副作用的代码不能因“结果没人用”而删除
参考资料
- Wikipedia(zh):死代码消除:移除不会影响结果的代码
- Wikipedia(zh):活跃变量分析:判断变量之后是否还会被使用
思考题答案(仅供参考)
思考题 1
不可达代码是根本执行不到的代码(例如恒假条件包住的代码);死代码是会执行、但产生的结果没有任何人使用。前者“走不到”,后者“白算了”。
思考题 2
因为有些代码虽然结果没人用,却带有副作用(打印、写文件、改共享状态等)。这些副作用是外部的可观察行为,删除它会改变程序行为,违反优化原则。所以只有纯计算才允许删。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪