LLVM学习笔记(25)

来源:互联网 发布:大脑是如何思考的知乎 编辑:程序博客网 时间:2024/05/29 05:00

3.4.3.2.       从PatternToMatch到Matcher

3.4.3.2.1. MatcherGen对象

完成了排序后,接着在151行遍历这些排好序的PatternToMatch对象,为它们生成Matcher对象(实际上是一系列DAGISel Matcher派生类)。

DAGISelEmitter::run(续)

149        // Convert each variant of each pattern intoa Matcher.

150        std::vector<Matcher*> PatternMatchers;

151        for (unsignedi = 0, e = Patterns.size(); i != e; ++i) {

152          for(unsigned Variant = 0; ; ++Variant) {

153            if (Matcher *M = ConvertPatternToMatcher(*Patterns[i],Variant, CGP))

154              PatternMatchers.push_back(M);

155            else

156              break;

157          }

158        }

151行的外层遍历使用的排序PatternToMatch对象,152行的内层则无限循环,直到153行的ConvertPatternToMatcher返回0为止(即遍历完匹配模式中ComplexPattern对象的RootNodes)。注意,每次参数Variant都加1。

1003   Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,

1004                                          unsignedVariant,

1005                                         const CodeGenDAGPatterns &CGP) {

1006     MatcherGen Gen(Pattern,CGP);

1007  

1008     // Generate thecode for the matcher.

1009     if (Gen.EmitMatcherCode(Variant))

1010       returnnullptr;

1011  

1012     // FIXME2: Killextra MoveParent commands at the end of the matcher sequence.

1013     // FIXME2: Splitresult code out to another table, and make the matcher end

1014     // with an"Emit <index>" command. This allows result generation stuff to be

1015     // shared andfactored?

1016  

1017     // If the matchsucceeds, then we generate Pattern.

1018     Gen.EmitResultCode();

1019  

1020     // Unconditionalmatch.

1021     returnGen.GetMatcher();

1022   }

Matcher实例由MatcherGen对象辅助产生,因此先在1006行如下构造MatcherGen实例。注意,是每个PatternToMatch对象分配一个实例。因此MatcherGen的变量NextRecordedOperandNo及容器VariableMap、MatchedChainNodes、MatchedGlueResultNodes、MatchedComplexPatterns、PhysRegInputs都专用于它所对应的PatternToMatch对象。

152      MatcherGen::MatcherGen(const PatternToMatch &pattern,

153                             constCodeGenDAGPatterns &cgp)

154      :Pattern(pattern), CGP(cgp), NextRecordedOperandNo(0),

155        TheMatcher(nullptr), CurPredicate(nullptr) {

156        // We need toproduce the matcher tree for the patterns source pattern.  To do

157        // this we needto match the structure as well as the types. To do the type

158        // matching, wewant to figure out the fewest number of type checks we need to

159        // emit.  For example, if there is only one integertype supported by a

160        // target, thereshould be no type comparisons at all for integer patterns!

161        //

162        // To figure outthe fewest number of type checks needed, clone the pattern,

163        // remove thetypes, then perform type inference on the pattern as a whole.

164        // If there areunresolved types, emit an explicit check for those types,

165        // apply the typeto the tree, then rerun type inference. Iterate until all

166        // types areresolved.

167        //

168        PatWithNoTypes =Pattern.getSrcPattern()->clone();

169        PatWithNoTypes->RemoveAllTypes();

170     

171        // If there aretypes that are manifestly known, infer them.

172        InferPossibleTypes();

173      }

156行开始的注释谈到,匹配结构时类型也要匹配,但希望尽可能少地进行类型检查。为了找出最少的类型检查数,首先克隆源模板,以下面的方法删除所有的类型。

1317   void TreePatternNode::RemoveAllTypes(){

1318     for (unsignedi = 0, e = Types.size(); i != e; ++i)

1319       Types[i] = EEVT::TypeSet(); // Reset tounknown type.

1320     if (isLeaf()) return;

1321     for (unsignedi = 0, e = getNumChildren(); i != e; ++i)

1322       getChild(i)->RemoveAllTypes();

1323   }

因为在1319行将所有的类型都设置为未知,那么下面的ApplyTypeConstraints时,在其内部调用的UpdateNodeType,进而MergeInTypeInfo时会直接利用目标系统给出的类型。当然,这个过程不保证所有的类型都能确定,因此上面的注释谈到类型未知的节点才需要生成类型检查代码。

179      void MatcherGen::InferPossibleTypes(){

180        // TP - Get*SOME* tree pattern, we don't care which. It is only used for

181        // diagnostics,which we know are impossible at this point.

182        TreePattern &TP =*CGP.pf_begin()->second;

183     

184        bool MadeChange = true;

185        while(MadeChange)

186          MadeChange = PatWithNoTypes->ApplyTypeConstraints(TP,

187                                                   true/*Ignore reg constraints*/);

188      }

3.4.3.2.2. 生成匹配代码的Matcher对象

MatcherGen::EmitMatcherCode方法生成一系列Matcher对象。这些对象将用于生成匹配输入模式的代码。所有Matcher对象都通过自身的Next域链接在一起。AddMatcher提供了相应的接口。

192      void MatcherGen::AddMatcher(Matcher*NewNode) {

193        if (CurPredicate)

194          CurPredicate->setNext(NewNode);

195        else

196          TheMatcher = NewNode;

197        CurPredicate = NewNode;

198      }

其中,MatcherGen的TheMatcher指向最顶层的Matcher对象,CurPredicate则指向最后生成的Matcher对象。

502      bool MatcherGen::EmitMatcherCode(unsignedVariant) {

503        // If the root ofthe pattern is a ComplexPattern and if it is specified to

504        // match somenumber of root opcodes, these are considered to be our variants.

505        // Depending onwhich variant we're generating code for, emit the root opcode

506        // check.

507        if (constComplexPattern *CP =

508                        Pattern.getSrcPattern()->getComplexPatternInfo(CGP)) {

509          conststd::vector<Record*> &OpNodes = CP->getRootNodes();

510          assert(!OpNodes.empty()&&"Complex Pattern must specify what it can match");

511          if (Variant >= OpNodes.size())return true;

512     

513          AddMatcher(newCheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant])));

514        } else {

515          if (Variant != 0) returntrue;

516        }

517     

518        // Emit thematcher for the pattern structure and types.

519        EmitMatchCode(Pattern.getSrcPattern(),PatWithNoTypes);

在508行,方法getComplexPatternInfo获取匹配模板中的ComplexPattern定义(如果没有,返回null)。ComplexPattern定义可以指定一个RootNodes列表,这是它的SelectFunc所要匹配的节点。因此,在513行为这些节点分别生成一个CheckOpcodeMatcher对象(匹配OpCode的Matcher),参数Variant用于顺序使用这些节点。一旦穷尽就返回true,进而ConvertPatternToMatcher返回0,最后DAGISelEmitter::run在156行跳出152行循环。

ComplexPattern定义之外,匹配模式的结构与类型进行匹配的Matcher对象由下面的方法产生。其中参数NodeNoTypes是参数N的去除类型版本。472行遍历两者的类型,将不一致的类型记录在容器ResultsToTypeCheck里,用于稍后生成类型匹配的Matcher实例。

465      void MatcherGen::EmitMatchCode(const TreePatternNode *N,

466                                     TreePatternNode*NodeNoTypes) {

467        // If N andNodeNoTypes don't agree on a type, then this is a case where we

468        // need to do atype check.  Emit the check, apply thetype to NodeNoTypes and

469        // reinfer anycorrelated types.

470        SmallVector<unsigned, 2>ResultsToTypeCheck;

471     

472        for (unsignedi = 0, e = NodeNoTypes->getNumTypes(); i != e; ++i) {

473          if (NodeNoTypes->getExtType(i) ==N->getExtType(i))continue;

474          NodeNoTypes->setType(i,N->getExtType(i));

475          InferPossibleTypes();

476          ResultsToTypeCheck.push_back(i);

477        }

478     

479        // If this nodehas a name associated with it, capture it in VariableMap. If

480        // we already sawthis in the pattern, emit code to verify dagness.

481        if (!N->getName().empty())

482          if (!recordUniqueNode(N->getName()))

483            return;

484     

485        if (N->isLeaf())

486          EmitLeafMatchCode(N);

487        else

488          EmitOperatorMatchCode(N,NodeNoTypes);

489     

490        // If there arenode predicates for this node, generate their checks.

491        for (unsignedi = 0, e = N->getPredicateFns().size(); i != e; ++i)

492          AddMatcher(newCheckPredicateMatcher(N->getPredicateFns()[i]));

493     

494        for (unsignedi = 0, e = ResultsToTypeCheck.size(); i != e; ++i)

495          AddMatcher(newCheckTypeMatcher(N->getType(ResultsToTypeCheck[i]),

496                                          ResultsToTypeCheck[i]));

497      }

如果节点是具名的,我们需要生成对这个具名节点进行名字检查的Matcher。

448      bool MatcherGen::recordUniqueNode(std::stringName) {

449        unsigned &VarMapEntry =VariableMap[Name];

450        if (VarMapEntry == 0) {

451          // If it is anamed node, we must emit a 'Record' opcode.

452          AddMatcher(new RecordMatcher("$" + Name,NextRecordedOperandNo));

453          VarMapEntry = ++NextRecordedOperandNo;

454          returntrue;

455        }

456     

457        // If we gethere, this is a second reference to a specific name.  Since

458        // we alreadyhave checked that the first reference is valid, we don't

459        // have torecursively match it, just check that it's the same as the

460        // previouslynamed thing.

461        AddMatcher(newCheckSameMatcher(VarMapEntry-1));

462        return false;

463      }

在这里VariableMap是MatcherGen的StringMap<unsigned>类型容器,NextRecordedOperandNo顾名思义就是下一个操作数的序号。对第一次出现的具名节点,要生成一个RecordMatcher对象。如果是再次出现,就需要一个CheckSameMatcher对象来检查同名的RecordMatcher对象是否一致。注意449行的VarMapEntry是一个引用,对第一次出现的具名节点,它所记录的序号实际上比真实序号大1,这是为了方便450行的判定(因为0序号是不使用的)。

如果是叶子节点,生成其匹配代码的Matcher对象由下面的方法来产生。注意,dag不能产生模式树的叶子节点。

206      void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {

207        assert(N->isLeaf()&& "Not a leaf?");

208     

209        // Direct match againstan integer constant.

210        if (IntInit *II =dyn_cast<IntInit>(N->getLeafValue())) {

211          // If this isthe root of the dag we're matching, we emit a redundant opcode

212          // check toensure that this gets folded into the normal top-level

213          //OpcodeSwitch.

214          if (N == Pattern.getSrcPattern()) {

215            constSDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed("imm"));

216            AddMatcher(newCheckOpcodeMatcher(NI));

217          }

218     

219          returnAddMatcher(new CheckIntegerMatcher(II->getValue()));

220        }

221     

222        // An UnsetInitrepresents a named node without any constraints.

223        if(isa<UnsetInit>(N->getLeafValue())) {

224          assert(N->hasName()&& "Unnamed ? leaf");

225          return;

226        }

227     

228        DefInit *DI =dyn_cast<DefInit>(N->getLeafValue());

229        if (!DI) {

230          errs() << "Unknown leaf kind:" << *N << "\n";

231          abort();

232        }

233     

234        Record *LeafRec = DI->getDef();

235     

236        // A ValueTypeleaf node can represent a register when named, or itself when

237        // unnamed.

238        if(LeafRec->isSubClassOf("ValueType")) {

239          // A namedValueType leaf always matches: (add i32:$a, i32:$b).

240          if (N->hasName())

241            return;

242          // An unnamedValueType as in (sext_inreg GPR:$foo, i8).

243          returnAddMatcher(newCheckValueTypeMatcher(LeafRec->getName()));

244        }

245     

246        if (// Handleregister references.  Nothing to do here,they always match.

247           LeafRec->isSubClassOf("RegisterClass") ||

248            LeafRec->isSubClassOf("RegisterOperand")||

249           LeafRec->isSubClassOf("PointerLikeRegClass") ||

250           LeafRec->isSubClassOf("SubRegIndex") ||

251            // Placeholder for SRCVALUE nodes. Nothing to do here.

252            LeafRec->getName() == "srcvalue")

253          return;

254     

255        // If we have aphysreg reference like (mul gpr:$src, EAX) then we need to

256        // record theregister

257        if(LeafRec->isSubClassOf("Register")) {

258          AddMatcher(newRecordMatcher("physreg input "+LeafRec->getName(),

259                                      NextRecordedOperandNo));

260         PhysRegInputs.push_back(std::make_pair(LeafRec,NextRecordedOperandNo++));

261          return;

262        }

263     

264        if (LeafRec->isSubClassOf("CondCode"))

265          returnAddMatcher(newCheckCondCodeMatcher(LeafRec->getName()));

266     

267        if(LeafRec->isSubClassOf("ComplexPattern")) {

268          // We can'tmodel ComplexPattern uses that don't have their name taken yet.

269          // TheOPC_CheckComplexPattern operation implicitly records the results.

270          if (N->getName().empty()) {

271            std::string S;

272            raw_string_ostream OS(S);

273            OS << "We expect complexpattern uses to have names: " << *N;

274            PrintFatalError(OS.str());

275          }

276     

277          // Rememberthis ComplexPattern so that we can emit it after all the other

278          // structuralmatches are done.

279          unsigned InputOperand =VariableMap[N->getName()] - 1;

280         MatchedComplexPatterns.push_back(std::make_pair(N, InputOperand));

281          return;

282        }

283     

284        errs() << "Unknown leaf kind:" << *N << "\n";

285        abort();

286      }

前面解析匹配模式时,我们看到能作为其叶子节点的类型无外乎:IntInit(整数,包括BitsInit)、UnsetInit(未初始化整数)、DefInit(任意Record定义)。对IntInit而言,如果它是唯一需要匹配的对象,我们需要确定它是(immval)中的操作数(CheckOpcodeMatcher对象)。

至于Definit,需要区分这些情形:

ValueType:需要检查操作数是否具有指定类型(CheckValueTypeMatcher对象)。

Register:在这个阶段,通常只需要指定寄存器类,让寄存器分配器来分配适用的寄存器(因此这里无需特别处理RegisterClass,RegisterOperand,PointerLikeRegClass与SubRegIndex)。如果特别指定了物理寄存器,就需要一个RecordMatcher实例,并把相关的参数(Record对象及Matcher对象的序号)保存入寄存器专用容器PhysRegInputs里。

CondCode:需要生成判断条件代码(CheckCondCodeMatcher对象)。

ComplexPattern:RecordMatcher实例已经由recordUniqueNode生成, MatchedComplexPatterns容器保存了它的信息用于稍后统一创建Matcher对象。

如果是非叶子节点,我们知道它的操作符可以是ComplexPattern,SDNode(在这里源模板不能是set,也不会是只能出现在输入、输出操作数描述里的out,in,ops)。293行的注释提到了非叶子节点ComplexPattern的处理,这个节点连同其操作数合为一个RecordMatcher实例(叶子节点的ComplexPattern则不如是,下面我们会看到)。

288      void MatcherGen::EmitOperatorMatchCode(const TreePatternNode *N,

289                                            TreePatternNode *NodeNoTypes) {

290        assert(!N->isLeaf()&& "Not an operator?");

291     

292        if(N->getOperator()->isSubClassOf("ComplexPattern")) {

293          // The"name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is

294          //"MY_PAT:op1:op2". We should already have validated that the uses are

295          // consistent.

296          std::string PatternName =N->getOperator()->getName();

297          for(unsigned i = 0; i < N->getNumChildren(); ++i) {

298            PatternName += ":";

299            PatternName +=N->getChild(i)->getName();

300          }

301     

302          if (recordUniqueNode(PatternName)){

303            autoNodeAndOpNum = std::make_pair(N, NextRecordedOperandNo - 1);

304           MatchedComplexPatterns.push_back(NodeAndOpNum);

305          }

306     

307          return;

308        }

309     

310        constSDNodeInfo &CInfo = CGP.getSDNodeInfo(N->getOperator());

311     

312        // If this is an'and R, 1234' where the operation is AND/OR and the RHS is

313        // a constantwithout a predicate fn that has more that one bit set, handle

314        // this as aspecial case.  This is usually fortargets that have special

315        // handling ofcertain large constants (e.g. alpha with it's 8/16/32-bit

316        // handlingstuff).  Using these instructions isoften far more efficient

317        // thanmaterializing the constant. Unfortunately, both the instcombiner

318        // and the dagcombiner can often infer that bits are dead, and thus drop

319        // them from themask in the dag.  For example, it mightturn 'AND X, 255'

320        // into 'AND X,254' if it knows the low bit is set. Emit code that checks

321        // to handlethis.

322        if ((N->getOperator()->getName() =="and" ||

323             N->getOperator()->getName() =="or") &&

324            N->getChild(1)->isLeaf() &&N->getChild(1)->getPredicateFns().empty() &&

325            N->getPredicateFns().empty()) {

326          if (IntInit *II =dyn_cast<IntInit>(N->getChild(1)->getLeafValue())) {

327           if (!isPowerOf2_32(II->getValue())){ // Don'tbother with single bits.

328              // If thisis at the root of the pattern, we emit a redundant

329              //CheckOpcode so that the following checks get factored properly under

330              // a singleopcode check.

331              if (N == Pattern.getSrcPattern())

332                AddMatcher(newCheckOpcodeMatcher(CInfo));

333     

334              // Emit theCheckAndImm/CheckOrImm node.

335              if (N->getOperator()->getName()== "and")

336                AddMatcher(newCheckAndImmMatcher(II->getValue()));

337              else

338                AddMatcher(newCheckOrImmMatcher(II->getValue()));

339     

340              // Matchthe LHS of the AND as appropriate.

341              AddMatcher(newMoveChildMatcher(0));

342             EmitMatchCode(N->getChild(0),NodeNoTypes->getChild(0));

343              AddMatcher(newMoveParentMatcher());

344              return;

345            }

346          }

347        }

348     

349        // Check that thecurrent opcode lines up.

350        AddMatcher(newCheckOpcodeMatcher(CInfo));

351     

352        // If this nodehas memory references (i.e. is a load or store), tell the

353        // interpreter tocapture them in the memref array.

354        if (N->NodeHasProperty(SDNPMemOperand,CGP))

355          AddMatcher(newRecordMemRefMatcher());

356     

357        // If this nodehas a chain, then the chain is operand #0 is the SDNode, and

358        // the childnumbers of the node are all offset by one.

359        unsigned OpNo = 0;

360        if (N->NodeHasProperty(SDNPHasChain, CGP)){

361          // Record thenode and remember it in our chained nodes list.

362          AddMatcher(newRecordMatcher("'" + N->getOperator()->getName() +

363                                              "' chained node",

364                                       NextRecordedOperandNo));

365          // Remember allof the input chains our pattern will match.

366         MatchedChainNodes.push_back(NextRecordedOperandNo++);

367     

368          // Don't lookat the input chain when matching the tree pattern to the

369          // SDNode.

370          OpNo = 1;

371     

372          // If this nodeis not the root and the subtree underneath it produces a

373          // chain, thenthe result of matching the node is also produce a chain.

374          // Beyond that,this means that we're also folding (at least) the root node

375          // into thenode that produce the chain (for example, matching

376          // "(addreg, (load ptr))" as a add_with_memory on X86).  This is

377          // problematic,if the 'reg' node also uses the load (say, its chain).

378          // Graphically:

379          //

380          //         [LD]

381          //           ^  ^

382          //           |    \                              DAG's likecheese.

383          //          /      |

384          //        /     [YY]

385          //       |       ^

386          //      [XX]--/

387          //

388          // It would beinvalid to fold XX and LD.  In this case,folding the two

389          // nodestogether would induce a cycle in the DAG, making it a 'cyclic DAG'

390          // To preventthis, we emit a dynamic check for legality before allowing

391          // this to befolded.

392          //

393          constTreePatternNode *Root = Pattern.getSrcPattern();

394          if (N != Root) {                            // Not the root of the pattern.

395            // If thereis a node between the root and this node, then we definitely

396            // need toemit the check.

397            bool NeedCheck = !Root->hasChild(N);

398     

399            // If it *is*an immediate child of the root, we can still need a check if

400            // the rootSDNode has multiple inputs.  For us, thismeans that it is an

401            // intrinsic,has multiple operands, or has other inputs like chain or

402            // glue).

403            if (!NeedCheck) {

404              constSDNodeInfo &PInfo = CGP.getSDNodeInfo(Root->getOperator());

405              NeedCheck =

406                Root->getOperator() ==CGP.get_intrinsic_void_sdnode() ||

407                Root->getOperator() ==CGP.get_intrinsic_w_chain_sdnode() ||

408                Root->getOperator() ==CGP.get_intrinsic_wo_chain_sdnode() ||

409                PInfo.getNumOperands() > 1 ||

410                PInfo.hasProperty(SDNPHasChain) ||

411                PInfo.hasProperty(SDNPInGlue) ||

412                PInfo.hasProperty(SDNPOptInGlue);

413            }

414     

415            if (NeedCheck)

416              AddMatcher(newCheckFoldableChainNodeMatcher());

417          }

418        }

419     

420        // If this nodehas an output glue and isn't the root, remember it.

421        if (N->NodeHasProperty(SDNPOutGlue, CGP)&&

422            N != Pattern.getSrcPattern()) {

423          // TODO: Thisredundantly records nodes with both glues and chains.

424     

425          // Record thenode and remember it in our chained nodes list.

426          AddMatcher(newRecordMatcher("'" + N->getOperator()->getName() +

427                                               "' glueoutput node",

428                                      NextRecordedOperandNo));

429          // Remember allof the nodes with output glue our pattern will match.

430         MatchedGlueResultNodes.push_back(NextRecordedOperandNo++);

431        }

432     

433        // If this nodeis known to have an input glue or if it *might* have an input

434        // glue, captureit as the glue input of the pattern.

435        if (N->NodeHasProperty(SDNPOptInGlue, CGP)||

436            N->NodeHasProperty(SDNPInGlue, CGP))

437          AddMatcher(newCaptureGlueInputMatcher());

438     

439        for (unsignedi = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {

440          // Get the codesuitable for matching this child.  Moveto the child, check

441          // it then moveback to the parent.

442          AddMatcher(newMoveChildMatcher(OpNo));

443          EmitMatchCode(N->getChild(i),NodeNoTypes->getChild(i));

444          AddMatcher(newMoveParentMatcher());

445        }

446      }

312行提到了一个特殊的情况,即操作符是and或or,右手侧操作数是只有一个比特位是1的常量,且没有伴随的谓词。在这种情况下,目标机器通常有更高效的专用指令。因此327~345行不处理这种情形。

这里的要匹配节点都是所谓的SelectionDAG节点。SelectionDAG包含两种类型的值:表示数据流的,以及表示控制流依赖性的。数据值是具有一个整数或浮点值类型的简单边。控制边被表示作“链,chain”边,类型是MVT::Other。这些边在具有副作用的节点间(比如load,store,call,return等)提供了一个次序。所有具有副作用的节点接受一个符号链作为输入,并产生一个新的符号链作为输出。按照惯例,符号链输入总是操作数0,而一个操作产生的最后的值总是链结果(如果没有glue节点的话)。

360~418行处理具有链的节点。372行的注释谈到一点,就是一个模式里所有具有链的节点都可能会依据链的顺序折叠起来,这就需要避免380~386行所给出的DAG的形式,TableGen产生一个CheckFoldableChainNodeMatcher对象用于生成对这种情况进行检查的代码。

421行的SDNPOutGlue属性,表示该操作会写标记寄存器。435行的SDNPOptInGlue属性与436行的SDNPInGlue属性分别表示可能及确定读标记寄存器。因此,在指令调度时,属性为SDNPOutGlue的节点会与属性为SDNPInGlue的后续节点一起调度,中间不会插入别的节点。

另外,注意在439行循环里,在进入子节点生成Matcher对象之前与之后,需要分别产生一个特殊的对象MoveChildMatcher与MoveParentMatcher来表示作用域的切换。

在MatcherGen::EmitMatchCode的最后,为谓词及需要检查的类型生成Matcher对象(在472行的循环我们把这些类型缓存起来了)。

MatcherGen::EmitMatcherCode(续)

521        // If the pattern has a predicate on it (e.g. onlyenabled when a subtarget

522        // feature is around,do the check).

523        if (!Pattern.getPredicateCheck().empty())

524          AddMatcher(newCheckPatternPredicateMatcher(Pattern.getPredicateCheck()));

525     

526        // Now that we'vecompleted the structural type match, emit any ComplexPattern

527        // checks (e.g.addrmode matches).  We emit this afterthe structural match

528        // because theyare generally more expensive to evaluate and more difficult to

529        // factor.

530        for (unsignedi = 0, e = MatchedComplexPatterns.size(); i != e; ++i) {

531          constTreePatternNode *N = MatchedComplexPatterns[i].first;

532     

533          // Rememberwhere the results of this match get stuck.

534          if (N->isLeaf()) {

535           NamedComplexPatternOperands[N->getName()] = NextRecordedOperandNo +1;

536          } else {

537            unsigned CurOp = NextRecordedOperandNo;

538            for(unsigned i = 0; i < N->getNumChildren(); ++i) {

539             NamedComplexPatternOperands[N->getChild(i)->getName()] = CurOp +1;

540              CurOp +=N->getChild(i)->getNumMIResults(CGP);

541            }

542          }

543     

544          // Get the slotwe recorded the value in from the name on the node.

545          unsigned RecNodeEntry =MatchedComplexPatterns[i].second;

546     

547          constComplexPattern &CP = *N->getComplexPatternInfo(CGP);

548     

549          // Emit aCheckComplexPat operation, which does the match (aborting if it

550          // fails) andpushes the matched operands onto the recorded nodes list.

551          AddMatcher(newCheckComplexPatMatcher(CP, RecNodeEntry,

552                                               N->getName(), NextRecordedOperandNo));

553     

554          // Record theright number of operands.

555          NextRecordedOperandNo +=CP.getNumOperands();

556          if (CP.hasProperty(SDNPHasChain)) {

557            // If thecomplex pattern has a chain, then we need to keep track of the

558            // fact thatwe just recorded a chain input.  Thechain input will be

559            // matched asthe last operand of the predicate if it was successful.

560            ++NextRecordedOperandNo;// Chained node operand.

561     

562            // It is thelast operand recorded.

563            assert(NextRecordedOperandNo> 1 &&

564                   "Should have recordedinput/result chains at least!");

565           MatchedChainNodes.push_back(NextRecordedOperandNo-1);

566          }

567     

568          // TODO:Complex patterns can't have output glues, if they did, we'd want

569          // to recordthem.

570        }

571     

572        return false;

573      }

524行的getPredicateCheck方法获取包含谓词方法的名字与参数CondString的字符串。

843      std::string PatternToMatch::getPredicateCheck()const {

844        std::string PredicateCheck;

845        for (Init *I: Predicates->getValues()) {

846          if (DefInit *Pred =dyn_cast<DefInit>(I)) {

847            Record *Def = Pred->getDef();

848            if(!Def->isSubClassOf("Predicate")) {

849      #ifndefNDEBUG

850              Def->dump();

851      #endif

852              llvm_unreachable("Unknownpredicate type!");

853            }

854            if (!PredicateCheck.empty())

855              PredicateCheck += " &&";

856            PredicateCheck += "(" +Def->getValueAsString("CondString") + ")";

857          }

858        }

859     

860        returnPredicateCheck;

861      }

前面将模式中所有ComplexPattern定义的信息保存在MatchedComplexPatterns容器里,现在可以为这些ComplexPattern对象生成CheckComplexPatMatcher实例了。NextRecordedOperandNo要计入ComplexPattern对象的结果个数。如果ComplexPattern对象有子节点,还要计入子节点里的ComplexPattern对象的结果个数。因为,结果代码需要在这些位置输出结果值。