3.4.2.5.3. ApplyTypeConstraints对Instruction的处理
前面看TreePatternNode::ApplyTypeConstraints()方法时,我们跳过了模式操作符是Instruction部分,现在是时候看一下,它到底对作为操作符的Instruction做了什么(v7.0在这部分的处理也是相同的)。
TreePatternNode::ApplyTypeConstraints(续)
1775 if (getOperator()->isSubClassOf("Instruction")) {
1776 const DAGInstruction &Inst = CDP.getInstruction(getOperator());
1777 CodeGenInstruction &InstInfo =
1778 CDP.getTargetInfo().getInstruction(getOperator());
1779
1780 bool MadeChange = false;
1781
1782 // Apply the result types to the node, these come from the things in the
1783 // (outs) list of the instruction.
1784 unsigned NumResultsToAdd = std::min(InstInfo.Operands.NumDefs,
1785 Inst.getNumResults());
1786 for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo)
1787 MadeChange |= UpdateNodeTypeFromInst(ResNo, Inst.getResult(ResNo), TP);
1788
1789 // If the instruction has implicit defs, we apply the first one as a result.
1790 // FIXME: This sucks, it should apply all implicit defs.
1791 if (!InstInfo.ImplicitDefs.empty()) {
1792 unsigned ResNo = NumResultsToAdd;
1793
1794 // FIXME: Generalize to multiple possible types and multiple possible
1795 // ImplicitDefs.
1796 MVT::SimpleValueType VT =
1797 InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo());
1798
1799 if (VT != MVT::Other)
1800 MadeChange |= UpdateNodeType(ResNo, VT, TP);
1801 }
1802
1803 // If this is an INSERT_SUBREG, constrain the source and destination VTs to
1804 // be the same.
1805 if (getOperator()->getName() == "INSERT_SUBREG") {
1806 assert(getChild(0)->getNumTypes() == 1 && "FIXME: Unhandled");
1807 MadeChange |= UpdateNodeType(0, getChild(0)->getExtType(0), TP);
1808 MadeChange |= getChild(0)->UpdateNodeType(0, getExtType(0), TP);
1809 } else if (getOperator()->getName() == "REG_SEQUENCE") {
1810 // We need to do extra, custom typechecking for REG_SEQUENCE since it is
1811 // variadic.
1812
1813 unsigned NChild = getNumChildren();
1814 if (NChild < 3) {
1815 TP.error("REG_SEQUENCE requires at least 3 operands!");
1816 return false;
1817 }
1818
1819 if (NChild % 2 == 0) {
1820 TP.error("REG_SEQUENCE requires an odd number of operands!");
1821 return false;
1822 }
1823
1824 if (!isOperandClass(getChild(0), "RegisterClass")) {
1825 TP.error("REG_SEQUENCE requires a RegisterClass for first operand!");
1826 return false;
1827 }
1828
1829 for (unsigned I = 1; I < NChild; I += 2) {
1830 TreePatternNode *SubIdxChild = getChild(I + 1);
1831 if (!isOperandClass(SubIdxChild, "SubRegIndex")) {
1832 TP.error("REG_SEQUENCE requires a SubRegIndex for operand " +
1833 itostr(I + 1) + "!");
1834 return false;
1835 }
1836 }
1837 }
在1784行,InstInfo.Operands.NumDefs是输出操作数的个数,而1785行的Inst.getNumResults()则是set的目标操作数个数。对于输出操作数,需要下面的方法来更新其类型信息(下面看到对于输入操作数也是一样的)。
1051 bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo,
1052 Record *Operand,
1053 TreePattern &TP) {
1054 // The 'unknown' operand indicates that types should be inferred from the
1055 // context.
1056 if (Operand->isSubClassOf("unknown_class"))
1057 return false;
1058
1059 // The Operand class specifies a type directly.
1060 if (Operand->isSubClassOf("Operand"))
1061 return UpdateNodeType(ResNo, getValueType(Operand->getValueAsDef("Type")),
1062 TP); <-- v7.0删除
Record *R = Operand->getValueAsDef("Type"); <-- v7.0增加
const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
return UpdateNodeType(ResNo, getValueTypeByHwMode(R, T.getHwModes()), TP);
1063
1064 // PointerLikeRegClass has a type that is determined at runtime.
1065 if (Operand->isSubClassOf("PointerLikeRegClass"))
1066 return UpdateNodeType(ResNo, MVT::iPTR, TP);
1067
1068 // Both RegisterClass and RegisterOperand operands derive their types from a
1069 // register class def.
1070 Record *RC = nullptr;
1071 if (Operand->isSubClassOf("RegisterClass"))
1072 RC = Operand;
1073 else if (Operand->isSubClassOf("RegisterOperand"))
1074 RC = Operand->getValueAsDef("RegClass");
1075
1076 assert(RC && "Unknown operand type");
1077 CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo();
1078 return UpdateNodeType(ResNo, Tgt.getRegisterClass(RC).getValueTypes(), TP);
1079 }
1791行的ImplicitDefs来自Instruction定义的Defs域,即被修改的非参数寄存器(对X86,比如EFLAG)。如果指令有隐含结果,通过下面的方法,尝试通过目标机器的信息,获取隐含结果寄存器的类型信息。
365 MVT::SimpleValueType CodeGenInstruction::
366 HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
367 if (ImplicitDefs.empty()) return MVT::Other;
368
369 // Check to see if the first implicit def has a resolvable type.
370 Record *FirstImplicitDef = ImplicitDefs[0];
371 assert(FirstImplicitDef->isSubClassOf("Register"));
372 const std::vector<MVT::SimpleValueType> &RegVTs =
373 TargetInfo.getRegisterVTs(FirstImplicitDef);
374 if (RegVTs.size() == 1 && RegVTs[0].isSimple()) <-- v7.0增加
375 return RegVTs[0].getSimple().SimpleTy; <-- v7.0增加
376 return MVT::Other;
377 }
参考GetNumNodeResults()的1196行分支,对Instruction类型操作符结果个数的计算。因此,在1784行的NumResultsToAdd就是放置隐含结果的起始索引。
1805行的INSERT_SUBREG与1809行的REG_SEQUENCE在TargetOpcode.h中有对应的枚举值,对这些枚举值的注释可以帮助我们理解上面的代码(v7.0中这些枚举值定义在TargetOpcode.h里,它们的定义在TargetOpcodes.def中通过HANDLE_TARGET_OPCODE宏自动生成)。
43 /// INSERT_SUBREG - This instruction takes three operands: a register that
44 /// has subregisters, a register providing an insert value, and a
45 /// subregister index. It returns the value of the first register with the
46 /// value of the second register inserted. The first register is often
47 /// defined by an IMPLICIT_DEF, because it is commonly used to implement
48 /// anyext operations on target architectures which support it.
49 INSERT_SUBREG = 7,
注释是这样说的:这条指令有3个操作数:一个有子寄存器的寄存器,一个提供插入值的寄存器,以及一个子寄存器索引。它返回插入第二个寄存器值的第一个寄存器。第一个寄存器通常由IMPLICIT_DEF定义,因为它通常用于在支持anyext操作的目标架构上实现anyext。
71 /// REG_SEQUENCE - This variadic instruction is used to form a register that
72 /// represents a consecutive sequence of sub-registers. It's used as a
73 /// register coalescing / allocation aid and must be eliminated before code
74 /// emission.
75 // In SDNode form, the first operand encodes the register class created by
76 // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index
77 // pair. Once it has been lowered to a MachineInstr, the regclass operand
78 // is no longer present.
79 /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
80 /// After register coalescing references of v1024 should be replace with
81 /// v1027:3, v1025 with v1027:4, etc.
82 REG_SEQUENCE = 12,
注释是这样说的:这是用于构成表示一个连续子寄存器序列的寄存器的可变数目参数指令。它用作寄存器合并/分配的一个辅助,并且在代码发布前必须消除。在SDNode形式里,第一个操作数编码了由REG_SEQUENCE创建的寄存器类,后续是命名了一个虚拟寄存器+子寄存器索引的各个对。一旦被降级到MachineInstr,regclass操作数就不再出现了。比如v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5。在寄存器合并后,v1024的引用由v1027:3替换,v1025由v1027:4替换,等等。
接下来1840行循环处理所有的输入、输出操作数。注意1857行的ChildResNo永远是0。1839行的ChildNo用于统计已经处理的子节点(树)的个数。
TreePatternNode::ApplyTypeConstraints(续)
1839 unsigned ChildNo = 0;
1840 for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
1841 Record *OperandNode = Inst.getOperand(i);
1842
1843 // If the instruction expects a predicate or optional def operand, we
1844 // codegen this by setting the operand to it's default value if it has a
1845 // non-empty DefaultOps field.
1846 if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
1847 !CDP.getDefaultOperand(OperandNode).DefaultOps.empty())
1848 continue;
1849
1850 // Verify that we didn't run out of provided operands.
1851 if (ChildNo >= getNumChildren()) {
1852 emitTooFewOperandsError(TP, getOperator()->getName(), getNumChildren());
1853 return false;
1854 }
1855
1856 TreePatternNode *Child = getChild(ChildNo++);
1857 unsigned ChildResNo = 0; // Instructions always use res #0 of their op.
1858
1859 // If the operand has sub-operands, they may be provided by distinct
1860 // child patterns, so attempt to match each sub-operand separately.
1861 if (OperandNode->isSubClassOf("Operand")) {
1862 DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
1863 if (unsigned NumArgs = MIOpInfo->getNumArgs()) {
1864 // But don't do that if the whole operand is being provided by
1865 // a single ComplexPattern-related Operand.
1866
1867 if (Child->getNumMIResults(CDP) < NumArgs) {
1868 // Match first sub-operand against the child we already have.
1869 Record *SubRec = cast<DefInit>(MIOpInfo->getArg(0))->getDef();
1870 MadeChange |=
1871 Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP);
1872
1873 // And the remaining sub-operands against subsequent children.
1874 for (unsigned Arg = 1; Arg < NumArgs; ++Arg) {
1875 if (ChildNo >= getNumChildren()) {
1876 emitTooFewOperandsError(TP, getOperator()->getName(),
1877 getNumChildren());
1878 return false;
1879 }
1880 Child = getChild(ChildNo++);
1881
1882 SubRec = cast<DefInit>(MIOpInfo->getArg(Arg))->getDef();
1883 MadeChange |=
1884 Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP);
1885 }
1886 continue;
1887 }
1888 }
1889 }
1890
1891 // If we didn't match by pieces above, attempt to match the whole
1892 // operand now.
1893 MadeChange |= Child->UpdateNodeTypeFromInst(ChildResNo, OperandNode, TP);
1894 }
1895
1896 if (!InstInfo.Operands.isVariadic && ChildNo != getNumChildren()) {
1897 emitTooManyOperandsError(TP, getOperator()->getName(),
1898 ChildNo, getNumChildren());
1899 return false;
1900 }
1901
1902 for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
1903 MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
1904 return MadeChange;
1905 }
1874行的循环处理Operand类型操作数所包含的子操作数。显而易见,如果具有子操作数,在模式里也必须有描述它们的部分,除非操作数是可变数目的(实际上,对于非常复杂的输入、输出操作数,在模式的描述中通常使用ComplexPattern定义来对应,通过特定的函数来处理,就像前面的例子bmi_andn)。
3.4.2.5.4. 构建PatternToMatch实例
在解析完所有的Instruction定义后,在下面的3111行循环遍历所产生的DAGInstruction实例,为它们生成PatternToMatch实例。这些PatternToMatch实例将是下面生成Matcher对象的依据。
TreePatternNode::ParseInstructions(续)
3110 // If we can, convert the instructions to be patterns that are matched!
3111 for (std::map<Record*, DAGInstruction, LessRecordByID>::iterator II =
3112 Instructions.begin(),
3113 E = Instructions.end(); II != E; ++II) {
3114 DAGInstruction &TheInst = II->second;
3115 TreePattern *I = TheInst.getPattern();
3116 if (!I) continue; // No pattern.
3117
3118 // FIXME: Assume only the first tree is the pattern. The others are clobber
3119 // nodes.
3120 TreePatternNode *Pattern = I->getTree(0);
3121 TreePatternNode *SrcPattern;
3122 if (Pattern->getOperator()->getName() == "set") {
3123 SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone();
3124 } else{
3125 // Not a set (store or something?)
3126 SrcPattern = Pattern;
3127 }
3128
3129 Record *Instr = II->first;
3130 AddPatternToMatch(I,
3131 PatternToMatch(Instr,
3132 Instr->getValueAsListInit("Predicates"),
3133 SrcPattern,
3134 TheInst.getResultPattern(),
3135 TheInst.getImpResults(),
3136 Instr->getValueAsInt("AddedComplexity"),
3137 Instr->getID()));
3138 }
3139 }
PatternToMatch的相关定义在文件CodeGenDAGPatterns.h,它包含了这些数据成员:
679 class PatternToMatch {
680 public:
681 PatternToMatch(Record *srcrecord, ListInit *preds,
682 TreePatternNode *src, TreePatternNode *dst,
683 const std::vector<Record*> &dstregs,
684 int complexity, unsigned uid, unsigned setmode = 0) <-- v7.0增加
685 : SrcRecord(srcrecord), Predicates(preds), SrcPattern(src), DstPattern(dst),
686 Dstregs(dstregs), AddedComplexity(complexity), ID(uid), ForceMode(setmode) {} <-- v7.0增加
687
688 Record *SrcRecord; // Originating Record for the pattern.
689 ListInit *Predicates; // Top level predicate conditions to match.
690 TreePatternNode *SrcPattern; // Source pattern to match.
691 TreePatternNode *DstPattern; // Resulting pattern.
692 std::vector<Record*> Dstregs; // Physical register defs being matched.
693 int AddedComplexity; // Add to matching pattern complexity.
694 unsigned ID; // Unique ID for the record.
unsigned ForceMode; // Force this mode in type inference when set. <-- v7.0增加
注意3133行的SrcPattern,如果匹配模式的操作数的set,SrcPattern就是代表其目标操作数的模式树,否则就是匹配模式本身。然后,这个PatternToMatch实例由AddPatternToMatch方法进行有效性检查,并最终加入容器PatternsToMatch里(类型std::vector<PatternToMatch>)。
3163 void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern,
3164 const PatternToMatch &PTM) {
3165 // Do some sanity checking on the pattern we're about to match.
3166 std::string Reason;
3167 if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this)) {
3168 PrintWarning(Pattern->getRecord()->getLoc(),
3169 Twine("Pattern can never match: ") + Reason);
3170 return;
3171 }
3172
3173 // If the source pattern's root is a complex pattern, that complex pattern
3174 // must specify the nodes it can potentially match.
3175 if (const ComplexPattern *CP =
3176 PTM.getSrcPattern()->getComplexPatternInfo(*this))
3177 if (CP->getRootNodes().empty())
3178 Pattern->error("ComplexPattern at root must specify list of opcodes it"
3179 " could match");
3180
3181
3182 // Find all of the named values in the input and output, ensure they have the
3183 // same type.
3184 std::map<std::string, NameRecord> SrcNames, DstNames;
3185 FindNames(PTM.getSrcPattern(), SrcNames, Pattern);
3186 FindNames(PTM.getDstPattern(), DstNames, Pattern);
3187
3188 // Scan all of the named values in the destination pattern, rejecting them if
3189 // they don't exist in the input pattern.
3190 for (std::map<std::string, NameRecord>::iterator
3191 I = DstNames.begin(), E = DstNames.end(); I != E; ++I) {
3192 if (SrcNames[I->first].first == nullptr)
3193 Pattern->error("Pattern has input without matching name in output: $" +
3194 I->first);
3195 }
3196
3197 // Scan all of the named values in the source pattern, rejecting them if the
3198 // name isn't used in the dest, and isn't used to tie two values together.
3199 for (std::map<std::string, NameRecord>::iterator
3200 I = SrcNames.begin(), E = SrcNames.end(); I != E; ++I)
3201 if (DstNames[I->first].first == nullptr && SrcNames[I->first].second == 1)
3202 Pattern->error("Pattern has dead named input: $" + I->first);
3203
3204 PatternsToMatch.push_back(PTM);
3205 }
首先检查SrcPattern是否符合目标机器的要求。实际上,canPatternMatch()基本上的工作就是检查符合交换律的操作符是否将立即数放在了左手侧(LHS),这是SelectionDAG要求的规范形式。
1957 bool TreePatternNode::canPatternMatch(std::string &Reason,
1958 const CodeGenDAGPatterns &CDP) {
1959 if (isLeaf()) return true;
1960
1961 for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
1962 if (!getChild(i)->canPatternMatch(Reason, CDP))
1963 return false;
1964
1965 // If this is an intrinsic, handle cases that would make it not match. For
1966 // example, if an operand is required to be an immediate.
1967 if (getOperator()->isSubClassOf("Intrinsic")) {
1968 // TODO:
1969 return true;
1970 }
1971
1972 if (getOperator()->isSubClassOf("ComplexPattern"))
1973 return true;
1974
1975 // If this node is a commutative operator, check that the LHS isn't an
1976 // immediate.
1977 const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator());
1978 bool isCommIntrinsic = isCommutativeIntrinsic(CDP);
1979 if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
1980 // Scan all of the operands of the node and make sure that only the last one
1981 // is a constant node, unless the RHS also is.
1982 if (!OnlyOnRHSOfCommutative(getChild(getNumChildren()-1))) {
1983 bool Skip = isCommIntrinsic ? 1 : 0; // First operand is intrinsic id.
1984 for (unsigned i = Skip, e = getNumChildren()-1; i != e; ++i)
1985 if (OnlyOnRHSOfCommutative(getChild(i))) {
1986 Reason="Immediate value must be on the RHS of commutative operators!";
1987 return false;
1988 }
1989 }
1990 }
1991
1992 return true;
1993 }
接下来检查ComplexPattern类型节点是否指定了匹配的目标对象。而源模板与目标模板是否具有相同的具名操作数(注意这里的源模板与目标模板只是PatternsToMatch里的命名而已,实际上它们都来自该Instruction定义的Pattern部分)。
通过检查的PatternToMatch对象被放入PatternsToMatch容器,表示这个对象应该能匹配得上。
V7.0的处理
V7.0 TreePatternNode::ParseInstructions()最后部分改动颇大的。不过目的都是遍历已有的DAGInstruction对象,构建PatternToMatch实例。 3694 // If we can, convert the instructions to be patterns that are matched! 3695 for (auto &Entry : Instructions) { 3696 Record *Instr = Entry.first; 3697 DAGInstruction &TheInst = Entry.second; 3698 TreePatternNodePtr SrcPattern = TheInst.getSrcPattern(); 3699 TreePatternNodePtr ResultPattern = TheInst.getResultPattern(); 3700 3701 if (SrcPattern && ResultPattern) { 3702 TreePattern Pattern(Instr, SrcPattern, true, *this); 3703 TreePattern Result(Instr, ResultPattern, false, *this); 3704 ParseOnePattern(Instr, Pattern, Result, TheInst.getImpResults()); 3705 } 3706 } 3707 } 首先,将指令的匹配模式与结果模式构建为TreePattern实例。接着,在下面的方法中内联片段并进行类型推导。4041行的PatternRewriter是在构造CodeGenDAGPatterns时传入的,当前为null。 3967 void CodeGenDAGPatterns::ParseOnePattern(Record *TheDef, 3968 TreePattern &Pattern, TreePattern &Result, 3969 const std::vector<Record *> &InstImpResults) { 3970 3971 // Inline pattern fragments and expand multiple alternatives. 3972 Pattern.InlinePatternFragments(); 3973 Result.InlinePatternFragments(); 3974 3975 if (Result.getNumTrees() != 1) 3976 Result.error("Cannot use multi-alternative fragments in result pattern!"); 3977 3978 // Infer types. 3979 bool IterateInference; 3980 bool InferredAllPatternTypes, InferredAllResultTypes; 3981 do { 3982 // Infer as many types as possible. If we cannot infer all of them, we 3983 // can never do anything with this pattern: report it to the user. 3984 InferredAllPatternTypes = 3985 Pattern.InferAllTypes(&Pattern.getNamedNodesMap()); 3986 3987 // Infer as many types as possible. If we cannot infer all of them, we 3988 // can never do anything with this pattern: report it to the user. 3989 InferredAllResultTypes = 3990 Result.InferAllTypes(&Pattern.getNamedNodesMap()); 3991 3992 IterateInference = false; 3993 3994 // Apply the type of the result to the source pattern. This helps us 3995 // resolve cases where the input type is known to be a pointer type (which 3996 // is considered resolved), but the result knows it needs to be 32- or 3997 // 64-bits. Infer the other way for good measure. 3998 for (auto T : Pattern.getTrees()) 3999 for (unsigned i = 0, e = std::min(Result.getOnlyTree()->getNumTypes(), 4000 T->getNumTypes()); 4001 i != e; ++i) { 4002 IterateInference |= T->UpdateNodeType( 4003 i, Result.getOnlyTree()->getExtType(i), Result); 4004 IterateInference |= Result.getOnlyTree()->UpdateNodeType( 4005 i, T->getExtType(i), Result); 4006 } 4007 4008 // If our iteration has converged and the input pattern's types are fully 4009 // resolved but the result pattern is not fully resolved, we may have a 4010 // situation where we have two instructions in the result pattern and 4011 // the instructions require a common register class, but don't care about 4012 // what actual MVT is used. This is actually a bug in our modelling: 4013 // output patterns should have register classes, not MVTs. 4014 // 4015 // In any case, to handle this, we just go through and disambiguate some 4016 // arbitrary types to the result pattern's nodes. 4017 if (!IterateInference && InferredAllPatternTypes && 4018 !InferredAllResultTypes) 4019 IterateInference = 4020 ForceArbitraryInstResultType(Result.getTree(0).get(), Result); 4021 } while (IterateInference); 4022 4023 // Verify that we inferred enough types that we can do something with the 4024 // pattern and result. If these fire the user has to add type casts. 4025 if (!InferredAllPatternTypes) 4026 Pattern.error("Could not infer all types in pattern!"); 4027 if (!InferredAllResultTypes) { 4028 Pattern.dump(); 4029 Result.error("Could not infer all types in pattern result!"); 4030 } 4031 4032 // Promote xform function to be an explicit node wherever set. 4033 TreePatternNodePtr DstShared = PromoteXForms(Result.getOnlyTree()); 4034 4035 TreePattern Temp(Result.getRecord(), DstShared, false, *this); 4036 Temp.InferAllTypes(); 4037 4038 ListInit *Preds = TheDef->getValueAsListInit("Predicates"); 4039 int Complexity = TheDef->getValueAsInt("AddedComplexity"); 4040 4041 if (PatternRewriter) 4042 PatternRewriter(&Pattern); 4043 4044 // A pattern may end up with an "impossible" type, i.e. a situation 4045 // where all types have been eliminated for some node in this pattern. 4046 // This could occur for intrinsics that only make sense for a specific 4047 // value type, and use a specific register class. If, for some mode, 4048 // that register class does not accept that type, the type inference 4049 // will lead to a contradiction, which is not an error however, but 4050 // a sign that this pattern will simply never match. 4051 if (Temp.getOnlyTree()->hasPossibleType()) 4052 for (auto T : Pattern.getTrees()) 4053 if (T->hasPossibleType()) 4054 AddPatternToMatch(&Pattern, 4055 PatternToMatch(TheDef, makePredList(Preds), 4056 T, Temp.getOnlyTree(), 4057 InstImpResults, Complexity, 4058 TheDef->getID())); 4059 } 上面4008行注释谈到:如果我们的迭代收敛并且输入模式里的类型被完全解析,但结果模式的类型没有完全解析,在我们在结果模式及输入模式里有两条要求同一个寄存器类,但不关心实际使用的MVT时,会出现这种情形。这是我们模型里的一个bug:输出模式应该使用寄存器类,不是MVT。 在这种情形里,通过下面的方法随机选择一个类型。 3922 static bool ForceArbitraryInstResultType(TreePatternNode *N, TreePattern &TP) { 3923 if (N->isLeaf()) 3924 return false; 3925 3926 // Analyze children. 3927 for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) 3928 if (ForceArbitraryInstResultType(N->getChild(i), TP)) 3929 return true; 3930 3931 if (!N->getOperator()->isSubClassOf("Instruction")) 3932 return false; 3933 3934 // If this type is already concrete or completely unknown we can't do 3935 // anything. 3936 TypeInfer &TI = TP.getInfer(); 3937 for (unsigned i = 0, e = N->getNumTypes(); i != e; ++i) { 3938 if (N->getExtType(i).empty() || TI.isConcrete(N->getExtType(i), false)) 3939 continue; 3940 3941 // Otherwise, force its type to an arbitrary choice. 3942 if (TI.forceArbitrary(N->getExtType(i))) 3943 return true; 3944 } 3945 3946 return false; 3947 } 3938行的isConcrete()如果返回true,表示指定的类型在每个硬件模式下都有唯一明确的MVT。如果在某个模式下有多于一个类型,在3942行通过forceArbitrary()方法任意选取一个类型 344 bool TypeInfer::forceArbitrary(TypeSetByHwMode &Out) { 345 ValidateOnExit _1(Out, *this); 346 if (TP.hasError()) 347 return false; 348 assert(!Out.empty() && "cannot pick from an empty set"); 349 350 bool Changed = false; 351 for (auto &I : Out) { 352 TypeSetByHwMode::SetType &S = I.second; 353 if (S.size() <= 1) 354 continue; 355 MVT T = *S.begin(); // Pick the first element. 356 S.clear(); 357 S.insert(T); 358 Changed = true; 359 } 360 return Changed; 361 } 最后在4055行,构建PatternToMatch实例时,谓词由makePredList()进行排序后交给构造函数。排序的目的是规范化不同次序的相同谓词,最终得到相同的谓词字符串。 |