🚀 优质资源分享 🚀
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
💛Python量化交易实战💛 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
**摘要:**常量传播,顾名思义,就是把常量传播到使用了这个常量的地方去,用常量替换原来的变量。
本文分享自华为云社区《编译器优化那些事儿(2):常量传播》,作者:毕昇小助手。
基础知识盘点
- **基本块 (Basic Block):**一个基本块内的指令,处理器会从基本块的第一条指令顺序执行到基本块的最后一条指令,中间不会跳转到其它地方去,也不会有其它地方跳转到基本块的非首条指令上来。
- **控制流图 (Control Flow Graph):**控制流图的节点是基本块,边代表基本块之间的跳转。基本块A到基本块B有一条边,表示基本块A的最后一条指令是一个跳转指令,跳转到了基本块B的第一条指令;或者基本块A的最后一条指令执行完可以顺序的走向基本块B的第一条指令。
- **SSA (Static Single Assignment):**静态单赋值,指程序的一种表示形式,在该形式中变量只被赋值一次,如果变量需要更新,会使用一个新的变量。决定使用哪个分支处的变量,会使用Φ函数。
例如
min = a;
if(min > b)
min = b;
return min;
转换为SSA形式为:
min = a;
if(min > b)
min2 = b;
return Φ(min, min2)
- **局部优化:**指基本块内,跨指令的优化。
- **全局优化:**过程(函数)内的,跨基本块的优化。
- **过程间的优化:**跨过程(函数),编译单元的优化。
1.什么是常量传播
首先来认识一下什么是常量传播,常量传播也叫常量折叠,但有些资料中对它们的定义又是区分开来的。下面来看看它们分别是什么?
常量传播,顾名思义,就是把常量传播到使用了这个常量的地方去,用常量替换原来的变量。
x = 3;
y = 4;
z = x + y;
->
x = 3;
y = 4;
z = 3 + 4;
什么是常量折叠?常量折叠就是当运算符左右两边都是常数时,把结果计算出来替代原来的那部分表达式。
z = 3 + 4;
–>
z = 7;
现在的常量传播优化技术能同时实现上面介绍的传播和折叠的功能,所以现在通常不对它们加以区分,本文后续就把常量传播和折叠统称为常量传播了。
为什么会有常量?
程序中的常量来源有3种
- 程序员书写的,比如magic number
- 宏定义展开后带来的,这种情况在大型工程文件中非常普遍
- 在程序优化过程中由其它的优化技术带来的常数
为什么要进行常量传播优化?
从上面简单的例子中可以看到,常量传播可以把原本在运行时的计算转移到编译时进行,减小了程序运行时的开销。同时常量传播还有助于实现其它的优化,比如死代码消除。
如何实现?
前面介绍的常量传播的例子非常简单而且直观。如果程序的控制逻辑比较复杂时,判断一个变量是否是常数,就不是一件简单的事了,需要借助数据流的分析才能判断某个变量是否是常量。而且这个判断是保守的,即不能充分证明某个变量是常量的话就认为它是变量。这种保守的分析结果是可以接受的,因为我们优化程序的时候在性能提升