当然,生成class和record这样的中间表示层只是TableGen的第一步工作,至于这些表格及表中信息在程序中如何被使用,以及是否由TableGen生成的原生表格再作二次加工生成其他数据产物或代码产物,由后续的程序决定。这样也就引出了TableGen工作流程上的划分,和经典编译器类似,TableGen的总体工作流程流程也分为前端和后端,如下图: ...
这个才是描述寄存器的主力。td[b135][w136]文件最终会通过tablegen生成xxxGenRegisterInfo, 供后续合入到Registerinfo类中去。 这里面还是比较简单的,首先继承一个寄存器基类,生成16bit[b137][w138]参数。 class xxxReg<bits<16> Enc, string n>: Register<n> { // 对于CMakeLists.txt中的tablegenablegen( ....
td[b135][w136]文件最终会通过tablegen生成xxxGenRegisterInfo, 供后续合入到Registerinfo类中去。 这里面还是比较简单的,首先继承一个寄存器基类,生成16bit[b137][w138]参数。 class xxxReg<bits<16> Enc, string n>: Register<n> { // 对于CMakeLists.txt中的tablegenablegen( ... -gen-emitter) let HW...
其主要思想也比较简单,就是通过模式将node匹配到机器指令。指令的描述和模式由 LLVM 后端开发者进行编写,主要使用TableGen语法在td文件中进行描述。同时复杂的模式也可以通过直接C++编码实现。下图是指令选择完成后的DAG图,可以看出t9使用MUL代替了原来的mul,t12节点使用PseudoRET代替了RISCWISD::Ret。 指令选择完DAG 指...
在开始之前,在您的开发计算器上必须已经拥有已编译好的 LLVM(参阅 参考资料 获取相关链接)。本文中的示例均基于 LLVM V3.0。对于 LLVM 代码的后期生成和安装,最重要的两个工具是 llc 和 lli。 llc 和 lli 因为LLVM 是一个虚拟机,所以它可能应该拥有自己的中间字节代码表示,...
全书分为3篇。第1篇介绍编译器基础知识,包括中间表示,重点介绍SSA、数据流分析、支配、循环等知识,此外还介绍了LLVM的后端描述语言TableGen。第二篇剖析分LLVM代码生成,其中对代码生成的每一步骤都有提及,着重介绍指令选择、指令调度、寄存器分配和编译优化。同时还以B
这些如 -ccc-print-phases 这样的 option 在编译时会生成.inc 这样的 C++ TableGen 文件。在 Options.td 可以看到全部的 option 定义。 在Clang 的 Pipeline 中很多实际行为都有对应的 Action,比如 preprocessor 时提供文件的 InputAction 和用于绑定机器架构的 BindArchAction。 使用clang main.c -arch i386 -arc...
图15继承自 TableGen 生成文件的 Cpu0 类 Fig. 15 Cpu0 classes inherited from TableGen generated files 由于llvm有很深的继承树,这里就不深挖了。受益于继承树结构,不需要在指令,帧/堆栈和选择 DAG 类中,实现太多代码,很多代码是由父类实现的。llvm-tblgen 根据Cpu0InstrInfo.td 的信息,生成 Cpu0GenInstr...
TableGen贯穿整个LLVM代码生成过程,在学习LLVM代码生成时需要对TableGen有所了解。限于篇幅,本书并没有介绍TableGen中的一些高级语法,例如foreach、defvar等,读者可以参考官方文档(https://llvm.org/docs/TableGen/ProgRef.html)进行学习。 本书在介绍代码生成时主要以BPF后端为例。BPF是一套虚拟指令集,指令数非常少,...