llvm学习笔记(5)

来源:互联网 发布:钢结构软件 编辑:程序博客网 时间:2024/05/16 07:54

2.2.4.  匹配模板

在Instruction定义的333行,成员Pattern描述了该指令匹配怎么样的SelectionDAG结构。这是一个list类型,因此存在一条指令匹配多个dag结构的可能。在上面的例子中,这部分就是312~315行的dag。LLVM将对这样的dag生成movq2dq\t{$src,$dst|$dst, $src}形式的汇编代码。

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(这是一个空类)。(在LLVM里,SDNode的定义出现在两处:一是在SelectDAGNodes.h里,是一个C++类。另一处在TargetSelectionDAG.td。每个SelectionDAG节点类型都有一个对应的SDNode定义)。

298     classSDNode<string opcode, SDTypeProfile typeprof,

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

300                  :SDPatternOperator {

301       stringOpcode  = opcode;

302       string SDClass= sdclass;

303      list<SDNodeProperty> Properties = props;

304       SDTypeProfileTypeProfile = typeprof;

305     }

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

2.2.4.1.1.  类型的描述

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

93       classSDTypeProfile<intnumresults, 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       classSDTypeConstraint<intopnum> {

23         int OperandNum= opnum;

24       }

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

27       classSDTCisVT<int OpNum, ValueTypevt> : SDTypeConstraint<OpNum> {

28         ValueType VT =vt;

29       }

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

31       classSDTCisPtrTy<int OpNum> :SDTypeConstraint<OpNum>;

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

34       classSDTCisInt<int OpNum> : SDTypeConstraint<OpNum>;

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

37       classSDTCisFP<int OpNum> : SDTypeConstraint<OpNum>;

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

40       classSDTCisVec<intOpNum> : SDTypeConstraint<OpNum>;

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

43       classSDTCisSameAs<int OpNum,int OtherOp> : SDTypeConstraint<OpNum> {

44         intOtherOperandNum = OtherOp;

45       }

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

49       classSDTCisVTSmallerThanOp<int OpNum, intOtherOp> : SDTypeConstraint<OpNum> {

50         int OtherOperandNum= OtherOp;

51       }

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

53       classSDTCisOpSmallerThanOp<int SmallOp, intBigOp> : SDTypeConstraint<SmallOp>{

54         int BigOperandNum = BigOp;

55       }

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

59       classSDTCisEltOfVec<int ThisOp, int OtherOp>

60         : SDTypeConstraint<ThisOp> {

61         int OtherOpNum = OtherOp;

62       }

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

66       classSDTCisSubVecOfVec<int ThisOp, int OtherOp>

67         : SDTypeConstraint<ThisOp> {

68         int OtherOpNum = OtherOp;

69       }

这个定义表示ThisOp指定的向量类型操作数比OtherOp指定的向量类型操作数长度短。

73       classSDTCVecEltisVT<int OpNum, ValueType vt> :SDTypeConstraint<OpNum> {

74         ValueType VT = vt;

75       }

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

79       classSDTCisSameNumEltsAs<int OpNum, intOtherOp> : SDTypeConstraint<OpNum> {

80         int OtherOperandNum = OtherOp;

81       }

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

有了上面的基本约束的定义,就可以给出目标机器无关的约束定义了,LLVM-3.6定义了如下的SDNode约束:

101     defSDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>;        // for'imm'.

102     defSDTFPLeaf:SDTypeProfile<1, 0, [SDTCisFP<0>]>;         // for'fpimm'.

103     defSDTPtrLeaf:SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;      // for'&g'.

104     defSDTOther:SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>;// for 'vt'.

105     defSDTUNDEF:SDTypeProfile<1, 0, []>;                    //for 'undef'.

106     defSDTUnaryOp:SDTypeProfile<1, 1, []>;                  // for bitconvert.

107    

108     defSDTIntBinOp:SDTypeProfile<1, 2, [     // add, and, or, xor, udiv, etc.

109       SDTCisSameAs<0, 1>, SDTCisSameAs<0,2>, SDTCisInt<0>

110     ]>;

111     defSDTIntShiftOp:SDTypeProfile<1, 2, [   // shl, sra, srl

112       SDTCisSameAs<0, 1>, SDTCisInt<0>,SDTCisInt<2>

113     ]>;

114     defSDTIntBinHiLoOp:SDTypeProfile<2, 2, [// mulhi, mullo, sdivrem,udivrem

115       SDTCisSameAs<0, 1>, SDTCisSameAs<0,2>, SDTCisSameAs<0, 3>,SDTCisInt<0>

116     ]>;

117    

118     defSDTFPBinOp:SDTypeProfile<1, 2, [      // fadd, fmul, etc.

119       SDTCisSameAs<0, 1>, SDTCisSameAs<0,2>, SDTCisFP<0>

120     ]>;

121     defSDTFPSignOp:SDTypeProfile<1, 2, [     // fcopysign.

122       SDTCisSameAs<0, 1>, SDTCisFP<0>,SDTCisFP<2>

123     ]>;

124     defSDTFPTernaryOp:SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc.

125       SDTCisSameAs<0, 1>, SDTCisSameAs<0,2>, SDTCisSameAs<0, 3>, SDTCisFP<0>

126     ]>;

127     defSDTIntUnaryOp:SDTypeProfile<1, 1, [  // ctlz

128       SDTCisSameAs<0, 1>, SDTCisInt<0>

129     ]>;

130     defSDTIntExtendOp:SDTypeProfile<1, 1, [ // sext, zext, anyext

131       SDTCisInt<0>, SDTCisInt<1>,SDTCisOpSmallerThanOp<1, 0>

132     ]>;

133     defSDTIntTruncOp:SDTypeProfile<1, 1, [  // trunc

134       SDTCisInt<0>, SDTCisInt<1>,SDTCisOpSmallerThanOp<0, 1>

135     ]>;

136     defSDTFPUnaryOp:SDTypeProfile<1, 1, [   // fneg, fsqrt, etc

137       SDTCisSameAs<0, 1>, SDTCisFP<0>

138     ]>;

139     defSDTFPRoundOp:SDTypeProfile<1, 1, [   // fround

140       SDTCisFP<0>, SDTCisFP<1>,SDTCisOpSmallerThanOp<0, 1>

141     ]>;

142     defSDTFPExtendOp: SDTypeProfile<1,1, [  //fextend

143       SDTCisFP<0>, SDTCisFP<1>,SDTCisOpSmallerThanOp<1, 0>

144     ]>;

145     defSDTIntToFPOp:SDTypeProfile<1, 1, [    // [su]int_to_fp

146       SDTCisFP<0>, SDTCisInt<1>

147     ]>;

148     defSDTFPToIntOp:SDTypeProfile<1, 1, [    // fp_to_[su]int

149       SDTCisInt<0>, SDTCisFP<1>

150     ]>;

151     defSDTExtInreg:SDTypeProfile<1, 2, [     // sext_inreg

152       SDTCisSameAs<0, 1>, SDTCisInt<0>,SDTCisVT<2, OtherVT>,

153       SDTCisVTSmallerThanOp<2, 1>

154     ]>;

155    

156     defSDTSetCC:SDTypeProfile<1, 3, [        // setcc

157       SDTCisInt<0>, SDTCisSameAs<1, 2>,SDTCisVT<3, OtherVT>

158     ]>;

159    

160     defSDTSelect:SDTypeProfile<1, 3, [       // select

161       SDTCisInt<1>, SDTCisSameAs<0, 2>,SDTCisSameAs<2, 3>

162     ]>;

163    

164     defSDTVSelect:SDTypeProfile<1, 3, [       // vselect

165       SDTCisInt<1>, SDTCisSameAs<0, 2>,SDTCisSameAs<2, 3>

166     ]>;

167    

168     defSDTSelectCC:SDTypeProfile<1, 5, [     // select_cc

169       SDTCisSameAs<1, 2>, SDTCisSameAs<3,4>, SDTCisSameAs<0, 3>,

170       SDTCisVT<5, OtherVT>

171     ]>;

172    

173     defSDTBr: SDTypeProfile<0, 1,[           //br

174       SDTCisVT<0, OtherVT>

175     ]>;

176    

177     defSDTBrCC: SDTypeProfile<0,4, [       //brcc

178       SDTCisVT<0, OtherVT>,SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>

179     ]>;

180    

181     defSDTBrcond: SDTypeProfile<0,2, [       //brcond

182       SDTCisInt<0>, SDTCisVT<1,OtherVT>

183     ]>;

184    

185     defSDTBrind:SDTypeProfile<0, 1, [        // brind

186       SDTCisPtrTy<0>

187     ]>;

188    

189     defSDTNone: SDTypeProfile<0,0, []>;      //ret, trap

190    

191     defSDTLoad: SDTypeProfile<1,1, [         //load

192       SDTCisPtrTy<1>

193     ]>;

194    

195     defSDTStore:SDTypeProfile<0, 2, [        // store

196       SDTCisPtrTy<1>

197     ]>;

198    

199     defSDTIStore:SDTypeProfile<1, 3, [       // indexed store

200       SDTCisSameAs<0, 2>,SDTCisPtrTy<0>, SDTCisPtrTy<3>

201     ]>;

202    

203     defSDTMaskedStore:SDTypeProfile<0, 3, [      // masked store

204       SDTCisPtrTy<0>, SDTCisVec<1>,SDTCisVec<2>

205     ]>;

206    

207     defSDTMaskedLoad:SDTypeProfile<1, 3, [      // masked load

208       SDTCisVec<0>, SDTCisPtrTy<1>,SDTCisVec<2>, SDTCisSameAs<0, 3>

209     ]>;

210    

211     defSDTMaskedGather:SDTypeProfile<2, 3, [      // masked gather

212       SDTCisVec<0>, SDTCisVec<1>,SDTCisSameAs<0, 2>, SDTCisSameAs<1, 3>,

213       SDTCisPtrTy<4>, SDTCVecEltisVT<1,i1>, SDTCisSameNumEltsAs<0, 1>

214     ]>;

215    

216     defSDTMaskedScatter:SDTypeProfile<1, 3, [      // masked scatter

217       SDTCisVec<0>, SDTCisVec<1>,SDTCisSameAs<0, 2>, SDTCisSameNumEltsAs<0, 1>,

218       SDTCVecEltisVT<0, i1>,SDTCisPtrTy<3>

219     ]>;

220    

221     defSDTVecShuffle:SDTypeProfile<1, 2, [

222       SDTCisSameAs<0, 1>, SDTCisSameAs<1,2>

223     ]>;

224     defSDTVecExtract:SDTypeProfile<1, 2, [  // vector extract

225       SDTCisEltOfVec<0, 1>,SDTCisPtrTy<2>

226     ]>;

227     defSDTVecInsert:SDTypeProfile<1, 3, [    // vector insert

228       SDTCisEltOfVec<2, 1>,SDTCisSameAs<0, 1>, SDTCisPtrTy<3>

229     ]>;

230    

231     defSDTSubVecExtract:SDTypeProfile<1, 2, [// subvector extract

232       SDTCisSubVecOfVec<0,1>,SDTCisInt<2>

233     ]>;

234     defSDTSubVecInsert:SDTypeProfile<1, 3, [// subvector insert

235       SDTCisSubVecOfVec<2, 1>,SDTCisSameAs<0,1>, SDTCisInt<3>

236     ]>;

237    

238     defSDTPrefetch:SDTypeProfile<0, 4, [     // prefetch

239       SDTCisPtrTy<0>, SDTCisSameAs<1,2>, SDTCisSameAs<1, 3>, SDTCisInt<1>

240     ]>;

241    

242     defSDTMemBarrier:SDTypeProfile<0, 5, [  // memory barrier

243       SDTCisSameAs<0,1>,  SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>,SDTCisSameAs<0,4>,

244       SDTCisInt<0>

245     ]>;

246     defSDTAtomicFence:SDTypeProfile<0, 2, [

247       SDTCisSameAs<0,1>, SDTCisPtrTy<0>

248     ]>;

249     defSDTAtomic3:SDTypeProfile<1, 3, [

250       SDTCisSameAs<0,2>,  SDTCisSameAs<0,3>, SDTCisInt<0>,SDTCisPtrTy<1>

251     ]>;

252     defSDTAtomic2:SDTypeProfile<1, 2, [

253       SDTCisSameAs<0,2>, SDTCisInt<0>,SDTCisPtrTy<1>

254     ]>;

255     defSDTAtomicStore: SDTypeProfile<0,2, [

256       SDTCisPtrTy<0>, SDTCisInt<1>

257     ]>;

258     defSDTAtomicLoad:SDTypeProfile<1, 1, [

259       SDTCisInt<0>, SDTCisPtrTy<1>

260     ]>;

261    

262     defSDTConvertOp:SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff,fs, fu, sf, su

263       SDTCisVT<2, OtherVT>, SDTCisVT<3,OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5>

264     ]>;

265    

266     classSDCallSeqStart<list<SDTypeConstraint>constraints> :

267             SDTypeProfile<0, 1, constraints>;

268     classSDCallSeqEnd<list<SDTypeConstraint>constraints> :

269             SDTypeProfile<0, 2, constraints>;

这些定义都将用于描述特定的指令,从其名字或定义后的注释可以看出这些指令。另外,目标机器也可以根据自己的需要,特别定制约束来描述自己特有的指令。

2.2.4.1.2.  属性的描述

SDNode的属性描述了SDNode所代表操作的特征,它由SDNodeProperty及其派生定义描述,目前LLVM-3.6定义了以下属性:

276      classSDNodeProperty;

277      defSDNPCommutative:SDNodeProperty;   // X op Y == Y op X

278      defSDNPAssociative:SDNodeProperty;   // (X op Y) op Z == X op (Y op Z)

279      defSDNPHasChain:SDNodeProperty;   // R/W chain operand and result

280      defSDNPOutGlue:SDNodeProperty;   // Write a flag result

281      defSDNPInGlue: SDNodeProperty;   // Read a flagoperand

282      defSDNPOptInGlue:SDNodeProperty;   // Optionally read a flag operand

283      defSDNPMayStore:SDNodeProperty;   // May write to memory, sets 'mayStore'.

284      defSDNPMayLoad:SDNodeProperty;   // May read memory, sets 'mayLoad'.

285      defSDNPSideEffect:SDNodeProperty;   // Sets 'HasUnmodelledSideEffects'.

286      defSDNPMemOperand:SDNodeProperty;   // Touches memory, has assoc MemOperand

287      defSDNPVariadic:SDNodeProperty;   // Node has variable arguments.

288      defSDNPWantRoot:SDNodeProperty;   // ComplexPattern gets the root of match

289      defSDNPWantParent: SDNodeProperty;  // ComplexPattern gets the parent

注释已经说得足够清楚了,不需要再赘述。比如,前面谈到的指令选择生成器知道加法符合交换律的知识就是由SDNPCommutative提供的。

2.2.4.1.3. SDNode的派生定义

LLVM在TD文件与C++代码中同时维护了两套一一对应的SDNode类型系统。这两套类型系统的纽带就是llvm/include/llvm/CodeGen目录下文件ISDOpcodes.h中定义的枚举类型NodeType。显然,这样做是为了让Tblgen知道如何将SDNode节点匹配到合适的C++对象。这些派生定义的数量相当多(这取决于LLVM IR的复杂性),而且也不复杂,我们就不一一列出了。举例来说,TableGen这样来定义立即数:

313      def imm :SDNode<"ISD::Constant"  , SDTIntLeaf , [],"ConstantSDNode">;

Imm对应枚举值ISD::Constant(类型NodeType),LLVM代码中的类ConstantSDNode。

0 0