ucc编译器(优化)

语言: CN / TW / HK

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

编译器优化几乎是现代编译器最重要的工作。一般编译器的优化有这么几层,a,中间代码生成前的优化,比如常量计算等等;b,中间代码生成后的优化,比如临时变量的删除,特别是那些只赋值不使用的变量;c,汇编阶段的优化,调节汇编指令的顺序,优化流水线,比如说寄存器不要写完后马上读;d,链接阶段的优化,删除从来没有使用的函数6

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,总结

ucc提供的优化方法其实不算很多,但是瑕不掩瑜,它相当于给我们打开一个优化的窗户,真正优化的方法要比这里看到的多得多。关于这方面的内容,推荐大家更多看看龙书中相关章节的内容。