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对象的结果个数。因为,结果代码需要在这些位置输出结果值。
- LLVM学习笔记(25)
- llvm学习笔记(1)
- llvm学习笔记(2)
- llvm学习笔记(3)
- llvm学习笔记(4)
- llvm学习笔记(5)
- LLVM学习笔记(6)
- LLVM学习笔记(7)
- LLVM学习笔记(8)
- LLVM学习笔记(9)
- LLVM学习笔记(10)
- LLVM学习笔记(11)
- LLVM学习笔记(12)
- LLVM学习笔记(13)
- LLVM学习笔记(14)
- LLVM学习笔记(15)
- LLVM学习笔记(20)
- LLVM学习笔记(16)
- 我在IT职场超15年:从程序员做到副总,送你21个超实用的职场法则!
- jq上传头像
- android微信源生SDK分享问题
- 职场中年危机,可能只是你放水太多又不接受现实而已
- Git入门
- LLVM学习笔记(25)
- protocolBuf的跨平台基础使用2
- centos7.x yum更新为网易源
- 每天一个linux命令(36):diff 命令
- 线程--猜数字
- [javaScript]今天业务上用到一个毫秒转年月日时分秒的功能,网上找了下,没有,自己随便写了个。记录
- linux环境下载和编译TRDP源码
- vue nextTick深入理解---vue性能优化、DOM更新时机、事件循环机制
- 编译与链接(二)——静态链接