LLVM后端入门8:Subtarget支持

子目标支持用于告知代码生成过程特定芯片组的指令集差异,若需要子目标支持,你应为目标架构实现一个目标特定的 XXXSubtarget 类。该类需处理命令行选项 -mcpu=-mattr=

TableGen 会利用 Target.td 和RISCVFeatures.td 文件中的定义,在RISCVGenSubtargetInfo.inc 中生成代码。如下所示,Target.td 中定义了 SubtargetFeature 接口。SubtargetFeature 接口的前四个字符串参数分别为:特性名称、由该特性设置的 XXXSubtarget 字段、XXXSubtarget 字段的值以及特性描述。(第五个参数是该特性隐含的其他特性列表,默认值为空数组。)

若字段值为字符串 "true" 或 "false",则该字段被视为布尔值,且仅能有一个 SubtargetFeature 引用它。否则,该字段被视为整数类型,其值可为枚举常量名称。若多个特性使用同一个整数字段,则该字段的值会被设为所有启用的、共享该字段的特性对应值中的最大值。

bash 复制代码
//===----------------------------------------------------------------------===//
// SubtargetFeature - A characteristic of the chip set.
//
class SubtargetFeature<string n, string f, string v, string d,
                       list<SubtargetFeature> i = []> {
  // Name - Feature name. Used by command line (-mattr=) to determine the
  // appropriate target chip.
  //
  string Name = n;

  // FieldName - Field in XXXSubtarget to be set by feature.
  //
  string FieldName = f;

  // Value - Value the XXXSubtarget field to be set to by feature.
  //
  // A value of "true" or "false" implies the field is a bool. Otherwise,
  // it is assumed to be an integer. the integer value may be the name of an
  // enum constant. If multiple features use the same integer field, the
  // field will be set to the maximum value of all enabled features that
  // share the field.
  //
  string Value = v;

  // Desc - Feature description. Used by command line (-mattr=) to display help
  // information.
  //
  string Desc = d;

  // Implies - Features that this feature implies are present. If one of those
  // features isn't set, then this one shouldn't be set either.
  //
  list<SubtargetFeature> Implies = i;
}

在RISCVFeaturestd文件中,有大量基于SubtargetFeature定义的特征

bash 复制代码
// Feature32Bit exists to mark CPUs that support RV32 to distinguish them from
// tuning CPU names.
def Feature32Bit
    : SubtargetFeature<"32bit", "IsRV32", "true", "Implements RV32">;
def Feature64Bit
    : SubtargetFeature<"64bit", "IsRV64", "true", "Implements RV64">;
def IsRV64 : Predicate<"Subtarget->is64Bit()">,
             AssemblerPredicate<(all_of Feature64Bit),
                                "RV64I Base Instruction Set">;
def IsRV32 : Predicate<"!Subtarget->is64Bit()">,
             AssemblerPredicate<(all_of (not Feature64Bit)),
                                "RV32I Base Instruction Set">;

defvar RV32 = DefaultMode;
def RV64 : HwMode<[IsRV64]>;

def FeatureRelax
    : SubtargetFeature<"relax", "EnableLinkerRelax", "true",
                       "Enable Linker relaxation.">;

def FeatureExactAssembly
    : SubtargetFeature<"exact-asm", "EnableExactAssembly", "true",
                       "Enable Exact Assembly (Disables Compression and Relaxation)">;

foreach i = {1-31} in
  def FeatureReserveX#i :
      SubtargetFeature<"reserve-x"#i, "UserReservedRegister[RISCV::X"#i#"]",
                       "true", "Reserve X"#i>;

def FeatureSaveRestore : SubtargetFeature<"save-restore", "EnableSaveRestore",
                                          "true", "Enable save/restore.">;

def FeatureNoTrailingSeqCstFence : SubtargetFeature<"no-trailing-seq-cst-fence",
                                          "EnableTrailingSeqCstFence",
                                          "false",
                                          "Disable trailing fence for seq-cst store.">;

def FeatureUnalignedScalarMem
   : SubtargetFeature<"unaligned-scalar-mem", "EnableUnalignedScalarMem",
                      "true", "Has reasonably performant unaligned scalar "
                      "loads and stores">;

第一个特征Feature32Bit定义了32位子处理器架构的特征:

bash 复制代码
def Feature32Bit  // 1. 自定义特性名
    : SubtargetFeature<  // 2. 继承LLVM标准基类
        "32bit",         // 3. 参数1:命令行/编译标识名
        "IsRV32",        // 4. 参数2:C++侧的布尔成员变量名
        "true",          // 5. 参数3:该变量的赋值/启用值
        "Implements RV32"// 6. 参数4:特性的描述字符串
      >;

而第二个特征Feature64Bit定义了64位RISC-V架构特性:

bash 复制代码
def Feature64Bit
    : SubtargetFeature<"64bit", "IsRV64", "true", "Implements RV64">;

从Target.td和RISCVFeatures.td文件生成的 RISCVGenSubtargetinfo.inc 会指定用于标识特性的枚举值、表示 CPU 特性和 CPU 子类型的常量数组,以及解析用于设置指定子目标选项的特性字符串的 ParseSubtargetFeatures 方法。生成的 RISCVGenSubtargetinfo.inc 文件应被包含在 RiscvSubtarget.cpp 中。XXXSubtarget 方法的目标特定实现应遵循以下伪代码:

cpp 复制代码
XXXSubtarget::XXXSubtarget(const Module &M, const std::string &FS) {
  // Set the default features
  // Determine default and user specified characteristics of the CPU
  // Call ParseSubtargetFeatures(FS, CPU) to parse the features string
  // Perform any additional operations
}

例如,RISCV的实现如下:

cpp 复制代码
RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
                               StringRef TuneCPU, StringRef FS,
                               StringRef ABIName, unsigned RVVVectorBitsMin,
                               unsigned RVVVectorBitsMax,
                               const TargetMachine &TM)
    : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
      RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
      FrameLowering(
          initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
      InstrInfo(*this), TLInfo(TM, *this) {
  TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
}
相关推荐
Once_day1 分钟前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~11 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
坚果派·白晓明22 分钟前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人29 分钟前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
张张努力变强2 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
小镇敲码人2 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn
平安的平安2 小时前
面向大模型算子开发的高效编程范式PyPTO深度解析
c++·mfc
June`2 小时前
muduo项目排查错误+测试
linux·c++·github·muduo网络库
C++ 老炮儿的技术栈2 小时前
VS2015 + Qt 实现图形化Hello World(详细步骤)
c语言·开发语言·c++·windows·qt
Once_day2 小时前
C++之《Effective C++》读书总结(4)
c语言·c++·effective c++