3.4.2.5.2. 有匹配模式的Instruction
对有模式的Instruction定义,第一步也是先生成CodeGenInstruction实例。接着把这个实例,连同记录了其匹配模式的DagInit列表,交给下面的方法来解析。目的也是生成DAGInstruction实例,但这里因为指令定义有匹配模式,处理起来复杂很多。
2903 const DAGInstruction &CodeGenDAGPatterns::parseInstructionPattern(
2904 CodeGenInstruction &CGI, ListInit *Pat, DAGInstMap &DAGInsts) {
2905
2906 assert(!DAGInsts.count(CGI.TheDef) && "Instruction already parsed!");
2907
2908 // Parse the instruction.
2909 TreePattern *I = new TreePattern(CGI.TheDef, Pat, true, *this);
2910 // Inline pattern fragments into it.
2911 I->InlinePatternFragments();
2912
2913 // Infer as many types as possible. If we cannot infer all of them, we can
2914 // never do anything with this instruction pattern: report it to the user.
2915 if (!I->InferAllTypes())
2916 I->error("Could not infer all types in pattern!");
2917
2918 // InstInputs - Keep track of all of the inputs of the instruction, along
2919 // with the record they are declared as.
2920 std::map<std::string, TreePatternNode*> InstInputs;
2921
2922 // InstResults - Keep track of all the virtual registers that are 'set'
2923 // in the instruction, including what reg class they are.
2924 std::map<std::string, TreePatternNode*> InstResults;
2925
2926 std::vector<Record*> InstImpResults;
2927
2928 // Verify that the top-level forms in the instruction are of void type, and
2929 // fill in the InstResults map.
2930 for (unsigned j = 0, e = I->getNumTrees(); j != e; ++j) {
2931 TreePatternNode *Pat = I->getTree(j);
2932 if (Pat->getNumTypes() != 0)
2933 I->error("Top-level forms in instruction pattern should have"
2934 " void types");
2935
2936 // Find inputs and outputs, and verify the structure of the uses/defs.
2937 FindPatternInputsAndOutputs(I, Pat, InstInputs, InstResults,
2938 InstImpResults);
2939 }
第一步解析这个模式,生成对应的TreePattern树,接着进行内联展开与类型推导。前面看TreePatternNode::ApplyTypeConstraints()方法时,我们跳过了模式操作符是Instruction部分,现在我们仍然要跳过它,因为当前的Instruction还未解析完,它是不可能作为当前模式操作符的。
接下来就要找出该模式的输入、输出以及隐含输出了,并把它们分别保存入相应的容器中。
2604 void CodeGenDAGPatterns::
2605 FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
2606 std::map<std::string, TreePatternNode*> &InstInputs,
2607 std::map<std::string, TreePatternNode*>&InstResults,
2608 std::vector<Record*> &InstImpResults) {
2609 if (Pat->isLeaf()) {
2610 bool isUse = HandleUse(I, Pat, InstInputs);
2611 if (!isUse && Pat->getTransformFn())
2612 I->error("Cannot specify a transform function for a non-input value!");
2613 return;
2614 }
2615
2616 if (Pat->getOperator()->getName() == "implicit") {
2617 for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
2618 TreePatternNode *Dest = Pat->getChild(i);
2619 if (!Dest->isLeaf())
2620 I->error("implicitly defined value should be a register!");
2621
2622 DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue());
2623 if (!Val || !Val->getDef()->isSubClassOf("Register"))
2624 I->error("implicitly defined value should be a register!");
2625 InstImpResults.push_back(Val->getDef());
2626 }
2627 return;
2628 }
2629
2630 if (Pat->getOperator()->getName() != "set") {
2631 // If this is not a set, verify that the children nodes are not void typed,
2632 // and recurse.
2633 for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
2634 if (Pat->getChild(i)->getNumTypes() == 0)
2635 I->error("Cannot have void nodes inside of patterns!");
2636 FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults,
2637 InstImpResults);
2638 }
2639
2640 // If this is a non-leaf node with no children, treat it basically as if
2641 // it were a leaf. This handles nodes like (imm).
2642 bool isUse = HandleUse(I, Pat, InstInputs);
2643
2644 if (!isUse && Pat->getTransformFn())
2645 I->error("Cannot specify a transform function for a non-input value!");
2646 return;
2647 }
2648
2649 // Otherwise, this is a set, validate and collect instruction results.
2650 if (Pat->getNumChildren() == 0)
2651 I->error("set requires operands!");
2652
2653 if (Pat->getTransformFn())
2654 I->error("Cannot specify a transform function on a set node!");
2655
2656 // Check the set destinations.
2657 unsigned NumDests = Pat->getNumChildren()-1;
2658 for (unsigned i = 0; i != NumDests; ++i) {
2659 TreePatternNode *Dest = Pat->getChild(i);
2660 if (!Dest->isLeaf())
2661 I->error("set destination should be a register!");
2662
2663 DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue());
2664 if (!Val) {
2665 I->error("set destination should be a register!");
2666 continue;
2667 }
2668
2669 if (Val->getDef()->isSubClassOf("RegisterClass") ||
2670 Val->getDef()->isSubClassOf("ValueType") ||
2671 Val->getDef()->isSubClassOf("RegisterOperand") ||
2672 Val->getDef()->isSubClassOf("PointerLikeRegClass")) {
2673 if (Dest->getName().empty())
2674 I->error("set destination must have a name!");
2675 if (InstResults.count(Dest->getName()))
2676 I->error("cannot set '" + Dest->getName() +"' multiple times");
2677 InstResults[Dest->getName()] = Dest;
2678 } else if (Val->getDef()->isSubClassOf("Register")) {
2679 InstImpResults.push_back(Val->getDef());
2680 } else {
2681 I->error("set destination should be a register!");
2682 }
2683 }
2684
2685 // Verify and collect info from the computation.
2686 FindPatternInputsAndOutputs(I, Pat->getChild(NumDests),
2687 InstInputs, InstResults, InstImpResults);
2688 }
一般情况下模式中给出的操作数都应视为输入操作数,除了以Implicit及set作为操作符的dag。Implicit的操作数必须是Register对象,并且这代表隐含结果。Set则要复杂些,首先set最后的操作数是源操作数,其他操作数都是目标操作数,set的作用是将源操作数设置给目标操作数。目标操作数是有限制的,首先它们必须是set这棵TreePattern树的叶子节点。其次,它们的类型必须是RegisterClass、ValueType、RegisterOperand、PointerLikeRegClass或Register之一,而且前四者都必须是具名的。另外,Register类型的目标操作数被视为隐含结果。Set的源操作数则要复杂一些,因此在2686行通过FindPatternInputsAndOutputs()递归来处理。
非set节点(2630行条件)可以有复杂的源操作数,因此也由FindPatternInputsAndOutputs()递归处理(2636行)。另外,输入操作数需要被记录到容器InstInputs里,HandleUse()方法执行这个操作,并进行一些合法性检查。
2554 static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
2555 std::map<std::string, TreePatternNode*> &InstInputs) {
2556 // No name -> not interesting.
2557 if (Pat->getName().empty()) {
2558 if (Pat->isLeaf()) {
2559 DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue());
2560 if (DI && (DI->getDef()->isSubClassOf("RegisterClass") ||
2561 DI->getDef()->isSubClassOf("RegisterOperand")))
2562 I->error("Input " + DI->getDef()->getName() + " must be named!");
2563 }
2564 return false;
2565 }
2566
2567 Record *Rec;
2568 if (Pat->isLeaf()) {
2569 DefInit *DI = dyn_cast<DefInit>(Pat->getLeafValue());
2570 if (!DI) I->error("Input $" + Pat->getName() + " must be an identifier!");
2571 Rec = DI->getDef();
2572 } else {
2573 Rec = Pat->getOperator();
2574 }
2575
2576 // SRCVALUE nodes are ignored.
2577 if (Rec->getName() == "srcvalue")
2578 return false;
2579
2580 TreePatternNode *&Slot = InstInputs[Pat->getName()];
2581 if (!Slot) {
2582 Slot = Pat;
2583 return true;
2584 }
2585 Record *SlotRec;
2586 if (Slot->isLeaf()) {
2587 SlotRec = cast<DefInit>(Slot->getLeafValue())->getDef();
2588 } else {
2589 assert(Slot->getNumChildren() == 0 && "can't be a use with children!");
2590 SlotRec = Slot->getOperator();
2591 }
2592
2593 // Ensure that the inputs agree if we've already seen this input.
2594 if (Rec != SlotRec)
2595 I->error("All $" + Pat->getName() + " inputs must agree with each other");
2596 if (Slot->getExtTypes() != Pat->getExtTypes())
2597 I->error("All $" + Pat->getName() + " inputs must agree with each other");
2598 return true;
2599 }
Srcvalue类型是不在考虑范围内的,不过LLVM似乎已经不再使用它了。如果同名操作数已经在InstInputs里,必须确保它们是一样的。在2580行输入操作数被保存入InstInputs容器。
回到CodeGenDAGPatterns::parseInstructionPattern(),2953行的CGI.Operands.size()给出了输入、输出操作数的总数,在CGI.Operands中输出操作数在前(参考CGIOperandList的构造函数)。
CodeGenDAGPatterns::parseInstructionPattern(续)
2941 // Now that we have inputs and outputs of the pattern, inspect the operands
2942 // list for the instruction. This determines the order that operands are
2943 // added to the machine instruction the node corresponds to.
2944 unsigned NumResults = InstResults.size();
2945
2946 // Parse the operands list from the (ops) list, validating it.
2947 assert(I->getArgList().empty() && "Args list should still be empty here!");
2948
2949 // Check that all of the results occur first in the list.
2950 std::vector<Record*> Results;
2951 SmallVector<TreePatternNode *, 2> ResNodes;
2952 for (unsigned i = 0; i != NumResults; ++i) {
2953 if (i == CGI.Operands.size())
2954 I->error("'" + InstResults.begin()->first +
2955 "' set but does not appear in operand list!");
2956 const std::string &OpName = CGI.Operands[i].Name;
2957
2958 // Check that it exists in InstResults.
2959 TreePatternNode *RNode = InstResults[OpName];
2960 if (!RNode)
2961 I->error("Operand $" + OpName + " does not exist in operand list!");
2962
2963 ResNodes.push_back(RNode);
2964
2965 Record *R = cast<DefInit>(RNode->getLeafValue())->getDef();
2966 if (!R)
2967 I->error("Operand $" + OpName + " should be a set destination: all "
2968 "outputs must occur before inputs in operand list!");
2969
2970 if (!checkOperandClass(CGI.Operands[i], R))
2971 I->error("Operand $" + OpName + " class mismatch!");
2972
2973 // Remember the return type.
2974 Results.push_back(CGI.Operands[i].Rec);
2975
2976 // Okay, this one checks out.
2977 InstResults.erase(OpName);
2978 }
2952行循环遍历输出操作数,调用checkOperandClass()方法检查操作数的Record对象与CGIOperandList::OperandInfo实例是否一致。在OperandInfo构造函数里,OperandInfo对象中保存了对应操作数的Record实例,即下面2888行的OI.Rec。而参数Leaf则是来自指令定义中的结果操作数。原则上两者必须是相同的,除非Leaf是ValueType或ComplexPattern类型。参考指令定义的例子一节的例子bmi_andn。在这个例子里可以发现对其中一个操作数$src2,OI.Rec是X86MemOperand(Operand对象),Leaf是addr(ComplexPattern对象)。
2886 static bool checkOperandClass(CGIOperandList::OperandInfo &OI,
2887 Record *Leaf) {
2888 if (OI.Rec == Leaf)
2889 return true;
2890
2891 // Allow direct value types to be used in instruction set patterns.
2892 // The type will be checked later.
2893 if (Leaf->isSubClassOf("ValueType"))
2894 return true;
2895
2896 // Patterns can also be ComplexPattern instances.
2897 if (Leaf->isSubClassOf("ComplexPattern"))
2898 return true;
2899
2900 return false;
2901 }
注意2977行的erase,完成2952行循环后,InstResults应该是空的。2985行的Operands容器将只包含输入操作数的Record对象。因此,2984行定义的容器ResultNodeOperands包含的将是输出操作数,它将用作代表结果的模式树的操作数。
CodeGenDAGPatterns::parseInstructionPattern(续)
2980 // Loop over the inputs next. Make a copy of InstInputs so we can destroy
2981 // the copy while we're checking the inputs.
2982 std::map<std::string, TreePatternNode*> InstInputsCheck(InstInputs);
2983
2984 std::vector<TreePatternNode*> ResultNodeOperands;
2985 std::vector<Record*> Operands;
2986 for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) {
2987 CGIOperandList::OperandInfo &Op = CGI.Operands[i];
2988 const std::string &OpName = Op.Name;
2989 if (OpName.empty())
2990 I->error("Operand #" + utostr(i) + " in operands list has no name!");
2991
2992 if (!InstInputsCheck.count(OpName)) {
2993 // If this is an operand with a DefaultOps set filled in, we can ignore
2994 // this. When we codegen it, we will do so as always executed.
2995 if (Op.Rec->isSubClassOf("OperandWithDefaultOps")) {
2996 // Does it have a non-empty DefaultOps field? If so, ignore this
2997 // operand.
2998 if (!getDefaultOperand(Op.Rec).DefaultOps.empty())
2999 continue;
3000 }
3001 I->error("Operand $" + OpName +
3002 " does not appear in the instruction pattern");
3003 }
3004 TreePatternNode *InVal = InstInputsCheck[OpName];
3005 InstInputsCheck.erase(OpName); // It occurred, remove from map.
3006
3007 if (InVal->isLeaf() && isa<DefInit>(InVal->getLeafValue())) {
3008 Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
3009 if (!checkOperandClass(Op, InRec))
3010 I->error("Operand $" + OpName + "'s register class disagrees"
3011 " between the operand and pattern");
3012 }
3013 Operands.push_back(Op.Rec);
3014
3015 // Construct the result for the dest-pattern operand list.
3016 TreePatternNode *OpNode = InVal->clone();
3017
3018 // No predicate is useful on the result.
3019 OpNode->clearPredicateFns();
3020
3021 // Promote the xform function to be an explicit node if set.
3022 if (Record *Xform = OpNode->getTransformFn()) {
3023 OpNode->setTransformFn(nullptr);
3024 std::vector<TreePatternNode*> Children;
3025 Children.push_back(OpNode);
3026 OpNode = new TreePatternNode(Xform, Children, OpNode->getNumTypes());
3027 }
3028
3029 ResultNodeOperands.push_back(OpNode);
3030 }
3016行克隆了输入操作数的TreePatternNode,如果其中有转换方法,还要将代表转换方法的SDNodeXForm节点作为这棵TreePattern树的根。这些克隆节点保存在ResultNodeOperands容器里。
下面3036行生成代表指令结果的树节点——ResultPattern,Instruction定义的Record对象为根,ResultNodeOperands作为孩子。在3053行构建一个TreePattern对象(注意,IsInput参数为false)来封装ResultPattern,目的在于调用TreePattern的InferAllTypes()方法,确认指令模式树中的具名操作数集合与这个TreePattern对象中的具名操作数一致。
CodeGenDAGPatterns::parseInstructionPattern(续)
3032 if (!InstInputsCheck.empty())
3033 I->error("Input operand $" + InstInputsCheck.begin()->first +
3034 " occurs in pattern but not in operands list!");
3035
3036 TreePatternNode *ResultPattern =
3037 new TreePatternNode(I->getRecord(), ResultNodeOperands,
3038 GetNumNodeResults(I->getRecord(), *this));
3039 // Copy fully inferred output node types to instruction result pattern.
3040 for (unsigned i = 0; i != NumResults; ++i) {
3041 assert(ResNodes[i]->getNumTypes() == 1 && "FIXME: Unhandled");
3042 ResultPattern->setType(i, ResNodes[i]->getExtType(0));
3043 }
3044
3045 // Create and insert the instruction.
3046 // FIXME: InstImpResults should not be part of DAGInstruction.
3047 DAGInstruction TheInst(I, Results, Operands, InstImpResults);
3048 DAGInsts.insert(std::make_pair(I->getRecord(), TheInst));
3049
3050 // Use a temporary tree pattern to infer all types and make sure that the
3051 // constructed result is correct. This depends on the instruction already
3052 // being inserted into the DAGInsts map.
3053 TreePattern Temp(I->getRecord(), ResultPattern, false, *this);
3054 Temp.InferAllTypes(&I->getNamedNodesMap());
3055
3056 DAGInstruction &TheInsertedInst = DAGInsts.find(I->getRecord())->second;
3057 TheInsertedInst.setResultPattern(Temp.getOnlyTree());
3058
3059 return TheInsertedInst;
3060 }
这里注意看一下3047行DAGInstruction的构建。参数I是指令的匹配模式TreePattern对象,Results是输出操作数,Operands是输入操作数,InstImpResults是隐含的输出结果。在3057行代表结果的模式树被设置为这个DAGInstruction实例的ResultPattern。
V7.0的处理
V7.0的处理稍有出入。首先在3491行在栈上创建当前指令匹配模式的TreePattern实例,而不是v3.6.1那样在堆上。另外,它也不着急着将这个TreePattern进行内联以及类型推导。 3485 void CodeGenDAGPatterns::parseInstructionPattern( 3486 CodeGenInstruction &CGI, ListInit *Pat, DAGInstMap &DAGInsts) { 3487 3488 assert(!DAGInsts.count(CGI.TheDef) && "Instruction already parsed!"); 3489 3490 // Parse the instruction. 3491 TreePattern I(CGI.TheDef, Pat, true, *this); 3492 3493 // InstInputs - Keep track of all of the inputs of the instruction, along 3494 // with the record they are declared as. 3495 std::map<std::string, TreePatternNodePtr> InstInputs; 3496 3497 // InstResults - Keep track of all the virtual registers that are 'set' 3498 // in the instruction, including what reg class they are. 3499 std::map<std::string, TreePatternNodePtr> InstResults; 3500 3501 std::vector<Record*> InstImpResults; 3502 3503 // Verify that the top-level forms in the instruction are of void type, and 3504 // fill in the InstResults map. 3505 SmallString<32> TypesString; 3506 for (unsigned j = 0, e = I.getNumTrees(); j != e; ++j) { 3507 TypesString.clear(); 3508 TreePatternNodePtr Pat = I.getTree(j); 3509 if (Pat->getNumTypes() != 0) { 3510 raw_svector_ostream OS(TypesString); 3511 for (unsigned k = 0, ke = Pat->getNumTypes(); k != ke; ++k) { 3512 if (k > 0) 3513 OS << ", "; 3514 Pat->getExtType(k).writeToStream(OS); 3515 } 3516 I.error("Top-level forms in instruction pattern should have" 3517 " void types, has types " + 3518 OS.str()); 3519 } 3520 3521 // Find inputs and outputs, and verify the structure of the uses/defs. 3522 FindPatternInputsAndOutputs(I, Pat, InstInputs, InstResults, 3523 InstImpResults); 3524 } 前面看到在TreePattern构造函数里,会按匹配模式解析dag对象。Instruction定义的Pattern域里每个dag对象将解析为一个TreePatternNode实例保存在Trees容器中。指令是没有类型的,因此3506行循环遍历这些TreePatternNode实例,检查是否有违规。 对具名模式,CodeGenDAGPatterns::FindPatternInputsAndOutputs()一进来就进行展开与类型推导,如果有多棵模式树,3189行TreePattern的getOnlyTree()方法会引发断言。这是v3.6.1没有做的检查。 3176 void CodeGenDAGPatterns::FindPatternInputsAndOutputs( 3177 TreePattern &I, TreePatternNodePtr Pat, 3178 std::map<std::string, TreePatternNodePtr> &InstInputs, 3179 std::map<std::string, TreePatternNodePtr> &InstResults, 3180 std::vector<Record *> &InstImpResults) { 3181 3182 // The instruction pattern still has unresolved fragments. For *named* 3183 // nodes we must resolve those here. This may not result in multiple 3184 // alternatives. 3185 if (!Pat->getName().empty()) { 3186 TreePattern SrcPattern(I.getRecord(), Pat, true, *this); 3187 SrcPattern.InlinePatternFragments(); 3188 SrcPattern.InferAllTypes(); 3189 Pat = SrcPattern.getOnlyTree(); 3190 } 3191 3192 if (Pat->isLeaf()) { 3193 bool isUse = HandleUse(I, Pat, InstInputs); 3194 if (!isUse && Pat->getTransformFn()) 3195 I.error("Cannot specify a transform function for a non-input value!"); 3196 return; 3197 } 3198 3199 if (Pat->getOperator()->getName() == "implicit") { 3200 for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { 3201 TreePatternNode *Dest = Pat->getChild(i); 3202 if (!Dest->isLeaf()) 3203 I.error("implicitly defined value should be a register!"); 3204 3205 DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue()); 3206 if (!Val || !Val->getDef()->isSubClassOf("Register")) 3207 I.error("implicitly defined value should be a register!"); 3208 InstImpResults.push_back(Val->getDef()); 3209 } 3210 return; 3211 } 3212 3213 if (Pat->getOperator()->getName() != "set") { 3214 // If this is not a set, verify that the children nodes are not void typed, 3215 // and recurse. 3216 for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) { 3217 if (Pat->getChild(i)->getNumTypes() == 0) 3218 I.error("Cannot have void nodes inside of patterns!"); 3219 FindPatternInputsAndOutputs(I, Pat->getChildShared(i), InstInputs, 3220 InstResults, InstImpResults); 3221 } 3222 3223 // If this is a non-leaf node with no children, treat it basically as if 3224 // it were a leaf. This handles nodes like (imm). 3225 bool isUse = HandleUse(I, Pat, InstInputs); 3226 3227 if (!isUse && Pat->getTransformFn()) 3228 I.error("Cannot specify a transform function for a non-input value!"); 3229 return; 3230 } 3231 3232 // Otherwise, this is a set, validate and collect instruction results. 3233 if (Pat->getNumChildren() == 0) 3234 I.error("set requires operands!"); 3235 3236 if (Pat->getTransformFn()) 3237 I.error("Cannot specify a transform function on a set node!"); 3238 3239 // Check the set destinations. 3240 unsigned NumDests = Pat->getNumChildren()-1; 3241 for (unsigned i = 0; i != NumDests; ++i) { 3242 TreePatternNodePtr Dest = Pat->getChildShared(i); 3243 // For set destinations we also must resolve fragments here. 3244 TreePattern DestPattern(I.getRecord(), Dest, false, *this); 3245 DestPattern.InlinePatternFragments(); 3246 DestPattern.InferAllTypes(); 3247 Dest = DestPattern.getOnlyTree(); 3248 3249 if (!Dest->isLeaf()) 3250 I.error("set destination should be a register!"); 3251 3252 DefInit *Val = dyn_cast<DefInit>(Dest->getLeafValue()); 3253 if (!Val) { 3254 I.error("set destination should be a register!"); 3255 continue; 3256 } 3257 3258 if (Val->getDef()->isSubClassOf("RegisterClass") || 3259 Val->getDef()->isSubClassOf("ValueType") || 3260 Val->getDef()->isSubClassOf("RegisterOperand") || 3261 Val->getDef()->isSubClassOf("PointerLikeRegClass")) { 3262 if (Dest->getName().empty()) 3263 I.error("set destination must have a name!"); 3264 if (InstResults.count(Dest->getName())) 3265 I.error("cannot set '" + Dest->getName() + "' multiple times"); 3266 InstResults[Dest->getName()] = Dest; 3267 } else if (Val->getDef()->isSubClassOf("Register")) { 3268 InstImpResults.push_back(Val->getDef()); 3269 } else { 3270 I.error("set destination should be a register!"); 3271 } 3272 } 3273 3274 // Verify and collect info from the computation. 3275 FindPatternInputsAndOutputs(I, Pat->getChildShared(NumDests), InstInputs, 3276 InstResults, InstImpResults); 3277 } 叶子节点很可能是操作数,因此调用HandleUse()来处理它。V7.0的HandleUse()与v3.6.1基本相同。首先,只处理具名节点。其次,RegisterClass与RegisterOperand类型节点是不允许匿名的。对满足条件的节点(参数Pat),加入参数InstInputs容器中,以名字作为索引。同名对象的多次加入是允许的,但它们必须来自相同的定义(对非叶子节点,这个定义是对应dag的操作符),而且存在一致的类型。 Dag通常是匿名的,它们由3199行以下的代码处理。除了implicit的操作数以及set最后一个以外的操作数,其他操作数都视为输入操作数。这里对可以作为输出操作数类型的检查与v3.6.1无异。不过,也是在处理输出操作数前,才进行内联与类型推导,并确保只生成一棵树(3242~3247行)。 CodeGenDAGPatterns::parseInstructionPattern(续) 3526 // Now that we have inputs and outputs of the pattern, inspect the operands 3527 // list for the instruction. This determines the order that operands are 3528 // added to the machine instruction the node corresponds to. 3529 unsigned NumResults = InstResults.size(); 3530 3531 // Parse the operands list from the (ops) list, validating it. 3532 assert(I.getArgList().empty() && "Args list should still be empty here!"); 3533 3534 // Check that all of the results occur first in the list. 3535 std::vector<Record*> Results; 3536 SmallVector<TreePatternNodePtr, 2> ResNodes; 3537 for (unsigned i = 0; i != NumResults; ++i) { 3538 if (i == CGI.Operands.size()) 3539 I.error("'" + InstResults.begin()->first + 3540 "' set but does not appear in operand list!"); 3541 const std::string &OpName = CGI.Operands[i].Name; 3542 3543 // Check that it exists in InstResults. 3544 TreePatternNodePtr RNode = InstResults[OpName]; 3545 if (!RNode) 3546 I.error("Operand $" + OpName + " does not exist in operand list!"); 3547 3548 3549 Record *R = cast<DefInit>(RNode->getLeafValue())->getDef(); 3550 ResNodes.push_back(std::move(RNode)); 3551 if (!R) 3552 I.error("Operand $" + OpName + " should be a set destination: all " 3553 "outputs must occur before inputs in operand list!"); 3554 3555 if (!checkOperandClass(CGI.Operands[i], R)) 3556 I.error("Operand $" + OpName + " class mismatch!"); 3557 3558 // Remember the return type. 3559 Results.push_back(CGI.Operands[i].Rec); 3560 3561 // Okay, this one checks out. 3562 InstResults.erase(OpName); 3563 } 3564 3565 // Loop over the inputs next. 3566 std::vector<TreePatternNodePtr> ResultNodeOperands; 3567 std::vector<Record*> Operands; 3568 for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) { 3569 CGIOperandList::OperandInfo &Op = CGI.Operands[i]; 3570 const std::string &OpName = Op.Name; 3571 if (OpName.empty()) 3572 I.error("Operand #" + Twine(i) + " in operands list has no name!"); 3573 3574 if (!InstInputs.count(OpName)) { 3575 // If this is an operand with a DefaultOps set filled in, we can ignore 3576 // this. When we codegen it, we will do so as always executed. 3577 if (Op.Rec->isSubClassOf("OperandWithDefaultOps")) { 3578 // Does it have a non-empty DefaultOps field? If so, ignore this 3579 // operand. 3580 if (!getDefaultOperand(Op.Rec).DefaultOps.empty()) 3581 continue; 3582 } 3583 I.error("Operand $" + OpName + 3584 " does not appear in the instruction pattern"); 3585 } 3586 TreePatternNodePtr InVal = InstInputs[OpName]; 3587 InstInputs.erase(OpName); // It occurred, remove from map. 3588 3589 if (InVal->isLeaf() && isa<DefInit>(InVal->getLeafValue())) { 3590 Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef(); 3591 if (!checkOperandClass(Op, InRec)) 3592 I.error("Operand $" + OpName + "'s register class disagrees" 3593 " between the operand and pattern"); 3594 } 3595 Operands.push_back(Op.Rec); 3596 3597 // Construct the result for the dest-pattern operand list. 3598 TreePatternNodePtr OpNode = InVal->clone(); 3599 3600 // No predicate is useful on the result. 3601 OpNode->clearPredicateFns(); 3602 3603 // Promote the xform function to be an explicit node if set. 3604 if (Record *Xform = OpNode->getTransformFn()) { 3605 OpNode->setTransformFn(nullptr); 3606 std::vector<TreePatternNodePtr> Children; 3607 Children.push_back(OpNode); 3608 OpNode = std::make_shared<TreePatternNode>(Xform, std::move(Children), 3609 OpNode->getNumTypes()); 3610 } 3611 3612 ResultNodeOperands.push_back(std::move(OpNode)); 3613 } 3614 3615 if (!InstInputs.empty()) 3616 I.error("Input operand $" + InstInputs.begin()->first + 3617 " occurs in pattern but not in operands list!"); 3618 3619 TreePatternNodePtr ResultPattern = std::make_shared<TreePatternNode>( 3620 I.getRecord(), std::move(ResultNodeOperands), 3621 GetNumNodeResults(I.getRecord(), *this)); 3622 // Copy fully inferred output node types to instruction result pattern. 3623 for (unsigned i = 0; i != NumResults; ++i) { 3624 assert(ResNodes[i]->getNumTypes() == 1 && "FIXME: Unhandled"); 3625 ResultPattern->setType(i, ResNodes[i]->getExtType(0)); 3626 } 3627 3628 // FIXME: Assume only the first tree is the pattern. The others are clobber 3629 // nodes. 3630 TreePatternNodePtr Pattern = I.getTree(0); 3631 TreePatternNodePtr SrcPattern; 3632 if (Pattern->getOperator()->getName() == "set") { 3633 SrcPattern = Pattern->getChild(Pattern->getNumChildren()-1)->clone(); 3634 } else{ 3635 // Not a set (store or something?) 3636 SrcPattern = Pattern; 3637 } 3638 3639 // Create and insert the instruction. 3640 // FIXME: InstImpResults should not be part of DAGInstruction. 3641 Record *R = I.getRecord(); 3642 DAGInsts.emplace(std::piecewise_construct, std::forward_as_tuple(R), 3643 std::forward_as_tuple(Results, Operands, InstImpResults, 3644 SrcPattern, ResultPattern)); 3645 3646 LLVM_DEBUG(I.dump()); 3647 } 与v3.6.1一样,CodeGenDAGPatterns::parseInstructionPattern()接下来根据指令定义里声明的输入、输出操作数(Instruction定义里的OutOperandList与InOperandList),检查从匹配模式得到的输入、输出操作数的个数、名字是否与定义一致(如果Instruction定义里使用了OperandWithDefaultOps类型操作数,这些操作数可以不出现在输入操作数列表中)。 注意3619行ResultPattern的构建。其中的ResultNodeOperands是输入操作数,它的结果类型由输出操作数类型确定(3625行)。SrcPattern则在3630~3637行获取,如果I有多棵子树(这些子树来自Instruction定义的Pattern域),目前我们只假定第一棵树是相关的,其他树是无关的。 在3642行,DAGInsts是std::map<Record*, DAGInstruction, LessRecordByID>类型容器,因此这行代码生成一个DAGInstruction实例,并与相关的Record*对象一起加入这个容器。 |