tag: 编译, 编译原理, 优化, 常量传播
不多说 先看结果
//源文件
{ Sample program
in TINY language
}
x:=4;{read x;} { input an integer }
if 0 < x then { don't compute if x <= 0 }
fact := 1;
repeat
fact := fact * x;
x := x - 1
until x = 0;
write fact { output factorial of x }
end
//parser之后未优化的结果
x:= 4
__compare_inner_1:= 0
__compare_inner_2:= x
__compare_inner_0:= __compare_inner_1 < __compare_inner_2
test __compare_inner_0
jz L-else
fact:= 1
L-repeat:
__compare_inner_3:= fact
__compare_inner_4:= x
fact:= __compare_inner_3 * __compare_inner_4
__compare_inner_5:= x
__compare_inner_6:= 1
x:= __compare_inner_5 - __compare_inner_6
__compare_inner_8:= x
__compare_inner_9:= 0
__compare_inner_7:= __compare_inner_8 = __compare_inner_9
test __compare_inner_7
jnz L-repeat
write fact
jmp L-end
L-esle:
L-end:
//常量传播之后
x:= 4
__compare_inner_1:= 0
__compare_inner_2:= 4
__compare_inner_0:= 1 < 4
fact:= 1
__compare_inner_3:= 24
__compare_inner_4:= 1
__compare_inner_5:= 1
__compare_inner_6:= 1
__compare_inner_7:= 1
__compare_inner_8:= 0
__compare_inner_9:= 0
fact:= 24
x:= 0
write fact
//去掉无用的代码
fact:= 24
write fact
if的常量传播只要取两个分支的交集就可以了
while的常量传播麻烦一些, 我是试着传播100次循环, 看在这之内有没有退出while. 如果退出就可以把这个while优化成 if(1), 如果不能退出就重新按while(1)来重新对while优化.
//已经上传到github
https://github.com/0x00-pl/my_prog/tree/dev/mtcc/mtcc