首页 / 程序编译方法、装置、设备、介质及程序产品

程序编译方法、装置、设备、介质及程序产品实质审查 发明

技术领域

[0001] 本申请涉及计算机程序编译技术领域,尤其涉及一种程序编译方法、装置、设备、介质及程序产品。

相关背景技术

[0002] 编译程序,也称为编译器,是指把用高级程序设计语言书写的源程序,翻译成等价的机器语言格式目标程序的过程。定值‑使用链(简称:DU链)和使用‑定值链(简称:UD链)是所有编译器中非常重要的一种结构,是编译器编译程序时对程序进行优化的先决条件。而在编译器编译程序过程中需要先对程序进行分析,进而创建DU链和UD链。
[0003] 目前创建DU链和UD链时,是采用数据流迭代不动点算法创建的。但是该算法进行DU链和UD链的创建时,创建过程比较耗时,导致创建效率较低,进而导致对程序的编译效率较低。

具体实施方式

[0038] 这里将详细地对示例性实施例进行说明,其示例表示在附图中。下面的描述涉及附图时,除非另有表示,不同附图中的相同数字表示相同或相似的要素。以下示例性实施例中所描述的实施方式并不代表与本公开相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本公开的一些方面相一致的装置和方法的例子。
[0039] 首先对本申请中的术语进行详细介绍:
[0040] 定值:对程序中变量的赋值即为定值。
[0041] 定值‑使用链:Define‑use链,简称DU链。对于程序中的变量有一个定值,该定值所有能够到达的使用的集合称为该变量在该定值处的定值‑使用链。所以DU链连接该变量的定值到它的所有可能流经到的使用。
[0042] 使用‑定值链:Use‑define链,简称UD链。对于程序中变量的一次使用,到达该使用的所有定值的集合称为使用‑定值链。UD链连接一个使用到所有可能流经到该使用的定值。
[0043] 基本程序块(Basic Block):程序代码的一种表示方式,每个基本块是满足下列条件的最大的连续指令序列:(1)控制流只能从基本程序块中的第一个指令进入该块;(2)除了基本块的最后一个指令,控制流在离开基本块之前不会停机或跳转。基本程序块形成控制流图的节点。
[0044] 为了清楚理解本申请的技术方案,首先对现有技术的方案进行详细介绍。
[0045] DU链和UD链是所有编译器中非常重要的一种结构,其可用于程序中变量的依赖关系分析,进而可用于进行常量传播、公共子表达式消除及死代码消除等编译优化。所以其是编译器编译程序时对程序进行优化的先决条件。
[0046] 目前编译器在创建DU链和UD链时,是采用数据流迭代不动点算法创建的。在采用数据流迭代不动点算法创建DU链和UD链时,会沿着目标程序的基本程序块的顺序,多次迭代地遍历基本程序块,收集语义信息,直到语义信息不再变化,认为目标程序收集全面了,进而完成DU链和UD链的准确及完整的创建。所以在采用数据流迭代不动点算法创建DU链和UD链时,需要多次迭代地遍历目标程序的基本程序块,所以导致创建过程比较耗时,导致创建效率较低,进而导致对程序的编译效率较低。
[0047] 所以在面对现有技术中的技术问题时,为了不再多次迭代遍历基本程序块,可通过对目标程序进行少量遍历,就可完成对目标程序的语义解析,并完成目标程序中所有变量的定值点及使用点的收集,进而根据收集到的各变量的定值点及使用点完成对目标程序的目标DU链及目标UD链的创建。而在目标程序中,同一个变量可能会被定值多次,为了能够进行少量遍历,就完成对目标程序中所有变量的定值点及使用点的收集,可在对目标程序进行一次遍历时,采用SSA算法对目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点,并针对各重命名后的变量,构建SSA形式名集合。在SSA形式名集合中具有各重命名后的变量对应的SSA形式名,定值点及使用点,进而基于SSA形式名集合,构建所述目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链。由于采用SSA算法对目标程序中的至少一个变量进行重命名,实现各重命名后的变量均具有一个对应的定值点,形成SSA形式名集合。所以只需要对目标程序进行少量遍历,就可基于SSA形式名集合中各重命名后的变量对应的SSA形式名,定值点及使用点构建目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链。所以有效减少了对目标程序的遍历次数,进而有效提高了DU链和UD链的创建效率及对程序的编译效率。
[0048] 图1为本申请一个实施例提供的程序编译方法的应用场景图,如图1所示,在程序编译方法对应的系统中可包括客户端设备1及服务端设备2。在用户开发或测试某个目标服务的目标程序,有对目标程序的编译需求时,可向服务端设备2发送目标程序的编译请求。在编译请求中可以包括目标程序的标识。服务端设备2基于目标程序的标识从存放待编译的目标程序的数据库或存储区域或存储设备中获取到待编译的目标程序,并采用本申请提供的程序编译方法对待编译的目标程序进行编译。具体地,采用SSA算法对目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点;针对各重命名后的变量,构建SSA形式名集合,SSA形式名集合中具有各重命名后的变量对应的SSA形式名,定值点及使用点;根据SSA形式名集合,构建目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链;基于目标DU链及UD链对目标程序进行编译。在编译完成后,将编译结果反馈给客户端设备1。
[0049] 可以理解的是,本实施例提供的程序编译方法还可以应用在其他应用场景中,本实施例中对此不做限定。
[0050] 下面以具体地实施例对本发明的技术方案以及本申请的技术方案如何解决上述技术问题进行详细说明。下面这几个具体的实施例可以相互结合,对于相同或相似的概念或过程可能在某些实施例中不再赘述。下面将结合附图,对本发明的实施例进行描述。
[0051] 图2为本申请一实施例提供的程序编译方法的流程图,如图2所示,本实施例提供的程序编译方法的执行主体为程序编译装置。则本实施例提供的程序编译方法包括以下步骤:
[0052] 步骤201,获取待编译的目标程序。
[0053] 其中,目标程序为需进行编译的程序。其可以为目标服务对应的程序,或者为其他类型的程序,本实施例中对此不做限定。
[0054] 其中,在目标程序中包括程序代码。目标程序可以控制流图的方式进行表示,控制流图中包括至少一个基本程序块。其中,基本程序块为只有一个入口和一个出口的一段顺序执行的程序序列。可以理解的是,在程序代码中具有至少一个变量,以及对至少一个变量的定值指令及使用指令。
[0055] 具体地,本实施例中,可预先将目标程序存储在数据库或者预设存储区域或者存储设备中,通过访问数据库或预设存储区域或者存储设备来获取目标程序。
[0056] 步骤202,采用静态单赋值SSA算法对目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点。
[0057] 其中,静态单赋值是一种中间表示,SSA中的所有赋值都是针对不同名字变量进行的。所以采用静态单赋值SSA算法对目标程序中的至少一个变量进行重命名后,每个重命名后的变量均具有一个对应的定值点。
[0058] 具体地,本实施例中,由于在目标程序中可能存在一个变量被进行了不同赋值的情况,即一个变量具有多个定值点。所以为了能够使每个变量均具有一个对应的定值点,静态单赋值SSA算法需要先对同一变量的多处定值进行合并,进行合并后来定义一个新的变量,再对这个新的变量及目标程序中其他变量均进行重命名,使目标程序中的每个重命名后的变量均具有一个对应的定值点。
[0059] 其中,重命名后的变量的名称为重命名后的变量的SSA形式名。
[0060] 步骤203,针对各重命名后的变量,构建SSA形式名集合,SSA形式名集合中具有各重命名后的变量对应的SSA形式名,定值点及使用点。
[0061] 具体地,可在对目标程序进行遍历的同时,对变量进行重命名,并在遍历到一个重命名后的变量后,确定该重命名后的变量的SSA形式名、定值点及使用点。进而将该重命名后的变量的SSA形式名、定制点及使用点存储到SSA形式名集合中,对目标程序遍历完后,在SSA形式名集合具有每个重命名后的变量的SSA形式名,定值点及使用点。
[0062] 步骤204,根据SSA形式名集合,构建目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链。
[0063] 其中,目标DU链为目标程序对应的DU链。目标UD链为目标程序对应的DU链。
[0064] 具体地,本实施例中,可先基于SSA形式名集合中的每个重命名后的变量,构建初始DU链和初始DU链。由于在SSA形式名集合中具有的重命名后的变量的数目比目标程序中的原有变量的数目多。其中多出的变量是基于目标程序中的原有变量生成的,所以可基于重命名后的变量与原有变量之间的关系,对初始DU链和初始DU链进行转换,获得目标DU链和目标UD链。
[0065] 步骤205,基于目标DU链及UD链对目标程序进行编译。
[0066] 本实施例中,基于目标DU链及UD链对目标程序进行优化分析,进而基于优化分析结果完成对目标程序的编译。可选地,优化分析方法可以是常量传播、公共子表达式消除及死代码消除等编译优化,此处仅用于示例说明,并不用于限定优化分析方法。
[0067] 具体的优化分析方法及基于优化分析结果完成对目标程序的编译的方法均为现有技术,在此不再一一赘述。
[0068] 本实施例提供的程序编译方法,通过获取待编译的目标程序;采用静态单赋值SSA算法对目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点;针对各重命名后的变量,构建SSA形式名集合,SSA形式名集合中具有各重命名后的变量对应的SSA形式名,定值点及使用点;根据SSA形式名集合,构建目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链;基于目标DU链及UD链对目标程序进行编译。由于采用SSA算法对目标程序中的至少一个变量进行重命名,实现各重命名后的变量均具有一个对应的定值点,形成SSA形式名集合。所以只需要对目标程序进行少量遍历,就可基于SSA形式名集合中各重命名后的变量对应的SSA形式名,定值点及使用点构建目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链。所以有效减少了对目标程序的遍历次数,进而有效提高了DU链和UD链的创建效率及对程序的编译效率。
[0069] 图3为本申请另一实施例提供的程序编译方法的流程图,如图3所示,本实施例提供的程序编译方法在上述实施例提供的程序编译方法的基础上,对步骤202‑步骤203进行进一步细化,则本实施例提供的程序编译方法包括以下步骤:
[0070] 步骤301,获取待编译的目标程序。
[0071] 本实施例中,步骤301的实现方式与上述实施例中的步骤201的实现方式类似,在此不再一一赘述。
[0072] 步骤302,采用静态单赋值SSA算法在目标程序中确定满足变量合并条件的位置。
[0073] 其中,满足变量合并条件的位置即为插入变量合并指令的位置。
[0074] 其中,变量合并指令也称为Phi(符号ф)指令。Phi指令是用于将目标程序中的同一变量多处定值合并起来,定义一个新的变量的指令。
[0075] 作为一种可选实施方式,步骤302包括以下步骤:
[0076] 步骤302a,确定目标程序中跨基本程序块的变量集合,以及目标程序中各基本程序块对应的定值变量集合。
[0077] 为了更好的对方案进行说明,该实施例中以图4中的目标程序为例进行具体方案的介绍。
[0078] 其中,跨基本程序块的变量指的是变量在不同的基本程序块内被定值使用的变量。反之,非跨基本程序块为变量只在该一个基本程序块内被定值使用的基本程序块。
[0079] 其中,定值变量集合中的定值变量为进行定值的变量。
[0080] 具体地,本实施例中,为了在满足变量合并条件的位置插入Phi指令,减少插入Phi指令的数量,获取到目标程序中的变量后,确定目标程序中各基本程序块对应的定值变量所构成的集合。并且可对于没必要插入Phi指令的非跨基本程序块中的变量进行删除,进而获取到目标程序中跨基本程序块的变量,并由跨基本程序块的变量构建跨基本程序块的变量集合。
[0081] 其中,定值变量集合可表示为effect_prs。跨基本程序块的变量集合可表示为global_prs。如图4所示的示例中,包括:入口及BB1‑BB6 7个基本程序块。effect_prs包括的定值变量有{a,b,c,x,p,y},所以定值变量集合可表示为effect_prs={a,b,c,x,p,y}。global_prs包括的变量有{a,b,x,p},所以跨基本程序块的变量集合可表示为global_prs={a,b,x,p}。
[0082] 步骤302b,针对跨基本程序块的变量集合中的各变量所属的辅助基本程序块,计算辅助基本程序块的支配边界。
[0083] 其中,辅助基本程序块为跨基本程序块的变量集合中的各变量所属的基本程序块。在上述示例性说明中,global_prs={a,b,x,p}中各变量所属的基本程序块集合为BB={BB1,BB2,BB3,BB4,BB5,BB6}。
[0084] 其中,在确定辅助基本程序块的支配边界(简称:DF)时,按照下面的方式进行确定:当且仅当第一基本程序块支配第二基本程序块的一个前驱基本程序块同时第一基本程序块不严格支配第二基本程序块,称为第二基本程序块是第一基本程序块的支配边界。
[0085] 在上述示例性说明中,跨基本程序块的变量集合中的各变量所属的基本程序块对应的支配边界为表1所示:
[0086] 表1:支配边界的示例性说明
[0087]
[0088] 示例性的,以BB2的支配边界是BB2,及BB4的支配边界是BB2进行说明。
[0089] 具体地,由于BB2支配BB2的前驱节点BB5,并且BB2又不严格支配BB2,所以BB2是BB2的支配边界。由于BB2的前驱包括BB1和BB5,BB4支配BB2的前驱BB5,同时BB4不严格支配BB2,所以BB2是BB4的支配边界。
[0090] 步骤302c,将活动变量所在基本程序块的支配边界的起始位置确定为满足变量合并条件的位置。
[0091] 其中,活动变量是同时存在于跨基本程序块的变量集合及定值变量集合中处于活动状态的变量。处于活动状态的变量为一个变量在一个基本程序块被定值,在其他基本程序块入口及之后被使用,则说明该变量在其他程序块及之后的基本程序块中是处于活动状态的变量。
[0092] 在上述示例性举例中,同时存在于跨基本程序块的变量集合及定值变量集合中处于活动状态的变量,同时又是支配边界BB2和BB4入口之后的变量为x。那么在支配边界BB2和BB4的起始位置确定为满足变量合并条件的位置。
[0093] 本实施例提供的程序编译方法,在采用静态单赋值SSA算法在目标程序中确定满足变量合并条件的位置时,确定目标程序中跨基本程序块的变量集合,以及目标程序中各基本程序块对应的定值变量集合;针对跨基本程序块的变量集合中的各变量所属的辅助基本程序块,确定辅助基本程序块的支配边界;将活动变量所在基本程序块的支配边界的起始位置确定为满足变量合并条件的位置。由于只确定出跨基本程序块的变量集合中的各变量所属的辅助基本程序块,确定辅助基本程序块的支配边界;将活动变量所在基本程序块的支配边界的起始位置确定为满足变量合并条件的位置。能够有效减少对非跨基本程序块插入Phi指令。
[0094] 步骤303,在满足变量合并条件的位置插入对应的变量合并指令。
[0095] 本实施例中,在支配边界为多个时,可以按照基本程序块的执行顺序在满足变量合并条件的位置插入对应的Phi指令,或者并行执行在满足变量合并条件的位置插入对应的Phi指令,本实施例中对此不做限定。
[0096] 在上述示例性说明中,如图5所示,为插入Phi指令的目标程序。在图5中,分别在BB2和BB4的起始位置插入了关于活动变量的Phi指令。
[0097] 步骤304,对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点。
[0098] 作为一种可选实施方式,本实施例中,步骤304包括以下步骤:
[0099] 步骤304a,确定带有变量合并指令的目标程序对应的支配者树。
[0100] 其中,在目标程序中,除入口基本程序块外,每个基本程序块(如为:A)都有唯一的直接支配基本程序块(表示为:idom(A)),且不成环,所有的基本程序块与支配基本程序块(表示为:(idom(A),A)之间的边形成一棵树,这棵树称为支配者树。
[0101] 本实施例中,确定带有变量合并指令的目标程序的支配者树的方式与未带有变量合并指令的目标程序的支配者树的方式类似,而确定未带有变量合并指令的目标程序的支配者树的方式为现有技术,所以不再一一赘述。
[0102] 在上述的示例性说明中,对应的支配者树具体为:从入口基本程序块引出的边指向BB1,从BB1引出的边指向BB2,从BB2引出的边指向BB3和BB4,从BB4引出的边指向BB5,从BB5引出的边指向BB6。
[0103] 步骤304b,对支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名。
[0104] 其中,非变量合并Phi指令为目标程序中不是Phi指令的指令。
[0105] 本实施例中,对支配者树中的基本程序块内的每个非变量合并指令的变量对应的定值及使用进行重命名,并对Phi指令中变量的定值进行重命名。
[0106] 作为一种可选实施方式,本实施例中,步骤304b包括以下步骤:
[0107] 步骤304b1,对支配者树中的基本程序块进行遍历。
[0108] 本实施例中,对于支配者树中的基本程序块按照基本程序块的执行顺序进行遍历,在对每个基本程序块进行遍历时,对非变量合并指令的变量以及变量合并指令的定值进行重命名。
[0109] 作为一种可选实施方式,步骤304b1还包括以下方案:
[0110] 响应于遍历到新的基本变量,对新的基本变量创建栈及对应的计数器,并对新的基本变量以初始SSA形式名压栈。
[0111] 其中,基本变量为在支配者树中的各变量。如在上述的示例性说明中,基本变量组成集合为{a,b,c,x,y,p}。
[0112] 具体地,本实施例中,在对支配者树中的基本程序块进行遍历的过程中,若遍历到一个新的基本变量,则为这个新的基本变量创建栈,栈用于存储该基本变量的至少一个SSA形式名。并为这个新的基本变量创建计数器,计数器用于对该新的基本变量的形式名的个数进行计数。计数器的计数是单调递增的,保证每个基本变量连续分配一个唯一的SSA形式名。
[0113] 其中,每个基本变量均具有一个基本名,对基本名结合对应的版本(英文为:version)号形成对应的至少一个SSA形式名。
[0114] 其中,初始SSA形式名对应的版本号为V1,示例性的,基本变量为PR1,在PR1被第一次定值时,被重命名为初始SSA形式名,为PR1V1,被第二次定值时,被重命名为PR1V2,以此类推。那么在上述示例性说明中,对于变量a,b,c,x,p,y,在第一次遍历到时,都是一个新的基本变量,均创建栈及对应的计数器,并对新的基本变量以初始SSA形式名压栈。那么对应的初始SSA形式名分别为a1,b1,c1,x 1,p1,y1。
[0115] 本实施例提供的程序编译方法,在对支配者树中的基本程序块进行遍历时,还包括响应于遍历到新的基本变量,对所述新的基本变量创建栈及对应的计数器,并对新的基本变量以初始SSA形式名压栈,通过对新的基本变量创建栈和对应计数器的方式,能够按照栈中的SSA形式名及单调递增的计数器进行重命名,能够有效保证每个重命名后的变量具有唯一的SSA形式名。
[0116] 步骤304b2,响应于遍历到非变量合并指令的变量,对非变量合并指令的变量对应的操作数,按照操作数对应的当前SSA形式名进行重写,对非变量合并指令的变量对应的定值创建新的SSA形式名,以完成非变量合并指令的变量的重命名。
[0117] 本实施例中,对于非变量合并指令的变量对应的操作数,将操作数重写为对应的基本变量的当前SSA形式名,完成对非变量合并指令的变量对应的操作数的重命名。对于非变量合并指令的变量对应的定值,基于基本变量的当前SSA形式名创建新的SSA形式名,完成对非变量合并指令的变量对应的定值的重命名。
[0118] 可选地,步骤304b2包括以下步骤:
[0119] 步骤304b2a,对当前非变量合并指令的变量对应的操作数,从操作数所属基本变量的栈中读取对应的当前SSA形式名,并按照操作数对应的当前SSA形式名进行重写。
[0120] 继续以上述的示例进行说明。如当前非变量合并指令的变量对应的操作数为BB1中非变量合并指令x=a+c中的a和c。对于基本变量a和c对应的栈中读取对应的当前SSA形式名分别为a1和c1。那么采用a1和c1替换掉a和c,完成了对操作数a和c的重写。
[0121] 步骤304b2b,获取当前非变量合并指令的变量对应的定值所属基本变量的栈,从定值所属基本变量的栈中读取对应的当前SSA形式名,基于对应的当前SSA形式名及对应计数器创建新的SSA形式名,新的SSA形式名用于写入所属基本变量的栈中。
[0122] 其中,非变量合并指令的变量对应的定值为非变量合并指令中对操作数进行操作的结果。
[0123] 其中,当前SSA形式名为位于栈顶的SSA形式名。
[0124] 具体地,在基于对应的当前SSA形式名及对应计数器创建新的SSA形式名时,获取当前SSA形式名中的基本名,并获取计数器中计数的数值,将计数的数值加上预设数值获得新的SSA形式名的版本号,并将当前SSA形式名中的基本名与版本号拼接,获得新的SSA形式名。
[0125] 其中,预设数值可以为1。
[0126] 继续以上述的示例进行说明。如当前非变量合并指令的变量对应的定值为BB3中非变量合并指令@p x=a+c中的x。获取x所属基本变量x的栈。在栈中存储的当前SSA形式名为x4,基于x4和对应计数器创建新的SSA形式名为x5,将x5写入x的栈中。并采用x5替换x,那么在x的栈中最上面的SSA形式名为x5。
[0127] 步骤304b3,响应于遍历到变量合并指令的定值,对变量合并指令的定值创建新的SSA形式名,以完成变量合并指令的定值的重命名。
[0128] 可选地,步骤304b3中,对变量合并指令的定值创建新的SSA形式名,包括以下方案:
[0129] 获取变量合并指令的定值所属基本变量的栈,从定值所属基本变量的栈中读取对应的当前SSA形式名,基于对应的当前SSA形式名及对应计数器创建新的SSA形式名,新的SSA形式名用于写入所属基本变量的栈中。
[0130] 具体地,在基于对应的当前SSA形式名及对应计数器创建新的SSA形式名时,与步骤304b2b中的类似,再次不在一一赘述。
[0131] 继续以上述的示例进行说明。如遍历到的变量合并指令为基本程序块BB2中的x<‑phi(x,x),其中,第一个x为变量合并指令的定值,确定所属基本变量x的栈,从基本变量x的栈中读取对应的当前SSA形式名为x1,则基于x1和对应计数器创建新的SSA形式名为x2。将x2写入x的栈中。那么在x的栈中最上面的SSA形式名为x2。
[0132] 本实施例中,在完成对x<‑phi(x,x)的定值x创建新的SSA形式名x2后,进行变量合并指令的定值的重命名,所以x<‑phi(x,x)重命名为x2<‑phi(x,x)。
[0133] 步骤304c,对基本程序块内的变量合并指令的操作数进行重命名,以使各重命名后的变量均具有一个对应的定值点。
[0134] 本实施例中,在完成对支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名后,再对基本程序块内的变量合并指令的操作数进行重命名。
[0135] 继续上述的示例进行说明。在完成对支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名后,对于BB2中的变量合并指令变为x2<‑phi(x,x)。那么对括号中的两个操作数x进行重命名。
[0136] 作为一种可选实施方式,本实施例中,步骤304c包括以下步骤:
[0137] 步骤304c1,确定变量合并指令的操作数的前驱基本程序块。
[0138] 步骤304c2,将前驱基本程序块中对应变量的重写后的SSA形式名确定为变量合并指令的操作数的SSA形式名,以完成对操作数进行重命名。
[0139] 其中,变量合并指令的操作数的前驱基本程序块为该操作数对应来源的基本程序块。
[0140] 本实施例中,可基于支配者树中包括变量合并指令的基本程序块中的基本变量的关系确定出变量合并指令的操作数的前驱基本程序块。并获取前驱基本程序块中对应变量中已经进行了重写后的SSA形式名,读取该重写后的SSA形式名,并将该重写后的SSA形式名确定为变量合并指令的操作数的SSA形式名,并按照SSA形式名完成对该操作数的重写,以完成对操作数的重命名。
[0141] 继续对上述的示例进行说明。BB2中的变量合并指令的前驱基本程序块分别为BB1和BB5。在BB1中对应变量x的重写后的SSA形式名为x1。在BB5中对应变量x的重写后的SSA形式名为x4,所以将x1和x4替换掉x2<‑phi(x,x)中的两个操作数x,完成对操作数的重写,重写后的变量合并指令为x2<‑phi(x1,x4)。
[0142] 需要说明的是,步骤302‑步骤304是对步骤202的一种可选实施方式。
[0143] 本实施例提供的程序编译方法,在采用静态单赋值SSA算法对所述目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点时,采用静态单赋值SSA算法在目标程序中确定满足变量合并条件的位置;在所述满足变量合并条件的位置插入对应的变量合并指令;对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点。通过确定满足变量合并条件的位置,并在满足变量合并条件的位置插入对应的变量合并指令,对带有变量合并指令的目标程序中的至少一个变量进行重命名,能够通过变量合并指令对同一变量的多处定值进行合并,定义新的变量,再对新的变量及目标程序中其他变量均进行重命名,准确控制目标程序中的每个重命名后的变量均具有一个对应的定值点。
[0144] 本实施例提供的程序编译方法,在对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点时,确定带有变量合并指令的目标程序对应的支配者树;对所述支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名;对所述基本程序块内的变量合并指令的操作数进行重命名,以使各重命名后的变量均具有一个对应的定值点。在对变量进行重命名时,按照非合并指令的变量及变量合并指令的定值及操作数的顺序进行,能够有效保证各重命名后的变量均具有一个对应的定值点。
[0145] 继续上述的示例进行说明,在执行完步骤302‑步骤304后,对应的目标程序为图6所示。在每个基本程序块中的变量的定值及使用均完成了重命名,并且各重命名后的变量均具有一个对应的定值点。
[0146] 作为一种可选实施方式,在步骤304之前,还可以包括以下方案:
[0147] 判断带有变量合并指令的目标程序中是否有满足移除条件的变量合并指令;对满足移除条件的变量合并指令进行移除处理。
[0148] 具体地,在对Phi指令的目标程序中的至少一个变量进行重命名之前,需要判断插入有Phi指令的目标程序是否有多余的Phi指令,若有多余的Phi指令,则说明满足移除条件,将满足移除条件的Phi指令进行移除后再对带有Phi指令目标程序中的至少一个变量进行重命名。能够有效减小对变量进行重命名的计算量,有效提高重命名的效率。
[0149] 可选地,满足移除条件的变量合并指令包括以下任意一种:
[0150] 变量合并指令的操作数有相同的定值点。
[0151] 变量合并指令的定值没有使用点并且与其他指令没有依赖链。
[0152] 具体地,在判断是否满足移除条件时,判断变量合并指令的操作数是否有相同的定值点,并且/或者判断变量合并指令的定值是否没有使用点并且与其他指令没有依赖链。
[0153] 具体地,在判断变量合并指令的操作数是否有相同的定值点时,若变量合并指令的使用的操作数的定值点位于同一个位置,则说明变量合并指令的操作数具有相同的定值点,反之,若变量合并指令的使用的操作数的定值点位于不同的位置,则说明变量合并指令的操作数具有不同的定值点。作为一种特殊情况,若变量合并指令的操作数的定值点为变量合并指令的操作数,其也是满足变量合并指令的使用的操作数的定值点位于同一个位置的。
[0154] 具体地,在判断判断变量合并指令的定值是否没有使用点并且与其他指令没有依赖链时,首先判断变量合并指令的定值是否没有使用点,若确定没有使用点,则确定该变量合并指令满足初步移除条件。但对变量进行重命名时,当指令中带有谓词时,会采用链表链接多条指令,形成依赖链,但是若在依赖链中也没有变量合并指令,则说明该变量合并指令已满足移除条件。反之,若确定有使用点,或者没有使用点,但该变量合并指令位于依赖链中,则说明不满足移除条件。
[0155] 本实施例提供的程序编译方法,满足移除条件的变量合并指令包括以下任意一种:变量合并指令的操作数有相同的定值点;变量合并指令的定值没有使用点并且与其他指令没有依赖链,能够将每种满足移除条件的变量合并指令进行移除,进一步减小对变量进行重命名的计算量。
[0156] 步骤305,对支配者树中的基本程序块遍历过程中,确定重命名后的变量的SSA形式名,定值点及使用点。
[0157] 本实施例中,在对支配者树的基本程序块进行遍历的过程中,在遍历到非变量合并指令的变量时,对变量对应的操作数以所属基本变量的栈中的栈顶的SSA形式名进行了重写,其中操作数来自于前驱基本程序块的变量,前驱基本程序块的变量已经进行了重命名,具有重命名后的SSA形式名。并且该操作数是前驱基本程序块中重命名后的变量的使用点,所以可将重命名后的变量的使用点与对应的重命名后的变量的SSA形式名进行关联存储。
[0158] 并且在遍历到非变量合并指令的变量时,也对非变量合并指令的变量的定值创建了新的SSA形式名,对定值进行了重写。所以可将该新的SSA形式名作为该变量的重命名后的变量的SSA形式名,并与该定值点进行关联存储。
[0159] 可以理解的是,在对支配者树的基本程序块进行遍历的过程中,遍历到变量合并指令的定值及操作数时,也会按照类似的方式将重命名后的变量的SSA形式名与对应的使用点与对应的进行关联存储。并将重命名后的变量的SSA形式名与对应定值点进行关联存储。
[0160] 所以在获得一个新的重命名后的变量的SSA形式名后,在遍历到对该新的重命名后的变量的定值时,将该新的重命名后的变量的SSA形式名与对应的定值点进行关联存储,后面在遍历到该新的重命名后的变量的使用时,即该新的重命名后的变量作为操作数时,将该新的重命名后的变量的使用点也与该新的重命名后的变量的SSA形式名进行关联存储,即可获得该新的重命名后的变量的SSA形式名,定值点及使用点。
[0161] 步骤306,基于重命名后的变量的SSA形式名,定值点及使用点构建SSA形式名集合。
[0162] 本实施例中,可按照变量出现顺序及基本程序块的执行顺序,将各重命名后的变量的SSA形式名,定值点及使用点存储到一个空的集合中,进而构建出SSA形式名集合。其中,每个重命名后的变量的SSA形式名,定值点及使用点可整体作为该SSA形式名集合中的一个元素。
[0163] 本实施例提供的程序编译方法,在针对各重命名后的变量,构建SSA形式名集合时,对所述支配者树中的基本程序块遍历过程中,确定重命名后的变量的SSA形式名,定值点及使用点;基于所述重命名后的变量的SSA形式名,定值点及使用点构建SSA形式名集合。能够有效保证在对目标程序一次遍历后,就可确定出至少一个变量对应的包括命名后的变量的SSA形式名,定值点及使用点的SSA形式名集合。
[0164] 作为一种可选实施方式,步骤306还包括以下方案:
[0165] 响应于目标程序中存在带有谓词的定值指令,采用链表存储带有谓词的定值指令中的多个定值点;将带有谓词的指令的定值重命名插入到前一个相同定值变量重命名所在链表的末尾处。
[0166] 本实施例中,作为一种特定的情况,判断目标程序中是否存在带有谓词的定值指令。示例性的,若在目标程序中存在带有@字符的定值指令,则确定存在带有谓词的指令。由于带有谓词的定值指令不一定执行,此时对应变量的定值会存在多个,那么在定值存在多个的情况下,可以采用链表在存储带有谓词的定值指令中的多个定值点。
[0167] 上述的示例进行说明,BB5对于变量X的定值点包含BB3和BB4中的两条带有谓词的定值指令。所以在存储重命名变量X的SSA形式名对应的定值点时,会存在x2<‑‑‑>x5和x3<‑‑‑>x4两条链表。
[0168] 本实施例中,在对带有谓词的定值指令中的多个定值点以链表进行存储后,将该带有谓词的指令的定值重命名插入到前一个相同定值变量重命名所在链表的末尾处,来保证该重命名后的变量的使用点之后的定值点不会误加入到DU链和UD链中。
[0169] 本实施例中,针对各重命名后的变量,构建SSA形式名集合时,响应于目标程序中存在带有谓词的定值指令,采用链表存储带有谓词的定值指令中的多个定值点;将链表插入到SSA形式名集合中对应重命名后的变量的末尾。能够在目标程序中存在带有谓词的定值指令时,以链表的形式对重命名变量的定值点进行准确存储,并且能够有效保证构建DU链和UD链的准确。
[0170] 需要说明的是,步骤305‑步骤306是对步骤203的一种可选实施方式。
[0171] 步骤307,根据SSA形式名集合,构建带有变量合并指令的目标程序对应的初始DU链和UD链。
[0172] 本实施例中,由于在SSA形式名集合中关联存储有各重命名后的变量的SSA形式名,定值点及使用点,所以按照目标程序中的指令的顺序,从SSA形式名集合获取到指令里对应的重命名后的变量的SSA形式名,定值点及使用点,进而构建出带有变量合并指令的目标程序对应的初始DU链和UD链。
[0173] 继续上述的示例进行说明,如表2所示,为构建出的带有变量合并指令的目标程序对应的初始Def list列表及初始Use list。
[0174] 其中,在表2中的每个语句对应带有变量合并指令的目标程序中的一个指令。Def list:表示右值使用的定值点列表,在该Def list中具有id信息的,表示这个指令中对应重命名后的变量对应的初始UD链,Use list:表示左值定值的使用点列表,在该Use list中具有id信息的,表示这个指令中对应重命名后的变量对应的初始DU链。
[0175] 表2:带有变量合并指令的目标程序对应的初始Def list及初始Use list[0176]语句1:a1=3 Def list Use list
a1(id:1)   Id:5 13 20
语句2:b1=4 Def list Use list
b1(id:2)   Id:14 21
语句3:c1=5 Def list Use list
c1(id:3)   Id:6
语句4:x1=a1+c1 Def list Use list
x1(id:4)   Id:9
a1(id:5) Id:1  
c1(id:6) Id:3  
语句5:setp p1 Def list Use list
p1(id:7)   Id:11 18
语句6:x2←phi(x1 x4) Def list Use list
x2(id:8)   Id:16 17
x1(id:9) Id:4  
x4(id:10) Id:15 19  
语句7:@p1 x5=a1+b1 Def list Use list
x5(id:12)   Id:17
p1(id:11) Id:7  
a1(id:13) Id:1  
b1(id:14) id:2  
语句8:x3←phi(x2,x5) Def list Use list
x3(id:15)   Id:10 23
x2(id:16) Id:8  
x5(id:17) Id:8 12  
语句9:@p1 x4=a1‑b1 Def list Use list
x4(id:19)   Id:10 23
p1(id:18) Id:7  
a1(id:20) Id:1  
b1(id:21) id:2  
语句10:y1=x4 Def list Use list
y1(id:22)    
x4(id:23) Id:15 19  
[0177] 步骤308,将变量合并指令中所有操作数的定值点合并到非变量合并指令的定值点中,并将变量合并指令中定值的使用点合并到非变量合并指令的使用点中。
[0178] 本实施例中,由于原有的目标程序中并没有变量合并指令,phi指令是一种伪指令,所以为了能够得到不带有phi指令的目标程序对应的目标DU链和目标UD链,需要将phi指令中所有操作数的定值点合并到非变量合并指令的定值点中,并将phi指令中定值的使用点合并到非变量合并指令的使用点中,来把phi指令中变量的操作数及定值脱离出来。
[0179] 作为一种可选实施方式,步骤308包括以下步骤:
[0180] 步骤3081,对基本程序块中的非变量合并指令进行遍历。
[0181] 步骤3082,响应于非变量合并指令的操作数的定值点是变量合并指令,将定值点是变量合并指令的非变量合并指令确定为目标非变量合并指令。
[0182] 具体地,本实施例中,按照基本程序块的执行顺序去遍历非变量合并指令。判断非变量合并指令的操作数的定值点是否为phi指令。若确定非变量合并指令的操作数的定值点是phi指令,则确定该非变量合并指令为目标变量合并指令。
[0183] 继续上述的示例进行说明。遍历到目标程序中的语句1到语句3,其并没有对变量的使用,即没有操作数,不需要处理。在遍历到语句4时,语句4的操作数为a1和c1。但a1和c1的定值并不是phi语句,确定其不是目标非变量合并指令。遍历到语句5,没有操作数,不需要处理。遍历到语句7,其对应的操作数为p1,a1和b1,但p1,a1和b1的定值不是phi指令,确定其不是目标非变量合并指令。遍历到语句9,操作数为p1,a1和b1,但p1,a1和b1的定值不是phi指令,确定其不是目标非变量合并指令。遍历到语句10,语句10的操作数为x4,x4的定值语句来自于语句8和语句9。其中语句8为phi指令,所以语句10为目标变量合并指令。
[0184] 步骤3083,将变量合并指令中所有操作数的定值点合并到目标非变量合并指令的定值点,形成定值点合并后的非变量合并指令。
[0185] 继续上述的示例进行说明。语句8中的所有操作数的定值点包括:id={4,12,19}。所以将语句8中的所有操作数的定值点合并到语句10的变量的定值点中。那么语句10对应的deflist包括:id={4,12,15,19}。由于id:15是条phi指令,在执行完步骤309后,语句10对应的deflist包括:id={4,12,19}。
[0186] 步骤3084,将变量合并指令中定值的使用点合并到定值点合并后的非变量合并指令中定值点所对应的非变量合并指令的使用点中。
[0187] 继续上述的示例进行说明。语句8中定值的使用点为id={10,23},由于id=10是phi指令,在在执行完步骤309后,会将id=10删除掉,将id=10及id=23合并到语句10的定值点对应的非变量合并指令语句4,语句7及语句9的使用点中。在执行完步骤309后,id=10会被删除掉,所以如表3所示,在语句4,语句7及语句9的使用点只包括了id=23。
[0188] 步骤309,删除初始DU链中与变量合并指令相关的DU关系并删除DU链中与变量合并指令相关的UD关系,并对执行删除后的DU链及UD链中的变量去除SSA形式名,以形成目标DU链及目标UD链。
[0189] 本实施例中,由于在执行完步骤308后,在非变量合并指令的定值中包括了变量合并指令中变量的所有操作数的定值点,并且在非变量合并指令的使用点中包括了变量合并指令中定值的使用点,所以就可删除变量合并指令相关的DU关系及变量合并指令相关的UD关系。
[0190] 具体地,在删除变量合并指令相关的DU关系时,可在Use list中进行删除,具体在Use list中删除使用点。在删除变量合并指令相关的UD关系时,可在Def list中进行删除,具体在Def list中删除定值点。
[0191] 本实施例中,在删除完变量合并指令相关的DU关系及变量合并指令相关的UD关系后,由于目标程序中只包括变量的基本名,所以对执行删除后的DU链及UD链中的变量去除SSA形式名中的版本号,只存在基础名后,形成了最终的目标DU链及目标UD链。
[0192] 上述的示例进行说明,目标程序对应的目标DU链和目标UD链。表示为表3所示。
[0193] 其中,在表3中,Def list:表示右值使用的定值点列表,在该Def list中具有id信息的,表示该变量的定值点,变量结合对应的所有的定值点表示该变量对应的目标UD链,Use list:表示左值定值的使用点列表,在该Use list中具有id信息的,表示该变量的使用点,变量结合对应的所有的使用点表示该变量对应的目标DU链。
[0194] 表3:目标程序对应的目标Def list和目标Use list
[0195] 语句1:a=3 Def list Use lista(id:1)   id:5,13,20
语句2:b=4 Def list Use list
b(id:2)   id:14,21
语句3:c=5 Def list Use list
c(id:3)   id:6
语句4:x=a+c Def list Use list
x(id:4)   id:23
a(id:5) id:1  
c(id:6) id:3  
语句5:setp p Def list Use list
p(id:7)   id:11,18
语句7:@p x=a+b Def list Use list
p(id:11) id:7  
x(id:12)   id:23
a(id:13) id:1  
b(id:14) id:2  
语句9:@p x=a‑b Def list Use list
p(id:18) id:7  
x(id:19)   id:23
a(id:20) id:1  
b(id:21) id:2  
语句10:y=x Def list Use list
y(id:22)    
x(id:23) id:4,12,19  
[0196] 需要说明的是,步骤307‑步骤309是对步骤204的一种可选实施方式。
[0197] 本实施例提供的程序编译方法,在根据所述SSA形式名集合,构建所述目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链时,根据所述SSA形式名集合,构建带有变量合并指令的目标程序对应的初始DU链和UD链;将所述变量合并指令中所有操作数的定值点合并到非变量合并指令的定值点中,并将所述变量合并指令中定值的使用点合并到非变量合并指令的使用点中;删除所述初始DU链中与变量合并指令相关的DU关系并删除DU链中与变量合并指令相关的UD关系,并对执行删除后的DU链及UD链中的变量去除SSA形式名中的版本号,以形成目标DU链及目标UD链。先基于SSA形式名集合,构建带有变量合并指令的目标程序对应的初始DU链和UD链,再通过将变量合并指令中变量的定值点和使用点合并到非变量合并指令中及删除初始DU链中与变量合并指令相关的DU关系,最终删除DU链中与变量合并指令相关的UD关系及去除SSA形式名中的版本号,可以构建出与现有技术中相同准确度的目标DU链及目标UD链,有效避免产生目标DU链及目标UD链中减小定值使用点数目的问题。
[0198] 步骤310,基于目标DU链及UD链对目标程序进行编译。
[0199] 本实施例中,步骤310的实现方式与上述实施例中的步骤205的实现方式类似,在此不再一一赘述。
[0200] 图7为本申请一个实施例提供的程序编译装置的结构示意图,如图7所示,本实施例提供的程序编译装置40包括:获取模块41,重命名模块42,第一构建模块43,第二构建模块44及编译模块45。
[0201] 其中,获取模块41,用于获取待编译的目标程序。重命名模块42,用于采用静态单赋值SSA算法对目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点。第一构建模块43,用于针对各重命名后的变量,构建SSA形式名集合,SSA形式名集合中具有各重命名后的变量对应的SSA形式名,定值点及使用点。第二构建模块44,用于根据SSA形式名集合,构建目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链。编译模块45,用于基于目标DU链及UD链对目标程序进行编译。
[0202] 可选地,重命名模块42,具体用于:
[0203] 采用静态单赋值SSA算法在目标程序中确定满足变量合并条件的位置;在满足变量合并条件的位置插入对应的变量合并指令;对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点。
[0204] 可选地,重命名模块42,在采用静态单赋值SSA算法在目标程序中确定满足变量合并条件的位置时,具体用于确定目标程序中跨基本程序块的变量集合,以及目标程序中各基本程序块对应的定值变量集合;针对跨基本程序块的变量集合中的各变量所属的辅助基本程序块,确定辅助基本程序块的支配边界;将活动变量所在基本程序块的支配边界的起始位置确定为满足变量合并条件的位置;活动变量是同时存在于跨基本程序块的变量集合及定值变量集合中处于活动状态的变量。
[0205] 可选地,重命名模块42,在对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点时,具体用于:
[0206] 确定带有变量合并指令的目标程序对应的支配者树;对支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名;对基本程序块内的变量合并指令的操作数进行重命名,以使各重命名后的变量均具有一个对应的定值点。
[0207] 可选地,重命名模块42,在对支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名时,具体用于:
[0208] 对支配者树中的基本程序块进行遍历;响应于遍历到非变量合并指令的变量,对非变量合并指令的变量对应的操作数,按照操作数对应的当前SSA形式名进行重写,对非变量合并指令的变量对应的定值创建新的SSA形式名,以完成非变量合并指令的变量的重命名;响应于遍历到变量合并指令的定值,对变量合并指令的定值创建新的SSA形式名,以完成变量合并指令的定值的重命名。
[0209] 可选地,重命名模块42,在对支配者树中的基本程序块进行遍历时,还用于:
[0210] 响应于遍历到新的基本变量,对新的基本变量创建栈及对应的计数器,并对新的基本变量以初始SSA形式名压栈。
[0211] 可选地,重命名模块42,在对非变量合并指令的变量对应的操作数,按照操作数对应的当前SSA形式名进行重写,对非变量合并指令的变量对应的定值创建新的SSA形式名时,具体用于:
[0212] 对当前非变量合并指令的变量对应的操作数,从操作数所属基本变量的栈中读取对应的当前SSA形式名,并按照操作数对应的当前SSA形式名进行重写;获取当前非变量合并指令的变量对应的定值所属基本变量的栈,从定值所属基本变量的栈中读取对应的当前SSA形式名,基于对应的当前SSA形式名及对应计数器创建新的SSA形式名,新的SSA形式名用于写入所属基本变量的栈中。
[0213] 可选地,重命名模块42,在对变量合并指令的定值创建新的SSA形式名时,具体用于:
[0214] 获取变量合并指令的定值所属基本变量的栈,从定值所属基本变量的栈中读取对应的当前SSA形式名,基于对应的当前SSA形式名及对应计数器创建新的SSA形式名,新的SSA形式名用于写入所属基本变量的栈中。
[0215] 可选地,重命名模块42,在对基本程序块内的变量合并指令的操作数进行重命名时,具体用于:
[0216] 确定变量合并指令的操作数的前驱基本程序块;将前驱基本程序块中对应变量的重写后的SSA形式名确定为变量合并指令的操作数的SSA形式名,以完成对操作数进行重命名。
[0217] 可选地,还包括:移除模块。
[0218] 其中,移除模块,用于判断带有变量合并指令的目标程序中是否有满足移除条件的变量合并指令;对满足移除条件的变量合并指令进行移除处理。
[0219] 可选地,满足移除条件的变量合并指令包括以下任意一种:
[0220] 变量合并指令的操作数有相同的定值点;变量合并指令的定值没有使用点并且与其他指令没有依赖链。
[0221] 可选地,第一构建模块43,具体用于:
[0222] 对支配者树中的基本程序块遍历过程中,确定重命名后的变量的SSA形式名,定值点及使用点;基于重命名后的变量的SSA形式名,定值点及使用点构建SSA形式名集合。
[0223] 可选地,第一构建模块43,在针对各重命名后的变量,构建SSA形式名集合时,还用于:
[0224] 响应于目标程序中存在带有谓词的定值指令,采用链表存储带有谓词的定值指令中的多个定值点;将带有谓词的指令的定值重命名插入到前一个相同定值变量重命名所在链表的末尾处。
[0225] 可选地,第二构建模块44,具体用于:
[0226] 根据SSA形式名集合,构建带有变量合并指令的目标程序对应的初始DU链和UD链;将变量合并指令中所有操作数的定值点合并到非变量合并指令的定值点中,并将变量合并指令中定值的使用点合并到非变量合并指令的使用点中;删除初始DU链中与变量合并指令相关的DU关系并删除DU链中与变量合并指令相关的UD关系,并对执行删除后的DU链及UD链中的变量去除SSA形式名中的版本号,以形成目标DU链及目标UD链。
[0227] 可选地,第二构建模块44,在将变量合并指令中所有操作数的定值点合并到非变量合并指令的定值点中,并将变量合并指令中定值的使用点合并到非变量合并指令的使用点中时,具体用于:
[0228] 对基本程序块中的非变量合并指令进行遍历;响应于非变量合并指令的操作数的定值点是变量合并指令,将定值点是变量合并指令的非变量合并指令确定为目标非变量合并指令;将变量合并指令中所有操作数的定值点合并到目标非变量合并指令的定值点,形成定值点合并后的非变量合并指令;将变量合并指令中定值的使用点合并到定值点合并后的非变量合并指令中定值点所对应的非变量合并指令的使用点中。
[0229] 本实施例提供的程序编译装置可以执行上述任意一个方法实施例提供的程序编译。其实现原理和技术效果类似,此处不再赘述。
[0230] 图8为本申请一个实施例提供的程序编译设备的结构示意图。如图8所示,本实施例提供的程序编译设备70,包括:
[0231] 包括:处理器72和存储器71;其中,存储器71,用于存储程序代码;处理器72,用于调用存储器中所存储的程度代码,执行上述任意一个实施例提供的程序编译方法。相关说明可以对应参见附图中的步骤所对应的相关描述和效果进行理解,此处不做过多赘述。
[0232] 其中,程序可以包括程序代码,程序代码包括计算机执行指令。存储器801可能包含高速RAM存储器,也可能还包括非易失性存储器(non‑volatile memory),例如至少一个磁盘存储器。
[0233] 其中,本实施例中,存储器71和处理器72通过总线连接。总线可以是工业标准体系结构(Industry Standard Architecture,简称为ISA)总线、外部设备互连(Peripheral Component Interconnect,简称为PCI)总线或扩展工业标准体系结构(Extended Industry Standard Architecture,简称为EISA)总线等。总线可以分为地址总线、数据总线、控制总线等。为便于表示,图8中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线。
[0234] 本申请实施例还提供一种计算机可读存储介质,计算机可读存储介质中存储有指令,当该指令在计算机上运行时,使得计算机执行上述任意一个实施例提供的程序编译方法。
[0235] 本申请实施例还提供一种计算机程序产品,包括计算机程序,计算机程序被处理器执行时实现上述任意一个实施例提供的程序编译方法。
[0236] 本申请实施例还提供一种人工智能芯片及板卡。上述任意一个实施例提供的程序编译方法采用人工智能芯片或板卡执行。图9是示出根据本申请实施例的板卡的结构图。如图9所示,板卡80包括芯片801,其是一种系统级芯片(System on Chip,SoC),或称片上系统,集成有一个或多个组合处理装置,组合处理装置是一种人工智能运算单元,用以支持各类深度学习和机器学习算法,满足计算机视觉、语音、自然语言处理、数据挖掘等领域复杂场景下的智能处理需求。特别是深度学习技术大量应用在云端智能领域,云端智能应用的一个显著特点是输入数据量大,对平台的存储能力和计算能力有很高的要求,此实施例的板卡80适用在云端智能应用,具有庞大的片外存储、片上存储和强大的计算能力。
[0237] 芯片801通过对外接口装置802与外部设备803相连接。外部设备803例如是服务器、计算机、摄像头、显示器、鼠标、键盘、网卡或wifi接口等。待处理的数据可以由外部设备803通过对外接口装置802传递至芯片801。芯片801的计算结果可以经由对外接口装置802传送回外部设备803。根据不同的应用场景,对外接口装置802可以具有不同的接口形式,例如PCIe接口等。
[0238] 板卡80还包括用于存储数据的存储器件804,其包括一个或多个存储单元805。存储器件804通过总线与控制器件806和芯片801进行连接和数据传输。板卡80中的控制器件806配置用于对芯片801的状态进行调控。为此,在一个应用场景中,控制器件806可以包括单片机(Micro Controller Unit,MCU)。
[0239] 在一种可能的实现方式中,还提供了一种组合处理装置,图10是示出根据本申请实施例的组合处理装置的结构图。如图10中所示,组合处理装置90包括计算装置901、接口装置902、处理装置903和存储装置904。
[0240] 计算装置901配置成执行用户指定的操作,主要实现为单核智能处理器或者多核智能处理器,用以执行深度学习或机器学习的计算,其可以通过接口装置902与处理装置903进行交互,以共同完成用户指定的操作。
[0241] 接口装置902用于在计算装置901与处理装置903间传输数据和控制指令。例如,计算装置901可以经由接口装置902从处理装置903中获取输入数据,写入计算装置901片上的存储装置。进一步,计算装置901可以经由接口装置902从处理装置903中获取控制指令,写入计算装置901片上的控制缓存中。替代地或可选地,接口装置902也可以读取计算装置901的存储装置中的数据并传输给处理装置903。
[0242] 处理装置903作为通用的处理装置,执行包括但不限于数据搬运、对计算装置901的开启和/或停止等基本控制。根据实现方式的不同,处理装置903可以是中央处理器(central processing unit,CPU)、图形处理器(graphics processing unit,GPU)或其他通用和/或专用处理器中的一种或多种类型的处理器,这些处理器包括但不限于数字信号处理器(digital signal processor,DSP)、专用集成电路(application specific integrated circuit,ASIC)、现场可编程门阵列(field‑programmable gate array,FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等,并且其数目可以根据实际需要来确定。如前,仅就本申请的计算装置901而言,其可以视为具有单核结构或者同构多核结构。然而,当将计算装置901和处理装置903整合共同考虑时,二者视为形成异构多核结构。
[0243] 存储装置904用以存储待处理的数据,其可以是DRAM 904,为DDR内存,大小通常为16G或更大,用于保存计算装置901和/或处理装置903的数据。
[0244] 图11中,是计算装置为单核的内部结构示意图。单核计算装置1000用以处理计算机视觉、语音、自然语言、数据挖掘等输入数据,单核计算装置1000包括三大模块:控制模块1001、运算模块1002及存储模块1003。
[0245] 控制模块1001用以协调并控制运算模块1002和存储模块1003的工作,以完成深度学习的任务,其包括取指单元(instruction fetch unit,IFU)10011及指令译码单元(instruction decode unit,IDU)10012。取指单元10011用以获取来自处理装置的指令,指令译码单元10012则将获取的指令进行译码,并将译码结果作为控制信息发送给运算模块1002和存储模块1003。
[0246] 运算模块1002包括向量运算单元10021及矩阵运算单元10022。向量运算单元10021用以执行向量运算,可支持向量乘、加、非线性变换等复杂运算;矩阵运算单元10022负责深度学习算法的核心计算,即矩阵乘及卷积。
[0247] 存储模块1003用来存储或搬运相关数据,包括神经元存储单元(neuron RAM,NRAM)10031、参数存储单元(weight RAM,WRAM)10032、直接内存访问模块(direct memory access,DMA)10033。NRAM 10031用以存储输入神经元、输出神经元和计算后的中间结果;WRAM 10032则用以存储深度学习网络的卷积核,即权值;DMA 10033通过总线1004连接DRAM 
904,负责单核计算装置1000与DRAM 904间的数据搬运。
[0248] 图12中,示出了计算装置为多核的内部结构示意图。多核计算装置1100采用分层结构设计,多核计算装置1100作为一个片上系统,其包括至少一个集群(cluster),每个集群又包括多个处理器核,换言之,多核计算装置1100是以片上系统‑集群‑处理器核的层次所构成的。
[0249] 以片上系统的层级来看,如图12所示,多核计算装置1100包括外部存储控制器1101、外设通信模块1102、片上互联模块1103、同步模块1104以及多个集群1105。
[0250] 外部存储控制器1101可以有多个,在图中示例性地展示2个,其用以响应处理器核发出的访问请求,访问外部存储设备,例如图10中的DRAM 904,从而自片外读取数据或是将数据写入。外设通信模块1102用以通过接口装置902接收来自处理装置的控制信号,启动计算装置901执行任务。片上互联模块1103将外部存储控制器1101、外设通信模块1102及多个集群1105连接起来,用以在各个模块间传输数据和控制信号。同步模块1104是一种全局同步屏障控制器(global barrier controller,GBC),用以协调各集群的工作进度,确保信息的同步。多个集群1105是多核计算装置1100的计算核心,在图中示例性地展示4个。以集群的层级来看,如图12所示,每个集群1105包括多个处理器核(IPU core)1106及一个存储核(MEM core)1107。示例性的,每个集群1105包括4个处理器核和1个存储器,存储器可以为DRAM 904。
[0251] 处理器核1106在图中示例性地展示4个,本申请不限制处理器核1106的数量。其内部架构如图10所示。每个处理器核1106类似于图13的单核计算装置1200,同样包括三大模块:控制模块1201、运算模块1202及存储模块1203。控制模块1201、运算模块1202及存储模块1203的功用及结构大致与控制模块1001、运算模块1002及存储模块1003相同,控制模块1201包括取指单元12011和指令译码单元12012。运算模块1202包括向量运算单元12021和矩阵运算单元12022。不再赘述。需特别说明的是,存储模块1203包括输入/输出直接内存访问模块(input/output direct memory access,IODMA)12033、搬运直接内存访问模块(move direct memory access,MVDMA)12034。IODMA 12033通过广播总线1109控制NRAM 
12031/WRAM 12032与DRAM 904的访存;MVDMA 12034则用以控制NRAM 12031/WRAM 12032与存储单元(SRAM)1108的访存。
[0252] 回到图12,存储核1107主要用以存储和通信,即存储处理器核1106间的共享数据或中间结果、以及执行集群1105与DRAM 904之间的通信、集群1105间彼此的通信、处理器核1106间彼此的通信等。在其他实施例中,存储核1107具有标量运算的能力,用以执行标量运算。
[0253] 存储核1107包括SRAM 1108、广播总线1109、集群直接内存访问模块(cluster direct memory access,CDMA)1110及全局直接内存访问模块(global direct memory access,GDMA)1111。SRAM 1108承担高性能数据中转站的角色,在同一个集群1105内不同处理器核1106之间所复用的数据不需要通过处理器核1106各自向DRAM 904获得,而是经SRAM 1108在处理器核1106间中转,存储核1107只需要将复用的数据从SRAM 1108迅速分发给多个处理器核1106即可,以提高核间通讯效率,亦大大减少片上片外的输入/输出访问。
[0254] 广播总线1109、CDMA 910及GDMA 1111则分别用来执行处理器核1106间的通信、集群1105间的通信和集群1105与DRAM 904的数据传输。以下将分别说明。
[0255] 广播总线1109用以完成集群1105内各处理器核1106间的高速通信,此实施例的广播总线1109支持核间通信方式包括单播、多播与广播。单播是指点对点(例如单一处理器核至单一处理器核)的数据传输,多播是将一份数据从SRAM 1108传输到特定几个处理器核1106的通信方式,而广播则是将一份数据从SRAM 1108传输到所有处理器核1106的通信方式,属于多播的一种特例。
[0256] CDMA 1110用以控制在同一个计算装置内不同集群1105间的SRAM 1108的访存。
[0257] GDMA 1111与外部存储控制器1101协同,用以控制集群1105的SRAM 1108到DRAM 904的访存,或是将数据自DRAM 904读取至SRAM 1108中。从前述可知,DRAM 904与NRAM 
10031或WRAM
[0258] 10032间的通信可以经由2个渠道来实现。第一个渠道是通过IODAM直接联系DRAM 904与NRAM 10031或WRAM 10032;第二个渠道是先经由GDMA 1111使得数据在DRAM 904与SRAM 1108间传输,再经过MVDMA使得数据在SRAM 1108与NRAM 10031或WRAM 10032间传输。
虽然表面上看来第二个渠道需要更多的元件参与,数据流较长,但实际上在部分实施例中,第二个渠道的带宽远大于第一个渠道,因此DRAM 904与NRAM 10031或WRAM 10032间的通信通过第二个渠道可能更有效率。本申请的实施例可根据本身硬件条件选择数据传输渠道。
[0259] 在其他实施例中,GDMA 1111的功能和IODMA的功能可以整合在同一部件中。本申请为了方便描述,将GDMA 1111和IODMA视为不同部件,对于本领域技术人员来说,只要其实现的功能以及达到的技术效果与本申请类似,即属于本申请的保护范围。进一步地,GDMA 1111的功能、IODMA的功能、CDMA 1110的功能、MVDMA的功能亦可以由同一部件来实现。
[0260] 本申请实施例还提供一种电子设备,电子设备包括人工智能芯片或板卡。
[0261] 依据以下条款可更好地理解前述内容(The foregoing may be better understood in view of the following clauses):
[0262] 条款1、一种程序编译方法,其中,包括:
[0263] 获取待编译的目标程序;
[0264] 采用静态单赋值SSA算法对所述目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点;
[0265] 针对各重命名后的变量,构建SSA形式名集合,所述SSA形式名集合中具有各重命名后的变量对应的SSA形式名,定值点及使用点;
[0266] 根据所述SSA形式名集合,构建所述目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链;
[0267] 基于目标DU链及UD链对所述目标程序进行编译。
[0268] 条款2、根据条款1所述的方法,其中,所述采用静态单赋值SSA算法对所述目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点,包括:
[0269] 采用静态单赋值SSA算法在目标程序中确定满足变量合并条件的位置;
[0270] 在所述满足变量合并条件的位置插入对应的变量合并指令;
[0271] 对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点。
[0272] 条款3、根据条款2所述的方法,其中,所述采用静态单赋值SSA算法在目标程序中确定满足变量合并条件的位置,包括:
[0273] 确定所述目标程序中跨基本程序块的变量集合,以及所述目标程序中各基本程序块对应的定值变量集合;
[0274] 针对所述跨基本程序块的变量集合中的各变量所属的辅助基本程序块,确定所述辅助基本程序块的支配边界;
[0275] 将活动变量所在基本程序块的支配边界的起始位置确定为满足变量合并条件的位置;所述活动变量是同时存在于跨基本程序块的变量集合及定值变量集合中处于活动状态的变量。
[0276] 条款4、根据条款2所述的方法,其中,所述对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点,包括:
[0277] 确定带有变量合并指令的目标程序对应的支配者树;
[0278] 对所述支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名;
[0279] 对所述基本程序块内的变量合并指令的操作数进行重命名,以使各重命名后的变量均具有一个对应的定值点。
[0280] 条款5、根据条款4所述的方法,其中,所述对所述支配者树中的基本程序块内的非变量合并指令的变量以及变量合并指令的定值进行重命名,包括:
[0281] 对支配者树中的基本程序块进行遍历;
[0282] 响应于遍历到非变量合并指令的变量,对所述非变量合并指令的变量对应的操作数,按照操作数对应的当前SSA形式名进行重写,对所述非变量合并指令的变量对应的定值创建新的SSA形式名,以完成非变量合并指令的变量的重命名;
[0283] 响应于遍历到变量合并指令的定值,对所述变量合并指令的定值创建新的SSA形式名,以完成变量合并指令的定值的重命名。
[0284] 条款6、根据条款5所述的方法,其中,所述对支配者树中的基本程序块进行遍历,还包括:
[0285] 响应于遍历到新的基本变量,对所述新的基本变量创建栈及对应的计数器,并对新的基本变量以初始SSA形式名压栈。
[0286] 条款7、根据条款6所述的方法,其中,所述对所述非变量合并指令的变量对应的操作数,按照操作数对应的当前SSA形式名进行重写,对所述非变量合并指令的变量对应的定值创建新的SSA形式名,包括:
[0287] 对当前非变量合并指令的变量对应的操作数,从所述操作数所属基本变量的栈中读取对应的当前SSA形式名,并按照操作数对应的当前SSA形式名进行重写;
[0288] 获取当前非变量合并指令的变量对应的定值所属基本变量的栈,从所述定值所属基本变量的栈中读取对应的当前SSA形式名,基于对应的当前SSA形式名及对应计数器创建新的SSA形式名,所述新的SSA形式名用于写入所属基本变量的栈中。
[0289] 条款8、根据条款6所述的方法,其中,所述对所述变量合并指令的定值创建新的SSA形式名,包括:
[0290] 获取所述变量合并指令的定值所属基本变量的栈,从所述定值所属基本变量的栈中读取对应的当前SSA形式名,基于对应的当前SSA形式名及对应计数器创建新的SSA形式名,所述新的SSA形式名用于写入所属基本变量的栈中。
[0291] 条款9、根据条款4所述的方法,其中,所述对所述基本程序块内的变量合并指令的操作数进行重命名,包括:
[0292] 确定所述变量合并指令的操作数的前驱基本程序块;
[0293] 将所述前驱基本程序块中对应变量的重写后的SSA形式名确定为变量合并指令的操作数的SSA形式名,以完成对所述操作数进行重命名。
[0294] 条款10、根据条款2所述的方法,其中,所述对带有变量合并指令的目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点之前,还包括:
[0295] 判断带有变量合并指令的目标程序中是否有满足移除条件的变量合并指令;
[0296] 对满足移除条件的变量合并指令进行移除处理。
[0297] 条款11、根据条款10所述的方法,其中,满足移除条件的变量合并指令包括以下任意一种:
[0298] 变量合并指令的操作数有相同的定值点;
[0299] 变量合并指令的定值没有使用点并且与其他指令没有依赖链。
[0300] 条款12、根据条款4‑11任一项所述的方法,其中,所述针对各重命名后的变量,构建SSA形式名集合,包括:
[0301] 对所述支配者树中的基本程序块遍历过程中,确定重命名后的变量的SSA形式名,定值点及使用点;
[0302] 基于所述重命名后的变量的SSA形式名,定值点及使用点构建SSA形式名集合。
[0303] 条款13、根据条款12所述的方法,其中,所述针对各重命名后的变量,构建SSA形式名集合,还包括:
[0304] 响应于目标程序中存在带有谓词的定值指令,采用链表存储所述带有谓词的定值指令中的多个定值点;
[0305] 将所述带有谓词的指令的定值重命名插入到前一个相同定值变量重命名所在链表的末尾处。
[0306] 条款14、根据条款1‑11任一项所述的方法,其中,所述根据所述SSA形式名集合,构建所述目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链,包括:
[0307] 根据所述SSA形式名集合,构建带有变量合并指令的目标程序对应的初始DU链和UD链;
[0308] 将所述变量合并指令中所有操作数的定值点合并到非变量合并指令的定值点中,并将所述变量合并指令中定值的使用点合并到非变量合并指令的使用点中;
[0309] 删除所述初始DU链中与变量合并指令相关的DU关系并删除DU链中与变量合并指令相关的UD关系,并对执行删除后的DU链及UD链中的变量去除SSA形式名中的版本号,以形成目标DU链及目标UD链。
[0310] 条款15、根据条款14所述的方法,其中,所述将所述变量合并指令中所有操作数的定值点合并到非变量合并指令的定值点中,并将所述变量合并指令中定值的使用点合并到非变量合并指令的使用点中,包括:
[0311] 对基本程序块中的非变量合并指令进行遍历;
[0312] 响应于非变量合并指令的操作数的定值点是变量合并指令,将定值点是变量合并指令的非变量合并指令确定为目标非变量合并指令;
[0313] 将变量合并指令中所有操作数的定值点合并到目标非变量合并指令的定值点,形成定值点合并后的非变量合并指令;
[0314] 将变量合并指令中定值的使用点合并到所述定值点合并后的非变量合并指令中定值点所对应的非变量合并指令的使用点中。
[0315] 条款16、一种程序编译装置,其中,包括:
[0316] 获取模块,用于获取待编译的目标程序;
[0317] 重命名模块,用于采用静态单赋值SSA算法对所述目标程序中的至少一个变量进行重命名,以使各重命名后的变量均具有一个对应的定值点;
[0318] 第一构建模块,用于针对各重命名后的变量,构建SSA形式名集合,所述SSA形式名集合中具有各重命名后的变量对应的SSA形式名,定值点及使用点;
[0319] 第二构建模块,用于根据所述SSA形式名集合,构建所述目标程序对应的目标定值‑使用DU链及目标使用‑定值UD链;
[0320] 编译模块,用于基于目标DU链及UD链对所述目标程序进行编译。
[0321] 条款17、一种程序编译设备,其中,包括:处理器,以及与所述处理器通信连接的存储器;
[0322] 所述存储器存储计算机执行指令;
[0323] 所述处理器执行所述存储器存储的计算机执行指令,以实现如条款1‑15中任一项所述的方法。
[0324] 条款18、一种计算机可读存储介质,其中,所述计算机可读存储介质中存储有计算机执行指令,所述计算机执行指令被处理器执行时用于实现如条款1‑15中任一项所述的方法。
[0325] 条款19、一种计算机程序产品,包括计算机程序,其中,所述计算机程序被处理器执行时实现如条款1‑15中任一项所述的方法。
[0326] 需要说明的是,对于前述的各方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本申请并不受所描述的动作顺序的限制,因为依据本申请,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于可选实施例,所涉及的动作和模块并不一定是本申请所必须的。
[0327] 进一步需要说明的是,虽然流程图中的各个步骤按照箭头的指示依次显示,但是这些步骤并不是必然按照箭头指示的顺序依次执行。除非本文中有明确的说明,这些步骤的执行并没有严格的顺序限制,这些步骤可以以其它的顺序执行。而且,流程图中的至少一部分步骤可以包括多个子步骤或者多个阶段,这些子步骤或者阶段并不必然是在同一时刻执行完成,而是可以在不同的时刻执行,这些子步骤或者阶段的执行顺序也不必然是依次进行,而是可以与其它步骤或者其它步骤的子步骤或者阶段的至少一部分轮流或者交替地执行。
[0328] 应该理解,上述的装置实施例仅是示意性的,本申请的装置还可通过其它的方式实现。例如,上述实施例中单元/模块的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式。例如,多个单元、模块或组件可以结合,或者可以集成到另一个系统,或一些特征可以忽略或不执行。
[0329] 另外,若无特别说明,在本申请各个实施例中的各功能单元/模块可以集成在一个单元/模块中,也可以是各个单元/模块单独物理存在,也可以两个或两个以上单元/模块集成在一起。上述集成的单元/模块既可以采用硬件的形式实现,也可以采用软件程序模块的形式实现。
[0330] 集成的单元/模块如果以硬件的形式实现时,该硬件可以是数字电路,模拟电路等等。硬件结构的物理实现包括但不局限于晶体管,忆阻器等等。若无特别说明,人工智能处理器可以是任何适当的硬件处理器,比如CPU、GPU、FPGA、DSP和ASIC等等。若无特别说明,存储单元可以是任何适当的磁存储介质或者磁光存储介质,比如,阻变式存储器RRAM(Resistive Random Access Memory)、动态随机存取存储器DRAM(Dynamic Random Access Memory)、静态随机存取存储器SRAM(Static Random‑Access Memory)、增强动态随机存取存储器EDRAM(Enhanced Dynamic Random Access Memory)、高带宽内存HBM(High‑Bandwidth Memory)、混合存储立方HMC(Hybrid Memory Cube)等等。
[0331] 集成的单元/模块如果以软件程序模块的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储器中。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储器中,包括若干指令用以使得一台计算机设备(可为个人计算机、服务器或者网络设备等)执行本申请各个实施例方法的全部或部分步骤。而前述的存储器包括:U盘、只读存储器(ROM,Read‑Only Memory)、随机存取存储器(RAM,Random Access Memory)、移动硬盘、磁碟或者光盘等各种可以存储程序代码的介质。
[0332] 在上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述的部分,可以参见其他实施例的相关描述。上述实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。

当前第1页 第1页 第2页 第3页