Stanford 大学80年代初期对RISC上的编译器进行研究;80年代后期转为对MIPS上的编译器进行研究,并在O2选项基础上添加全局优化;90年代初期,又在O3基础上,添加了循环优化。
80年代末开发的cydrome cydra5编译器包含了软流水software pipeling,在它的基础上,SGI开发了一款新的编译器,添加了Floating-pt Performance?。
1997年,SGI将上述两款编译器,以及stanford的SUIF和Rice的IPA,集成到MIPSpro编译器上,2000年又添加对安腾Itanium的支持,发展为Pro64或者又称Open64编译器。
1994: Development started to compile for MIPS R10000
1996: SGI MIPSpro compiler shipped
1998: Started retargetting to Itanium, changed front-ends to gcc/g++
2000: Pro64 compiler open-sourced via GPL
2001: SGI dropped support, UDel renamed compiler to Open64
2001 – 2004: ORC project funded by Intel for Itanium
2003: PathScale started work to retarget to X86
2004: PathScale X86 compiler shipped in April
将open64移植到X86和X86-64;
针对64位X86 linux的性能领头羊;
GNU和open64之间的桥梁;
私有的openmp运行时库;
建立基础结构。
1) 多个前端,单一后端;
2) 一种中间形式,但支持多层次的优化;
3) 持续的lower表示。
1) LNO:针对循环的优化,基于数据依赖data dependency;
2) WOPT:全局标量优化,基于SSA;
3) IPA:过程间优化,基于整个程序的分析;
4) CG:依赖于目标机。
1) 任何阶段都可以调用whirl简化器;
2) 共享分析的数据;
3) 各个阶段可以相互调用。
1) 支持多个前端的语言;
2) 支持多个后端的处理器;
3) 支持中端优化的转变;
4) 是各个阶段的接口;
5) 提升编译器设计时的模块化;
6) 减少重复的功能设计;
7) 是现代编译器中的一个重要的基础结构。
1)higher level,
优点:有更多的结构;代码序列短;有更多的程序信息;
缺点:结构等级化;可做的优化很少。
2)lower level,
优点:结构平稳;可做优化多;
缺点:结构少;代码长;程序信息少。
1) 优化机会在lower level出现的,就要靠后实现;
2) 早期阶段暴露的优化机会有:
Inline; 常数传播 const propagation;循环合并loop fusion。
3) 早期阶段为后面的阶段计算有用信息:
别名和指针分析;Use-Def;数据依赖。
4) 代价小的优化,可以多做几次。
5) 破坏程序信息的优化,尽量靠后。
1) common/com/wn_core.h
2) 每个函数体最终用一个树表示;
3) 对不同的结构,建立不同的符号表,可以参看common/com/symtab*.h
最小的WN只有24字节;压缩域空间;二进制的读写?
4)在各个阶段,whril的存在不同的文件中:
前端生成 *.B; IPA/inline *.I; LNO *.N; WOPT *.O
他们都可以dump出来。
1) operator 操作码
2) desc 操作数的机器或标量类型
3) rtype 结果的机器或者标量类型
4) opcode 一个记录?(operator, rtype, desc)
5) symbol table index: 唯一地确定一个程序中的符号或者标示符
6) high level type: 程序中声明的类型
7) field-id: 唯一的标示结构体或者联合中的一个域
1)语句节点statement node是顺序节点;
2)副作用side effect只发生在语句的边界,并且只涉及三种语句:store, call, asm
3)表达式节点expression node不是顺序节点;
4)表达式节点计算时没有副作用,所以允许激进的表达式调度?
5)程序在源代码中的位置信息,只在语句节点下可用。
作用:为whirl node添加额外的注释信息,对短暂的信息很有用。
需要克服wn空间确定的难题。
Wn一般分为几种不同类型。
每个wn都存有一个Map_id,在一种wn类型中它是唯一的,且与map table中的wn信息对应。
1) very high whirl
可以重新翻译成C或Fortran的程序;
有几种结构仅存在于这一层:comma操作码;嵌套函数调用;C的条件运算符。
Inline作用在这一层。
2) high whirl
支持循环级别的优化;
确定的控制流;
主要的结构有:Array(数据依赖分析,向量化),Do loop,if语句,fortran I/O语句
IPA,PREOPT,LNO作用在这一层;
能够反编译回源程序;
可以让用户看见inline和LNO的效果。
3) mid whirl
此时中间表示与RISC指令一一对应;
控制流通过jump显示出来;
地址计算、位域访问也开始显现;
复数扩展到浮点操作;
WOPT在这一层作用。
4) low whirl
一些intrinsics转变为call调用;
Linkage 转换显示出来;
数据层计算完毕