LLVM (6) 11.5 一个目标可重定向的LLVM代码生成器

来源:互联网 发布:人工智能的利弊800字 编辑:程序博客网 时间:2024/06/18 12:30
LLVM代码生成器负责将LLVM IR翻译为特定的目标机器码。代码生成器的另一个工作是为一个给定的目标生成一个尽可能最好的机器码。理想地,每一个代码生成器对于目标来说应该是完全的用户代码。但是,另一方面,对于每个目标代码生成器需要解决相似的问题。例如,每个目标需要给寄存器赋值,并且尽管每个目标有不同的寄存器文件,然而算法应该尽可能的被共享。

与优化器中的方法相似,LLVM的代码生成器将代码生成问题划分为独立的pass——指令选择、寄存器分配、调度、代码布局优化和组装发射(assembly emission)——并且提供需要内建的、默认执行的pass。目标开发者有机会在默认的pass中选择、重写以及实现完全的用户目标pass。例如,由于x86只有很少的寄存器,x86后端使用register-pressure-reducing调度。但是,由于其有很多寄存器,PowerPC后端采用一个延迟优化调度。x86后端使用一个用户pass去操作x87浮点指针堆栈,并且ARM后端使用用户pass在使用它们的函数中摆放constant pool island。这种灵活性允许目标开发者无需为目标编写一个完整的代码生成器就可以生成良好的代码。

11.5.1 LLVM目标表述文件

混合匹配(mix and match)方法允许目标开发者选择对他们的体系结构有用的选项以及在不同目标中复用大量代码。这带来另一种挑战:每一个共享的组件需要能够以一种通用方法推测目标专有特性。例如,一个共享的寄存器分配器需要知道每个目标的寄存器文件和指令和寄存器操作之间的约束关系。LLVM的解决方案是为每个目标提供以特定领域语言(.td文件)的目标描述,该语言用tblgen工具进行处理。对于x86目标的简单建立流程在图11.5中。


.td文件支持的不同子系统允许目标开发者建立目标的不同部分。例如,x86后端定义一个寄存器类保存所有的命名为“GR32”的32位寄存器(在.td文件中,目标定义是cap):

def GR32 : RegisterClass<[i32], 32,  [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP,  R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { ... }



这个定义表示在该类中寄存器保存32位整数值(“i32”),32位对齐,有16个特殊寄存器(在.td文件的其它部分定义)和一些信息规定分配顺序和其它事情。给定这个定义,特殊指令能够进行参考,使用它作为一个操作数。例如,补充的32位寄存器定义为:
let Constraints = "$src = $dst" indef NOT32r : I<0xF7, MRM2r,              (outs GR32:$dst), (ins GR32:$src),              "not{l}\t$dst",              [(set GR32:$dst, (not GR32:$src))]>;
这个定义表明NOT32r是一个指令(使用I tblgen类),规定编码信息(0xF7, MRM2r),定义32位的输出寄存器$dst和有一个32位的输入寄存器$src(GR32寄存器类定义对于该操作数哪个寄存器有效),为指令规定汇编语法(使用{}操作AT&T和Intel语法),规定指令的效果以及提供与最后一行匹配的模式。在第一行的“let”限制告诉寄存器分配器输入和输出寄存器应该被分配到相同的寄存器。

这个定义是非常丰富的指令定义。因此,据此一般LLVM代码能够做很多事情(tblgen)。这个定义足够编译器通过输入数据模型匹配进行指令选择。它也告诉寄存器分配器如何处理,足够用来编码和解码指令到机器码字符,足够用来以文本方式解析和打印指令。这些能力允许x86目标去支持生成一个独立的(stand-alone)x86汇编器(嵌入去替换GNU汇编器“gas”)和从目标描述反汇编器,如同为JIT编码指令的操作。

除了提供有用的功能,具有从相同“truth”生成的多种信息也具有其它好处。这种方法使得汇编器和反汇编器几乎不可能存在汇编语法或者二进制编码不一致的情况。也使得目标描述能够很简单地测试:指令编码能够被单元测试而无需涉及到整个代码生成器。

尽管我们试图得到尽可能多的目标信息并且以一种很好表达的形式写入.td文件中,然而我们仍然没有所有的全部。因此,我们要求目标开发者为不同的支持实例写一些C++代码并且实现任何需要的目标专有pass(例如X86FloatingPoint.cpp操作x87浮点数堆栈)。当LLVM继续生产新目标,增加能够描述在.td文件中的目标数量越来越重要。我们持续增加.td文件表述去解决这个。一个重大的好处是随着时间推移在LLVM写目标越来越简单。

0 0
原创粉丝点击