CN1257454C - 用于展开计算机程序中超级块的编译装置和方法 - Google Patents
用于展开计算机程序中超级块的编译装置和方法 Download PDFInfo
- Publication number
- CN1257454C CN1257454C CNB200310103003XA CN200310103003A CN1257454C CN 1257454 C CN1257454 C CN 1257454C CN B200310103003X A CNB200310103003X A CN B200310103003XA CN 200310103003 A CN200310103003 A CN 200310103003A CN 1257454 C CN1257454 C CN 1257454C
- Authority
- CN
- China
- Prior art keywords
- superblock
- iterations
- piece
- instruction stream
- compiling
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Fee Related
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/44—Encoding
- G06F8/443—Optimisation
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
一种超级块展开器在第一指令流中生成一超级块,并取决于超级块对不同展开类型的适应性,使用不同的方法展开该超级块。如果超级块的迭代数足够小并且如果在编译时知道迭代数,则超级块展开器使用完全展开。如果超级块的迭代数对于完全展开太大并且如果在编译时知道迭代数,则超级块展开器使用静态展开。如果迭代数在编译时不知道,则超级块展开器使用动态展开。这些展开方法的每一个可包括向第一指令流插入计数校正代码,以说明执行退出超级块。通过提供这里所公开的超级块的高级展开方式,可以改进代码性能。
Description
技术领域
本发明一般涉及计算机系统,并特别涉及产生计算机系统可执行代码的编译器。
背景技术
由于计算机时代的出现,计算机系统已发展为非常复杂的装置,并且在许多不同的装置中可找到计算机系统。在硬件和软件(例如计算机程序)两方面惊人的进展已经彻底改进了计算机系统的性能。与早期的计算机程序相比,现代软件已变得非常复杂。许多现代的计算机程序有数万或数十万条指令。计算机程序的执行时间(因而性能)与计算机程序运行时执行的指令数密切相关。这样,随计算机程序的大小和复杂性的增加,计算机程序的执行时间也增加。
与早期的计算机程序不同,现代计算机程序一般以程序员易于理解的高级语言编写。称为编译器的专门的软件工具采取称为“源代码”的这种人可读的计算机程序形式,并将其转换为可由计算机系统执行的“机器代码”或“目标代码”指令。因为编译器产生最终在计算机系统上执行的机器代码指令流,故编译器把源代码转换为目标代码的方式影响着计算机程序的执行时间。
计算机程序、特别是复杂计算机程序的执行时间,是计算机程序内指令的编排和类型的函数。循环影响计算机程序的执行时间。如果计算机程序包含许多循环,或包含执行次数相对大的任何循环,则执行循环所费时间将显著影响计算机程序的执行时间。
为了优化现代计算机程序的性能,已经开发了简表程序(profiler),以便预测和/或测量计算机程序的运行时间性能。简表程序一般产生估计计算机程序不同部分被执行频度的简表数据。使用简表数据,优化程序(诸如优化编译器)可形成决策以优化计算机程序中的循环,以便改进计算机程序的执行速度。
使用简表数据优化计算机程序中的循环的已知方法,并没有提供优化的解决方案。结果是,现有技术可能在导致计算机程序的执行时间较长的循环中不产生作用。没有用于优化计算机程序中循环的改进的装置和方法,编译器产生的计算机程序不能充分地按其应被优化的程度来优化。
发明内容
根据优选实施例,超级块展开器(unroller)在第一指令流中生成一超级块,并依据超级块对不同展开类型的适用性,使用不同的方法展开超级块。如果超级块的迭代数充分小,并且如果在编译时间知道迭代数,则超级块展开器使用完全展开。如果对于完全展开超级块的迭代数太大,并且如果在编译时间知道迭代数,则超级块展开器使用静态展开。如果超级块的迭代数在编译时间不知道,则超级块展开器使用动态展开。这些展开方法的每一个可包含将计数校正代码插入到第一指令流,用于说明超级块退出的执行。可通过提供这里公开的超级块改进的展开而改进代码性能。
从以下如附图所示本发明优选实施例的更为详细的说明,本发明以上和其它特点及优点将明显可见。
本发明的一个目的在于提供一种处理指令流的装置,包括:至少一个处理器;连接到该至少一个处理器的一存储器;驻留在存储器中的第一指令流;以及基于简表的超级块展开器,驻留在存储器中并由至少一个处理器执行,超级块展开器根据简表数据在第一指令流中形成并展开一超级块,超级块展开器包括一计数校正器,当执行退出超级块时,该计数校正器对第一指令流作出至少一个改变以调节循环计数器。
本发明的又一个目的是提供一种处理指令流的装置,包括:至少一个处理器;连接到该至少一个处理器的一存储器;驻留在存储器中的第一指令流;基于简表的超级块展开器,驻留在存储器中并由至少一个处理器执行,超级块展开器根据简表数据在第一指令流中形成并展开超级块,超级块展开器包括一计数校正器,当执行退出超级块时,该计数校正器对第一指令流作出至少一个改变以调节循环计数器,其中如果超级块的迭代数足够小并如果在编译时知道迭代数,则超级块展开器使用完全展开,其中如果超级块的迭代数对于完全展开太大并如果在编译时知道迭代数,则超级块展开器使用静态展开,并且其中如果迭代数在编译时不知道,则超级块展开器使用动态展开。
本发明的又一个目的是提供一种优化第一指令流的方法,包括以下步骤:根据简表数据在第一指令流中生成一超级块;展开该超级块;以及如果需要,向超级块外部提供计数校正代码,以调节至少一个计数值,说明从该超级块退出。
本发明的又一个目的是提供一种优化第一指令流的方法,包括以下步骤:根据简表数据在第一指令流中生成一超级块;如果超级块的迭代数足够小并如果在编译时知道迭代数,则执行超级块完全展开;如果超级块的迭代数对于完全展开太大并如果在编译时知道迭代数,则执行超级块静态展开;如果超级块迭代数在编译时不知道,则执行超级块动态展开;以及如果需要,向超级块外部提供计数校正代码,以调节至少一个计数值,说明从该超级块退出。
附图说明
以下将参照附图说明本发明的优选实施例,其中相同的标号标记相同的组成部分,并且:
图1是根据优选实施例的计算机系统的一框图;
图2是现有技术的一编译器系统的框图;
图3是一流程图,表示使用图2的编译器系统编译源代码的一种现有技术方法的步骤;
图4是一流程图,表示现有技术中已知的超级块的普通展开;
图5是一示例控制流图,表示按简表数据指示提供代码的热通路;
图6是用于从图5中所示控制流图产生超级块的现有技术方法的流程图;
图7是表示使用根据图4中现有技术方法的普通展开,图6中的超级块如何被展开的控制流图;
图8是根据优选实施例用于展开超级块的方法的流程图;
图9是根据优选实施例用于执行超级块完全展开的方法的流程图;
图10是根据优选实施例用于执行超级块静态展开的方法的流程图;
图11是根据优选实施例用于执行超级块动态展开的方法的流程图;
图12是根据优选实施例用于对完全展开校正计数的方法的流程图;
图13是根据优选实施例用于对不完全展开校正计数的方法的流程图;
图14是根据优选实施例用于添加定常校正块的方法的流程图;
图15是根据优选实施例用于执行突增(bump)优化和校正的方法的流程图;
图16是根据优选实施例用于对于突增优化和校正处理块的方法的流程图;
图17是根据优选实施例用于处理拷贝语句(copy statement)的方法的流程图;
图18是根据优选实施例用于处理突增语句(bump statement)的方法的流程图;
图19是根据优选实施例用于处理一般语句的方法的流程图;
图20是根据优选实施例用于对选择的块添加拷贝校正块的方法的流程图;
图21是根据优选实施例用于添加定标校正块的方法的流程图;
图22是根据优选实施例用于添加逆向校正逻辑的方法的流程图;
图23是根据优选实施例用于添加剩余迭代校正块的方法的流程图;
图24是一示例控制流图;
图25是根据本发明的优选实施例在超级块形成后图24的示例控制流图;
图26是完全展开图25的超级块三次之后的示例控制流图;
图27是根据优选实施例添加计数校正代码之后图26的控制流图;
图28是一示例控制流图;
图29是在超级块形成后且展开超级块三次之后图28的控制流图;
图30是根据优选实施例带有添加计数校正代码的图29的控制流图;
图31是一示例控制流图;
图32是在超级块形成后且展开超级块三次之后图31的控制流图;
图33是根据优选实施例带有添加某些计数校正代码的图32的控制流图;
图34是根据优选实施例带有附加的计数校正代码的图33的控制流图;
图35是一示例控制流图;
图36是在超级块形成后图35的控制流图;
图37是根据优选实施例在展开超级块两次后图36的控制流图;
图38是根据优选实施例带有添加某些计数校正代码的图37的控制流图;
图39是根据优选实施例带有扩展块以表示改变的指令的图38的控制流图;
图40是施加几种现有技术优化后图39的控制流图。
具体实施方式
1.0概述
本发明涉及优化计算机程序中的循环。对于不熟悉编译器或已知的循环优化方法的人,这一节概述将提供有助于理解本发明的背景信息。
已知的编译器
图2示出包括一前端编译器210和后端编译器220的现有技术编译系统200。对于大多数已知的编译器,在前端编译器210与后端编译器220之间有一个结构划分(由虚线260指示)。前端编译器210用来把源代码转换为中间表示215。后端编译器220用来把中间表示215转换为用于特定硬件配置(即平台)的机器代码225。前端编译器与后端编译器之间这一指定划分是有效的,因为它允许对于数种不同的语言(例如C++,Java,Ada等)的前端编译器,对给定的平台(例如IBM iSeries)一种单独的后端编译器一起来使用。类似地,如果代码需要被编译以运行在不同的平台上,则对于Java编程语言的单一前端编译器可与多个后端编译器一起来使用。
前端编译器210包括IR代码产生器212,该产生器处理源代码205并产生中间表示215中的指令。后端编译器220包括机器代码产生器222,该产生器处理中间表示215并产生在特定平台上可执行的机器代码。后端编译器220还包括简表程序224,用来当机器代码225以一组样本输入运行时获得简表数据226。如这里所使用的术语“样本输入”意思是指模拟机器代码在其预定环境中实际执行的输入。机器代码产生器222包括使用简表数据226,通过根据简表数据226二次处理中间表示代码215,优化机器代码225的能力。
已知编译器中基于简表的循环优化
图3示出使用图2中的现有技术编译系统200,用于编译源代码的现有技术方法300的流程图。首先,前端编译器把源代码翻译为中间表示(IR)代码(步骤310)。然后,后端编译器处理中间表示,向机器代码插入测试代码(步骤320)。当机器代码225以被指定模拟执行机器代码225实际环境的示例输入集执行时,测试代码是一般使计数器增量的代码,以保持跟踪机器代码225中每一分支被执行的次数对没有被执行的次数是多少。一旦测试代码被插入到机器代码225,被测试的程序(即机器代码)使用样本输入运行,并收集关于执行的简表数据(步骤330)。对于测试代码的情形,简表数据由指示机器代码中每一分支被执行的次数对没有被执行的次数计数值组成。然后后端编译器重新把IR代码编译为机器代码,采用简表数据以提高计算机程序的优化(步骤340)。从图2和3注意,基于简表的优化一般是在后端编译器中进行的。然而,基于简表的优化还可通过链接时间优化程序执行,或者能够在程序运行时顺便执行。
图3的方法300在步骤320假设,简表程序把测试代码插入到机器代码。然而要注意,简表形成也可以通过样本出现,这使用操作系统中基于时间的中断周期地暂停程序的执行,并确定当前的地址。样本不需要插入测试代码,并且是收集简表数据的另一已知的方式。一般样本比插入测试代码所产生的干扰小,但这也相应地使精确性降低。样本限于识别代码的那些块是频繁执行的,但一般不指出哪些分支被转到频繁执行的块。
在业内有许多已知的途径获得简表数据并使用简表数据优化代码。对于使用简表数据优化代码的一种特别方式一般的讨论,参见Schmidt等的“Profile-Directed Restructuring of Operating System Code”,IBM SystemJournal,vol.37no.2,p.270-290(1998)。
现有技术中根据简表数据优化循环的一种已知的方式是循环展开,这是在预期迭代多次每次它们被输入的循环上使用的一种技术。循环体由本身的N个拷贝代替,其中N是被试探确定的一个展开因子。最后的迭代变为以第一迭代为目标,于是N个拷贝共同形成一扩展循环。展开的迭代能够在循环内一同被优化。
业内用来优化循环的一种技术形成超级块。超级块是没有旁侧入口即结合点的代码部分。超级块的形成最初被开发为跨越较大的代码块找到更多的指令级并行性。超级块形成背后的基本想法是要通过复制代码从“热”代码迹去除结合点。超级块形成在以下文献中有详细描述Hwu等的“TheSuperblock:An Effective Technique for VLIW and SuperscalarCompilation”,Journal of Suercomputing,7,229-248(1993)。
循环展开的现有技术概念已经用于超级块循环。然而,对于超级块循环已知的循环展开限于普通的展开。参见图4,现有技术方法400以使用尾部复制对于循环展开形成超级块开始(步骤410)。尾部复制的概念在以下更为详细讨论。一旦在步骤410形成超级块,方法400确定超级块是否适于展开(步骤420)。如果否(步骤420=否),则方法400结束。如果是(步骤420=是),可对超级块执行普通的展开(步骤430)。随后一个例子示出图4中的各步骤。
图5中示出对于计算机程序中一循环的示例控制流图。块PH是在循环前面的“前标头”块,块PE是循环之后的“后出口”块,且块A,B,C,D,E和F是循环的成员。我们假设简表数据指示在运行时通路A-C-D-F是远远占优势的通路(如图5中加粗箭头所指),但在两个块D和F处都有结合点。如图6所示,按Hwu等的Supra所述施加尾部复制生成跟随第一结合点之后的迹中的块的拷贝。块D’和F’的引入允许迹A-C-D-F存在而没有结合点,这允许更为优化。例如,来自C和D的指令能够被一同优化,而此前这是可能是办不到的。超级块的形成在循环中特别有用,其中从最热的循环迹中去除结合点引起程序性能明显的改进。
一旦超级块在循环中被识别,假设超级块构成一完全循环迭代,现有技术可执行超级块普通的展开。普通展开意思是超级块本身可被复制一次或多次,以允许跨越不同循环迭代发现优化机会。由于每一迭代不包含结合点,这导致如图7所示不包含结合点的较大的超级块,其中图6的超级块已经被展开三次。
现有技术方法的一个问题在于,只是使用普通的展开来展开超级块。普通展开不试图确定每次进行循环时超级块如何频繁被执行。因而,归纳条件(例如,减1并与零比较,如果相等则转移)在循环迹的每一拷贝的结束被复制。这样,在图7中,块F的每一拷贝,即F1,F2,F3和F’有可能退出到块PE。然而,常常有这样的情形,即我们知道循环将如何频繁地被执行。例如,形式“for(i=1;i<5;i++){...}”的C++循环将严格地执行五次。在这种情形下,就不必使块F的每一拷贝包含归纳条件和转移。但如图7所示业内所知的超级块的普通展开不识别这种情形。结果是,本来可进行的现有技术中的某些优化当前没有进行。
现有技术没有利用去除包含不需要归纳条件和转移(与超级块展开不同,这对于全循环展开是普遍的)的原因是因为,有过早离开超级块迹的弧这样的问题。不仅块F(F3)最后的拷贝返回块A1循环的顶部,而且尾部拷贝块F’也返回。块F’本身还包含归纳条件的一个拷贝。如果归纳条件从超级块迹被去除,但不从尾部拷贝块去除,则在尾部拷贝块中循环终止将不会正确执行。此外,如果展开的超级块在块A1通过弧从块F’被重新进入,则剩余的迭代数可能不正确。优选实施例提供了设有计数校正的更先进的方式展开超级块,其中如果需要允许超级块以更高级的方式展开,这将允许更高水平的优化,同时总会产生正确的结果。
2.0详细描述
优选实施例提供了一种编译器,这种编译器通过展开循环中的超级块,以消除通过循环的热通路中的结合点,进行增强的循环优化。一个或多个指令可被添加到较不频繁执行的通路,以允许超级块较好的优化。这些附加的指令提供了计数校正,考虑了何时进入和退出循环的尾部而不是在超级块中执行热迹的情形。通过提供更高级的展开准则和方法,以较不频繁执行的循环部分中的指令为代价,循环的整体性能得到提高。
现在参见图1,计算机系统100是适于实现根据本发明优选实施例的装置的系统。计算机系统100是一IBM iSeries计算机系统。然而,业内专业人员将可理解,本发明的机制和装置同等适用于任何计算机系统,而不论计算机系统是复杂的多用户计算装置,还是单用户工作站,或嵌入控制系统。如图1所示,计算机系统100包括处理器110,主存储器120,海量存储器接口130,显示器接口140,及网络接口150。这些系统组件通过使用系统总线160互连。海量存储器接口130用来把海量存储装置储如直接访问存储装置155)连接到计算机系统100。直接访问存储装置155的一个特定类型是可读且可写的CD-RW驱动器,这可向CD-RW 195存储并从其读取数据。
根据优选实施例的主存储器120包含数据121、操作系统122、源代码123、中间表示124、简表数据125、编译器126以及机器代码129。数据121表示作为往来于计算机系统100中任何程序的任何数据。操作系统122是工业界所知道的OS/400多任务操作系统;然而,业内专业人员可看到,在本发明的精神和范围内,不限于任何一个操作系统。源代码123是以高级语言编写的计算机程序或其一部分。中间表示124是通过前端编译器从源代码123产生的中间代码,该前端编译器可以是编译器126的一部分,或图1中未示出的不同的编译器。简表数据125是通过任何适当的编制简表方法收集的数据,包括没有限制的测试简表程序和样本简表程序。简表数据125适当包含一个分支被执行次数的计数。编译器126包括超级块展开器127,该程序根据简表数据125优化中间表示124中的代码。超级块展开器127包括计数校正器128,该程序考虑当执行进入或离开超级块时对循环计数器进行的所需的变化。注意,产生简表数据125的简表程序在图1中未明显示出,但假设为编译器126的一部分。机器指令129是由编译器126从中间表示124产生的可执行代码。
注意,源代码123,中间表示124,简表数据125,编译器126,及机器代码129都表示为驻留在存储器120中,以便于在一个图示中表示出所有这些组成部分。业内专业人员将看到,对于大多数编译器这不是通常的操作方式。前端编译器可以处理源代码123,并从其产生中间表示124。这一处理可出现在与计算机系统100分开的一计算机系统中。这时简表程序可向中间表示124插入测试代码,并在不同的计算机系统上运行被测试的代码以收集简表数据125。简表程序126处理中间表示124并从其产生机器代码129,它也可出现在不同的计算机系统上。在极端情形下,源代码123可驻留在第一计算机系统上,且前端编译器可驻留在第二计算机系统上。前端编译器可从第一计算机系统读取源代码123,产生中间表示124,并把中间表示124存储在第三计算机系统上。然后简表程序可从第三计算机系统读取中间表示,插入测试代码,并在第四计算机系统上存储被测试代码。然后简表程序从第四计算机系统读取被测试代码,在第五计算机系统上执行该被测试代码,并且将结果简表数据存储在第六计算机系统上。编译器126能够在第七计算机系统上执行,它从第三计算机系统读取中间表示124,并从第六计算机系统读取简表数据,并从其产生机器代码129,该机器代码可写入第八计算机系统。这一简单的例子表示,优选实施例明显延伸到任何适当的配置和任何数目的计算机系统,以实现前端和后端编译。如以上例子所述,这里所讲的“装置”明显延伸到多计算机配置。
计算机系统100采用熟知的虚拟寻址机制,这允许计算机系统100的程序的行为如同它们只是在访问一个巨大的、单一的存储实体,而不是访问多个较小的存储实体,诸如主存储器120和DASD装置155。因而,虽然数据121、操作系统122、源代码123、中间表示124、简表数据125、编译器126及机器代码129表示为驻留在主存储器120中,但业内专业人员可看出,这些项目不必同时完全包含在主存储器120中。还应当注意,术语“存储器”这里用来一般地表示计算机系统100的整个的虚拟存储器,并可包含连接到计算机系统100的其它计算机系统的虚拟存储器。
处理器110可由一个或多个微处理器和/或集成电路构成。处理器110执行存储在主存储器120中的程序指令。主存储器120存储处理器110可访问的程序和数据。当计算机系统100启动时,处理器110最初执行构成操作系统122的程序指令。操作系统122是管理计算机系统100资源的一种复杂的程序。这些资源的某些是处理器110、主存储器120、海量存储接口130、显示器接口140、网络接口150及系统总线160。
虽然计算机系统100表示为只包含单个的处理器和单个的系统总线,但业内专业人员应看到,本发明可使用具有多处理器和/或多总线的计算机系统实施。此外,优选实施例中使用的接口每一个包括分开的全编程的微处理器,用来从处理器110卸载计算密集的处理。然而,业内专业人员可看到,本发明同等适用于简单使用I/O适配器执行类似功能的计算机系统。
显示接口140用来直接把一个或多个显示器165连接到计算机系统100。这些显示器165,可能是非智能化(即哑)终端或全编程工作站,用来允许系统管理员和用户可与计算机系统100通信。然而要注意,虽然装设了显示接口140以支持与一个或多个显示器165通信,但计算机系统100并不是一定需要显示器165,因为与用户和其它处理所有需要的交互作用可通过网络接口150来进行。
网络接口150用来把其它计算机系统和/或工作站(例如图1中的175)通过网络170连接到计算机系统100。不论计算机系统100如何连接到其它计算机系统和或工作站,本发明是同等适用的,不论网络连接170是使用当前的模拟和/或数字技术或通过某些未来联网机制。此外,许多不同的网络协议能够用来实现网络。这些协议是专门的计算机程序,允许计算机通过网络170通信。TCP/IP(传输控制协议/因特网协议)一种适用的网络的一个例子。
在这点,重要的是要注意,虽然已经并将继续在全功能计算机系统的场合对本发明进行描述,业内专业人员可看到,本发明能够以各种形式作为程序产品分布,并且不论用来实际进行分布的信号承载介质的具体类型如何,本发明同等适用。适用的信号承载介质的例子包括:记录型介质,诸如软盘和CD-RW(例如,图1的195),及传输类型介质,诸如数字和模拟通信链路。
现在,我们转向由图8-23所示超级块展开器127执行的功能。超级块展开器127中计数校正器128保证循环计数器对循环中每一可能的执行通路有正确的值。现在参见图8,根据优选实施例的方法800允许比现有技术中更多类型超级块的展开。首先,使用尾部复制形成超级块(步骤410),这与图4的现有技术方法400相同。如果超级块不适合展开(步骤420=否),执行方法800。如果超级块适合展开(步骤420=是),这时方法800进行一系列检验,以确定如果有则对超级块执行什么类型的展开。如果完全展开是可接受的(步骤830=是),则执行完全展开(步骤840)。如果不能接受完全展开(步骤830=否),则方法800检验看静态展开是否可接受(步骤850)。如果是(步骤850=是),执行静态展开(步骤860)。如果静态展开不可接受(步骤850=否),方法800检验看动态展开是否可接受(步骤870)。如果是(步骤870=是),执行动态展开(步骤880)。如果否(步骤870=否),执行方法800。注意,步骤840,860和880的细节在以下更为详细讨论的其它图示中示出。步骤840,860和880中共同特征是循环计数器值的校正,以说明离开或重新进入展开的超级块。
由于执行普通展开的受限值,图8中的方法800不包含执行诸如出现在图4的块430中的普通展开的任何步骤。然而,业内专业人员可看到,普通展开能够作为方法800的一部分包含在优选实施例的范围内。
注意,图8-23中的许多步骤是在后继的图示中被扩展到多个步骤的步骤。例如,图8中的步骤840还作为图9中包括多个步骤的方法840示出。因此,相同的标号指示符,就不同引用的流程图来说可能称为步骤或方法。
在优选实施例中,步骤420确定循环是否有单个的闭锁块,超级块是否足够小考虑用于展开,超级块是否构成完全循环迭代,以及循环计数初始化和迭代条件是否能够被正确确定。如果能够确定循环迭代的确切次数,完全的和静态的展开只是在步骤830和850中可接受。并对步骤830,850和870中所有可接受性测试,只要从展开所得的代码复制量不超过可调节限制,则展开就是可接受的。
在图8的步骤840中执行完全展开的步骤示于图9。首先,对表示展开因子UF的变量指定迭代计数的值(步骤910)。然后复制超级块UF次(步骤920)。复制超级块包括拷贝指令并更新控制流。循环终止转移被去除(步骤930)。因为我们知道所有的迭代将被执行,可以去除对每一迭代的闭锁转移。并且最后,必须对计数校正以说明完全展开(步骤940)。
图9中的计数校正940的细节示于图12中。许多计算机体系结构具有计数转移指令,用于使用特定计数寄存器CTR优化循环。我们假设一指令,该指令使计数寄存器的值减量,将其与零比较并且如果值非零返回循环顶部。我们假设,循环已经被优化,以在适当的情况下使用计数转移指令。如果循环是计数转移循环(步骤1210=是),则添加不变的校正块(步骤1220)。图14中示出在步骤1220添加不变的校正块的细节。如果循环不是计数转移循环(步骤1210=否),执行突增优化和校正(步骤1230)。突增优化和校正1230的细节示于图15。
参见图14,示出图12中步骤1220的添加不变校正块的细节。首先,计数器I被初始化为2(步骤1410)。如果计数器I的值大于展开因子UF(步骤1420=否),则执行方法1220。如果计数器I的值小于或等于展开因子UF(步骤1420=是),则对变量V指定展开因子UF减迭代值I加1(步骤1430)。然后B被指定为迭代I中的第一块(步骤1440)。对于退出展开的迹的B之外的每一后继弧,沿该弧添加包含代码的块,以便把V的值加载到计数寄存器中。如果迭代I中还有块要处理(步骤1460=是),对B指定迭代I中下一个的块,并将控制传送到步骤1450。如果迭代I中不再有块(步骤1460=否),I的值增1(步骤1480),且将控制传送到步骤1420。图14的方法1220通过以离开超级块迹时剩余的完全的或和局部的迭代数V加载计数寄存器CTR,来校正对计数转移循环完全展开的计数。
图15中示出图12的步骤1230中执行突增优化和校正的细节。步骤1230用于不使用计数转移指令循环的计数校正,不论循环是完全、静态地或动态地被展开。我们从图8的步骤420中适宜性测试知道,循环包含使用来对循环终止进行测试的值增量和减量的单个“突增指令”,以及保证每当执行循环时突增指令被执行。然而与计数转移指令不同,突增指令能够从测试和转移分开。它可出现在循环的顶部、循环的末端或之间某处。而且,通过突增指令计算的值可由循环中其它计算使用,这样我们在没有更多的分析时不能轻易地去除它或改变其值。
理想上,循环应有形式为X=X+N的突增指令,其中X是循环终止寄存器。但正好象我们可能有通过循环散开的拷贝指令,诸如:Y=X;Z=Y+N;X=Z。当然,有其它更多的我们必须解决的复杂的可能性。
最好是把X=X+N的UF拷贝转换为单个的突增指令X=X+(UF*N),并使插入的突增表示只在从循环向备份循环(即包含尾部复制块的原始循环)早先退出时执行。我们这样作的方式是要改变每一突增指令以指向新的寄存器Y1,并沿每一退出弧从Y1向循环终止寄存器X添加一拷贝。后来的优化阶段通常将确定Y1只沿退出弧使用,并把突增指令推出到有拷贝的地方。这种方案的复杂性在于,我们必须在突增指令来到的循环中小心,并如果我们在突增指令之前退出,则使用YI-1。
为了便于这样进行,我们保持对两个寄存器集合的跟踪。S0包含所有与在突增指令之前循环终止寄存器X有相同值的寄存器,S1包含那些与突增指令之后的X等同的寄存器。在每一迭代的开始,S0获得S1旧值,而S1变为空。集合S0包含不同于X的某种寄存器的规范表示Rep(S0)。S1类似地包含不同于X的某种寄存器的规范的表示。想法是要从循环中尽可能地去除X的使用,以便于突增计算中涉及的指令的移动。我们把从X到新寄存器X’的拷贝放置在循环的开头。X’表示X的初始值。所有突增指令将向X’添加多个初始突增值N,而不是向X添加突增值。
现在我们转向图15,描述实现图12中的突增优化和校正1230的详细步骤。首先,识别循环终止寄存器X和原始突增量N(步骤1510)。分配新的寄存器X’,并在第一展开迭代的开头插入拷贝语句X’=X(步骤1520)。集合S0初始化为包含X’和X;集合S1初始化为空;而新的寄存器Y0初始化为X’的值(步骤1530)。这时I设置为值1(步骤1540)。如果I大于展开因子UF(步骤1550=否),执行方法1230。如果I小于或等于展开因子UF(步骤1550=是),则分配新的符号寄存器Y1(步骤1560),并把B设置为展开的迭代I中的第一块(步骤1570)。然后对B处理以进行突增优化和校正(步骤1580)。注意,步骤1580的细节示于图16。如果在展开迭代I中有更多的块(步骤1590=是),则B被设置为展开迭代I中的下一个块(步骤1592),把控制传送到步骤1580。如果在展开迭代I中没有更多的块(步骤1590=否),则S1拷贝到S0;S1设置为空;且I增1(步骤1594)。在这一点,控制被传送到步骤1550,并继续进行处理。
对于在步骤1580的突增优化和校正的块B的处理更为详细地示于图16。在B中有更多的语句要处理(步骤1610=是),于是S被设置为B中第一语句(步骤1630)。如果S是形式为R’=R的拷贝语句(步骤1640=是),则处理拷贝语句(步骤1650)。注意,处理步骤1650中处理拷贝语句的细节示于图17中。如果S不是形式为R’=R的拷贝语句(步骤1640=否),则我们检验看S是否为可能的突增语句(步骤1660)。如果是(步骤1660=是),则处理突增语句S(步骤1670)。步骤1670中突增语句S的处理细节示于图18。如果S不是可能的突增语句(步骤1660=否),则处理常规语句S(步骤1680)。在步骤1680处理常规语句的细节示于图19。如果在B中有更多的语句要处理(步骤1610=是),则S设置为B中下一个语句(步骤1630),并在步骤1640处理继续进行。如果B中没有更多的语句要处理(步骤1610=否),则B的拷贝校正块被添加(步骤1620)。图16中步骤1620的细节示于图20。
图16的步骤1650中的拷贝语句S的处理在图17中更为详细地示出。如果R不是集合S0的元素(步骤1710=否),且不是S1的元素(步骤1730=否),则执行方法1650。如果R是集合S0的元素(步骤1710=是),则把R’添加到集合S0,从R1去除R’,并在S中以规范表示Rep(S0)代替R。如果R不是集合S0的元素(步骤1710=否),但是集合S1的元素(步骤1730=是),则R’添加到集合S1,从集合S0去除R’,并在S中以规范表示Rep(S1)代替R。
现在考虑图18中所示的图16步骤1670中处理突增语句S的细节。注意,在图16的步骤1660中S已经被确定为形式R’=R+N。如果R不是集合S0的元素(步骤1810=否),且不是S1的元素(步骤1850=否),则执行方法1670。如果R是S0的元素(步骤1810=是),则在S之前生成新的突增指令Y1=X’+C,其中C=N*I(步骤1820)。然后,以规范表示Rep(S0)代替S中的R(步骤1830)。然后R’和Y1添加到S1,并从S0去除R’和Y1(步骤1840)。如果R不是S0的元素(步骤1810=否),但是S1的元素(步骤1850=是),则在S中以规范表示Rep(S1)代替R(步骤1860)。
图16的步骤1680中处理常规语句S的细节示于图19。对每一在S中使用的寄存器R,R是集合S0的一个元素,以规范表示Rep(S0)代替R(步骤1910)。对每一在S中使用的寄存器R,R是集合S1的一个元素,以规范表示Rep(S1)代替R(步骤1920)。并对S中每一定义的寄存器R’,从S0和S1去除R’(步骤1930)。
图16的步骤1620中添加拷贝校正块的细节示于图20。如果X是集合S1的元素(步骤2010=是),则对变量Z指定Y1的值(步骤2020)。如果X不是集合S1的元素(2010=否),则对变量Z指定YI-1的值(步骤2030)。如果有来自B所未处理的退出弧(步骤2040=是),A被设置为来自B的下一个未处理的退出弧(步骤2050),且一个新的块沿包含拷贝语句X=Z的A插入(步骤2060)。然后在步骤2040继续进行处理,且处理进行到来自B的所有退出弧已经被处理为止(步骤2040=否)。
图8的步骤860中进行静态展开的步骤示于图10。首先,使用一个或多个适当的试探法确定静态展开因子UF(步骤1010)。用于确定展开因子UF的试探法可约束展开的迭代总数及复制的指令总数。试探法还可通过超级块在其达到闭锁转移之前退出的似然性限制展开因子。此外,试探法可限制所需的剩余迭代数。一旦展开因子UF已经被确定,超级块就被复制UF次(步骤1020)。复制超级块包括拷贝指令和更新控制流。内部循环终止转移被去除(步骤1030)。在步骤1030去除对除了最后的之外每一迭代的闭锁转移。然后生成任何所需的剩余的迭代(步骤1040)。如果迭代总数不能通过展开因子UF除尽,剩余的迭代放置在展开循环之前弥补差。剩余迭代也是超级块而非整个循环的复制。最后,必须对计数进行校正以说明不完全展开(步骤1050)。
对于图10步骤1050的不完全展开的计数校正的细节示于图13中。如果循环是计数转移循环(步骤1310=是),则添加定标校正块(步骤1320)并添加剩余的迭代校正块(步骤1330)。如果找到任何逸出弧(步骤1340=是),则添加逆校正逻辑(步骤1360)。在这点,计数寄存器初始化被修改(步骤1350)。如果没有找到逸出弧(步骤1340=否),则修改计数寄存器初始化(步骤1350)而无需添加在步骤1360的逆校正逻辑。
如果循环不是计数转移循环(步骤1310=否),执行突增优化和校正(步骤1230),这将参照以上图12详细讨论。然后生成模测试块W,,其目标是展开的迹和备份循环的标头(步骤1370)。块W包含计算X模UF的代码,其中X是图12的方法1230中使用的循环终止寄存器,且UF是这一循环的展开因子。然后闭锁弧从备份循环到块W重新定向(步骤1380)。如果块W中的模测试返回零,这引起循环转移到展开的超级块的标头,并否则转移到备份循环标头。这保证了控制将可尽快返回展开循环迹。
返回参照图13,添加定标校正块的步骤1320的细节示于图21。步骤1320对于计数转移循环执行,它不能完全被展开。首先,I被设置为值1(步骤2110)。如果I大于展开因子UF(步骤2120=否),则执行方法1320。如果I小于或等于展开因子UF(步骤2120=是),则B设置为迭代I中的第一块(步骤2130)。对于退出展开迹的B之外的每一弧,包含代码CTR=CTR*UF-(I-1)的块C沿A添加(步骤2140)。如果迭代I中有任何未处理的块(步骤2150=是),则B设置为迭代I中的下一个块(步骤2170),且处理在步骤2140继续进行。如果迭代I中所有的块已被处理(步骤2150=否),则I增1(步骤2160),且处理在步骤2120继续进行。
在图13的步骤1360中添加逆校正逻辑的细节示于图22。首先,块W沿从原始闭锁块到原始循环标头块的弧添加(步骤2210)。如果原始闭锁块没有被尾部复制(步骤2220=否),则控制传送到步骤2240。如果原始闭锁块被尾部复制(步骤2220=是),则从双闭锁块到循环标头块的弧另外被重定向到目标块W(步骤2230)。在块W中产生代码以执行以下步骤:对于展开因子UF计算计数器CTR的模;比较CTR模UF与零;如果CTR模UF为零,则转移到展开迹,否则转移到原始循环标头块(步骤2240)。然后从W向展开迹的标头块添加一弧(步骤2250)。然后沿新的弧(步骤2260)插入块R-1(步骤2260)。然后在块R-1中产生代码以计算CTR=CTR/UF(步骤2270)。
图13中步骤1330的细节示于图23。首先,I设置为1,且L设置为剩余的迭代数(步骤2310)。如果I大于L(步骤2320=否),则执行方法1330。如果这时I小于或等于L(步骤2320=是),则B设置为剩余迭代I中的第一块(步骤2330)。如果执行静态展开(步骤2340=是),对于来自B退出剩余迭代且目标为备份循环的每一弧A,沿弧A添加包含代码CTR=(CTR*UF)-1的块C。如果没有执行静态展开(步骤2340=否),则对于来自B的退出剩余迭代且目标为备份循环的每一弧A,沿弧A添加包含代码CTR=(CTR*UF)+(2*(L-I+1))的块C。如果在迭代I中仍然有未处理的块(步骤2370=是),则将B设置为迭代中的下一个块(步骤2390),并在步骤2340继续进行处理。一旦迭代I中所有所块已被处理(步骤2370=否),则I增1(步骤2380),且在步骤2320继续进行处理。
在图8的步骤880中执行动态展开的步骤的细节示于图11。首先,使用一个或多个适当的试探法确定动态展开因子UF(步骤1110),该法可能比图10的步骤1010中用来确定静态展开因子的试探法有更多的限制。一旦已确定展开因子UF,超级块即被复制UF次(步骤1120)。复制超级块包括拷贝指令和更新控制流。去除内部循环终止转移(步骤1130)。在步骤1130对每一迭代除了最后的之外可去除闭锁转移。然后生成任何所需剩余迭代和模测试(步骤1140)。如果迭代总数不能由展开因子UF整除,剩余迭代放置在展开循环之前以弥补差。对于动态展开,我们生成循环之前的UF-1剩余迭代。在这些之前,我们设置代码以确定运行时间迭代T的总数,并确定T模UF的余数。该结果引起我们转移到适当的剩余迭代以保证这一剩余迭代数在展开循环之前执行。最后,必须校正计数以说明未完全的展开(步骤1050),这在以上参照图10中步骤1050已详细讨论。
现在给出例子解释图8-23中所示的方法。图24表示包含五个基本块A,B,C,D和E的代码部分的示例控制流图。图24中对每一弧的执行频度以数字表示在弧的旁边。在优选实施例中,这些执行频度是从简表数据125确定的。我们假设这是一计数转移循环,在块A计数寄存器CTR初始化为3,并在块D中的“bcf”指令。bcf指令在PowerPC中指令集中被定义,并在执行时,使计数寄存器CTR减量,并如果结果为非零,则转移。从执行频度注意到通过循环的热迹包含块B和D。这一循环总是严格地执行三次。以这一假设,我们现在返回图8的方法800。
使用步骤410中的尾部复制通过复制D’形成一超级块,结果如图25所示。图24的执行频度需要确定热迹,这指出超级块如何形成。超级块一旦形成,就不需要示出执行频度,因而它们在图25-27中未示出。对于图25中所示的超级块,我们假设它适宜展开(步骤420=是),并且完全展开是可接受的(步骤830=是)。然后我们执行完全展开(步骤840),这在图9中详细示出。
假设循环总是执行三次,展开因子UF设置为3(步骤910)。然后超级块复制三次(步骤920),并去除循环终止转移(步骤930),结果得到图26中所示的控制流图。对于展开三次的复制是B1,D1,B2,D2,B3和D3。块B,C,D和D’形成备份循环。然后我们对完全校正执行如图12中详细所示的计数校正。
我们假设,这是计数转移循环(步骤1210=是),因而我们需要添加不变的校正块(步骤1220),这在图14中详细示出。I设置为2(步骤1410)。2是小于3的展开因子UF(步骤1420=是),于是V设置为(3-2+1)或2的值(步骤1430)。B设置为第二迭代中的第一块(步骤1440),这是图26中例子的B2。然后步骤1450在B2和C之间添加块R2,其中R2包括把2加载到计数器CTR的代码。在第二迭代中仍然有更多的块(步骤1460=是),于是B设置为第二迭代中的下一个块D2(步骤1470)。步骤1450中,对于块D2,没有退出展开迹的弧,于是什么都不作。在第二迭代中不再有块(步骤1460=否),于是I增加到3(步骤1480)。I仍然小于或等于展开因子3(步骤1420=是),于是V设置为值1,且B设置为块B3,即第三迭代中的第一块。在步骤1450,块R3添加到B3与C之间,其中R3包含把1加载到计数器CTR的代码。在第三迭代中有更多的块(步骤1460=是),于是B设置为第三迭代中下一个块,即D3。在步骤1450中,对于D3,没有退出展开迹的弧,于是什么都不作。在第三迭代中不再有块(步骤1460=否),于是I增量到4(步骤1480)。步骤1420现在为否,于是执行方法1220。完全展开图26的超级块的结果示于图27。注意,块R2和R3包含计数校正代码,调节计数器CTR以说明离开热迹执行备份循环中不太频繁执行的代码。
图28对于一简单静态展开例子示出示例控制流图。执行频度的变化示出每个入口循环执行30次。我们还假设这是计数转移循环,在块A中有30加载到CTR,并且块D中有bcf语句。参见图8,使用尾部形成的超级块的形成(步骤410)导致图25所示的控制流图。我们假设超级块适宜展开(步骤420=是),且完全展开是不可接受的(步骤830=否),因为复制热迹三十次将导致过多的代码膨胀。我们进而假设静态展开是可接受的(步骤850=是),于是我们在步骤860执行图10详细示出的静态展开。
我们选择静态展开因子UF为3(步骤1010)。注意,展开因子UF的确定可使用任何适用的试探法进行。我们复制超级块三次(步骤1020),并去除内部循环终止转移(步骤1030)。结果如图29所示。注意由于循环不完全展开,除了从D3到B1附加的弧之外,图29是与图26的控制流图是相同的。不再有剩余的迭代,因为30可被展开因子3整除,于是步骤1040不作什么。然后我们对不完全展开校正计数(步骤1050),这在图13中更为详细示出。
在我们最初的假设中,我们假设这是计数转移循环,于是步骤1310=是。结果是,我们需要添加图21详细示出的定标校正块(步骤1320)。I设置为值1(步骤2110)。1小于展开因子3,于是步骤2120=是。B设置为第一迭代中的第一块,即B1。步骤2140在B1与C之间添加块R1,其中B1包含代码CTR=CTR*3。在第一迭代中仍然有未处理的块(步骤2150=是),于是B设置为第一迭代中的下一个块,即D1。没有来自D1的退出展开迹的弧,于是步骤2140什么也不作。在第一迭代中不再有未处理的块(步骤2150=否),于是I增加1达到值2(步骤2160)。步骤2120仍然为是,于是B设置为第二迭代中的第一块,即B2。步骤2140在B2与C之间添加块R2,其中R2包含代码CTR=(CTR*3)-1。在第二迭代中仍然有未处理的块(步骤2150=是),于是B指定给下一个块,即D2。不再有合格的弧,于是步骤2140什么也不作。在第二迭代中不再有未处理的块(步骤2150=否),于是I增加1达到值3(步骤2160)。步骤2120仍然为是,于是B设置为第三迭代中的第一块,即B3。步骤2140在B3与C之间添加块R3,其中R3包含代码CTR=(CTR*3)-2。在第三迭代中仍然有未处理的块(步骤2150=是),于是B设置为第三迭代中的下一个块,即D3。D3没有合格的弧,于是步骤2140不采取行动。第三迭代中不再有未处理的块(步骤2150=否),于是I增加1达到值4(步骤2160)。步骤2120现在为否,这结束步骤1320。这样,我们返回图13,并然后添加图23详细示出的剩余迭代校正块(步骤1330)。
步骤2310设置I为1且设置L为零,因为没有剩余迭代。在步骤2320中,I的值(1)大于L的值(零),于是步骤2320=否,并执行步骤1330。现在返回图13,发现有逸出弧(步骤1340=是)。图29中逸出弧的例子是B1与C之间,B2与C之间,及B3与C之间的弧。这些弧的每一个逸出热迹。因此,如图22详细所示,添加逆校正逻辑(步骤1360)。
步骤2210在D与B之间添加块W。原始闭锁块D被尾部复制(步骤2220=是),如图29中块D’所示。然后从D’到B的弧重定向到目标W(步骤2230)。然后在块W中产生代码,使CTR模3与零比较,并且如果为真则转移到展开迹,否则转移到原始循环标头块B(步骤2240)。然后从W到展开的迹的标头块B1添加一弧(步骤2250)。然后沿新的弧从W到B1添加一新的块R-1(步骤2260)。然后在R-1中产生代码计算CTR=CTR/3。在这点,执行步骤1360,于是控制返回图13中的步骤1350。然后从CTR=30到CTR=10修改块A中计数寄存器初始化(步骤1350)。现在执行步骤1050,执行步骤860,这完成图8所示的方法800。该结果示于图30的控制流图中。
图31的控制流图是可使用动态展开的一例子。执行频度如图31所示,每个入口的循环执行平均数为六。我们对此例子假设,块A包含从输入参数P加载CTR的代码,于是我们不能确定编译时迭代确切的数目。还假设D包含bcf指令。我们现在返回图8的方法800看图31的控制流图如何被处理。
图8的步骤410使用尾部复制产生超级块,再次产生图25的结果。我们假设超级块适合展开(步骤420=是)。完全展开是不可接受的(步骤830=否),因为不能确定确切的迭代计数。由于这一相同的原因,静态展开也是不可接受的(步骤850=否)。我们假设动态展开是可接受的(步骤870=是),于是在步骤880执行图11中更详细示出的动态展开。
我们选择动态展开因子UF为3(步骤1110)。这里还使用任何适当的试探法确定动态展开因子UF。然后我们复制超级块三次(步骤1120),去除内部循环终止转移(步骤1130),并生成剩余迭代和模测试(步骤1140)。结果是图32的控制流图。有两个剩余迭代LB1到LD2在展开循环B1到D3之前。需要两个模测试块M1和M2以确定在哪里开始。块M1取参数值模3,并且如果结果为零,转移到B1,这是展开的循环开始。如果M1中的模测试为非零,M2中的模测试确定需要多少剩余迭代。如果来自M1中的模测试结果为1,则转移到LB2,否则它直落入LB1。因为动态展开是不完全展开,计数必须被校正(步骤1050),如图13更为详细所示。
这是计数转移循环(步骤1310=是),于是需要添加定标校正块(步骤1320),如图21更为详细所示。以图21的方法1320处理图32的控制流图导致添加块R1,R2和R3,这与图30所示并讨论的静态展开例子中所作的相同。一旦步骤1320完成,控制传送到图13的步骤1330。添加图23中详细所示的剩余迭代校正块(步骤1330)。I被设置为1,且L设置为2,即剩余迭代数(步骤2310)。I小于L,于是步骤2320为是。B设置为LB1,即第一剩余迭代中的第一块(步骤2330)。这是动态展开而非静态展开的情形,于是步骤2340=否。步骤2360在LB1与C之间添加块LR1,其中LR1包含代码CTR=(CTR*3)-1。在第一迭代中仍然有未处理的块(步骤2370=是),于是B设置为第一迭代中下一个块LD1(步骤2390)。步骤2340=否,但对于LD1没有合格的弧(只注意目标为备份循环的弧),于是步骤2360不作任何事情。在第一迭代中不再有未处理的块(步骤2370=否),于是I增加1达到值2(步骤2380),并且控制传送到步骤2320。
步骤2320仍然为真,于是B设置为第二剩余迭代中的第一块LB2(步骤2330)。步骤2340为否。然后步骤2360在LB2与C之间添加块LR2,其中LR2包含代码CTR=(CTR*3)-2。在第二剩余迭代中仍然有未处理的块(步骤2370=是),于是B设置为第二剩余迭代中下一个块LD2(步骤2390)。步骤2340为否。不再有来自LD2合格的弧,于是步骤2360不作任何事。第二剩余迭代中所有的块已被处理(步骤2370=否),于是I增加1达到值3(步骤2380)。在这点,I不小于或等于L,于是步骤2320=否,并执行步骤1330。这点的结果由图33的控制流图示出。
现在返回图13,发现有逸出弧(步骤1340=是),于是添加图22中详细所示的逆校正逻辑(步骤1360)。在这种情形下,图22的步骤1360执行与图30中所示静态展开例子中执行的相同的步骤,即添加块W和R-1,并重新定向弧。一旦在图13的步骤1360添加了逆校正逻辑,计数寄存器初始化即被修改(步骤1350)以说明展开。块A中的计数寄存器初始化变为CTR=(P/3)+1。在这点,执行图13的方法1050,执行图10的步骤1050,并执行图8的步骤860。结果是,执行方法800。这些结果示于图34的控制流图中。
最后的例子对不使用计数寄存器的循环使用静态展开。图35示出一控制流图,其中某些决内的某些语句是可见的。我们假设有更多的语句出现,但在这个例子中使用如图35所示的。我们能够在编译时间确定循环将每个入口确切执行十次。我们假设变量“d”在循环之外而不是之内使用。为了后继的优化,我们还假设所有变量“b”和“c”的提及如图35所示。我们现在转向图8的方法800,看静态展开怎样用来展开图35所示的程序部分。
图8的步骤410尾部复制结果是图36的控制流图,其中D和G都被复制。我们假设超级块适合展开(步骤420=是)。完全展开是不可接受的(步骤830=否),因为展开循环十次将导致更多的代码量。我们假设静态展开是可接受的(步骤850=是)。结果是,执行图10详细所示的静态展开(步骤860)。
我们选择静态展开因子为2。超级块被复制两次(步骤1020),并去除内部循环终止转移(步骤1030)。没有剩余迭代(步骤1040),因为10可被2整除。结果是图37所示的控制流图。因为展开是非完全的,需要计数校正(步骤1050),如图13更详细所示。
这不是计数转移循环(步骤1310=否),于是执行突增优化和校正(步骤1230),如图15中更为详细所示。步骤1510确定,寄存器a是循环终止寄存器,因为它用于在图35块D中循环的末端比较中,并且原始突增量N为1。新的寄存器X’被分配,且拷贝语句X’=X插入在第一展开迭代的开始(步骤1520)。对于图35中的特定例子,分配一新的寄存器r,且拷贝指令r=a插入在B1的顶部。集合S0以成员X’=r和X=a初始化;集合S1初始化为空;且Y0初始化为X’=r(步骤1530)。然后I设置为值1(步骤1540)。I小于UF(步骤1550=是),于是Y1设置为我们称为t的新的符号寄存器(步骤1560)。B设置为展开的第一迭代中的块B1(步骤1570)。然后为了突增优化和校正对B1进行处理(步骤1580),如图16中更为详细所示。
我们现在检查B1中的第一语句S,这是b=a(从图35)。注意,我们不考虑在图15的步骤1520中添加到B1的语句。S是拷贝语句,使得R’=b以及R=a(步骤1640=是)。然后处理拷贝语句S(步骤1650),如图17中更为详细所述。R对应于a,这是S0的一元素(步骤1710=是)。然后为b的R’被添加到集合S0;从集合S1去除b(它没有作用),以规范的表示r代替S中的a,导致语句S为b=r(步骤1720)。在这点,执行图16中的步骤1650。在B中有更多要处理的语句(步骤1610=是),于是S设置为B中下一个语句,这是“d=b*2”。这一语句不是拷贝语句(步骤1640=否),且不是可能的突增语句(步骤1660=否),于是处理一般语句S(步骤1680),如图19更为详细所示。
寄存器b是在作为集合S0的元素的S中使用的寄存器,于是b由语句S中的r代替(步骤1910),结果是d=r*2。在S中没有被使用的集合S1的元素的寄存器,因而步骤1920什么都不作。S中定义的寄存器d既不在S0也不在S1,于是步骤1930什么都不作。在这点,执行步骤1680,这把控制传送到图16中的步骤1610。B1中不再有要处理的语句(步骤1610=否),于是对于B1添加拷贝校正块(步骤1620),如图20详细所示。
寄存器a对应于图20中的X,且不是集合S1的元素(步骤2010=否)。结果是,Z设置为等于r(步骤2030)。有未处理的来自B退出弧(步骤2040=是),于是A设置为来自B的下一个未处理的退出弧,即从B1到C的弧(步骤2050)。沿该弧插入包含代码“a=r”新的块RB1(步骤2060)。所有来自B的退出弧已被处理(步骤2040=否),于是执行步骤1620,这意味着还执行步骤1580。参见图15,在第一展开的迭代中还有块要处理(步骤1590=是),于是B设置为第一展开的迭代中下一个块D1(步骤1592)。然后为了突增优化及校正处理D1(步骤1580),如图16详细所示。
S设置为D1中第一语句,这是c=b+1。这一语句不是拷贝语句(步骤1640=否),但这是可能的突增语句(步骤1660),使R’=c及R=b。结果是,突增语句被处理(步骤1670),如图18详细所示。
寄存器b是集合S中一元素(步骤1810=是),于是指令t=r+1插入在D1中的S之前(步骤1820)。然后寄存器b以集合S0规范的表示代替,这是r(步骤1830)。结果是读取c=r+1的语句S。寄存器t和c添加到带有表示t的集合S1,而集合S。保持为{r,a,b}。在这点,执行步骤1670,该步骤把控制传送到图16的步骤1610。在D1中还有语句要处理(步骤1610=是),于是S设置为D1中下一个语句,即a=c(步骤1630)。这一语句是拷贝语句(步骤1640=是),使得R’=a和R=c。然后处理拷贝语句a=c(步骤1650),如图17中详细所示。寄存器c不是S0的元素(步骤1710=否),但它是集合S1的元素(步骤1730=是)。寄存器a添加到集合S1,结果是S1={t,c,a};从集合S0去除a,导致S0={r,b};且c在语句S中以规范表示t代替,导致语句a=t(步骤1740)。现在执行步骤1650,该步骤把控制传送到图16的步骤1610。B中没有更多的语句要处理(步骤1610=否),于是添加对于B的拷贝校正块(步骤1620),如图20中详细所示。
寄存器a对应于步骤2010中的X,并且是当前包含{t,c,a}的S1的元素。在步骤2020设置Z为t。有未处理的来自D1的退出弧(步骤2040=是),于是A设置为来自B的下一个未处理的退出弧,即从D1到F的弧(步骤2050)。一新的包含代码a=t的块RD1被插入(步骤2060)。在这点,执行步骤1620并执行步骤1580,该步骤把控制传送到图15中的步骤1590。在展开的第一迭代中还有更多的块(步骤1590=是),于是B设置为展开的第一迭代中的下一个块G1(步骤1592)。由于去除了转移(步骤1610=否)G1中没有语句。对于G1添加拷贝校正块(步骤1620),如图20详细所示。
寄存器a仍然对应于步骤2010中的X,并且是当前包含t,c和a的S1的元素。Z在步骤2020设置为t。没有来自G1未处理的退出弧(步骤2040=否),于是执行步骤1620,执行步骤1580,该步骤把控制传送到图15的步骤1590。在第一展开的迭代中不再有更多的块(步骤1590=否),于是S1被拷贝到S0,S1被设置为空;且I增加1达到值2(步骤1594)。这样S0包含{t,c,a},而S1为空。I仍然小于或等于展开因子UF(步骤1550=是),于是对于Y2分配一新的符号寄存器u(步骤1560)。然后B设置为展开的第二迭代中的第一块B2(步骤1570)。然后为了突增优化与校正对B2进行处理(步骤1580),如图16详细所示。
B中有更多的语句要处理(步骤1610=是),于是对S指定B中下一个语句,其为b=a。S是拷贝语句(步骤1640=是),使得R’=b及R=a。然后我们处理图17中详细所示的拷贝语句S(步骤1650)。寄存器a是当前包含{t,c,a}的S0的一个元素(步骤1710=是)。结果是,b添加到S0,导致S0包含{t,c,a,b};b从S1去除,但因为它不在S1中,这不作任何事;并且S中的a由t代替,导致语句S读取b=t。在这点,执行步骤1650,该步骤把控制传送到图16的步骤1610。B2中仍然还有语句要处理(步骤1610=是),于是S设置为B2中下一个语句,即d=b*2。该语句不是拷贝语句(步骤1640=否)且不是可能的突增语句(步骤1660=否),于是处理图19详细所示的一般的语句S(步骤1680)。
寄存器b是语句S中使用的寄存器,这也是集合S0的一个元素,于是b由语句S中的t代替,导致语句d=t*2。步骤1920和1930什么都不作,所以执行步骤1680把控制传送到图16中的步骤1610。B2中不再有要处理的校正块(步骤1610=否),于是添加如图20详细所示对于B的拷贝校正块(步骤1620)。寄存器a对应于步骤2010中的X,且不在集合S1中(步骤2010=否)。在步骤2030将Z设置为t。有来自B2的未处理的退出弧(步骤2040=是),即从B2到C的弧。A指定给这一弧(步骤2050)。然后沿弧A插入一新的块RB2,其中RB2包含代码a=t(步骤2060)。不再有来自B2的退出弧(步骤2040=否),于是执行步骤1620,执行步骤1580,把控制传送到图15中的步骤1590。在第二展开的迭代中有更多的块(步骤1590=是),于是B设置为第二展开的迭代中的下一个块D2(步骤1592)。然后为突增优化和校正处理如图16详细所示的D2。
D2中还有语句(步骤1610=是),于是S设置为D2中下一个语句,即c=b+1。这语句不是拷贝语句(步骤1640=否),但是一可能的突增语句(步骤1660=是),使得R’=c及R=b。然后处理图18详细所示的突增语句(步骤1670)。寄存器b是当前包含{t,c,a,b}的S0的一元素(步骤1810=是),于是新的突增指令u=r+2插入到S之前(步骤1820)。语句S中的b由t代替,导致c=t+1(步骤1830)。然后寄存器c和u添加到S1(这是空),导致S1包含{c,u},带有表示u;且c和u从S0去除,结果是S0包含{t,a,b}(步骤1840)。在这点,执行步骤1670,该步骤把控制传送到图16的步骤1610。D2中还有语句(步骤1610=是),于是S设置为D2中的下一个的语句,即a=c。这是一拷贝语句(步骤1640=是),使得R’=a及R=c。这样我们处理图17详细所示的拷贝语句a=c(步骤1650)。
寄存器c不是集合S0的元素(步骤1710=否),但是S1的元素(步骤1730=是)。结果是,a添加到S1,导致S1包含{u,c,a};a从S0去除,导致S0包含{t,b};并且语句S中的c以表示u代替,导致a=u的语句S(步骤1740)。执行把控制传送到图16的步骤1610的步骤1650。D2中不再有要处理的语句(步骤1610=否),于是对于D2添加如图20中详细所示的拷贝校正块(步骤1620)。
寄存器a对应于步骤2010中的X,并且a是S1的元素(步骤2010=是),于是Z设置为u(步骤2020)。有来自D2未处理的退出弧(步骤2040=是),即从D2到F的弧。将A指定给这一弧(步骤2050)。然后沿弧A插入一个新的块RD2,其中RD2包含代码a=u(步骤2060)。不再有来自D2未处理的退出弧(步骤2040=否),于是执行步骤1620,执行步骤1580,这将控制传送到图15的步骤1590。在第二展开迭代中有另一块G2(步骤1590=是),于是B设置为第二展开迭代中下一个块G2(步骤1592)。然后为突增优化与校正处理图16中详细所示的G2(步骤1580)。
G2中还有要处理的语句(步骤1610=是),于是S设置为B中下一个语句,即“如果a≤10则转移”(步骤1630)。这一语句不是拷贝语句(步骤1640=否),且不是可能的突增语句(步骤1660=否),于是如图19详细所示处理这一般的语句(步骤1680)。步骤1910不起作用。步骤1920把语句S变为“如果u≤10则转移”。步骤1930不起作用。这完成了步骤1680,这把控制传送到图16的步骤1610。G2中不再有更多要处理的语句(步骤1610=否),于是如图20详细所示对G2添加拷贝校正块。
寄存器a对应于步骤2010中的X,并且是集合S1中的元素(步骤2010=是)。然后Z设置为u(步骤2020)。有来自G2未处理的退出弧(步骤2040=是),即从G2到E的弧。A设置为这一弧(步骤2050),且沿A插入一个新的块RG2,其中RG2包含代码a=u(步骤2060)。不再有来自G2未处理的退出弧(步骤2040=否),于是执行步骤1620,执行步骤1580,这将控制传送到图15的步骤1590。第二展开迭代中不再有块(步骤1590=否),于是S1拷贝到S0,S1设置为空,且I增加1而达到值3(步骤1594)。I现在大于展开因子2,于是步骤1550=否,且步骤1230完成。返回图13,添加一个新的块W,包含这样的代码,即如果寄存器a模2有为零的值则转移到块B1,否则转移到块B(步骤1370)。从G和G’到B的弧重定向到块W(步骤1380)。现在完成了步骤1050,完成步骤860,这就完成了图8的方法800。结果示于图38的高级控制流图中。图39示出相同的控制流图,通过以上详述的图6的步骤860执行静态展开引入的对指令的变化。
图39初看起来似乎我们并没有对代码有很大改进。引入了很多额外的指令。但是优选实施例的方法依赖于几个现有技术优化阶段在图39的控制流图上的执行。一个这种优化是在Hwu等的Reference,supra描述的操作迁移。其它现有技术优化在Muchnik,“Advanced Compiler Design andImplementation”,Morgan Kaufman Publishers,(1997)有描述,并包括:无效代码删除,拷贝传播,值编号,及转移整直。转移整直组合了块G1和B2。对图39的控制流图施加现有技术优化的结果由图40的控制流图示出。
这里所执行的突增优化在每一展开迭代中从突增指令和相关的指令去除了相依关系。这样,只要控制保持在超级块中,必须被执行的突增指令只是图40的块D2中的“u=a+2”。如果在任何点控制退出超级块,则只要沿那些退出通路恢复适当的值。这使得预期通路、超级块的操作非常有效。当离开超级块时,取不很频繁的通路,我们只付出其它操作的代价。由于某些指令被复制几次,这是根据代码膨胀某种代价进行的,但降低了那些指令执行的总数。
优选实施例允许执行超级块完全的、静态或动态的展开。如果控制退出超级块,则执行计数校正以调节循环计数器值。通过提供用于展开超级块的更高级的方法,可对计算机程序作出更多的优化,从而提高其运行时性能。
业内专业人员将看到,在本发明的范围内可以有很多变形。这样,虽然已经参照其优选实施例具体展示和描述了本发明,但业内专业人员将能够理解,在不背离本发明的精神和范围之下,其中可作出在形式和细节上这些和其它的变化。
Claims (13)
1.一种处理指令流的装置,包括:
至少一个处理器;
连接到该至少一个处理器的一存储器;
驻留在存储器中的第一指令流;以及
基于简表的超级块展开器,驻留在存储器中并由至少一个处理器执行,超级块展开器根据简表数据在第一指令流中形成并展开一超级块,超级块展开器包括一计数校正器,当执行退出超级块时,该计数校正器对第一指令流作出至少一个改变以调节循环计数器。
2.权利要求1的装置,其中由超级块展开器执行的展开类型包括完全展开、静态展开及动态展开。
3.权利要求1的装置,其中如果超级块的迭代数足够小并且如果在编译时知道迭代数,则超级块展开器使用完全展开。
4.权利要求1的装置,其中如果超级块的迭代数对于完全展开太大并且如果在编译时知道迭代数,则超级块展开器使用静态展开。
5.权利要求1的装置,其中如果超级块的迭代数在编译时不知道,则超级块展开器使用动态展开。
6.权利要求1的装置,其中计数校正器在第一指令流中在超级块之外插入至少一个块,该块调节至少一个计数器值以说明从该超级块退出。
7.一种处理指令流的装置,包括:
至少一个处理器;
连接到该至少一个处理器的一存储器;
驻留在存储器中的第一指令流;
基于简表的超级块展开器,驻留在存储器中并由至少一个处理器执行,超级块展开器根据简表数据在第一指令流中形成并展开超级块,超级块展开器包括一计数校正器,当执行退出超级块时,该计数校正器对第一指令流作出至少一个改变以调节循环计数器,其中如果超级块的迭代数足够小并如果在编译时知道迭代数,则超级块展开器使用完全展开,其中如果超级块的迭代数对于完全展开太大并如果在编译时知道迭代数,则超级块展开器使用静态展开,并且其中如果迭代数在编译时不知道,则超级块展开器使用动态展开。
8.权利要求7的装置,其中计数校正器在第一指令流中在超级块之外插入至少一个块,该块调节至少一个计数器值以说明从该超级块退出。
9.一种优化第一指令流的方法,包括以下步骤:
根据简表数据在第一指令流中生成一超级块;
展开该超级块;以及
如果需要,向超级块外部提供计数校正代码,以调节至少一个计数值,说明从该超级块退出。
10.权利要求9的方法,其中展开超级块的步骤包括,如果超级块的迭代数足够小并且如果在编译时知道迭代数,则执行超级块完全展开的步骤。
11.权利要求9的方法,其中展开超级块的步骤包括,如果超级块的迭代数对于完全展开太大并且如果在编译时知道迭代数,则执行超级块静态展开的步骤。
12.权利要求9的方法,其中展开超级块的步骤包括,如果超级块迭代数在编译时不知道,则执行超级块动态展开的步骤。
13.一种优化第一指令流的方法,包括以下步骤:
根据简表数据在第一指令流中生成一超级块;
如果超级块的迭代数足够小并如果在编译时知道迭代数,则执行超级块完全展开;
如果超级块的迭代数对于完全展开太大并如果在编译时知道迭代数,则执行超级块静态展开;
如果超级块迭代数在编译时不知道,则执行超级块动态展开;以及
如果需要,向超级块外部提供计数校正代码,以调节至少一个计数值,说明从该超级块退出。
Applications Claiming Priority (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US10/282,811 | 2002-10-29 | ||
US10/282,811 US7086043B2 (en) | 2002-10-29 | 2002-10-29 | Compiler apparatus and method for unrolling a superblock in a computer program |
Publications (2)
Publication Number | Publication Date |
---|---|
CN1499370A CN1499370A (zh) | 2004-05-26 |
CN1257454C true CN1257454C (zh) | 2006-05-24 |
Family
ID=32107461
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CNB200310103003XA Expired - Fee Related CN1257454C (zh) | 2002-10-29 | 2003-10-28 | 用于展开计算机程序中超级块的编译装置和方法 |
Country Status (3)
Country | Link |
---|---|
US (1) | US7086043B2 (zh) |
JP (1) | JP2004152287A (zh) |
CN (1) | CN1257454C (zh) |
Families Citing this family (24)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6986128B2 (en) * | 2000-01-07 | 2006-01-10 | Sony Computer Entertainment Inc. | Multiple stage program recompiler and method |
US7386838B2 (en) * | 2003-04-03 | 2008-06-10 | International Business Machines Corporation | Method and apparatus for obtaining profile data for use in optimizing computer programming code |
US7367023B2 (en) * | 2003-07-10 | 2008-04-29 | International Business Machines Corporation | Method and apparatus for generating computer programming code selectively optimized for execution performance and not optimized for serviceability |
US20050183079A1 (en) * | 2004-02-03 | 2005-08-18 | Jayashankar Bharadwaj | Tail duplicating during block layout |
US7971191B2 (en) * | 2004-06-10 | 2011-06-28 | Hewlett-Packard Development Company, L.P. | System and method for analyzing a process |
US20050283772A1 (en) * | 2004-06-22 | 2005-12-22 | Kalyan Muthukumar | Determination of loop unrolling factor for software loops |
US20060048122A1 (en) * | 2004-08-30 | 2006-03-02 | International Business Machines Corporation | Method, system and computer program product for hierarchical loop optimization of machine executable code |
US7814468B1 (en) * | 2005-04-20 | 2010-10-12 | Oracle America, Inc. | Method for loop reformulation |
US7594223B2 (en) * | 2005-06-27 | 2009-09-22 | Hewlett-Packard Development Company, L.P. | Straight-line post-increment optimization for memory access instructions |
US20070033592A1 (en) * | 2005-08-04 | 2007-02-08 | International Business Machines Corporation | Method, apparatus, and computer program product for adaptive process dispatch in a computer system having a plurality of processors |
US7856618B2 (en) * | 2005-08-04 | 2010-12-21 | International Business Machines Corporation | Adaptively generating code for a computer program |
US20070089097A1 (en) * | 2005-10-13 | 2007-04-19 | Liangxiao Hu | Region based code straightening |
US8381203B1 (en) * | 2006-11-03 | 2013-02-19 | Nvidia Corporation | Insertion of multithreaded execution synchronization points in a software program |
US7937695B2 (en) * | 2007-04-27 | 2011-05-03 | International Business Machines Corporation | Reducing number of exception checks |
US8205209B2 (en) * | 2008-03-18 | 2012-06-19 | International Business Machines Corporation | Selecting a number of processing resources to run an application effectively while saving power |
US7493610B1 (en) * | 2008-03-27 | 2009-02-17 | International Business Machines Corporation | Versioning optimization for dynamically-typed languages |
US8745607B2 (en) * | 2011-11-11 | 2014-06-03 | International Business Machines Corporation | Reducing branch misprediction impact in nested loop code |
US8881126B2 (en) * | 2012-07-31 | 2014-11-04 | Oracle International Corporation | Systems and methods for testing a compiler through compile-time decision feedback |
US10078505B2 (en) | 2016-07-20 | 2018-09-18 | International Business Machines Corporation | Partial connection of iterations during loop unrolling |
CN106569799B (zh) * | 2016-10-17 | 2020-08-11 | 搜游网络科技(北京)有限公司 | 程序处理方法及其设备 |
JP6790869B2 (ja) | 2017-01-25 | 2020-11-25 | 富士通株式会社 | コンパイル方法、コンパイルプログラム及び情報処理装置 |
US10534693B2 (en) * | 2017-05-04 | 2020-01-14 | Microsoft Technology Licensing, Llc | Temporary de-optimization of target functions in a cloud debugger |
US10613964B2 (en) | 2017-05-04 | 2020-04-07 | Microsoft Technology Licensing, Llc | Conditional debugging of server-side production code |
JP7335591B2 (ja) * | 2019-07-22 | 2023-08-30 | コネクトフリー株式会社 | コンピューティングシステムおよび情報処理方法 |
Family Cites Families (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6035123A (en) * | 1995-11-08 | 2000-03-07 | Digital Equipment Corporation | Determining hardware complexity of software operations |
US5696956A (en) * | 1995-11-08 | 1997-12-09 | Digital Equipment Corporation | Dynamically programmable reduced instruction set computer with programmable processor loading on program number field and program number register contents |
US6760833B1 (en) * | 1997-08-01 | 2004-07-06 | Micron Technology, Inc. | Split embedded DRAM processor |
US6539541B1 (en) * | 1999-08-20 | 2003-03-25 | Intel Corporation | Method of constructing and unrolling speculatively counted loops |
US6832370B1 (en) * | 2000-05-09 | 2004-12-14 | Hewlett-Packard Development, L.P. | Data speculation within modulo scheduled loops |
US7146607B2 (en) * | 2002-09-17 | 2006-12-05 | International Business Machines Corporation | Method and system for transparent dynamic optimization in a multiprocessing environment |
-
2002
- 2002-10-29 US US10/282,811 patent/US7086043B2/en not_active Expired - Fee Related
-
2003
- 2003-10-20 JP JP2003359921A patent/JP2004152287A/ja active Pending
- 2003-10-28 CN CNB200310103003XA patent/CN1257454C/zh not_active Expired - Fee Related
Also Published As
Publication number | Publication date |
---|---|
CN1499370A (zh) | 2004-05-26 |
JP2004152287A (ja) | 2004-05-27 |
US20040083459A1 (en) | 2004-04-29 |
US7086043B2 (en) | 2006-08-01 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN1257454C (zh) | 用于展开计算机程序中超级块的编译装置和方法 | |
Martinez et al. | Astor: A program repair library for java | |
Johnson et al. | Min-cut program decomposition for thread-level speculation | |
CN1284080C (zh) | 基于值特化来优化软件代码的方法和装置 | |
CA2288614C (en) | Loop allocation for optimizing compilers | |
CN100481007C (zh) | 无需额外的代码分析来进行链接时代码优化的方法和系统 | |
Mendis et al. | goSLP: globally optimized superword level parallelism framework | |
JPH09282179A (ja) | オーバーヘッド命令を最小限にする最適化コンパイラにおける命令スケジューリングの方法および装置 | |
Blickstein et al. | The GEM optimizing compiler system | |
Domagała et al. | Register allocation and promotion through combined instruction scheduling and loop unrolling | |
CN1310386A (zh) | 映射电路和方法 | |
JPH0926884A (ja) | バイナリ操作を必要とするタスク中に必要なフロー情報を使用可能とする方法および装置 | |
US8117604B2 (en) | Architecture cloning for power PC processors | |
JP6481515B2 (ja) | 情報処理装置、コンパイル方法、及びコンパイラプログラム | |
Briggs et al. | Goal-directed interprocedural optimization | |
De Sutter et al. | Instruction set limitation in support of software diversity | |
Fireman et al. | New algorithms for simd alignment | |
Chambers | Staged compilation | |
Seto | Scalar replacement with polyhedral model | |
Aleta et al. | AGAMOS: A graph-based approach to modulo scheduling for clustered microarchitectures | |
CN1881175A (zh) | 一种解决多寄存器组冲突的方法 | |
Winkel | Optimal versus heuristic global code scheduling | |
O’Boyle et al. | Feedback assisted iterative compilation | |
Amirjanov et al. | Scheduling of directed acyclic graphs by a genetic algorithm with a repairing mechanism | |
Kirovski et al. | Engineering change protocols for behavioral and system synthesis |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant | ||
C17 | Cessation of patent right | ||
CF01 | Termination of patent right due to non-payment of annual fee |
Granted publication date: 20060524 Termination date: 20091130 |