一种C语言编译效率优化的方法与流程

文档序号:17159556发布日期:2019-03-20 00:28阅读:394来源:国知局
一种C语言编译效率优化的方法与流程

本发明涉及编译器技术领域,特别是涉及c语言的编译优化技术,具体是涉及一种c语言编译效率优化的方法。



背景技术:

c语言是一种结构化语言,具有丰富的运算符和数据类型,便于实现各类复杂的数据结构。它还可以直接访问内存的物理地址,进行位(bit)一级的操作。由于c语言实现了对硬件的编程操作,因此c语言集高级语言和低级语言的功能于一体。c语言还具有效率高,可移植性强等特点,因此可以广泛的移植到了各种平台的计算机或单片机上。

编译是从源代码到能直接被计算机或虚拟机执行的目标代码的翻译过程,首先编译器进行语法分析,也就是要把那些字符串分离出来,然后进行语义分析,就是把各个由语法分析分析出的语法单元的意义搞清楚。最后生成的是目标文件,也称为obj文件,再经过链接器的链接就可以生成最后的exe文件。

伪指令是所有编译器在进行词法、语法、语义分析后,生成的中间代码,中间代码与具体机器无关,最后再由中间代码生成目标机器代码。

c语言编译器的编译效率是衡量一个编译器好坏的重要指标,编译出来二进制文件越小,程序占用的rom空间也就越小,在程序存储器空间受限的系统上面,这点非常重要,可以大大降低产品成本,提高系统性能。



技术实现要素:

本发明的目的是提供一种c语言编译效率优化的方法,该方法是在c语言编译器从中间的伪指令在生成汇编码前,针对中间的伪指令进行优化,通过该方法其编译出来的hex格式文档较传统的优化10%至20%,进而提高嵌入式应用程序的运行速度并能够使用节省的存储器大小来提供更丰富的功能。

本发明的是通过以下的技方案来实现的:

本发明的技术方案是提供一种c语言编译效率优化的方法,该方法包括如下的步骤:

s1、获取每个节点中的节点信息,对节点信息进行保存,其中的每个节点是指每一条伪指令,一条伪指令就是一个节点,节点信息包括有指令编号、指令的各操作数、返回值的类型、指令类型、及指令的引用关系;

s2、根据节点中指令的引用关系,找出每个节点的前置节点和引用节点,其中,前置节点是指一个节点的运行需要依赖的位于其前面的节点;引用节点是指在一个节点中引用的其它节点,两个节点相互构成为依赖节点。

s3、获取位于第一个节点的所有依赖节点,把第一个节点向下移动到有依赖节点时停止下沉,重复该步骤操作,对每个节点依次执行该步骤,这样就让每个节点的前置节点中的依赖节点尽量靠近自已;

s4、获取位于最后一个节点的所有依赖节点,把第一个节点向上移动到有依赖节点时停止上移,重复该步骤操作;在上移过程中,判断该节点的前面是否是依赖节点,如果是,则把该节点放至依赖节点的下面,也就是让自已尽量靠近到所依赖节点的下面;

s5、删除所有节点中开始的movelw指令,开始位置的movelw指令是常量移动到工作寄存器的指令,这些指令cf无效对于工作寄存器来说没有影响;

s6、删除所有节点中连续的movfw_es指令和movwf_es指令;

s7、删除所有节点中连续的movewf指令,因为两条连续的移动变量至工作寄存器,只有最后一条才会影响到工作寄存器,前面的都可以删除。

本发明的技术方案通过对生成目标代码前的伪指进行优化,以达到减少机器码量,从而提高编译的效率。

附图说明

图1是c语言编译器将源代码编译成目前代码的工作流程图。

图2是本实施例中的方法的处理流程图。

图3是本实施例中的向下移动节点的原理图。

图4是本实施例中的向上移动节点的原理图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。

如图1所示,c语言编译器分通常分为前端和后端两个部分,前端进行词法、语法分析和语义分析,产生中间ir(指令寄存器)指令,ir指令作为后端的输入,再经过各种指令选择、指令调度、寄存器分配、指令调度及代码生成,最终生成目标代码,本方是在第二次指令调度中执行,在生成目标代码前,先对伪指令再次进行优化,来达到减少机器码量的。

以如下的一段c语言源代码为例:

按现有的c语言编译器则生成的伪指令序列为:

t26:i8=movlw-26targetconstant:i8-90<0>

t41:ch=clrf-41targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-93<4>,t0

t43:ch=clrf-43targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-94<5>,t0

t44:ch=tokenfactor-44t41,t43

t45:ch=clrf-45targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-92<2>,t44

t47:ch=clrf-47targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-91<3>,t44

t48:ch=tokenfactor-48t45,t47

t49:ch=clrf-49targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-93<4>,t48

t50:ch=clrf-50targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-94<5>,t48

t51:ch=tokenfactor-51t49,t50

t30:i8=movlw-30targetconstant:i8-95<100>

t57:i8,i8,ch,glue=addfw_cfromload-57t30,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-92<2>,t51

t58:i8,i8,ch,glue=addfw_cfromload-58t26,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-91<3>,t51,t57:3

t61:ch=pic16cycleinst-61t57,t0

t62:ch=pic16cycleinst-62t58,t0

t88:ch=tokenfactor-88t61,t62,t57:2,t58:2

t64:ch=movwf_es-64t57,targetconstant:i8-90<0>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t88

t65:ch=movwf_es-65t58,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t88

t66:ch=tokenfactor-66t64,t65

t73:i8,i8,ch=movfw_es-73targetconstant:i8-94<5>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t66

t72:i8,i8,ch=movfw_es-72targetconstant:i8-93<4>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t66

t77:i8,i8,ch,glue=addfw_cfromload-77t72,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-92<2>,t66

t78:i8,i8,ch,glue=addfw_cfromload-78t26,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-91<3>,t66,t77:3

t81:ch=pic16cycleinst-81t77,t0

t82:ch=pic16cycleinst-82t78,t0

t87:ch=tokenfactor-87t81,t82,t72:2,t77:2,t78:2

t84:ch=movwf_es-84t77,targetconstant:i8-90<0>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t87

t85:ch=movwf_es-85t78,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t87

t86:ch=tokenfactor-86t84,t85

t24ch=retuan-24t86

在该伪指令序列中,以t57节点为列解释如下,其中t57表示该条指令的编号,i8,i8,ch,glue表示该条指令的各操作数、返回值的类型;addfw_cfromload表示指令类型;t30表示该处的参数是t30的指令输出,t30是t57的前置节点;targetconstant,targetexternalsymbol表示参数是常量或一个外部符号;t51是t57指令的前置节点,也就是说,需要先执行t51后,才能再执行t57。

再经过代码生成后,生成的汇编代码如下:

可以看到,因为t57的计算需要用到4个参数,因些,需要把这些参数反复的从临时寄存器推到工作寄存器,并执行addwfc指令,如果某个变量正好处于工作寄存器,则不需要执行move动作,如果能够使指令的所有依赖参数能提到指令前,则可以大大减少move指令的数量。因此,本实施例就是要尽量把指令的依赖指令移动该指令的前面,但必须正确处理指令的优先级及依赖关系。

同样以上述的c语言源代码为例,本实施例是提供一种c语言编译效率优化的方法,主要包括如下步骤:

1、从伪指令序例中的每行节点中提取节点信息,节点信息保存在下面的结构体中,

structnodedata

mntypemtype;//节点类型

unsignedopcode;//指令操作码

unsignedmc_opcode;//mc指令操作码

intnumopts;//操作数的数量

sdnode*poptsd[max_opts_num];//操作数节点

intposrefsd;//refsd在操作数列表中的位置

sdnode*prefsd[2];//

intposfrontsd;//frontsd在操作数列表中的位置

sdnode*pfrontsd;

intposgluesd;//gluesd在操作数列表中的位置

sdnode*pgluesd;

intpossymbol;//符合操作数的位置

intposimm;//立即数的位置

externalsymbolsdnode*pes;//如果是targetexternalsynbol

globaladdresssdnode*pga;//如果是targetglobaladdress

regeistersdnode*preg;//如果是copytoreg或copyfromreg

int64_tconstval;//如果是targetglobaladdress表示位索引,如果是targetexternalsynbol,表示此拟寄存器的索引号;

//boolistempsym;//是否为临时符号

boolismovedownfail;//是否该节点尝试往下移失败,如果该节点不能往下移,那么也不允计其它节点往上移动到该节点的上面

uint32_tflags;

intmovenum;//该节点被移动了多少次

structnodedata*pnext;//下一个节点

2、根据每个节点中引用关系,找出前置节点和引用节点,如代码中的t88,它的前置节点为t61,t62,t57,t58,而在t57中又引用了t30。

3、获取伪指令序列中的第一个节点的依赖节点,把第一个节点向下改变顺序,当发现有依赖节点时,停止下沉,对伪指令序列中的每个节点依次执行该操作,这样就让所有依赖节点尽量靠近自已。其原理如图3中所示,t5依赖于t1,不断的进行下沉判断,直到t1位于t5上面为止。

4、经过上述步骤处理后的伪指令序列中,获取最后一个节点的所有依赖节点,再将最后一个节点开始向上移动,判断其上方的目标节点是否为依赖节点,如果是,则把该节点放至目标节点下面,否则继续向上移动,对伪指令序列中的每个节点依次执行该操作,也就是要让该节点尽量靠近到所依赖节点的下面,其原理如图4中所示,t9依赖于t5,不断的进行上移判断,直到t9位于t5上面为止。

5、删除所有节点中开始的的movelw指令。

6、删除所有节点中连续的movfw_es指令和movwf_es指令。

7、删除所有节点中连续的movewf指令。

经过上述步骤处理后优化后的伪指序列如下:

t41:ch=clrf-41targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-93<4>,t0

t43:ch=clrf-43targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-94<5>,t0

t44:ch=tokenfactor-44t41,t43

t45:ch=clrf-45targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-92<2>,t44

t47:ch=clrf-47targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-91<3>,t44

t48:ch=tokenfactor-48t45,t47

t49:ch=clrf-49targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-93<4>,t48

t50:ch=clrf-50targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-94<5>,t48

t51:ch=tokenfactor-51t49,t50

t30:i8=movlw-30targetconstant:i8-95<100>

t57:i8,i8,ch,glue=addfw_cfromload-57t30,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-92<2>,t51

t64:ch=movwf_es-64t57,targetconstant:i8-90<0>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t88

t26:i8=movlw-26targetconstant:i8-90<0>

t58:i8,i8,ch,glue=addfw_cfromload-58t26,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-91<3>,t51,t57:3

t65:ch=movwf_es-65t58,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t88

t88:ch=tokenfactor-88t61,t62,t57:2,t58:2

t66:ch=tokenfactor-66t64,t65

t72:i8,i8,ch=movfw_es-72targetconstant:i8-93<4>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t66

t77:i8,i8,ch,glue=addfw_cfromload-77t72,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-92<2>,t66

t84:ch=movwf_es-84t77,targetconstant:i8-90<0>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t87

t73:i8,i8,ch=movfw_es-73targetconstant:i8-94<5>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t66

t78:i8,i8,ch,glue=addfw_cfromload-78t26,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-91<3>,t66,t77:3

t85:ch=movwf_es-85t78,targetconstant:i8-89<1>,targetexternalsymbol:i8-25’_main.temp.’,targetconstant:i8-89<1>,t87

t87:ch=tokenfactor-87t81,t82,t72:2,t77:2,t78:2

t86:ch=tokenfactor-86t84,t85

t24ch=retuan-24t86

可以发现,中间的伪指令已减少多条,再经过代码生成后,生成的汇编代码如下:

通过比较,可以很明显的看到生成的汇编指令少了九条,本实施例仅是以简单的一小段代码为例,在实际中c语言源代码通常都是上万或几十万条,经过优化后的汇编指令能更多的提高效率。

以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1