《一种针对混合长度指令集的寄存器分配方法.pdf》由会员分享,可在线阅读,更多相关《一种针对混合长度指令集的寄存器分配方法.pdf(12页珍藏版)》请在专利查询网上搜索。
1、10申请公布号CN102360280A43申请公布日20120222CN102360280ACN102360280A21申请号201110333460222申请日20111028G06F9/30200601G06F9/31820060171申请人浙江大学地址310027浙江省杭州市西湖区浙大路38号72发明人李莹闫卫斌吴朝晖尹建伟邓水光吴健74专利代理机构杭州裕阳专利事务所普通合伙33221代理人江助菊54发明名称一种针对混合长度指令集的寄存器分配方法57摘要本发明公开了一种针对混合长度指令集的寄存器分配方法,通过对传统的图着色寄存器分配方法上进行少量的修改,即可充分利用混编指令集的特点,生成。
2、代码密度更高的代码,具有简单实用,可靠性强的特点。51INTCL19中华人民共和国国家知识产权局12发明专利申请权利要求书2页说明书6页附图3页CN102360297A1/2页21一种针对混合长度指令集的寄存器分配方法,其特征在于,包括如下步骤1)查找函数中的所有生命周期,通过设置标志位是否置位来判断设该生命期为A类生命期还是B类生命期;2)执行图着色寄存器分配方法的RENUMBER1、BUILD1、COALESCE1、SPILLCOST1、和SIMPLIFY1五个过程,为所有A类生命期分配LOREGS寄存器,得到未进行任何溢出操作的冲突图G1;3)计算空闲LOREGS寄存器数M,如果所述冲突。
3、图G1非空,则空闲LOREGS寄存器数M为0,如果所述冲突图G1为空图,则执行图着色寄存器分配方法的SELECT1过程,并根据生成的寄存器分配方案计算空闲的LOREGS寄存器数M,并记录空闲寄存器信息;4)执行图着色寄存器分配方法的RENUMBER2、BUILD2、COALESCE2、SIMPLIFY2、SPILLCODE2和SELECT2过程,为B类生命期分配HIREGS寄存器和M个空闲的LOREGS寄存器,并根据生成的分配方案计算空闲的HIREGS寄存器数量N,并记录空闲寄存器信息;5)执行图着色寄存器分配方法的SPILLCODE1和SELECT1过程,如果SELECT1过程已经在步骤3)。
4、执行则结束所有步骤,如果没有,则重复执行SPILLCODE1、RENUMBER1、BUILD1、COALESCE1、SPILLCOST1、SIMPLIFY1过程直到所述冲突图G1为空,然后执行SELECT1过程为A类生命期生成寄存器分配方案;RENUMBER1、BUILD1、COALESCE1、SPILLCOST1、SIMPLIFY1、SPILLCODE1、SELECT1、RENUMBER2、BUILD2、COALESCE2、SPILLCOST2、SIMPLIFY2、SPILLCODE2和SELECT2过程均为图着色寄存器分配方法的步骤;所述图着色寄存器分配方法包括如下步骤11)RENUMBE。
5、R在数据流分析的基础上,找到函数中的所有生命期,并为其分配唯一的编号,其中一个生命期从一个变量的一次定值开始,到对该值的最后一次使用结束;12BUILD建立冲突图G,所述冲突图G中的结点为生命期,边则表示通过其相连的两个生命期有冲突,不能为它们分配同一个寄存器;13)COALESCE判断是否需要合并生命期,如需要则通过合并生命期删除不必要的复制语句,合并后返回,重新执行步骤12),如不需要合并,则执行步骤14);14)SPILLCOST计算每个生命期的溢出代价;15)SIMPLIFY对所述冲突图G进行简化,反复地检查图G,删除G中度数小于可用寄存器数K的节点,删除的同时将该节点压入栈S;16)。
6、SPILLCODE当所述冲突图G中所有节点的度都大于等于K时,需要将溢出代价最小的生命期溢出,即删除其节点,将其压入栈S,并将其标记为溢出,溢出一个生命期之后返回执行步骤11);17)SELECT当所述冲突图G为空时,将栈S中的生命期弹出,为其分配寄存器,并为标记为溢出的生命期插入溢出代码;所述LOREGS寄存器为短指令可寻址的寄存器,剩下的为所述HIREGS寄存器,所述标志位是否置位的标准为将有A类指令引用的生命期设为置位,将只有B类指令引用的生命期设为不置位;所述A类指令为一条指令最终生成的机器指令是长指令还是短指令取决于其分配到的寄存器;权利要求书CN102360280ACN102360。
7、297A2/2页3所述B类指令为不论其寄存器操作数分配到哪个寄存器,其必然生成一条长指令,或者必然生成一条短指令。2根据权利要求1所述的一种针对混合长度指令集的寄存器分配方法,其特征在于,所述标志位设于记录生命期信息的结构体中。3根据权利要求1所述的一种针对混合长度指令集的寄存器分配方法,其特征在于,所述步骤5)中SPILLCODE1的过程包括如下步骤31)在构造所述冲突图G1保存一个所述冲突图G1的备份冲突图G1BACKUP;32)每次SIMPLIFY1决定溢出某个生命期L时,首先判断是否有空闲的HIREGS寄存器可用于溢出,如果有,那么在L的每次赋值后和使用前插入MOVE指令,并记录生命期。
8、L溢出到HIREGS寄存器的信息;并且当每个HIREGS寄存器都已经有关联的溢出生命期时,根据所述备份冲突图G1BACKUP判断是否有寄存器关联的所有溢出生命期都不与当前要溢出的生命期L冲突,如果有这样的寄存器,那么它可用于L的溢出,如果没有空闲的HIREGS用于溢出,那么SPILLCODE1使用LOAD/STORE指令将生命期溢出到存储器。权利要求书CN102360280ACN102360297A1/6页4一种针对混合长度指令集的寄存器分配方法技术领域0001本发明涉及一种编译技术,尤其涉及一种针对混合长度指令集的寄存器分配方法。背景技术0002嵌入式系统常采用RISC架构,其指令集一般为定。
9、长指令集,即只具有单一长度的指令。指令长度一般为整数个字节,例如,16位指令,32位指令。较长的指令长度可以编码更多的操作数,寻址更多的寄存器,或者可使用更大的立即数等,故一般具有更好的性能;而较短的指令长度可以使得编译生成的可执行程序更小。为了在具有长指令高性能的同时具有短指令的高代码密度,现代的RISC处理器开始采用两种或者两种以上不同长度指令混合编码的指令集。例如,ARM的THUMB2指令集和中天微公司的CSKYV2指令集都是16位与32位指令混合编码的指令集(以下简称“混编指令集”)。0003在混编指令集中,短指令相比长指令而言,寻址的操作数个数少,可编码的立即数范围小,或者单个地址只。
10、可使用部分寄存器。例如,在CSKYV2指令集中,长指令可使用R0R31全部共32个通用寄存器,而绝大多数短指令只可使用R0R15共16个通用寄存器;长指令一般具有3操作数,而短指令最多只有2操作数。短指令在功能上是长指令的一个子集。通常,编译器按照长指令的功能来生成汇编指令,而汇编器生成机器指令时,会根据指令的类型和其操作数来决定生成长指令还是短指令。0004以CSKYV2为例,如果一条指令的某个寄存器操作数被分配了R16R31的寄存器,那么该指令将生成一条长指令(个别指令除外,下外将介绍);但一条指令即使只使用R0R15的寄存器,它也并不一定生成短指令,因为它可能使用了超出短指令可编码范围的。
11、立即数,或者使用了3个不同的操作数等等。以CSKYV2为例,如果一条指令的某个寄存器操作数被分配了R16R31的寄存器,那么该指令将生成一条长指令(个别指令除外,下外将介绍);但一条指令即使只使用R0R15的寄存器,它也并不一定生成短指令,因为它可能使用了超出短指令可编码范围的立即数,或者使用了3个不同的操作数,等等。如果一条指令最终生成的机器指令是长指令还是短指令取决于其分配到的寄存器(以下简称A类指令);反之,如果不论其寄存器操作数分配到哪个寄存器,其必然生成一条长指令,或者必然生成一条短指令(以下简称B类指令)。如何以较小的代价使得所有的A类指令最终生成的机器指令为短指令,是技术人员需要。
12、克服的难点。发明内容0005针对上述技术难点,本发明的提出一种针对混合长度指令集的寄存器分配方法。0006为了解决上述技术问题,本发明的技术方案如下一种针对混合长度指令集的寄存器分配方法,包括如下步骤1)查找函数中的所有生命周期,通过设置标志位是否置位来判断设该生命期为A类生命期还是B类生命期;说明书CN102360280ACN102360297A2/6页52)执行图着色寄存器分配方法的RENUMBER1、BUILD1、COALESCE1、SPILLCOST1、和SIMPLIFY1五个过程,为所有A类生命期分配LOREGS寄存器,得到未进行任何溢出操作的冲突图G1;3)计算空闲LOREGS寄存。
13、器数M,如果所述冲突图G1非空,则空闲LOREGS寄存器数M为0,如果所述冲突图G1为空图,则执行图着色寄存器分配方法的SELECT1过程,并根据生成的寄存器分配方案计算空闲的LOREGS寄存器数M,并记录空闲寄存器信息;4)执行图着色寄存器分配方法的RENUMBER2、BUILD2、COALESCE2、SIMPLIFY2、SPILLCODE2和SELECT2过程,为B类生命期分配HIREGS寄存器和M个空闲的LOREGS寄存器,并根据生成的分配方案计算空闲的HIREGS寄存器数量N,并记录空闲寄存器信息;5)执行图着色寄存器分配方法的SPILLCODE1和SELECT1过程,如果SELECT。
14、1过程已经在步骤3)执行,则步骤结束,如果没有,重复执行SPILLCODE1、RENUMBER1、BUILD1、COALESCE1、SPILLCOST1、SIMPLIFY1过程直到所述冲突图G1为空,然后执行SELECT1过程为A类生命期生成寄存器分配方案;RENUMBER1、BUILD1、COALESCE1、SPILLCOST1、SIMPLIFY1、SPILLCODE1、SELECT1、RENUMBER2、BUILD2、COALESCE2、SPILLCOST2、SIMPLIFY2、SPILLCODE2和SELECT2过程均为图着色寄存器分配方法的步骤;所述图着色寄存器分配方法包括如下步骤11。
15、)RENUMBER在数据流分析的基础上,找到函数中的所有生命期,并为其分配唯一的编号,其中一个生命期从一个变量的一次定值开始,到对该值的最后一次使用结束;12BUILD建立冲突图G,所述冲突图G中的结点为生命期,边则表示通过其相连的两个生命期有冲突,不能为它们分配同一个寄存器;13)COALESCE判断是否需要合并生命期,如需要则通过合并生命期删除不必要的复制语句,合并后返回,重新执行步骤12),如不需要合并,则执行步骤14);14)SPILLCOST计算每个生命期的溢出代价;15)SIMPLIFY对所述冲突图G进行简化,反复地检查图G,删除G中度数小于可用寄存器数K的节点,删除的同时将该节点。
16、压入栈S;16)SPILLCODE当所述冲突图G中所有节点的度都大于等于K时,需要将溢出代价最小的生命期溢出,即删除其节点,将其压入栈S,并将其标记为溢出,溢出一个生命期之后返回执行步骤11);17)SELECT当所述冲突图G为空时,将栈S中的生命期弹出,为其分配寄存器,并为标记为溢出的生命期插入溢出代码;所述LOREGS寄存器为短指令可寻址的寄存器,剩下的为所述HIREGS寄存器,所述标志位是否置位的标准为将有A类指令引用的生命期设为置位,将只有B类指令引用的生命期设为不置位;所述A类指令为一条指令最终生成的机器指令是长指令还是短指令取决于其分配到的寄存器;所述B类指令为不论其寄存器操作数分。
17、配到哪个寄存器,其必然生成一条长指令,或者必然生成一条短指令。说明书CN102360280ACN102360297A3/6页60007进一步的,所述标志位设于记录生命期信息的结构体中。0008进一步的,所述步骤5)中SPILLCODE1的过程包括如下步骤31)在构造所述冲突图G1保存一个所述冲突图G1的备份冲突图G1BACKUP;32)每次SIMPLIFY1决定溢出某个生命期L时,首先判断是否有空闲的HIREGS寄存器可用于溢出,如果有,那么在L的每次赋值后和使用前插入MOVE指令,并记录生命期L溢出到HIREGS寄存器的信息;并且当每个HIREGS寄存器都已经有关联的溢出生命期时,根据所述备。
18、份冲突图G1BACKUP判断是否有寄存器关联的所有溢出生命期都不与当前要溢出的生命期L冲突,如果有这样的寄存器,那么它可用于L的溢出,如果没有空闲的HIREGS用于溢出,那么SPILLCODE1使用LOAD/STORE指令将生命期溢出到存储器。0009本发明的有益效果在于适用于具有两种或两种以上不同长度指令,并且其中较短指令可访问寄存器的集合为较长指令可访问寄存器的集合的子集的指令集,本发明可提高生成代码的指令密度,并且简单实用,可靠性强,最终以较小的代价使得所有的A类指令最终生成的机器指令为短指令。附图说明0010图1为图着色寄存器分配方法的基本流程图;图2为本发明的具体实施流程图;图3为标。
19、记生命期类型流程图;图4为SPILLCODE1流程图;图5为备份的冲突图的部分图。具体实施方式0011下面将结合附图和具体实施方式对本发明做进一步的说明。0012本发明是一种在图着色寄存器分配法基础上进行改进的寄存器分配方法。图着色是传统的,也是最为常用的寄存器分配方法,其基本流程如图1所示,各阶段的简要说明如下重命名(RENUMBER)在本阶段之前,中间代码可以引用数目无限的“虚拟寄存器”。本阶段在数据流分析的基础上,找到函数中的所有生命期,并为其分配唯一的编号。一个生命期从一个变量的一次定值开始,到对该值的最后一次使用结束。0013构造冲突图BUILD本阶段建立“冲突图G”,G中的结点为生。
20、命期,边则表示通过其相连的两个生命期有冲突,即它们在某条指令处同时活跃,故不能为它们分配同一个寄存器。0014合并生命期COALESCE本阶段通过合并生命期来删除不必要的复制语句。合并生命期改变了冲突图,故合并之后需要重新执行“BUILD”过程。0015溢出代价分析SPILLCOST本阶段用于计算每个生命期的溢出代价。0016简化冲突图SIMPLIFY本阶段中对冲突图G进行简化,反复地检查图G,删除G中度数小于可用寄存器数K的节点,删除的同时将该节点压入栈S。0017插入溢出代码SPILLCODE当图G中所有节点的度都大于等于K时,“SIMPLIFY”过程无法继续。此时,需要将溢出代价最小的生。
21、命期溢出,即删除其节点,将其压入栈S,并将其标记为溢出。溢出一个生命期之后需要从“重命名”阶段重新开始执行图说明书CN102360280ACN102360297A4/6页7着色算法。0018着色SELECT图G最终会被简化为一个空图,此时将栈S中的生命期弹出,为其分配寄存器,并为标记为溢出的生命期插入溢出代码。0019首先将寄存器进行分类,其中大多数短指令可寻址的寄存器称为LOREGS,而其余的寄存器称为HIREGS。然后为每个生命期增加一个标志位,标记其是否曾被A类指令引用,将只有B类指令引用的生命期称为“B类生命期”;而将有A类指令引用的生命期称为“A类生命期”,并通过扫描整个函数的指令流。
22、为每个生命期设置该标记。0020接着执行两个图着色过程,为A类生命期分配LOREGS,为B类生命期分配HIREGS;如果LOREGS、HIREGS分别足够A类生命期、B类生命期使用,或者两个图着色过程寄存器都不足,都需要溢出生命期,那么这两个图着色过程独立进行。如果LOREGS足够A类生命期分配且有空闲,但HIREGS不够B类生命期分配,那么将LOREGS中空闲的寄存器和HIREGS寄存器一起分配给B类生命期。反之,如果HIREGS有空闲而LOREGS不足,那么在LOREGS分配过程中生成溢出代码时,优先将生命期溢出到空闲的HIREGS,当无HIREGS寄存器可进行溢出时才溢出到存储器。002。
23、1本方法的具体实现流程如图2所示,具体步骤如下一、生命期标记。本阶段查找函数中的所有生命期;并通过扫描当前函数的所有指令对每个生命期的类型进行标记。0022二、RENUMBER1、BUILD1、COALESCE1、SPILLCOST1、和SIMPLIFY1。本步骤执行图着色算法流程中的前5个阶段,为所有A类生命期分配LOREGS寄存器。本步骤执行结束后,将得到未进行任何溢出操作的冲突图G1。0023三、计算空闲LOREGS寄存器数。本步骤计算空闲的LOREGS寄存器数M,如果G1非空,那么M为0;反之,如果G1为空图,那么我们执行SELECT1过程,并根据生成的寄存器分配方案计算空闲的LORE。
24、GS寄存器数,并记录空闲寄存器信息。0024四、RENUMBER2、BUILD2、COALESCE2、SPILLCOST2、SIMPLIFY2、SPILLCODE2和SELECT2。本步骤是一个完整的传统图着色寄存器分配过程。我们使用这一过程为B类生命期分配HIREGS寄存器和M个空闲的LOREGS寄存器。并根据生成的分配方案计算空闲的HIREGS寄存器数量N,并记录空闲寄存器信息。0025五、SPILLCODE1和SELECT1。如果G1为空,那么SELECT1已在步骤三中执行,整个算法结束;否则,重复执行SPILLCODE1、RENUMBER1、BUILD1、COALESCE1、SPILL。
25、COST1、SIMPLIFY1过程,直到G1为空,然后SELECT1为A类生命期生成寄存器分配方案。本步骤的特殊之处在于,如果N0,那么在执行插入SPILLCODE1时,我们优先将生命期溢出到空闲的HIREGS寄存器,只有当无HIREGS寄存器可用时,才将生命期溢出到存储器。这样做的优点在于使用MOVE指令生成的将生命期溢出到空闲的HIREGS寄存器的代码,其执行速度一般要快于使用LOAD/STORE执行生成的将生命期溢出到存储器的代码。0026另外,混编指令集通常提供特殊的短指令MOVE,它是一条短指令,但可以寻址所有的寄存器。此时,使用MOVE指令生成的将生命期溢出到空闲HIREGS寄存器。
26、的代码相比溢出到存储器将更加高效(使用了短指令进行溢出,而不是通常的长指令)。0027本方法只需要在传统的图着色寄存器分配方法上进行少量的修改,即可充分利用混编指令集的特点,生成代码密度更高的代码,具有简单实用,可靠性强的特点。说明书CN102360280ACN102360297A5/6页80028下面结合具体实例进行更加详细的说明首先,在记录生命期信息的结构体中增加一个标志位FLAG_SHORT,如果该标志位置位,则说明该生命期是一个A类生命期,否则其为一个B类生命期。在“生命期识别”过程结束后,增加一个“标记生命期类型”的过程,如图3所示。该过程通过依次扫描当前函数中的每一条指令,为每一个。
27、生命期设置FLAG_SHORT标志。0029然后,需要执行两个图着色过程。其中SELECT1为所有A类生命期分配LOREGS寄存器;SELECT2为所有B类生命期分配HIREGS寄存器以及可能的空闲LOREGS寄存器。并且SELECT2可能在SELECT1完成之后执行,也可能在SELECT1的第一次简化冲突图G1过程后执行,如图2所示。这取决于LOREGS是否足够A类生命期分配,如果足够使用,那么SELECT1首先执行完毕,这样剩余的空闲LOREGS能够提供给SELECT2阶段进行分配;否则,SELECT1在执行第一次SIMPLIFY1过程后,执行整个SELECT2流程,这样如果SELECT2。
28、过程有空闲的HIREGS的话,它们可以用于SELECT1的插入SPILLCODE1阶段。总之,我们使用了SELECT1、SELECT2两个图着色过程,其中SELECT1为所有FLAG_SHORT为TRUE的生命期分配LOREGS寄存器;SELECT2为所有FLAG_SHORT为FALSE的生命期分配HIREGS寄存器和可能的空闲LOREGS寄存器。这两个图着色过程中,本发明只需要在传统的图着色算法中增加一个对生命期的FLAG_SHORT标志的判断,使SELECT1、SELECT2分别处理FLAG_SHORT为TRUE、FALSE的生命期,并简单的重新组织SELECT1、SELECT2的执行流程。
29、即可。0030最后,本发明还可以修改传统图着色算法的溢出过程插入SPILLCODE1,其流程如图4所示。首先,在执行构造冲突图G1过程时,需要保存一个备份的冲突图G1BACKUP;然后在每次简化冲突图G1决定溢出某个生命期L时,首先判断是否有空闲的HIREGS可用于溢出,如果有,那么在L的每次赋值后和使用前插入MOVE指令,并记录生命期L溢出到HIREGS的信息。需要注意的是,当每个HIREGS都已经有关联的溢出生命期时,并不意味着没有HIREGS可用于溢出;这时,需要根据G1BACKUP判断是否有某个寄存器,其关联的所有溢出生命期都不与当前要溢出的生命期L冲突,如果有这样的寄存器,那么它可用。
30、于L的溢出。如果没有空闲的HIREGS用于溢出,那么SPILLCODE1执行与传统图着色算法同样的过程,即使用LOAD/STORE指令将生命期溢出到存储器。0031以下是一个溢出到寄存器的例子,首先给出在构造冲突图G1执行结束后备份的G1BACKUP,如下图所示(为了简化说明,示意图中只包括4个生命期,可以认为是冲突图的一小部分)假设有两个空闲的HIREGS寄存器R1,R2可用于溢出,现在需要溢出生命期3,而之前的溢出操作对HIREGS的使用情况如下表HIREGS寄存器已溢出的生命期R11R22表HIREGS寄存器溢出情况记录如流程图4所示,首先得到第一个可用于溢出的HIREGS寄存器R1,并。
31、且根据上表可知,生命期1已经溢出到了R1,而当前要溢出生命期3,根据备份的冲突图G1BACKUP,可知生命期1、3有冲突,故R1不能用于溢出生命期3。接下来,得到第二个可用于溢出的HIREGS寄存器R2,根据G1BACKUP可知,生命期2、3无冲突,说明生命期3活跃的时间段说明书CN102360280ACN102360297A6/6页9内,生命期2已经不再使用,故可以将生命期3溢出到R2,将该信息填入表1,并在需要使用生命期2的地方插入MOVE指令将其值从R2拷贝到相应的LOREGS寄存器,在使用结束之后插入MOVE指令将其值从相应的LOREGS寄存器拷贝到R2。0032以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员,在不脱离本发明构思的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明保护范围内。说明书CN102360280ACN102360297A1/3页10图1图2说明书附图CN102360280ACN102360297A2/3页11图3说明书附图CN102360280ACN102360297A3/3页12图4图5说明书附图CN102360280A。