ucc编译器(优化)
Posted 费晓行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ucc编译器(优化)相关的知识,希望对你有一定的参考价值。
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
编译器优化几乎是现代编译器最重要的工作。一般编译器的优化有这么几层,a,中间代码生成前的优化,比如常量计算等等;b,中间代码生成后的优化,比如临时变量的删除,特别是那些只赋值不使用的变量;c,汇编阶段的优化,调节汇编指令的顺序,优化流水线,比如说寄存器不要写完后马上读;d,链接阶段的优化,删除从来没有使用的函数
1、ucc编译器支持的优化
主要前面两种,即中间代码生成时的优化、生成后的优化
2、配套文件
中间代码生成前的优化,fold.c
中间代码生成后的优化,simple.c、flow.c
3、fold.c内容,主要是完成常量的计算
/**
* Constant folding. e.g. 3 + 4
*/
AstExpression FoldConstant(AstExpression expr)
{
// type code, see TypeCode().
int tcode;
union value val;
AstExpression expr1, expr2;
// other code
}
4, 中间代码生成后的优化
4.1 函数入口 simple.c/optimize
void Optimize(FunctionSymbol fsym)
{
BBlock bb;
// iterater every basic block, do peep hole optimization
bb = fsym->entryBB;
while (bb != NULL)
{
PeepHole(bb);
bb = bb->next;
}
// iterate every basic block, eliminate dead code
bb = fsym->entryBB;
while (bb != NULL)
{
EliminateCode(bb);
ExamineJump(bb);
bb = bb->next;
}
bb = fsym->entryBB;
while (bb != NULL)
{
bb = TryMergeBBlock(bb, bb->next);
}
}
4.2 优化方法之PeepHole
这种方法类似于滑动窗口,看看特定窗口之内有没有冗余代码。一边删除冗余代码,一边移动窗口往前滑行。比如,这种赋值,
/**
t1:f(); --- inst
num = t1; --- ninst
/After Optimization
num:f();
*/
4.3 优化之EliminateCode
这种方法主要是删除只使用一次的中间变量。
if (opds[0]->kind == SK_Temp && opds[0]->ref == 1)
{
opds[0]->ref = 0;
opds[1]->ref--;
if (opds[2]) opds[2]->ref--;
inst->prev->next = inst->next;
inst->next->prev = inst->prev;
found = 1;
bb->ninst--;
}
4.3 优化之ExamineJump
这种方法主要是删除无效跳转。
/**
* jump to jump conditional jump to jump
*
* jmp bb1 if a < b jmp bb1
* ... ...
* bb1: jmp bb2 bb1: jmp bb2
*
*/
4.4优化之TryMergeBBlock
这种优化是对相连的block进行处理,总共有6种情况,分别是
a,bb2 == NULL
b,bb1->nsucc == 1 && bb2->npred == 1 && bb1->succs->bb == bb2
c,bb1->ninst == 0
d,bb2->ninst == 0 && bb2->npred == 0
e,bb2->ninst == 0 && bb2->npred == 1 && bb2->preds->bb == bb1
f,其他
5、gcc的优化
-O0、-O1、-O2、-O3、-Og、-Os、-Ofast
具体意义,参考https://zhuanlan.zhihu.com/p/196785332
平常使用,一般就是-O0、或者直接-O3
中间的优化很少使用
6、汇编指令顺序的调整
编译顺序的调整主要是为了让cpu执行的更快
比如
add ax, ax, bx
sw ptr[0], ax
add cx, cx, dx
sw pr[1], cx
如果优化一下顺序,可以变成
add ax, ax, bx
/* other instructions */
add cx, cx, dx
/* other instructions */
sw ptr[0], ax
/* other instructions */
sw pr[1], cx
/* other instructions */
7、gcc中去除不需要的链接函数
编译时添加 -ffunction-sections -fdata-sections
链接时添加-Wl,-gc-sections即可
8,总结
ucc提供的优化方法其实不算很多,但是瑕不掩瑜,它相当于给我们打开一个优化的窗户,真正优化的方法要比这里看到的多得多。关于这方面的内容,推荐大家更多看看龙书中相关章节的内容。
以上是关于ucc编译器(优化)的主要内容,如果未能解决你的问题,请参考以下文章