LLVM 学习记录:TD 里面的 def、defm、defvar 有什么区别

Posted by 叉叉敌 on May 23, 2024

前面学习了如何添加一个 intrinsic 函数的过程,发现有涉及到 td table gen 语言的格式,这个需要注意。

有几个关键字,def,defm,defvar 的区别?

这个内容非常的简单,使用的时候注意下即可。官方文档把这个称为 record,翻译过来是记录?anyway,随便是什么,记住就是一个标识符吧。

首先了解下什么 single class,和 multiclass

重要的一点就是:class 类型只能从一个 class 类型继承,而 multiclass 类型可以从多个 class 类型继承。

class 类型通常比 multiclass 类型更有效率,因为 LLVM 可以更轻松地优化 class 类型。

还是用 amd 的 td 文件来举例:

https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/IntrinsicsAMDGPU.td

single class

class AMDGPUReadPreloadRegisterIntrinsic
  : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;

标识符 class 开头的就是单类。单类的名称是AMDGPUReadPreloadRegisterIntrinsic

multi class

multiclass AMDGPUReadPreloadRegisterIntrinsic_xyz {
  def _x : AMDGPUReadPreloadRegisterIntrinsic;
  def _y : AMDGPUReadPreloadRegisterIntrinsic;
  def _z : AMDGPUReadPreloadRegisterIntrinsic;
}

关键字是 multiclass,就是多类。

这里多类的名称是AMDGPUReadPreloadRegisterIntrinsic_xyz,然后里面包含了多个单类AMDGPUReadPreloadRegisterIntrinsic

btw,每个类都有一个名为 NAME(大写)的隐式模板参数,它绑定到从该类继承的 Def 或 Defm 的名称。如果该类由匿名记录继承,则名称未指定,但全局唯一。

学了容易忘记,建议是用到的时候,可以看一下,基本上就知道了。

区别

def 就是单纯的定义个单类的变量; defm,这个多了一个 m,m 代表的就是 multiclass,就是定义的多类。

Feature defm def defvar  
Type of entity Multiclass Class Global variable  
Inheritance Multiple inheritance Single inheritance None  
Can define types Yes Yes No

其实看了上面的 class 和 multiclass 的定义,就大概知道怎么用了。

还有更多的 def* ,> https://llvm.org/docs/TableGen/ProgRef.html#id24