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编译器(优化)的主要内容,如果未能解决你的问题,请参考以下文章

ucc编译器(汇编生成)

ucc编译器(语义分析)

ucc编译器(词法分析)

ucc编译器(语法解析)

ucc编译器(中间代码生成)

EAN、ITF-14、UCC/EAN-128三种条码分别都有哪些特征?