LLVM--TableGen程序员手册笔记

本文翻译自TableGen Programmer’s Reference
1.1 介绍
TableGen使用输入文件中的信息生成复杂的输出文件,输入源文件比输出文件更容易编码,也更容易维护和修改. 输入文件中供TableGen处理的信息以声明式(declarative)风格编码,信息包括类和记录.内部化的记录被传递到各种后端,后端从记录的子集提取信息,并生成多个输出文件.

本文档将详细介绍LLVM TableGen工具。它适用于需要使用TableGen为项目生成代码的程序员。如果您想简单了解TableGen,请查看TableGen概述。TableGen的各种*-tblgen命令在 tblgen Family - Description to C++ Code中有介绍

RegisterInfo是一个后端的例子,它为特定的目标机器生成寄存器文件信息,供LLVM目标无关代码生成器使用。LLVM TableGen后端介绍参见TableGen Backends,如果要编写一个新的后端,请参考 TableGen Backend Developer’s Guide。

下面是后端可以做的一些事情。

为特定目标机器生成寄存器文件信息;
为目标生成指令定义;
生成代码生成器匹配指令与中间表示(IR)节点的模式;
生成Clang语义属性标识符;
生成Clang抽象语法树(AST)声明节点定义;
生成ClangAST语句节点定义;

1.1.1 概念
TableGen源文件主要包含两种信息:abstract records 和 concrete records, 即classes 和records, 有时record同时指abstract records 和 concrete records.

1.4 类型
类型用于检查错误,执行隐式转换,并帮助接口设计人员约束允许的输入.每个值都需要有一个关联的类型.

TableGen支持混合使用低级类型(bit)和高级类型(如dag).这种灵活性允许您方便而紧凑地描述各种记录.

bit 为布尔值
int 类型表示64整型数,例如5和-42

string
类型表示任意长度的有序字符序列

bits
bits表示位宽固定为n的整数,n可以为任意值.这n个bit可以单独访问.这种类型的字段用于表示指令操作代码,寄存器号或地址模式/寄存器/位移.字段的位可以单独设置.也可以作为子字段设置.例如,在指令地址中,寻址模式,基址寄存器号和位移可以分别设置.

list
此类型表示一个列表, 其元素为尖括号中指定的类型.元素类型是任意的,它甚至可以是另一种列表类型.列表元素索引下标从0开始.

class: 指定一些类型数据的集合表示,必须用def或defm来使用这个类定义记录之后, 内部数据才被分配.用来声明多个记录的共有信息, 支持继承和重载等特性.

dag 这种类型表示节点组成的嵌套的有向无环图.每个节点有一个操作符和零个或多个参数(或操作数).参数可以是另一个dag对象,允许任意的节点和边树. 例如,DAG用于指令选择算法使用的代码模式.

2.值和表示式
?: 未定义
0b1000: 位值, 注意它的长度是固定的,他不会自动扩展和截断
7: 十进制数
0x7f: 十六进制数
“foo”: 单行的字符串值,可以直接赋值给string或code;
[{…}]:代码片段, 通常用于code,但其实就是多行字符串值;
[X,Y,Z]:列表, type是指定列表中元素类型,一般情况下可以省略,TableGen前端能够推测类型,极少数特殊情况下需要明确指定;
{a,b, 0b10}: 初始化bits这样的类型,第一位是a变量的值,第二位是b,三四位是"0b1"和"0b0";
value: 值的引用,比如上边出现的X,Y,Z,a,b;
value{17}: 值的引用并截取一位;
value{15-17}:值的引用并截取一部分, -两边必须要连续

DEF: 记录的引用;
CLASS: 匿名定义的引用, 是模板参数,这里是这个意思, 对于一个带模板参数的类,通过指定模板参数,可以直接定义一个匿名的记录, 这里就是引用这个匿名记录;
X, Y:引用一个指 的子域,常用的记录上;
list[4-7, 17, 2-3]:列表片段,比如这个例子中,引用了列表list的第4,5,6,7,17,2,3这几位
foreach = [] in {}:一种循环体结构,依次将list中的值赋给var,并执行body体, 类似于C++11 中foreach, body中仅可以包含def和的defm;
foreach = [] in : 同上,不同是循环体只有一条语句,不需要{}
!listsplat(a, size):将指定a列表中的子项重复包含size次
!listplat(0, 2), 等效于[0, 0].
值的定义
值的定义是记录中的内容条目,必须先定义这个值,才能在其它值定义引用这个值,或者可以使用let来重置这个值.值的定义的组成结构: 类型+ 值名字, 指定值的内容可以通过在后边跟等号+的内容来完成,需要有终止符;

Let表达式
记录中的Let表达式被用于记录中某个值的内容.经常在当一个类定义了它的子类需要覆盖这个值的时候使用. Let表达式的组成结构: Let + 值名字 + = + 新的值内容

class D:C {let V = 0;}
def Z:D
需要注意的是, 记录中变量的重新赋值实现的相对较晚, 也就是在类内的值初始化完毕后才能实现记录中的值赋值, 如下个例:
class A {
int Y = x;
int Yplus1 = !add(Y, 1);
int xplus1 = !add(x, 1);
}

文件相关
文件包含
TableGen支持 include关键字, 能够扩展其它的td文件到当前的td文件中,和C系的文件包含意思一样.要包含的文件用""包含.比如:
include “foo.td”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值