TargetInstrInfo类提供的机器指令描述接口,由于机器指令通常是与target 相关,因此该类提供的大部分接口都是虚函数,具体实现有每个target 后端来实现,
其中TargetInstrInfo类接口主要提供获取机器指令信息接口,出了一些标准接口之外,每个target在实现的机器指令接口类还可以可以按照需要进行扩展,
整个amdgpu后端机器接口指令继承关系如下图所示:
MCInstrInfoMCInstrInfo该类为描述机器指令接口基础类,位于llvm\include\llvm\MC\MCInstrInfo.h文件中,提供了几个基本的指令接口,该接口是所有指令描述共有的属性接口:
Interface | description |
---|---|
unsigned getNumOpcodes() | 用于获取指令的op 数目 |
MCInstrDesc &get(unsigned Opcode) | 返回对机器指令描述 |
StringRef getName(unsigned Opcode) | 根据opcode 返回指令的名称 |
bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI,std::string &Info) | 该指令是否被废弃掉,返回值true表明指令被废弃 |
TargetInstrInfo:针对所有target 机器指令描述具有相同属性抽象:
位于llvm\lib\CodeGen\TargetInstrInfo.cpp文件中
- 该类中的接口很多都是虚拟接口,主要是因为每个target指令不同,因此需要针对target,在继承TargetInstrInfo基础上对该虚拟接口进行实现,
- 该类在MCInstrInfo类基础上进一步扩展出了新的接口,对机器指令的常用 *** 作进一步做了抽象。
- 该类提供的接口大部分都需要提供MachineInstr即通过指令选择调度生成的机器三地址形式
- 该类接口使用都是位于指令选择调度之后。
AMDGPUGenInstrInfo类为AMDGPU 后端对TargetInstrInfo继承,
该类位于build/lib/Target/AMDGPU/AMDGPUGenInstrInfo.inc,是由TableGen自动生成,生成命令如下:
llvm-tblgen -gen-instr-info ./AMDGPU.td -I ../../../include
该类在AMDGPU中也属于一个过渡类,本身并没有任何多余功能:
namespace llvm {
struct AMDGPUGenInstrInfo : public TargetInstrInfo {
explicit AMDGPUGenInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);
~AMDGPUGenInstrInfo() override = default;
};
} // end namespace llvm
SIInstrInfo
SIInstrInfo为AMDGPU 后端提供的机器指令描述接口类,位于\llvm\lib\Target\AMDGPU\SIInstrInfo.cpp文件中,
该接口提供了指令中的大部分接口,一般需要查询指令信息或者对一个指令进行 *** 作可以使用该类接口:
- isXXX接口:主要查询指令的指令是否属于某些类型
- insertXXX接口:提供在指令前插入指令类型指令,例如插入s_noop指令接口insertNoop, 插入一个返回指令insertReturn
- getXXX接口:获取指令指令中信息。
SIInstrInfo主要提供机器指令接口,接口参数中一般需要传入所需要 *** 作MachineInstr 机器指令
每个target会有全局唯一SIInstrInfo接口
GCNSubtarget该类提供了对target进行抽象封装,里面包含对target特性记录以及重要数据:主要分为数据部分和接口部分,
位于llvm\lib\Target\AMDGPU\GCNSubtarget.cpp
数据记部分主要记录当前target一些特性:
... ...
// for XNACK.
bool EnableXNACK;
bool EnableTgSplit;
bool EnableCuMode;
bool TrapHandler;
... ...
// Subtarget statically properties set by tablegen
bool FP64;
bool FMA;
bool MIMG_R128;
bool CIInsts;
bool GFX8Insts;
bool GFX9Insts;
bool GFX90AInsts;
bool GFX10Insts;
bool GFX10_3Insts;
bool GFX7GFX8GFX9Insts;
bool SGPRInitBug;
bool NegativeScratchOffsetBug;
bool NegativeUnalignedScratchOffsetBug;
bool HasSMemRealTime;
bool HasIntClamp;
bool HasFmaMixInsts;
bool HasMovrel;
bool HasVGPRIndexMode;
bool HasScalarStores;
bool HasScalarAtomics;
bool HasSDWAOmod;
bool HasSDWAScalar;
bool HasSDWASdst;
bool HasSDWAMac;
bool HasSDWAOutModsVOPC;
... ..
接口部分主要分为:
- getXXXX接口:主要用于提供获取target中相关特性信息
- hasXXX接口:主要查询是否用于某些特性,例如:hasAddr64、hasAddr64等
SIInstrInfo属于指令集描述接口,本身也属于GCNSubtarget中一员:
GCNSubtarget 提供了getInstrInfo()用于方便获取SIInstrInfo
GCNSubtarget类继承关系GCNSubtarget整个类继承关系如下图所示:
继承关系思路与类似:
- MCSubtargetInfo 为所有subtarget的基础抽象,该抽象与具体target 无关,位于llvm\include\llvm\MC\MCSubtargetInfo.h文件
- TargetSubtargetInfo:大部分都是虚拟接口,由target实现,位于llvm\include\llvm\CodeGen\TargetSubtargetInfo.h文件
- AMDGPUGenSubtargetInfo: 由tabelGen 生成的AMDGPUGenSubtargetInfo.inc文件中,生成命令为:
llvm-tblgen -gen-subtarget ./AMDGPU.td -I ../../../includ
- AMDGPUSubtarget:为AMDGPU 基础类,里面包括AMGPU各种基础特性以及接口实现,作为GCN和R600两个平台中具有的相同特性实现
- GCNSubtarget: 为GCN subtarget实现。
MachineInstr 又简称为MI,LLVM通过指令选择及调度将IR中的IR指令转换成对应的target 机器指令,机器指令以三地址表示形式
该类位于llvm\lib\CodeGen\MachineInstr.cpp
每个MachineInstr 实例代表了一条机器指令
MachineInstr是对机器指令的抽象,只能用来跟踪指令的operands以及opcode。
MachineInst类中没有任何关系指令的描述及解释信息,如果要获取指令中描述信息以及其他 *** 作需要通过TargetInstrInfo中提供的接口实现。
operands可能为:register、 a constant integer,a basic block reference, etc
opcode :对应的是机器指令opcode, 一般位于 *InstrInfo.td, AMDGPU对应的opcode 会在编译之后位于build/lib/Target/AMDGPU/AMDGPUGenInstrInfo.inc文件中,手动生成命令如下:
llvm-tblgen -gen-instr-info ./AMDGPU.td -I ../../../include/
调试过程中可以使用上述命令生成AMDGPUGenInstrInfo.inc文件查看AMDGPU指令对应opcode.
如何创建MachineInstrLLVM提供了BuildMI机制,用来创建一个机器指令,位于llvm\include\llvm\CodeGen\MachineInstrBuilder.h文件
例如在SIInstrInfo中提供了insertNoops方法 用来创建一个s_nop指令并查到到该指令之前:
void SIInstrInfo::insertNoops(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned Quantity) const {
DebugLoc DL = MBB.findDebugLoc(MI);
while (Quantity > 0) {
unsigned Arg = std::min(Quantity, 8u);
Quantity -= Arg;
BuildMI(MBB, MI, DL, get(AMDGPU::S_NOP)).addImm(Arg - 1);
}
}
BuildMI最终是通过MachineInstrBuilder类来实现构建一个机器指令:
MachineInstrBuilderMachineInstrBuilder类除了提供创建MachineInstr之外,还提供了创建之后各种 *** 作:LLVM: llvm::MachineInstrBuilder Class Reference
例如下图:
参考资料The LLVM Target-Independent Code Generator — LLVM 15.0.0git documentation
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)