此文是Fred Chow在德拉华大学所讲open64课程讲义的翻译,转载请注明出处 http://www.lingcc.com
Fred Chow 原版讲义见最后一页
- 软件开发指南
使用内部选项来开关每个优化–测试正常后的优化选项默认打开.尽量按照模块化原理开发,相关的模块定义尽量本地化。#ifdef Is_True_On宏来标记来断言和确认的使用。通过断言,确认程序和DevWarns协助debug。虽然包含debug信息的编译器速度慢很多,但是可以尽早的发现错误。
- Debug辅助工具
四类:抽取某个阶段内和不同阶段间的程序代码(使用选项 -tr???);抽取某个阶段内或不同阶段间的符号表(使用选项 -ts???);分析/优化过程中方便跟踪的工具(使用选项 -tt???);提供能在调试器中调用的打印程序。
- 存储管理
使用存储池机制(commom/util/memory.c)代替malloc/free.提供任意数量的独立操作的存储池,有类似栈的操作,pop是释放内存的唯一方式。使用基于临时特性的存储池–永久的、PU级的、阶段级的和基本块级的。
- 如何增加一个编译选项
若不在某个选项组中,则从driver/OPTIONS中添加,否则找出要添加的组,编辑包含该组选项表的文件common/com/config_*,先引入一个临时变量保存选项值,如果需要的话,引入对用的set选项来检测用户是否设置该选项,编译器不会覆盖用户的设置。若选项的默认值不固定,则在common/com/config.cxx中设置该选项的默认值。需要注意的是,-CG选项组在文件be/cg/cgdriver.cxx文件中。
- 如何增加一个intrinsic
修改common/com文件夹下的intrn_info.cxx(定义特殊属性的表)、winitrinsic.h和wutil.cxx。(译者注:最新的open64已经将所有的intrinsic集中到一个文件–intrn_entry.def文件中,然后include到上面三个文件中,在通过宏控制如何在这三个文件中表示).另外也需要前端能生成对应的intrinsic。若需要把intrinsic lower成内联代码或库调用(即NOT_CGINTRINSIC)则修改文件be/com/emulate.cxx;否则,若通过CG展开(CGINTRINSIC),则修改be/cg/whirl2ops.cxx和be/cg/x8664/expand.cxx两个文件
- 如何增加一条机器指令
修改common/targ_info/isa/x8664/下的这些文件:isa.cxx、isa_operands.cxx,isa_pack.cxx,isa_print.cxx,isa_properties.cxx,isa_subset.cxx和common/targ_info/proc/x8664/*_si.cxx,来在CG中生成指令
- 如何增加一个WHIRL操作符
先修改common/com下的opcode_gen_core.h和opcode_gen_core.cxx文件;再在common/com/wn.cxx中支持该WHIRL操作数的生成,然后告诉编译器如何lowering和优化这个新操作符。若该操作符是L WHIRL,则需要在CG阶段将其展开。
- 如何区别是否为优化bug?
找出引起此bug的源程序文件,可以在.o二进制文件中搜索关键字。向后查找,分析出引起这个bug的阶段。例如:找出一个后端的优化bug。1,使用选项-CG:opt=0,通过 ->bug在CG中 2,使用选项-PHASE:w=off,通过 ->bug在WOPT中 3,使用选项 -PHASE:i=off,通过->bug在LNO或者LNO预优化阶段 4, 使用选项 -LNO:opt=0,通过->bug在LNO中 5,使用选项-PHASE:i=off:p,通过->bug在LNO中 6,使用选项-PHASE:i=off:p,报错->bug在LNO预优化阶段 7,使用选项-PHASE:i=off:w=off -CG:opt=0,报错->bug在VHO中
- 如果在某个优化阶段中找出优化bug
先找出包含此bug的PU,可以通过在这个独立的PU中打开和关闭相应的阶段和二进制搜索来找到。可以通过向后查找,通过选项逐个关闭优化的方式找出阶段中哪个特定的优化bug。可以通过以下三种方法找出该特定优化中哪段代码引起了这个bug:使用这个更少的选项加上此特定优化和二进制搜索、找出能引起此bug的最小的优化选项集合、通过对比两个编译器输出的不同能缩小查找范围。
- 如何构造某个处理器的机器模型
机器模型中相关的文件如下,并以被编译的次序:isa.cxx->指令的ascii名字、isa_properties.cxx->列出给定属性的opcode、isa_subset.cxx->将指令分成若干子集、isa_registers.cxx->将寄存器按属性分成不同的寄存器类,描述每个寄存器类中的子类、isa_enums.cxx->描述针对指令,为它赋值的修改器(?),修改器集成在指令中、isa_lits.cxx->列出指令中不同类型立即数的支持情况、isa_operands.cxx->指出每条指令的操作数和结果,以及它们的类型、*_si.cxx->指出每个指令的调度特性、isa_print.cxx->指出每个指令在汇编输出中的打印格式、isa_pack.cxx->指出Intanium CPU中的填充格式、isa_bundle.cxx->指定Itanium中的指令束、isa_decode.cxx->指令解码信息(现在已经没有)、isa_pseudo.cxx->伪指令的编码和解码信息(现在已经没有)、abi_properties.cxx->指定链接时相关的寄存器使用约定、proc.cxx->目标机上有不同调度属性的变量名(?)、proc_properties.cxx->定义一个处理器属性列表,并将目标机变量和它的属性一起列出。
- 移植到新处理器上的步骤
第一,在顶层的Makefile.gsetup中增加目标机器;第二,创建编译目录targia32_<targ>;第三,通过在每个子文件夹中设置Makefile来开始编译,包括编译include;第四,在common/com文件夹中,创建<targ>/config_targ.h,编译libcmplrs、libiberty和libcomutil;第五,在common/targ_info,创建<targ>文件夹和文件,编译targ_info;第六,为新处理器配置GNU前端(使用最接近目标机的MD(?)),编译cc1/cc1plus(GNU交叉编译);第七,将libspin融入GNU前端,编译libspin和有libspin链接的cc1/cc1plus;第八,在common/com/<targ>文件夹中为目标机创建文件,编译wgen,ir_tools,libelf,libelfutil,libdwarf,libunwindP;最后,创建be/cg/<targ>中的文件,编译be、cg、driver、wopt、ipl、lno、inline、whirl2c、ipa。
此文是Fred Chow在德拉华大学所讲open64课程讲义的翻译,转载请注明出处 http://www.lingcc.com
Fred Chow 原版讲义见最后一页

近期评论