编译器的优化方法

常见的编译器优化方法

寄存器分配

寄存器分配是指,编译器将内存中的值缓存在寄存器中,之后一直用访问寄存器来代表对这个内存的访问的。

由于计算机中内存访问速度远远不如寄存器的访问速度,所以比编译器一般会把变量拷贝至寄存器中以提高访问速度。但是寄存器的数量是有限的。

新型 x86 处理器提供以下可以通过编译器进行分配的寄存器:

所有 x64 处理器提供 16 个 64 位的通用寄存器、8 个 80 位的浮点寄存器和至少 16 个矢量寄存器(每个矢量寄存器至少 128 位)。

常量折叠 (Constant Folding)

常量折叠,又称常量传播 (Constant Propagation),如果一个表达式可以确定为常量,在他的下一个定义 (Definition) 前,可以进行常量传播。常量,就是说在编译期时,能够直接计算出结果(这个结果往往是常量)的变量,将被编译器由直接计算出的结果常量来替换这个变量。

1
2
3
4
5
int x = 1;
int y = x; // x = 1, => y = 1
x = 3;
int z = 2 * y; // z => 2 * y = 2 * 1 = 2
int y2 = x * 2; // x = 3, => y2 = 6

这段代码在编译期间即可被转换为:

1
2
3
4
5
int x = 1;
int y = 1;
x = 3;
int z = 2;
int y2 = 6;

也就是直接使用等号右边的常量值来代替左边的’变量’

死代码消除 (Deadcode Elimination)

没有使用到的代码将会被编译器删除

1
2
3
4
5
6
7
double fun (void)
{
int x = 1;
int y = 2;
double xx = 1231.2312;
return xx;
}

该代码将会被转换为:

1
2
3
4
5
double fun (void)
{
double xx = 1231.2312;
return xx;
}

公共子表达式删除

公共子表达式消除是说,如果一个表达式E已经计算过了,并且从先前的计算到现在的E中的变量都没有发生变化,那么E的此次出现就成为了公共子表达式,因此,编译器可判断其不需要再次进行计算浪费性能。

参考资料

编译器使用的寄存器分配优化

https://zhuanlan.zhihu.com/p/381490718

https://oi-wiki.org/lang/optimizations/


编译器的优化方法
https://ysc2.github.io/ysc2.github.io/2023/11/09/编译器的优化方法/
作者
Ysc
发布于
2023年11月9日
许可协议