3.4.2.4.3. 类型推导
3.4.2.4.3.1. 应用类型限定
在展开PatFrag模式之后,对展开结果要进行类型推导,采纳其中类型限定的约束,以尽早检查是否有类型错误。这由下面的TreePattern:: InferAllTypes()方法来完成(v7.0的InferAllTypes()版本逻辑上与v3.6.1的是一致的,因此不再列出)。
2246 bool TreePattern::
2247 InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) {
2248 if (NamedNodes.empty())
2249 ComputeNamedNodes();
2250
2251 bool MadeChange = true;
2252 while (MadeChange) {
2253 MadeChange = false;
2254 for (unsigned i = 0, e = Trees.size(); i != e; ++i) {
2255 MadeChange |= Trees[i]->ApplyTypeConstraints(*this, false);
2256 MadeChange |= SimplifyTree(Trees[i]);
2257 }
2258
2259 // If there are constraints on our named nodes, apply them.
2260 for (StringMap<SmallVector<TreePatternNode*,1> >::iterator
2261 I = NamedNodes.begin(), E = NamedNodes.end(); I != E; ++I) {
2262 SmallVectorImpl<TreePatternNode*> &Nodes = I->second;
2263
2264 // If we have input named node types, propagate their types to the named
2265 // values here.
2266 if (InNamedTypes) {
2267 if (!InNamedTypes->count(I->getKey())) {
2268 error("Node '" + std::string(I->getKey()) +
2269 "' in output pattern but not input pattern");
2270 return true;
2271 }
2272
2273 const SmallVectorImpl<TreePatternNode*> &InNodes =
2274 InNamedTypes->find(I->getKey())->second;
2275
2276 // The input types should be fully resolved by now.
2277 for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
2278 // If this node is a register class, and it is the root of the pattern
2279 // then we're mapping something onto an input register. We allow
2280 // changing the type of the input register in this case. This allows
2281 // us to match things like:
2282 // def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>;
2283 if (Nodes[i] == Trees[0] && Nodes[i]->isLeaf()) {
2284 DefInit *DI = dyn_cast<DefInit>(Nodes[i]->getLeafValue());
2285 if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
2286 DI->getDef()->isSubClassOf("RegisterOperand")))
2287 continue;
2288 }
2289
2290 assert(Nodes[i]->getNumTypes() == 1 &&
2291 InNodes[0]->getNumTypes() == 1 &&
2292 "FIXME: cannot name multiple result nodes yet");
2293 MadeChange |= Nodes[i]->UpdateNodeType(0, InNodes[0]->getExtType(0),
2294 *this);
2295 }
2296 }
2297
2298 // If there are multiple nodes with the same name, they must all have the
2299 // same type.
2300 if (I->second.size() > 1) {
2301 for (unsigned i = 0, e = Nodes.size()-1; i != e; ++i) {
2302 TreePatternNode *N1 = Nodes[i], *N2 = Nodes[i+1];
2303 assert(N1->getNumTypes() == 1 && N2->getNumTypes() == 1 &&
2304 "FIXME: cannot name multiple result nodes yet");
2305
2306 MadeChange |= N1->UpdateNodeType(0, N2->getExtType(0), *this);
2307 MadeChange |= N2->UpdateNodeType(0, N1->getExtType(0), *this);
2308 }
2309 }
2310 }
2311 }
2312
2313 bool HasUnresolvedTypes = false;
2314 for (unsigned i = 0, e = Trees.size(); i != e; ++i)
2315 HasUnresolvedTypes |= Trees[i]->ContainsUnresolvedType();
2316 return !HasUnresolvedTypes;
2317 }
2248行的NamedNodes是TreePattern的StringMap<SmallVector<TreePatternNode*,1>>类型容器,它用于记录模式树中的具名节点。因此,首先调用下面的函数保存具名节点的名字。
2026 void TreePattern::ComputeNamedNodes() {
2027 for (unsigned i = 0, e = Trees.size(); i != e; ++i)
2028 ComputeNamedNodes(Trees[i]);
2029 }
2030
2031 void TreePattern::ComputeNamedNodes(TreePatternNode *N) {
2032 if (!N->getName().empty())
2033 NamedNodes[N->getName()].push_back(N);
2034
2035 for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
2036 ComputeNamedNodes(N->getChild(i));
2037 }
2033行的N->getName()所返回的Name(类型std::string)是通过setName方法设置的。实际上这些名字都对应形如模式变量node:$name的名字,即name(参考TreePattern::ParseTreePattern(),在最顶层调用中参数OpName是””,最上层的节点是没有名字的)。
2254行循环逐个调用TreePattern树的TreePatternNode::ApplyTypeConstraints()方法,应用相关的类型限定,以期能确定具体的类型。如果该TreePattern树(包括各级节点)类型发生了改变,就返回true,否则返回false。
1653 bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
1654 if (TP.hasError())
1655 return false;
1656
1657 CodeGenDAGPatterns &CDP = TP.getDAGPatterns();
1658 if (isLeaf()) {
1659 if (DefInit *DI = dyn_cast<DefInit>(getLeafValue())) {
1660 // If it's a regclass or something else known, include the type.
1661 bool MadeChange = false;
1662 for (unsigned i = 0, e = Types.size(); i != e; ++i)
1663 MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i,
1664 NotRegisters,
1665 !hasName(), TP), TP);
1666 return MadeChange;
1667 }
1668
1669 if (IntInit *II = dyn_cast<IntInit>(getLeafValue())) {
1670 assert(Types.size() == 1 && "Invalid IntInit");
1671
1672 // Int inits are always integers. :)
1673 bool MadeChange = Types[0].EnforceInteger(TP);
1674
1675 if (!Types[0].isConcrete())
1676 return MadeChange;
1677
1678 MVT::SimpleValueType VT = getType(0);
1679 if (VT == MVT::iPTR || VT == MVT::iPTRAny)
1680 return MadeChange;
1681
1682 unsigned Size = MVT(VT).getSizeInBits();
1683 // Make sure that the value is representable for this type.
1684 if (Size >= 32) return MadeChange;
1685
1686 // Check that the value doesn't use more bits than we have. It must either
1687 // be a sign- or zero-extended equivalent of the original.
1688 int64_t SignBitAndAbove = II->getValue() >> (Size - 1);
1689 if (SignBitAndAbove == -1 || SignBitAndAbove == 0 || SignBitAndAbove == 1)
1690 return MadeChange;
1691
1692 TP.error("Integer value '" + itostr(II->getValue()) +
1693 "' is out of range for type '" + getEnumName(getType(0)) + "'!");
1694 return false;
1695 }
1696 return false;
1697 }
ApplyTypeConstraints()将对子树递归。因此在方法的开头首先处理叶子节点。对于DefInit,这有可能是寄存器,它们可能具有隐含的类型,通过下面的方法来推导这些类型(DefInit代表任意一个def定义)。
1436 static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
1437 bool NotRegisters,
1438 bool Unnamed,
1439 TreePattern &TP) {
1440 // Check to see if this is a register operand.
1441 if (R->isSubClassOf("RegisterOperand")) {
1442 assert(ResNo == 0 && "Regoperand ref only has one result!");
1443 if (NotRegisters)
1444 return EEVT::TypeSet(); // Unknown.
1445 Record *RegClass = R->getValueAsDef("RegClass");
1446 const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
1447 return EEVT::TypeSet(T.getRegisterClass(RegClass).getValueTypes());
1448 }
1449
1450 // Check to see if this is a register or a register class.
1451 if (R->isSubClassOf("RegisterClass")) {
1452 assert(ResNo == 0 && "Regclass ref only has one result!");
1453 // An unnamed register class represents itself as an i32 immediate, for
1454 // example on a COPY_TO_REGCLASS instruction.
1455 if (Unnamed)
1456 return EEVT::TypeSet(MVT::i32, TP);
1457
1458 // In a named operand, the register class provides the possible set of
1459 // types.
1460 if (NotRegisters)
1461 return EEVT::TypeSet(); // Unknown.
1462 const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
1463 return EEVT::TypeSet(T.getRegisterClass(R).getValueTypes());
1464 }
1465
1466 if (R->isSubClassOf("PatFrag")) {
1467 assert(ResNo == 0 && "FIXME: PatFrag with multiple results?");
1468 // Pattern fragment types will be resolved when they are inlined.
1469 return EEVT::TypeSet(); // Unknown.
1470 }
1471
1472 if (R->isSubClassOf("Register")) {
1473 assert(ResNo == 0 && "Registers only produce one result!");
1474 if (NotRegisters)
1475 return EEVT::TypeSet(); // Unknown.
1476 const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
1477 return EEVT::TypeSet(T.getRegisterVTs(R));
1478 }
1479
1480 if (R->isSubClassOf("SubRegIndex")) {
1481 assert(ResNo == 0 && "SubRegisterIndices only produce one result!");
1482 return EEVT::TypeSet(MVT::i32, TP);
1483 }
1484
1485 if (R->isSubClassOf("ValueType")) {
1486 assert(ResNo == 0 && "This node only has one result!");
1487 // An unnamed VTSDNode represents itself as an MVT::Other immediate.
1488 //
1489 // (sext_inreg GPR:$src, i16)
1490 // ~~~
1491 if (Unnamed)
1492 return EEVT::TypeSet(MVT::Other, TP);
1493 // With a name, the ValueType simply provides the type of the named
1494 // variable.
1495 //
1496 // (sext_inreg i32:$src, i16)
1497 // ~~~~~~~~
1498 if (NotRegisters)
1499 return EEVT::TypeSet(); // Unknown.
1500 return EEVT::TypeSet(getValueType(R), TP);
1501 }
1502
1503 if (R->isSubClassOf("CondCode")) {
1504 assert(ResNo == 0 && "This node only has one result!");
1505 // Using a CondCodeSDNode.
1506 return EEVT::TypeSet(MVT::Other, TP);
1507 }
1508
1509 if (R->isSubClassOf("ComplexPattern")) {
1510 assert(ResNo == 0 && "FIXME: ComplexPattern with multiple results?");
1511 if (NotRegisters)
1512 return EEVT::TypeSet(); // Unknown.
1513 return EEVT::TypeSet(TP.getDAGPatterns().getComplexPattern(R).getValueType(),
1514 TP);
1515 }
1516 if (R->isSubClassOf("PointerLikeRegClass")) {
1517 assert(ResNo == 0 && "Regclass can only have one result!");
1518 return EEVT::TypeSet(MVT::iPTR, TP);
1519 }
1520
1521 if (R->getName() == "node" || R->getName() == "srcvalue" ||
1522 R->getName() == "zero_reg") {
1523 // Placeholder.
1524 return EEVT::TypeSet(); // Unknown.
1525 }
1526
1527 if (R->isSubClassOf("Operand"))
1528 return EEVT::TypeSet(getValueType(R->getValueAsDef("Type")));
1529
1530 TP.error("Unknown node flavor used in pattern: " + R->getName());
1531 return EEVT::TypeSet(MVT::Other, TP);
1532 }
名字空间EEVT内的类TypeSet用于表示节点可能具有的类型。它有三个状态:1)空,类型完全未知,可以是任意有效的目标机器类型;2)多个受限类型(比如v4i32 + v4f32),实际类型仅是其中之一;3)只有一个具体类型(具体类型的定义参考SimpleValueType的定义),类型完全已知。
这个方法返回一个封装了可能类型的EEVT::TypeSet对象,并由ApplyTypeConstraints() 1663行处的UpdateNodeType()整合入模式树的类型。这里分别调用了EEVT::TypeSet的三种构造函数:
60 TypeSet() {}
47 EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) {
48 if (VT == MVT::iAny)
49 EnforceInteger(TP);
50 else if (VT == MVT::fAny)
51 EnforceFloatingPoint(TP);
52 else if (VT == MVT::vAny)
53 EnforceVector(TP);
54 else {
55 assert((VT < MVT::LAST_VALUETYPE || VT == MVT::iPTR ||
56 VT == MVT::iPTRAny || VT == MVT::Any) && "Not a concrete type!");
57 TypeVec.push_back(VT);
58 }
59 }
62 EEVT::TypeSet::TypeSet(ArrayRef<MVT::SimpleValueType> VTList) {
63 assert(!VTList.empty() && "empty list?");
64 TypeVec.append(VTList.begin(), VTList.end());
65
66 if (!VTList.empty())
67 assert(VTList[0] != MVT::iAny && VTList[0] != MVT::vAny &&
68 VTList[0] != MVT::fAny);
69
70 // Verify no duplicates.
71 array_pod_sort(TypeVec.begin(), TypeVec.end());
72 assert(std::unique(TypeVec.begin(), TypeVec.end()) == TypeVec.end());
73 }
所谓的隐含类型,实际上都在别处给出了。其中1441行的RegisterOperand类型节点代表存放在寄存器里的操作数,1451行的RegisterClass类型节点代表寄存器的类型(寄存器按可存放值的类型进行分类),1472行的Register类型节点则代表寄存器,1480行的SubRegIndex类型节点则是寄存器索引,1503行的CondCode类型节点代表条件表达式(如SETEQ,SETGT等),而1509与1527行的ComplexPattern与Operand(表示一般操作数)类型节点在定义时必须指定其类型,1516行的PointerLikeRegClass类型节点用于列举可保存指针的寄存器。
回到TreePatternNode::ApplyTypeConstraints(),另一种能推断类型的叶子节点就是IntInit,1673行的EnforceInteger在有已知类型的情况下,滤除非整形类型(如果滤除了某些类型,该方法返回true),而在没有已知类型的情况下,通过目标机器的描述载入整形,如果成功载入,返回true,否则返回false。
TreePatternNode::ApplyTypeConstraints(续)
1699 // special handling for set, which isn't really an SDNode.
1700 if (getOperator()->getName() == "set") {
1701 assert(getNumTypes() == 0 && "Set doesn't produce a value");
1702 assert(getNumChildren() >= 2 && "Missing RHS of a set?");
1703 unsigned NC = getNumChildren();
1704
1705 TreePatternNode *SetVal = getChild(NC-1);
1706 bool MadeChange = SetVal->ApplyTypeConstraints(TP, NotRegisters);
1707
1708 for (unsigned i = 0; i < NC-1; ++i) {
1709 TreePatternNode *Child = getChild(i);
1710 MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
1711
1712 // Types of operands must match.
1713 MadeChange |= Child->UpdateNodeType(0, SetVal->getExtType(i), TP);
1714 MadeChange |= SetVal->UpdateNodeType(i, Child->getExtType(0), TP);
1715 }
1716 return MadeChange;
1717 }
1718
1719 if (getOperator()->getName() == "implicit") {
1720 assert(getNumTypes() == 0 && "Node doesn't produce a value");
1721
1722 bool MadeChange = false;
1723 for (unsigned i = 0; i < getNumChildren(); ++i)
1724 MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
1725 return MadeChange;
1726 }
1727
1728 if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
1729 bool MadeChange = false;
1730
1731 // Apply the result type to the node.
1732 unsigned NumRetVTs = Int->IS.RetVTs.size();
1733 unsigned NumParamVTs = Int->IS.ParamVTs.size();
1734
1735 for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
1736 MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP);
1737
1738 if (getNumChildren() != NumParamVTs + 1) {
1739 TP.error("Intrinsic '" + Int->Name + "' expects " +
1740 utostr(NumParamVTs) + " operands, not " +
1741 utostr(getNumChildren() - 1) + " operands!");
1742 return false;
1743 }
1744
1745 // Apply type info to the intrinsic ID.
1746 MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP);
1747
1748 for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) {
1749 MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters);
1750
1751 MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i];
1752 assert(getChild(i+1)->getNumTypes() == 1 && "Unhandled case");
1753 MadeChange |= getChild(i+1)->UpdateNodeType(0, OpVT, TP);
1754 }
1755 return MadeChange;
1756 }
1757
1758 if (getOperator()->isSubClassOf("SDNode")) {
1759 const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator());
1760
1761 // Check that the number of operands is sane. Negative operands -> varargs.
1762 if (NI.getNumOperands() >= 0 &&
1763 getNumChildren() != (unsigned)NI.getNumOperands()) {
1764 TP.error(getOperator()->getName() + " node requires exactly " +
1765 itostr(NI.getNumOperands()) + " operands!");
1766 return false;
1767 }
1768
1769 bool MadeChange = NI.ApplyTypeConstraints(this, TP);
1770 for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
1771 MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
1772 return MadeChange;
1773 }
1700行的set可以带若干个操作数(不少于2),其中最后的操作数是要设置的值,其余都是设置的目标。因此1708行的循环将设置值与每个设置目标进行融合,任意一个发生变化就返回true。
操作符implicit用于代表其操作数是隐含的,对X86来说,最常见的结构是:(implicit EFLAGS)。Implicit本身不产生值,是没有类型的,因此只需考虑操作数(子树)。
至于固有函数,在TreePattern::ParseTreePattern()的2175行将其ID插入为第一个操作数(但没设置类型),因此在1746行将它设为MVT::iPTR类型。而CodeGenIntrinsic的IS.RetVTs与IS.ParamVTs容器分别保存了该固有函数的返回类型与参数类型。因此,在1735行的循环使用返回类型更新该固有函数的类型(固有函数的类型由返回类型确定)。而1748行的循环实际上是将固有函数声明中对参数类型的描述更新到这棵TreePattern树里。其中1749行调用的ApplyTypeConstraints()方法的定义如下:
254 bool ApplyTypeConstraints(TreePatternNode *N, TreePattern &TP) const {
255 bool MadeChange = false;
256 for (unsigned i = 0, e = TypeConstraints.size(); i != e; ++i)
257 MadeChange |= TypeConstraints[i].ApplyTypeConstraint(N, *this, TP);
258 return MadeChange;
259 }
下一个考虑的类型是SDNode定义。在SDNode定义里我们可以通过SDTypeProfile指定类型。这些类型限定的描述(在SDNodeInfo构造函数里生成SDTypeConstraint实例)保存在对应SDNodeInfo对象的TypeConstraints容器里,通过下面的方法应用它们。
948 bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N,
949 const SDNodeInfo &NodeInfo,
950 TreePattern &TP) const {
951 if (TP.hasError())
952 return false;
953
954 unsigned ResNo = 0; // The result number being referenced.
955 TreePatternNode *NodeToApply = getOperandNum(OperandNo, N, NodeInfo, ResNo);
956
957 switch (ConstraintType) {
958 case SDTCisVT:
959 // Operand must be a particular type.
960 return NodeToApply->UpdateNodeType(ResNo, x.SDTCisVT_Info.VT, TP);
961 case SDTCisPtrTy:
962 // Operand must be same as target pointer type.
963 return NodeToApply->UpdateNodeType(ResNo, MVT::iPTR, TP);
964 case SDTCisInt:
965 // Require it to be one of the legal integer VTs.
966 return NodeToApply->getExtType(ResNo).EnforceInteger(TP);
967 case SDTCisFP:
968 // Require it to be one of the legal fp VTs.
969 return NodeToApply->getExtType(ResNo).EnforceFloatingPoint(TP);
970 case SDTCisVec:
971 // Require it to be one of the legal vector VTs.
972 return NodeToApply->getExtType(ResNo).EnforceVector(TP);
973 case SDTCisSameAs: {
974 unsigned OResNo = 0;
975 TreePatternNode *OtherNode =
976 getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NodeInfo, OResNo);
977 return NodeToApply->UpdateNodeType(ResNo, OtherNode->getExtType(OResNo),TP)|
978 OtherNode->UpdateNodeType(OResNo,NodeToApply->getExtType(ResNo),TP);
979 }
980 case SDTCisVTSmallerThanOp: {
981 // The NodeToApply must be a leaf node that is a VT. OtherOperandNum must
982 // have an integer type that is smaller than the VT.
983 if (!NodeToApply->isLeaf() ||
984 !isa<DefInit>(NodeToApply->getLeafValue()) ||
985 !static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef()
986 ->isSubClassOf("ValueType")) {
987 TP.error(N->getOperator()->getName() + " expects a VT operand!");
988 return false;
989 }
990 MVT::SimpleValueType VT =
991 getValueType(static_cast<DefInit*>(NodeToApply->getLeafValue())->getDef());
992
993 EEVT::TypeSet TypeListTmp(VT, TP);
994
995 unsigned OResNo = 0;
996 TreePatternNode *OtherNode =
997 getOperandNum(x.SDTCisVTSmallerThanOp_Info.OtherOperandNum, N, NodeInfo,
998 OResNo);
999
1000 return TypeListTmp.EnforceSmallerThan(OtherNode->getExtType(OResNo), TP);
1001 }
1002 case SDTCisOpSmallerThanOp: {
1003 unsigned BResNo = 0;
1004 TreePatternNode *BigOperand =
1005 getOperandNum(x.SDTCisOpSmallerThanOp_Info.BigOperandNum, N, NodeInfo,
1006 BResNo);
1007 return NodeToApply->getExtType(ResNo).
1008 EnforceSmallerThan(BigOperand->getExtType(BResNo), TP);
1009 }
1010 case SDTCisEltOfVec: {
1011 unsigned VResNo = 0;
1012 TreePatternNode *VecOperand =
1013 getOperandNum(x.SDTCisEltOfVec_Info.OtherOperandNum, N, NodeInfo,
1014 VResNo);
1015
1016 // Filter vector types out of VecOperand that don't have the right element
1017 // type.
1018 return VecOperand->getExtType(VResNo).
1019 EnforceVectorEltTypeIs(NodeToApply->getExtType(ResNo), TP);
1020 }
1021 case SDTCisSubVecOfVec: {
1022 unsigned VResNo = 0;
1023 TreePatternNode *BigVecOperand =
1024 getOperandNum(x.SDTCisSubVecOfVec_Info.OtherOperandNum, N, NodeInfo,
1025 VResNo);
1026
1027 // Filter vector types out of BigVecOperand that don't have the
1028 // right subvector type.
1029 return BigVecOperand->getExtType(VResNo).
1030 EnforceVectorSubVectorTypeIs(NodeToApply->getExtType(ResNo), TP);
1031 }
1032 case SDTCVecEltisVT: {
1033 return NodeToApply->getExtType(ResNo).
1034 EnforceVectorEltTypeIs(x.SDTCVecEltisVT_Info.VT, TP);
1035 }
1036 case SDTCisSameNumEltsAs: {
1037 unsigned OResNo = 0;
1038 TreePatternNode *OtherNode =
1039 getOperandNum(x.SDTCisSameNumEltsAs_Info.OtherOperandNum,
1040 N, NodeInfo, OResNo);
1041 return OtherNode->getExtType(OResNo).
1042 EnforceVectorSameNumElts(NodeToApply->getExtType(ResNo), TP);
1043 }
1044 }
1045 llvm_unreachable("Invalid ConstraintType!");
1046 }
955行的OperandNo是SDTypeConstraint的成员,来自SDTypeConstraint定义中的OperandNum域,表示该限定应用于第几个参数,而960行及以下出现的x是SDTypeConstraint中的一个union成员,用于保存各种限定的数据。如果指定节点的类型信息发生改变,这个方法返回true,否则返回false(类型冲突将报错)。
回到TreePatternNode::ApplyTypeConstraints(),接下来处理Instruction定义。但我们暂时还没解析Instruction,因此这里不会有这个需求。
TreePatternNode::ApplyTypeConstraints(续)
1907 if (getOperator()->isSubClassOf("ComplexPattern")) {
1908 bool MadeChange = false;
1909
1910 for (unsigned i = 0; i < getNumChildren(); ++i)
1911 MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
1912
1913 return MadeChange;
1914 }
1915
1916 assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
1917
1918 // Node transforms always take one operand.
1919 if (getNumChildren() != 1) {
1920 TP.error("Node transform '" + getOperator()->getName() +
1921 "' requires one operand!");
1922 return false;
1923 }
1924
1925 bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
1926
1927
1928 // If either the output or input of the xform does not have exact
1929 // type info. We assume they must be the same. Otherwise, it is perfectly
1930 // legal to transform from one type to a completely different type.
1931 #if 0
1932 if (!hasTypeSet() || !getChild(0)->hasTypeSet()) {
1933 bool MadeChange = UpdateNodeType(getChild(0)->getExtType(), TP);
1934 MadeChange |= getChild(0)->UpdateNodeType(getExtType(), TP);
1935 return MadeChange;
1936 }
1937 #endif
1938 return MadeChange;
1939 }
对ComplexPattern与SDNodeXForm定义的处理都很简单,分别对它们的操作数应用类型限定。
V7.0的处理
V7.0版本的TreePatternNode::ApplyTypeConstraints()方法是这样处理的: 2224 bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { 2225 if (TP.hasError()) 2226 return false; 2227 2228 CodeGenDAGPatterns &CDP = TP.getDAGPatterns(); 2229 if (isLeaf()) { 2230 if (DefInit *DI = dyn_cast<DefInit>(getLeafValue())) { 2231 // If it's a regclass or something else known, include the type. 2232 bool MadeChange = false; 2233 for (unsigned i = 0, e = Types.size(); i != e; ++i) 2234 MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i, 2235 NotRegisters, 2236 !hasName(), TP), TP); 2237 return MadeChange; 2238 } 2239 2240 if (IntInit *II = dyn_cast<IntInit>(getLeafValue())) { 2241 assert(Types.size() == 1 && "Invalid IntInit"); 2242 2243 // Int inits are always integers. :) 2244 bool MadeChange = TP.getInfer().EnforceInteger(Types[0]); 2245 2246 if (!TP.getInfer().isConcrete(Types[0], false)) 2247 return MadeChange; 2248 2249 ValueTypeByHwMode VVT = TP.getInfer().getConcrete(Types[0], false); 2250 for (auto &P : VVT) { 2251 MVT::SimpleValueType VT = P.second.SimpleTy; 2252 if (VT == MVT::iPTR || VT == MVT::iPTRAny) 2253 continue; 2254 unsigned Size = MVT(VT).getSizeInBits(); 2255 // Make sure that the value is representable for this type. 2256 if (Size >= 32) 2257 continue; 2258 // Check that the value doesn't use more bits than we have. It must 2259 // either be a sign- or zero-extended equivalent of the original. 2260 int64_t SignBitAndAbove = II->getValue() >> (Size - 1); 2261 if (SignBitAndAbove == -1 || SignBitAndAbove == 0 || 2262 SignBitAndAbove == 1) 2263 continue; 2264 2265 TP.error("Integer value '" + Twine(II->getValue()) + 2266 "' is out of range for type '" + getEnumName(VT) + "'!"); 2267 break; 2268 } 2269 return MadeChange; 2270 } 2271 2272 return false; 2273 } TreePatternNode::ApplyTypeConstraints()根据TreePatternNode实例的定义采取不同的处理。首先是叶子节点,它是从下面对dag定义处理的过程中递归进来的。这主要考虑两种情况,其他情形都不处理(2272行返回false)。第一种是def定义的情形。那么会根据该定义的Record对象,由getImplicitType()来确定这个定义是否有要应用的隐含类型(这是getImplicitType()唯一使用的地方)。 TreePatternNode::ApplyTypeConstraints() 2033行的循环是将getImplicitType()返回的类型作为约束应用到这个TreePatternNode的(多个)结果类型上。 参数NotRegisters如果是true,表示不考虑寄存器约束条件。在当前上下文里,NotRegisters是false,只有后面在MatcherGen的上下文里它才是true。 参数Unnamed用于在类似(COPY_TO_REGCLASS GPR:$src, F8RC)这样的定义中选择类型,当它为true时,getImplicitType()返回匿名dag操作数(即F8RC)的类型;否则返回具名dag操作数(即GPR:$src)的类型。 1991 static TypeSetByHwMode getImplicitType(Record *R, unsigned ResNo, 1992 bool NotRegisters, 1993 bool Unnamed, 1994 TreePattern &TP) { 1995 CodeGenDAGPatterns &CDP = TP.getDAGPatterns(); 1996 1997 // Check to see if this is a register operand. 1998 if (R->isSubClassOf("RegisterOperand")) { 1999 assert(ResNo == 0 && "Regoperand ref only has one result!"); 2000 if (NotRegisters) 2001 return TypeSetByHwMode(); // Unknown. 2002 Record *RegClass = R->getValueAsDef("RegClass"); 2003 const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); 2004 return TypeSetByHwMode(T.getRegisterClass(RegClass).getValueTypes()); 2005 } 2006 2007 // Check to see if this is a register or a register class. 2008 if (R->isSubClassOf("RegisterClass")) { 2009 assert(ResNo == 0 && "Regclass ref only has one result!"); 2010 // An unnamed register class represents itself as an i32 immediate, for 2011 // example on a COPY_TO_REGCLASS instruction. 2012 if (Unnamed) 2013 return TypeSetByHwMode(MVT::i32); 2014 2015 // In a named operand, the register class provides the possible set of 2016 // types. 2017 if (NotRegisters) 2018 return TypeSetByHwMode(); // Unknown. 2019 const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); 2020 return TypeSetByHwMode(T.getRegisterClass(R).getValueTypes()); 2021 } 2022 2023 if (R->isSubClassOf("PatFrags")) { 2024 assert(ResNo == 0 && "FIXME: PatFrag with multiple results?"); 2025 // Pattern fragment types will be resolved when they are inlined. 2026 return TypeSetByHwMode(); // Unknown. 2027 } 2028 2029 if (R->isSubClassOf("Register")) { 2030 assert(ResNo == 0 && "Registers only produce one result!"); 2031 if (NotRegisters) 2032 return TypeSetByHwMode(); // Unknown. 2033 const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); 2034 return TypeSetByHwMode(T.getRegisterVTs(R)); 2035 } 2036 2037 if (R->isSubClassOf("SubRegIndex")) { 2038 assert(ResNo == 0 && "SubRegisterIndices only produce one result!"); 2039 return TypeSetByHwMode(MVT::i32); 2040 } 2041 2042 if (R->isSubClassOf("ValueType")) { 2043 assert(ResNo == 0 && "This node only has one result!"); 2044 // An unnamed VTSDNode represents itself as an MVT::Other immediate. 2045 // 2046 // (sext_inreg GPR:$src, i16) 2047 // ~~~ 2048 if (Unnamed) 2049 return TypeSetByHwMode(MVT::Other); 2050 // With a name, the ValueType simply provides the type of the named 2051 // variable. 2052 // 2053 // (sext_inreg i32:$src, i16) 2054 // ~~~~~~~~ 2055 if (NotRegisters) 2056 return TypeSetByHwMode(); // Unknown. 2057 const CodeGenHwModes &CGH = CDP.getTargetInfo().getHwModes(); 2058 return TypeSetByHwMode(getValueTypeByHwMode(R, CGH)); 2059 } 2060 2061 if (R->isSubClassOf("CondCode")) { 2062 assert(ResNo == 0 && "This node only has one result!"); 2063 // Using a CondCodeSDNode. 2064 return TypeSetByHwMode(MVT::Other); 2065 } 2066 2067 if (R->isSubClassOf("ComplexPattern")) { 2068 assert(ResNo == 0 && "FIXME: ComplexPattern with multiple results?"); 2069 if (NotRegisters) 2070 return TypeSetByHwMode(); // Unknown. 2071 return TypeSetByHwMode(CDP.getComplexPattern(R).getValueType()); 2072 } 2073 if (R->isSubClassOf("PointerLikeRegClass")) { 2074 assert(ResNo == 0 && "Regclass can only have one result!"); 2075 TypeSetByHwMode VTS(MVT::iPTR); 2076 TP.getInfer().expandOverloads(VTS); 2077 return VTS; 2078 } 2079 2080 if (R->getName() == "node" || R->getName() == "srcvalue" || 2081 R->getName() == "zero_reg") { 2082 // Placeholder. 2083 return TypeSetByHwMode(); // Unknown. 2084 } 2085 2086 if (R->isSubClassOf("Operand")) { 2087 const CodeGenHwModes &CGH = CDP.getTargetInfo().getHwModes(); 2088 Record *T = R->getValueAsDef("Type"); 2089 return TypeSetByHwMode(getValueTypeByHwMode(T, CGH)); 2090 } 2091 2092 TP.error("Unknown node flavor used in pattern: " + R->getName()); 2093 return TypeSetByHwMode(MVT::Other); 2094 } getImplicitType()的逻辑并不复杂。比如,对涉及寄存器的定义与ComplexPattern定义,如果NotRegisters是true,返回空的TypeSetByHwMode类型。UpdateNodeType()将忽略它,返回false。其他定义的处理不再解释。 第二种情形就是整数字面量(IntInit),这个定义生成的TreePatternNode实例总是只有一个返回类型。在2244行首先通过TypeInfer::EnforceInteger()获取其中的整数类型: 363 bool TypeInfer::EnforceInteger(TypeSetByHwMode &Out) { 364 ValidateOnExit _1(Out, *this); 365 if (TP.hasError()) 366 return false; 367 if (!Out.empty()) 368 return Out.constrain(isIntegerOrPtr); 369 370 return Out.assign_if(getLegalTypes(), isIntegerOrPtr); 371 } 368行的constrain()是另一个模板版本。连同assign_if(),它们的定义如下: 147 template <typename Predicate> 148 bool TypeSetByHwMode::constrain(Predicate P) { 149 bool Changed = false; 150 for (auto &I : *this) 151 Changed |= berase_if(I.second, [&P](MVT VT) { return !P(VT); }); 152 return Changed; 153 } 154 155 template <typename Predicate> 156 bool TypeSetByHwMode::assign_if(const TypeSetByHwMode &VTS, Predicate P) { 157 assert(empty()); 158 for (const auto &I : VTS) { 159 SetType &S = getOrCreate(I.first); 160 for (auto J : I.second) 161 if (P(J)) 162 S.insert(J); 163 } 164 return !empty(); 165 } TreePatternNode::ApplyTypeConstraints() 2246行的TypeInfer::isConcrete()检查每个硬件模式是否都只有一个关联类型(如果第二个参数是true,允许有硬件模式没有关联类型,这里是false)。如果不满足条件,提前退出。否则,继续在2249行获取这些类型到VVT。在2250行循环检查这个IntInit值的有效性(是否对类型溢出)。 2275~2302行处理固有函数,我们跳过。 TreePatternNode::ApplyTypeConstraints(续) 2275 if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) { 2276 bool MadeChange = false; 2277 2278 // Apply the result type to the node. 2279 unsigned NumRetVTs = Int->IS.RetVTs.size(); 2280 unsigned NumParamVTs = Int->IS.ParamVTs.size(); 2281 2282 for (unsigned i = 0, e = NumRetVTs; i != e; ++i) 2283 MadeChange |= UpdateNodeType(i, Int->IS.RetVTs[i], TP); 2284 2285 if (getNumChildren() != NumParamVTs + 1) { 2286 TP.error("Intrinsic '" + Int->Name + "' expects " + Twine(NumParamVTs) + 2287 " operands, not " + Twine(getNumChildren() - 1) + " operands!"); 2288 return false; 2289 } 2290 2291 // Apply type info to the intrinsic ID. 2292 MadeChange |= getChild(0)->UpdateNodeType(0, MVT::iPTR, TP); 2293 2294 for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i) { 2295 MadeChange |= getChild(i+1)->ApplyTypeConstraints(TP, NotRegisters); 2296 2297 MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i]; 2298 assert(getChild(i+1)->getNumTypes() == 1 && "Unhandled case"); 2299 MadeChange |= getChild(i+1)->UpdateNodeType(0, OpVT, TP); 2300 } 2301 return MadeChange; 2302 } 2303 2304 if (getOperator()->isSubClassOf("SDNode")) { 2305 const SDNodeInfo &NI = CDP.getSDNodeInfo(getOperator()); 2306 2307 // Check that the number of operands is sane. Negative operands -> varargs. 2308 if (NI.getNumOperands() >= 0 && 2309 getNumChildren() != (unsigned)NI.getNumOperands()) { 2310 TP.error(getOperator()->getName() + " node requires exactly " + 2311 Twine(NI.getNumOperands()) + " operands!"); 2312 return false; 2313 } 2314 2315 bool MadeChange = false; 2316 for (unsigned i = 0, e = getNumChildren(); i != e; ++i) 2317 MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); 2318 MadeChange |= NI.ApplyTypeConstraints(this, TP); 2319 return MadeChange; 2320 } 对于SDNode来说,2308~2313行检查TreePatternNode(使用处)的子节点数与SDNodeInfo(定义处)中操作数个数一致。在2316行循环中,2318行的SDNodeInfo::ApplyTypeConstraints()是对TreePatternNode实例应用SDNode定义里的类型限定。具体细节与v3.6.1版本的基本相同。 同样,这里先跳过对Instruction定义的处理。 TreePatternNode::ApplyTypeConstraints(续) 2454 if (getOperator()->isSubClassOf("ComplexPattern")) { 2455 bool MadeChange = false; 2456 2457 for (unsigned i = 0; i < getNumChildren(); ++i) 2458 MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters); 2459 2460 return MadeChange; 2461 } 2462 2463 assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!"); 2464 2465 // Node transforms always take one operand. 2466 if (getNumChildren() != 1) { 2467 TP.error("Node transform '" + getOperator()->getName() + 2468 "' requires one operand!"); 2469 return false; 2470 } 2471 2472 bool MadeChange = getChild(0)->ApplyTypeConstraints(TP, NotRegisters); 2473 return MadeChange; 2474 } |