【转】为LLVM移植一个新的后端所需的几个基本步骤

时间:2022-01-20 19:23:23
To write a compiler backend for LLVM that converts the LLVM IR to code for a specified target (machine or other language), follow these steps:
Create a subclass of the TargetMachine class that describes characteristics of your target machine. Copy existing examples of specific TargetMachine class and header files; for example, start with SparcTargetMachine.cpp and SparcTargetMachine.h, but change the file names for your target. Similarly, change code that references "Sparc" to reference your target.
Describe the register set of the target. Use TableGen to generate code for register definition, register aliases, and register classes from a target-specific RegisterInfo.td input file. You should also write additional code for a subclass of the TargetRegisterInfo class that represents the class register file data used for register allocation and also describes the interactions between registers.
Describe the instruction set of the target. Use TableGen to generate code for target-specific instructions from target-specific versions ofTargetInstrFormats.td and TargetInstrInfo.td. You should write additional code for a subclass of the TargetInstrInfo class to represent machine instructions supported by the target machine.
Describe the selection and conversion of the LLVM IR from a Directed Acyclic Graph (DAG) representation of instructions to native target-specific instructions. Use TableGen to generate code that matches patterns and selects instructions based on additional information in a target-specific version of TargetInstrInfo.td. Write code for XXXISelDAGToDAG.cpp, where XXX identifies the specific target, to perform pattern matching and DAG-to-DAG instruction selection. Also write code in XXXISelLowering.cpp to replace or remove operations and data types that are not supported natively in a.
Write code for an assembly printer that converts LLVM IR to a GAS format for your target machine. You should add assembly strings to the instructions defined in your target-specific version of TargetInstrInfo.td. You should also write code for a subclass of AsmPrinter that performs the LLVM-to-assembly conversion and a trivial subclass of TargetAsmInfo.
Optionally, add support for subtargets (i.e., variants with different capabilities). You should also write code for a subclass of the TargetSubtarget class, which allows you to use the -mcpu= and -mattr= command-line options.
Optionally, add JIT support and create a machine code emitter (subclass of TargetJITInfo) that is used to emit binary code directly into memory.

In the .cpp and .h. files, initially stub up these methods and then implement them later. Initially, you may not know which private members that the class will need and which components will need to be subclassed.


为LLVM编写一个编译器后端以将LLVM IR (中间语言, 或称中间表示)转换到某个特定的目标机或语言,应遵循以下几步:
  • 建立一个描述目标机特性的TargetMachine 的子类. 你可以复制一些已经存在的某个目标机的类和头文件,比如说, SparcTargetMachine.cpp和SparcTargetMachine.h, 把Sparc这个名字改成你所要移植的目标机的名字, 同样的, 也要修改代码中的与Sparc相关的地方.
  • 描 述目标机的寄存器. 在RegisterInfo.td中描述目标机特定的寄存器定义、寄存器别名和寄存器的种类,把它做为TableGen的输入生成包含这些信息的代码。你 可能还需要为TargetRegisterInfo这个类写一些子类,在这当中描述一些用于寄存器分配时的信息以及描述各个寄存器之间的是否互相影响等。
  • 描 述目标机的指令集。在TargetInstrFormats.td和TargetInstrInfo.td两个文件中描述目标机指令集的各个版本,之后用 TableGen生成描述目标机的代码。同样的,在之前生成的代码中为TargetInstrInfo这个类写一些附加的子类,以描述目标机的指令。
  • 描 述如何把用LLVM IR指令描述的DAG(有向无环图)选择并转换成本地目标机的指令。使用包含目标机附加信息的TargetInstrInfo.td作为TableGen 的输入,生成包含指令匹配和选择的代码。为XXXISelDAGToDAG.cpp(XXX代表目标机的名字)编写模式匹配和DAG到DAG指令选择的代 码。在XXXISelLowering.cpp中, 还需要替换或者删掉在SelectionDAG里不支持的操作或者数据类型。
  • 编 写汇编代码生成器的代码以将LLVM IR转换为针对你目标机的GAS格式。你应该在描述你目标机的TargetInstrInfo.td中为每条指令加入对应的字符串名称。你还应该为 AsmPrinter这个类写一些子类以描述从LLVM到汇编的转换,TargetAsmInfo也有一些很琐碎的子类需要完成。
  • (可选的)加入所支持的子目标机(如:同一目标机的不同特性的变体)。这需要为TargetSubtarget这个类添加一些子类,以使你能够使用像 –mcpu= 和 –mattr=这样的命令行选项。
  • (可选的)添加JIT(Just In Time,运行时编译执行)支持并且完成一个指令发射器,它能够把编译出的二进制码直接发射到内存中去。

在.cpp和.h文件中,首先定义这些方法但不要急于实现他。在最开始的时候,你通常不知道这些类需要哪些私有的成员,也不知到组成它需要哪些子类。