3.4.3.2. 从PatternToMatch到Matcher
3.4.3.2.1. MatcherGen对象
完成了排序后,接着在151行遍历这些排好序的PatternToMatch对象,为它们生成Matcher对象(实际上是一系列DAGISelMatcher派生类)。
DAGISelEmitter::run(续)
149 // Convert each variant of each pattern into a Matcher.
150 std::vector<Matcher*> PatternMatchers;
151 for (unsigned i = 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传入ConvertPatternToMatcher()来遍历RootNodes实现的。
1003 Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
1004 unsigned Variant,
1005 const CodeGenDAGPatterns &CGP) {
1006 MatcherGen Gen(Pattern, CGP);
1007
1008 // Generate the code for the matcher.
1009 if (Gen.EmitMatcherCode(Variant))
1010 return nullptr;
1011
1012 // FIXME2: Kill extra MoveParent commands at the end of the matcher sequence.
1013 // FIXME2: Split result 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 and factored?
1016
1017 // If the match succeeds, then we generate Pattern.
1018 Gen.EmitResultCode();
1019
1020 // Unconditional match.
1021 return Gen.GetMatcher();
1022 }
Matcher实例由MatcherGen对象辅助产生,因此先在1006行如下构造MatcherGen实例。注意,是每个PatternToMatch对象分配一个实例。因此MatcherGen的变量NextRecordedOperandNo及容器VariableMap、MatchedChainNodes、MatchedGlueResultNodes、MatchedComplexPatterns、PhysRegInputs都有专用的PatternToMatch对象。
152 MatcherGen::MatcherGen(const PatternToMatch &pattern,
153 const CodeGenDAGPatterns &cgp)
154 : Pattern(pattern), CGP(cgp), NextRecordedOperandNo(0),
155 TheMatcher(nullptr), CurPredicate(nullptr) {
156 // We need to produce the matcher tree for the patterns source pattern. To do
157 // this we need to match the structure as well as the types. To do the type
158 // matching, we want to figure out the fewest number of type checks we need to
159 // emit. For example, if there is only one integer type supported by a
160 // target, there should be no type comparisons at all for integer patterns!
161 //
162 // To figure out the fewest number of type checks needed, clone the pattern,
163 // remove the types, then perform type inference on the pattern as a whole.
164 // If there are unresolved types, emit an explicit check for those types,
165 // apply the type to the tree, then rerun type inference. Iterate until all
166 // types are resolved.
167 //
168 PatWithNoTypes = Pattern.getSrcPattern()->clone();
169 PatWithNoTypes->RemoveAllTypes();
170
171 // If there are types that are manifestly known, infer them.
172 InferPossibleTypes(Pattern.ForceMode); <-- v7.0增加参数
173 }
156行开始的注释谈到,匹配结构时类型也要匹配,但希望尽可能少地进行类型检查。为了找出最少的类型检查数,首先克隆源模板,以下面的方法删除所有的类型。
1317 void TreePatternNode::RemoveAllTypes() {
1318 for (unsigned i = 0, e = Types.size(); i != e; ++i)
1319 Types[i] = EEVT::TypeSet(); // Reset to unknown type. <-- v7.0删除
std::fill(Types.begin(), Types.end(), TypeSetByHwMode()); <-- v7.0增加
1320 if (isLeaf()) return;
1321 for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
1322 getChild(i)->RemoveAllTypes();
1323 }
因为在1319行将所有的类型都设置为未知,那么下面的ApplyTypeConstraints(),在其内部调用的UpdateNodeType(),进而MergeInTypeInfo()时会直接利用目标系统给出的类型。当然,这个过程不保证所有的类型都能确定,因此上面的注释谈到类型未知的节点才需要生成类型检查代码。
179 void MatcherGen::InferPossibleTypes(unsigned ForceMode) { <-- v7.0增加
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;
TP.getInfer().CodeGen = true; <-- v7.0增加
TP.getInfer().ForceMode = ForceMode;
183
184 bool MadeChange = true;
185 while (MadeChange)
186 MadeChange = PatWithNoTypes->ApplyTypeConstraints(TP,
187 true/*Ignore reg constraints*/);
188 }
在v7.0中,MatcherGen::InferPossibleTypes()的参数ForceMode来自PatternToMatch实例的ForceMode成员,用于表明该匹配适用的硬件模式。设置了这个域后,将影响在186行调用的ApplyTypeConstraints()的行为(细节参考前面章节)。
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(unsigned Variant) {
503 // If the root of the pattern is a ComplexPattern and if it is specified to
504 // match some number of root opcodes, these are considered to be our variants.
505 // Depending on which variant we're generating code for, emit the root opcode
506 // check.
507 if (const ComplexPattern *CP =
508 Pattern.getSrcPattern()->getComplexPatternInfo(CGP)) {
509 const std::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(new CheckOpcodeMatcher(CGP.getSDNodeInfo(OpNodes[Variant])));
514 } else {
515 if (Variant != 0) return true;
516 }
517
518 // Emit the matcher for the pattern structure and types.
519 EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes, Pattern.ForceMode); <-- v7.0增加
在508行,方法getComplexPatternInfo()获取匹配模板中的ComplexPattern定义(如果没有,返回null)。ComplexPattern定义可以指定一个RootNodes列表,这是它的SelectFunc要匹配的节点。因此,在513行为这些节点分别生成一个CheckOpcodeMatcher对象(匹配OpCode的Matcher),参数Variant来自DAGISelEmitter::run() 152行的循环变量,用于顺序遍历ComplexPattern操作数,一旦穷尽就返回true(这表示Variant是无效的),进而ConvertPatternToMatcher()返回0,最后在DAGISelEmitter::run() 156行跳出152行循环。对于非ComplexPattern,Variant有效值只能是0。
ComplexPattern定义之外,对匹配模式的结构与类型进行匹配的Matcher对象由下面的方法产生。其中参数NodeNoTypes是参数N的去除类型版本。472行遍历两者的类型,将不一致的类型记录在容器ResultsToTypeCheck里,用于稍后生成类型匹配的Matcher实例。
465 void MatcherGen::EmitMatchCode(const TreePatternNode *N,
466 TreePatternNode *NodeNoTypes,
unsigned ForceMode) { <-- v7.0增加
467 // If N and NodeNoTypes don't agree on a type, then this is a case where we
468 // need to do a type check. Emit the check, apply the type to NodeNoTypes and
469 // reinfer any correlated types.
470 SmallVector<unsigned, 2> ResultsToTypeCheck;
471
472 for (unsigned i = 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(ForceMode); <-- v7.0增加
476 ResultsToTypeCheck.push_back(i);
477 }
478
479 // If this node has a name associated with it, capture it in VariableMap. If
480 // we already saw this 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, ForceMode); <-- v7.0增加
489
490 // If there are node predicates for this node, generate their checks.
491 for (unsigned i = 0, e = N->getPredicateFns().size(); i != e; ++i)
492 AddMatcher(new CheckPredicateMatcher(N->getPredicateFns()[i]));
493
494 for (unsigned i = 0, e = ResultsToTypeCheck.size(); i != e; ++i)
495 AddMatcher(new CheckTypeMatcher(N->getType(ResultsToTypeCheck[i]),
496 ResultsToTypeCheck[i]));
497 }
如果节点是具名的,我们需要生成对这个具名节点进行名字检查的Matcher。
448 bool MatcherGen::recordUniqueNode(std::string Name) {
449 unsigned &VarMapEntry = VariableMap[Name];
450 if (VarMapEntry == 0) {
451 // If it is a named node, we must emit a 'Record' opcode.
452 AddMatcher(new RecordMatcher("$" + Name, NextRecordedOperandNo));
453 VarMapEntry = ++NextRecordedOperandNo;
454 return true;
455 }
456
457 // If we get here, this is a second reference to a specific name. Since
458 // we already have checked that the first reference is valid, we don't
459 // have to recursively match it, just check that it's the same as the
460 // previously named thing.
461 AddMatcher(new CheckSameMatcher(VarMapEntry-1));
462 return false;
463 }
在这里VariableMap是MatcherGen的StringMap<unsigned>类型容器,NextRecordedOperandNo用作SelectionDAGISel::SelectCodeCommon()函数里临时容器RecordedNodes里的序号,在指令选择时将会用选则产生SDValue节点填充这个容器,这些节点的序号就是NextRecordedOperandNo的对应值。这些是可能会用于选中指令的节点。
对第一次出现的具名节点,要生成一个RecordMatcher对象,在指令选择时将会记录对应的SDNode对象。如果是再次出现,就需要一个CheckSameMatcher对象来检查同名的RecordMatcher对象是否一致。注意449行的VarMapEntry是一个引用,对第一次出现的具名节点,它所记录的序号实际上比真实序号大1,这是为了方便450行的判定(因为0序号是不使用的)。
除了recordUniqueNode()里会生成RecordMatcher,还有这样几处:ComplexPattern定义(它也是具名的,也是通过recordUniqueNode()生成),Register定义,带有chain节点或glue节点的TreePatternNode。它们对应的SDNode对象有可能作为选择结果的操作数,
如果是叶子节点,生成其匹配代码的Matcher对象由下面的方法来产生。注意,dag不会产生模式树的叶子节点。
206 void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
207 assert(N->isLeaf() && "Not a leaf?");
208
209 // Direct match against an integer constant.
210 if (IntInit *II = dyn_cast<IntInit>(N->getLeafValue())) {
211 // If this is the root of the dag we're matching, we emit a redundant opcode
212 // check to ensure that this gets folded into the normal top-level
213 // OpcodeSwitch.
214 if (N == Pattern.getSrcPattern()) {
215 const SDNodeInfo &NI = CGP.getSDNodeInfo(CGP.getSDNodeNamed("imm"));
216 AddMatcher(new CheckOpcodeMatcher(NI));
217 }
218
219 return AddMatcher(new CheckIntegerMatcher(II->getValue()));
220 }
221
222 // An UnsetInit represents 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 ValueType leaf node can represent a register when named, or itself when
237 // unnamed.
238 if (LeafRec->isSubClassOf("ValueType")) {
239 // A named ValueType leaf always matches: (add i32:$a, i32:$b).
240 if (N->hasName())
241 return;
242 // An unnamed ValueType as in (sext_inreg GPR:$foo, i8).
243 return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName()));
244 }
245
246 if (// Handle register 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 // Place holder for SRCVALUE nodes. Nothing to do here.
252 LeafRec->getName() == "srcvalue")
253 return;
254
255 // If we have a physreg reference like (mul gpr:$src, EAX) then we need to
256 // record the register
257 if (LeafRec->isSubClassOf("Register")) {
258 AddMatcher(new RecordMatcher("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 return AddMatcher(new CheckCondCodeMatcher(LeafRec->getName()));
266
267 if (LeafRec->isSubClassOf("ComplexPattern")) {
268 // We can't model ComplexPattern uses that don't have their name taken yet.
269 // The OPC_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 complex pattern uses to have names: " << *N;
274 PrintFatalError(OS.str());
275 }
276
277 // Remember this ComplexPattern so that we can emit it after all the other
278 // structural matches 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而言,如果它是唯一需要匹配的对象,我们需要确定它是(imm val)中的操作数(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,
unsigned ForceMode) { <-- v7.0增加
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 auto NodeAndOpNum = std::make_pair(N, NextRecordedOperandNo - 1);
304 MatchedComplexPatterns.push_back(NodeAndOpNum);
305 }
306
307 return;
308 }
309
310 const SDNodeInfo &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 constant without a predicate fn that has more that one bit set, handle
314 // this as a special case. This is usually for targets that have special
315 // handling of certain large constants (e.g. alpha with it's 8/16/32-bit
316 // handling stuff). Using these instructions is often far more efficient
317 // than materializing the constant. Unfortunately, both the instcombiner
318 // and the dag combiner can often infer that bits are dead, and thus drop
319 // them from the mask in the dag. For example, it might turn 'AND X, 255'
320 // into 'AND X, 254' if it knows the low bit is set. Emit code that checks
321 // to handle this.
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't bother with single bits.
328 // If this is at the root of the pattern, we emit a redundant
329 // CheckOpcode so that the following checks get factored properly under
330 // a single opcode check.
331 if (N == Pattern.getSrcPattern())
332 AddMatcher(new CheckOpcodeMatcher(CInfo));
333
334 // Emit the CheckAndImm/CheckOrImm node.
335 if (N->getOperator()->getName() == "and")
336 AddMatcher(new CheckAndImmMatcher(II->getValue()));
337 else
338 AddMatcher(new CheckOrImmMatcher(II->getValue()));
339
340 // Match the LHS of the AND as appropriate.
341 AddMatcher(new MoveChildMatcher(0));
342 EmitMatchCode(N->getChild(0), NodeNoTypes->getChild(0), ForceMode); <-- v7.0增加
343 AddMatcher(new MoveParentMatcher());
344 return;
345 }
346 }
347 }
348
349 // Check that the current opcode lines up.
350 AddMatcher(new CheckOpcodeMatcher(CInfo));
351
352 // If this node has memory references (i.e. is a load or store), tell the
353 // interpreter to capture them in the memref array.
354 if (N->NodeHasProperty(SDNPMemOperand, CGP))
355 AddMatcher(new RecordMemRefMatcher());
356
357 // If this node has a chain, then the chain is operand #0 is the SDNode, and
358 // the child numbers of the node are all offset by one.
359 unsigned OpNo = 0;
360 if (N->NodeHasProperty(SDNPHasChain, CGP)) {
361 // Record the node and remember it in our chained nodes list.
362 AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
363 "' chained node",
364 NextRecordedOperandNo));
365 // Remember all of the input chains our pattern will match.
366 MatchedChainNodes.push_back(NextRecordedOperandNo++);
367
368 // Don't look at the input chain when matching the tree pattern to the
369 // SDNode.
370 OpNo = 1;
371
372 // If this node is not the root and the subtree underneath it produces a
373 // chain, then the 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 the node that produce the chain (for example, matching
376 // "(add reg, (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 like cheese.
383 // / |
384 // / [YY]
385 // | ^
386 // [XX]--/
387 //
388 // It would be invalid to fold XX and LD. In this case, folding the two
389 // nodes together would induce a cycle in the DAG, making it a 'cyclic DAG'
390 // To prevent this, we emit a dynamic check for legality before allowing
391 // this to be folded.
392 //
393 const TreePatternNode *Root = Pattern.getSrcPattern();
394 if (N != Root) { // Not the root of the pattern.
395 // If there is a node between the root and this node, then we definitely
396 // need to emit 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 root SDNode has multiple inputs. For us, this means that it is an
401 // intrinsic, has multiple operands, or has other inputs like chain or
402 // glue).
403 if (!NeedCheck) {
404 const SDNodeInfo &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(new CheckFoldableChainNodeMatcher());
417 }
418 }
419
420 // If this node has an output glue and isn't the root, remember it.
421 if (N->NodeHasProperty(SDNPOutGlue, CGP) &&
422 N != Pattern.getSrcPattern()) {
423 // TODO: This redundantly records nodes with both glues and chains.
424
425 // Record the node and remember it in our chained nodes list.
426 AddMatcher(new RecordMatcher("'" + N->getOperator()->getName() +
427 "' glue output node",
428 NextRecordedOperandNo));
429 // Remember all of the nodes with output glue our pattern will match. <-- v7.0删除
430 MatchedGlueResultNodes.push_back(NextRecordedOperandNo++);
431 }
432
433 // If this node is known to have an input glue or if it *might* have an input
434 // glue, capture it as the glue input of the pattern.
435 if (N->NodeHasProperty(SDNPOptInGlue, CGP) ||
436 N->NodeHasProperty(SDNPInGlue, CGP))
437 AddMatcher(new CaptureGlueInputMatcher());
438
439 for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
440 // Get the code suitable for matching this child. Move to the child, check
441 // it then move back to the parent.
442 AddMatcher(new MoveChildMatcher(OpNo));
443 EmitMatchCode(N->getChild(i), NodeNoTypes->getChild(i), ForceMode); ß v7.0增加
444 AddMatcher(new MoveParentMatcher());
445 }
446 }
312行提到了一个特殊的情况,即操作符是and或or,右手侧操作数是多个比特位是1的常量,且没有伴随的谓词,在这种情况下,目标机器通常有更高效的专用指令。注释里提到指令合并器与dag合并器会进行一些优化,比如“AND X, 255”,如果X的最低位为0(注释称为1,但似乎应该为0),它们将被优化为“AND X, 254”(这条指令可能更短),为此生成CheckAndImmMatcher或CheckOrImmMatcher来匹配这种情形。
这里的要匹配节点都是所谓的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来表示作用域的切换。它们将产生在在指令选择时进出子SDNode节点的代码。
在MatcherGen::EmitMatchCode()的最后,为谓词及需要检查的类型生成Matcher对象(在472行的循环我们把这些类型缓存起来了)。
MatcherGen::EmitMatcherCode(续)
521 // If the pattern has a predicate on it (e.g. only enabled when a subtarget
522 // feature is around, do the check).
523 if (!Pattern.getPredicateCheck().empty())
524 AddMatcher(new CheckPatternPredicateMatcher(Pattern.getPredicateCheck()));
525
526 // Now that we've completed the structural type match, emit any ComplexPattern
527 // checks (e.g. addrmode matches). We emit this after the structural match
528 // because they are generally more expensive to evaluate and more difficult to
529 // factor.
530 for (unsigned i = 0, e = MatchedComplexPatterns.size(); i != e; ++i) {
531 const TreePatternNode *N = MatchedComplexPatterns[i].first;
532
533 // Remember where 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 slot we recorded the value in from the name on the node.
545 unsigned RecNodeEntry = MatchedComplexPatterns[i].second;
546
547 const ComplexPattern &CP = *N->getComplexPatternInfo(CGP);
548
549 // Emit a CheckComplexPat operation, which does the match (aborting if it
550 // fails) and pushes the matched operands onto the recorded nodes list.
551 AddMatcher(new CheckComplexPatMatcher(CP, RecNodeEntry,
552 N->getName(), NextRecordedOperandNo));
553
554 // Record the right number of operands.
555 NextRecordedOperandNo += CP.getNumOperands();
556 if (CP.hasProperty(SDNPHasChain)) {
557 // If the complex pattern has a chain, then we need to keep track of the
558 // fact that we just recorded a chain input. The chain input will be
559 // matched as the last operand of the predicate if it was successful.
560 ++NextRecordedOperandNo; // Chained node operand.
561
562 // It is the last operand recorded.
563 assert(NextRecordedOperandNo > 1 &&
564 "Should have recorded input/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 record them.
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 #ifndef NDEBUG
850 Def->dump();
851 #endif
852 llvm_unreachable("Unknown predicate type!");
853 }
854 if (!PredicateCheck.empty())
855 PredicateCheck += " && ";
856 PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
857 }
858 }
859
860 return PredicateCheck;
861 }
V7.0的版本如下: 1312 std::string PatternToMatch::getPredicateCheck() const { 1313 SmallVector<const Predicate*,4> PredList; 1314 for (const Predicate &P : Predicates) 1315 PredList.push_back(&P); 1316 llvm::sort(PredList.begin(), PredList.end(), deref<llvm::less>()); 1317 1318 std::string Check; 1319 for (unsigned i = 0, e = PredList.size(); i != e; ++i) { 1320 if (i != 0) 1321 Check += " && "; 1322 Check += '(' + PredList[i]->getCondString() + ')'; 1323 } 1324 return Check; 1325 } 为了更高效地生成谓词代码,v7.0首先对Predicate进行排序,因此在Predicate里引入了“<”操作符。其中ifCond是bool类型成员,Features是std::string类型成员。 999 bool operator<(const Predicate &P) const { 1000 if (IsHwMode != P.IsHwMode) 1001 return IsHwMode < P.IsHwMode; 1002 assert(!Def == !P.Def && "Inconsistency between Def and IsHwMode"); 1003 if (IfCond != P.IfCond) 1004 return IfCond < P.IfCond; 1005 if (Def) 1006 return LessRecord()(Def, P.Def); 1007 return Features < P.Features; 1008 } 在原来PatternToMatch::getPredicateCheck()进行的检查,移到了上面1002行(更严格)。 |
前面将模式中所有ComplexPattern定义的信息保存在MatchedComplexPatterns容器里,现在可以为这些ComplexPattern对象生成CheckComplexPatMatcher实例了。NextRecordedOperandNo要计入ComplexPattern对象的结果个数。如果ComplexPattern对象有子节点,还要计入子节点里的ComplexPattern对象的结果个数。因为结果代码需要在这些位置输出结果值。因为ComplexPattern是具名的,因此535行的NamedComplexPatternOperands容器(StringMap<unsigned>类型)记录下相关SDValue对象在RecordedNodes里的索引。这将用于后面生成具名操作数的Matcher对象时(参见EmitResultOfNamedOperand())。