2.4.2.4.2. PatFrag的展开
在第一步完成后,我们为所有的PatFrag生成了TreePattern实例。接着,2490行的for循环对其中的片段进行展开。在第一次调用ParsePatternFragments()时(CodeGenDAGPatterns构造函数的2355行),展开输入模式。在第二次调用时(CodeGenDAGPatterns构造函数的2358行),展开输出模式(OutPatFrag定义)。展开由TreePattern的InlinePatternFragments()方法执行:
601 void InlinePatternFragments() {
602 for (unsigned i = 0, e = Trees.size(); i != e; ++i)
603 Trees[i] = Trees[i]->InlinePatternFragments(*this);
604 }
实际上PatFrag都只包含一棵TreePatternNode树。不过其他结构,比如Pattern,Instruction都会调用这个函数,它们可能有多棵树。每棵树的展开由TreePatternNode::InlinePatternFragments()方法来完成。
1358 TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
1359 if (TP.hasError())
1360 return nullptr;
1361
1362 if (isLeaf())
1363 return this; // nothing to do.
1364 Record *Op = getOperator();
1365
1366 if (!Op->isSubClassOf("PatFrag")) {
1367 // Just recursively inline children nodes.
1368 for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
1369 TreePatternNode *Child = getChild(i);
1370 TreePatternNode *NewChild = Child->InlinePatternFragments(TP);
1371
1372 assert((Child->getPredicateFns().empty() ||
1373 NewChild->getPredicateFns() == Child->getPredicateFns()) &&
1374 "Non-empty child predicate clobbered!");
1375
1376 setChild(i, NewChild);
1377 }
1378 return this;
1379 }
1380
1381 // Otherwise, we found a reference to a fragment. First, look up its
1382 // TreePattern record.
1383 TreePattern *Frag = TP.getDAGPatterns().getPatternFragment(Op);
1384
1385 // Verify that we are passing the right number of operands.
1386 if (Frag->getNumArgs() != Children.size()) {
1387 TP.error("'" + Op->getName() + "' fragment requires " +
1388 utostr(Frag->getNumArgs()) + " operands!");
1389 return nullptr;
1390 }
1391
1392 TreePatternNode *FragTree = Frag->getOnlyTree()->clone();
1393
1394 TreePredicateFn PredFn(Frag);
1395 if (!PredFn.isAlwaysTrue())
1396 FragTree->addPredicateFn(PredFn);
1397
1398 // Resolve formal arguments to their actual value.
1399 if (Frag->getNumArgs()) {
1400 // Compute the map of formal to actual arguments.
1401 std::map<std::string, TreePatternNode*> ArgMap;
1402 for (unsigned i = 0, e = Frag->getNumArgs(); i != e; ++i)
1403 ArgMap[Frag->getArgName(i)] = getChild(i)->InlinePatternFragments(TP);
1404
1405 FragTree->SubstituteFormalArguments(ArgMap);
1406 }
1407
1408 FragTree->setName(getName());
1409 for (unsigned i = 0, e = Types.size(); i != e; ++i)
1410 FragTree->