llvm学习笔记(5)

2.2.4. 匹配模板

在Instruction定义的333行,成员Pattern描述了该指令匹配怎么样的SelectionDAG结构。这是一个list类型,因此存在一条指令匹配多个dag结构的可能。在上面的例子中,这部分就是312~315行的dag。LLVM将对这样的dag生成movq2dq\t{$src, $dst|$dst, $src}形式的汇编代码(实际上,指令选择会生成一个MachineSDNode实例,其操作码是指令TD定义的名字,如上面的MMX_MOVQ2DQrr,其他TableGen过程会导出同名的枚举值以供使用)。

2.2.4.1. SDNode

C++类SDNode是构成LLVM的指令选择器所使用的DAG的节点。在TableGen根据TD文件为指令选择生成的代码中,其核心函数SelectCode就具有原型:SDNode *SelectCode(SDNode *N),参数N是要进行指令选择的IR形式的DAG,返回值也是SDNode类型,即选中的指令。

TableGen不能直接使用C++类,与之对应,它也有自己的SDNode定义。它主要作为dag值的操作符,描述这个dag所代表的操作、操作数,SDNode派生自TD类SDPatternOperator(这是一个空类。v7.0中将下面303行的Properties移进了这个类)。(在LLVM里,SDNode的定义出现在两处:一是在SelectDAGNodes.h里,是一个C++类。另一处在TargetSelectionDAG.td。每个SelectionDAG节点类型都有一个对应的SDNode定义)。

298     class SDNode<string opcode, SDTypeProfile typeprof,

299                  list<SDNodeProperty> props = [], string sdclass = "SDNode">

300                  : SDPatternOperator {

301       string Opcode  = opcode;

302       string SDClass = sdclass;

303       list<SDNodeProperty> Properties = props;

304       SDTypeProfile TypeProfile = typeprof;

305     }

虽然TD语言有类似C++的语法,但它更类似于一个函数式语言,或者说更类似于C++的泛型形式,所有类型一旦声明(定义)就不能更改。要表示新的信息,就必须定义新的类,或具现一个尚未存在的模板实例。

2.2.4.1.1. 类型的描述

在上面的SDNode定义里,参数typeprof用来描述这个SDNode的类型要求。其类型SDTypeProfile的定义如下。它用于描述操作的“类型”。

93       class SDTypeProfile<int numresults, int numoperands,

94                           list<SDTypeConstraint> constraints> {

95         int NumResults = numresults;

96         int NumOperands = numoperands;

97         list<SDTypeConstraint> Constraints = constraints;

98       }

很显然NumResults与NumOperands分别说明有几个结果及几个操作数,其中如果NumOperands是-1,则表示操作数的数目不定。Constraints则描述了对操作数类型的约束,SDTypeConstraint是一个简单的类。

22       class SDTypeConstraint<int opnum> {

23         int OperandNum = opnum;

24       }

OperandNum指明该约束适用第几个操作数。显然这个类是不足够的,需要高级一点的派生类,于是就有了下面的定义:

27       class SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {

28         ValueType VT = vt;

29       }

这个定义表示OpNum所指向操作数必须具有指定的VT(ValueType)类型。

31       class SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>;

这个定义表示OpNum所指向操作数的类型是指针。

34       class SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>;

这个定义表示OpNum所指向操作数的类型是整形。

37       class SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>;

这个定义表示OpNum所指向操作数的类型是浮点类型。

40       class SDTCisVec<int OpNum> : SDTypeConstraint<OpNum>;

这个定义表示OpNum所指向操作数的类型是向量。

43       class SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {

44         int OtherOperandNum = OtherOp;

45       }

这个定义表示OpNum所指定操作数与OtherOp所指定的操作数具有相同的类型。

49       class SDTCisVTSmallerThanOp<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {

50         int OtherOperandNum = OtherOp;

51       }

这个定义表示OpNum所指定操作数必须是VT派生类型,OtherOp所指定操作数则是整形,且前者的长度小于后者。

53       class SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{

54         int BigOperandNum = BigOp;

55       }

这个定义表示SmallOp与BigOp类型相同(注意不限定操作数必须VT类型),但前者的长度小于后者。

59       class SDTCisEltOfVec<int ThisOp, int OtherOp>

60         : SDTypeConstraint<ThisOp> {

61         int OtherOpNum = OtherOp;

62       }

这个定义表示ThisOp指定的操作数与OtherOp指定向量的元素具有相同的标量类型。

66       class SDTCisSubVecOfVec<int ThisOp, int OtherOp>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值