LLVM学习笔记(21)
来源:互联网 发布:推广平台源码 编辑:程序博客网 时间:2024/06/02 02:23
3.4.2.6. Pattern的处理
我们已经知道Pattern定义可以将通用的IR的指令表示映射为特定于目标机器的指令(对目标机器不同的型号,可以映射到这些型号特有的、更高效的指令)。因此,对指令选择,Pattern定义是有益的补充。因为Pattern定义会援引指令,因此需要在解析完所有的指令定义后才开始。
3386 void CodeGenDAGPatterns::ParsePatterns(){
3387 std::vector<Record*> Patterns =Records.getAllDerivedDefinitions("Pattern");
3388
3389 for (unsignedi = 0, e = Patterns.size(); i != e; ++i) {
3390 Record *CurPattern = Patterns[i];
3391 DagInit *Tree =CurPattern->getValueAsDag("PatternToMatch");
3392
3393 // If thepattern references the null_frag, there's nothing to do.
3394 if (hasNullFragReference(Tree))
3395 continue;
3396
3397 TreePattern *Pattern = new TreePattern(CurPattern, Tree, true, *this);
3398
3399 // Inlinepattern fragments into it.
3400 Pattern->InlinePatternFragments();
3401
3402 ListInit *LI =CurPattern->getValueAsListInit("ResultInstrs");
3403 if (LI->empty()) continue; // no pattern.
3404
3405 // Parse theinstruction.
3406 TreePattern Result(CurPattern, LI, false, *this);
3407
3408 // Inlinepattern fragments into it.
3409 Result.InlinePatternFragments();
3410
3411 if (Result.getNumTrees() != 1)
3412 Result.error("Cannot handleinstructions producing instructions "
3413 "with temporaries yet!");
3414
3415 bool IterateInference;
3416 bool InferredAllPatternTypes,InferredAllResultTypes;
3417 do {
3418 // Infer asmany types as possible. If we cannotinfer all of them, we
3419 // can neverdo anything with this pattern: report it to the user.
3420 InferredAllPatternTypes =
3421 Pattern->InferAllTypes(&Pattern->getNamedNodesMap());
3422
3423 // Infer asmany types as possible. If we cannotinfer all of them, we
3424 // can neverdo anything with this pattern: report it to the user.
3425 InferredAllResultTypes =
3426 Result.InferAllTypes(&Pattern->getNamedNodesMap());
3427
3428 IterateInference = false;
3429
3430 // Apply thetype of the result to the source pattern. This helps us
3431 // resolvecases where the input type is known to be a pointer type (which
3432 // isconsidered resolved), but the result knows it needs to be 32- or
3433 //64-bits. Infer the other way for goodmeasure.
3434 for(unsigned i = 0, e = std::min(Result.getTree(0)->getNumTypes(),
3435 Pattern->getTree(0)->getNumTypes());
3436 i != e; ++i) {
3437 IterateInference =Pattern->getTree(0)->UpdateNodeType(
3438 i,Result.getTree(0)->getExtType(i), Result);
3439 IterateInference |=Result.getTree(0)->UpdateNodeType(
3440 i,Pattern->getTree(0)->getExtType(i), Result);
3441 }
3442
3443 // If ouriteration has converged and the input pattern's types are fully
3444 // resolvedbut the result pattern is not fully resolved, we may have a
3445 // situationwhere we have two instructions in the result pattern and
3446 // theinstructions require a common register class, but don't care about
3447 // whatactual MVT is used. This is actually abug in our modelling:
3448 // outputpatterns should have register classes, not MVTs.
3449 //
3450 // In anycase, to handle this, we just go through and disambiguate some
3451 // arbitrarytypes to the result pattern's nodes.
3452 if (!IterateInference &&InferredAllPatternTypes &&
3453 !InferredAllResultTypes)
3454 IterateInference =
3455 ForceArbitraryInstResultType(Result.getTree(0),Result);
3456 } while(IterateInference);
3457
3458 // Verify thatwe inferred enough types that we can do something with the
3459 // pattern andresult. If these fire the user has toadd type casts.
3460 if (!InferredAllPatternTypes)
3461 Pattern->error("Could not inferall types in pattern!");
3462 if (!InferredAllResultTypes) {
3463 Pattern->dump();
3464 Result.error("Could not infer alltypes in pattern result!");
3465 }
3466
3467 // Validatethat the input pattern is correct.
3468 std::map<std::string,TreePatternNode*> InstInputs;
3469 std::map<std::string,TreePatternNode*> InstResults;
3470 std::vector<Record*> InstImpResults;
3471 for(unsigned j = 0, ee = Pattern->getNumTrees(); j != ee; ++j)
3472 FindPatternInputsAndOutputs(Pattern,Pattern->getTree(j),
3473 InstInputs,InstResults,
3474 InstImpResults);
3475
3476 // Promote thexform function to be an explicit node if set.
3477 TreePatternNode *DstPattern =Result.getOnlyTree();
3478 std::vector<TreePatternNode*>ResultNodeOperands;
3479 for(unsigned ii = 0, ee = DstPattern->getNumChildren(); ii != ee; ++ii) {
3480 TreePatternNode *OpNode =DstPattern->getChild(ii);
3481 if (Record *Xform =OpNode->getTransformFn()) {
3482 OpNode->setTransformFn(nullptr);
3483 std::vector<TreePatternNode*>Children;
3484 Children.push_back(OpNode);
3485 OpNode = newTreePatternNode(Xform, Children, OpNode->getNumTypes());
3486 }
3487 ResultNodeOperands.push_back(OpNode);
3488 }
3489 DstPattern = Result.getOnlyTree();
3490 if (!DstPattern->isLeaf())
3491 DstPattern = newTreePatternNode(DstPattern->getOperator(),
3492 ResultNodeOperands,
3493 DstPattern->getNumTypes());
3494
3495 for(unsigned i = 0, e = Result.getOnlyTree()->getNumTypes(); i != e; ++i)
3496 DstPattern->setType(i,Result.getOnlyTree()->getExtType(i));
3497
3498 TreePattern Temp(Result.getRecord(),DstPattern, false, *this);
3499 Temp.InferAllTypes();
3500
3501
3502 AddPatternToMatch(Pattern,
3503 PatternToMatch(CurPattern,
3504 CurPattern->getValueAsListInit("Predicates"),
3505 Pattern->getTree(0),
3506 Temp.getOnlyTree(), InstImpResults,
3507 CurPattern->getValueAsInt("AddedComplexity"),
3508 CurPattern->getID()));
3509 }
3510 }
上面根据Pattern定义的PatternToMatch与ResultInstrs,分别建立了两棵TreePattern树,Pattern与Result,注意Pattern被视为输入模板,Result则是输出目标,因此它们的处理与内联展开是有区别的。接着在3417行循环里不停地进行类型推导迭代,直到不再发生变化。
3455行的ForceArbitraryInstResultType尝试尽可能地确定Result包含的返型。
3360 static boolForceArbitraryInstResultType(TreePatternNode*N, TreePattern &TP) {
3361 if (N->isLeaf())
3362 return false;
3363
3364 // Analyzechildren.
3365 for (unsignedi = 0, e = N->getNumChildren(); i != e; ++i)
3366 if(ForceArbitraryInstResultType(N->getChild(i), TP))
3367 return true;
3368
3369 if(!N->getOperator()->isSubClassOf("Instruction"))
3370 return false;
3371
3372 // If this typeis already concrete or completely unknown we can't do
3373 // anything.
3374 for (unsignedi = 0, e = N->getNumTypes(); i != e; ++i) {
3375 if(N->getExtType(i).isCompletelyUnknown() || N->getExtType(i).isConcrete())
3376 continue;
3377
3378 // Otherwise,force its type to the first possibility (an arbitrary choice).
3379 if (N->getExtType(i).MergeInTypeInfo(N->getExtType(i).getTypeList()[0],TP))
3380 return true;
3381 }
3382
3383 return false;
3384 }
在3379行,如果指定的返回类型既不是确定,又不是完全未知,就将它尽可能向第一个类型靠拢。
因为只有所有的类型都能推导出来时InferAllTypes才返回true,因此在3468行以下类型都是已知的。接下来在Pattern中确定输入操作数、结果及隐含结果。而Result则用于表示指令的结果。最后生成PatternToMatch实例。这些操作都与对Instruction的处理类似。
- LLVM学习笔记(21)
- llvm学习笔记(1)
- llvm学习笔记(2)
- llvm学习笔记(3)
- llvm学习笔记(4)
- llvm学习笔记(5)
- LLVM学习笔记(6)
- LLVM学习笔记(7)
- LLVM学习笔记(8)
- LLVM学习笔记(9)
- LLVM学习笔记(10)
- LLVM学习笔记(11)
- LLVM学习笔记(12)
- LLVM学习笔记(13)
- LLVM学习笔记(14)
- LLVM学习笔记(15)
- LLVM学习笔记(20)
- LLVM学习笔记(16)
- Parallel&Distributed Algorithm-1
- 每天一道LeetCode-----某个数在递增序列第一次和最后一次出现的位置
- AFN提交类型和回应类型
- SpringBatch配置多线程step
- JavaWeb框架-【Hibernate+Struts2】-框架世界的联手-图书管理系统
- LLVM学习笔记(21)
- leetcode 6 ZigZag Conversion
- Android,沉浸式状态栏,状态栏以及Toolbar颜色分开设置
- 提示错误:A child Container failed during start
- C99中的for语句
- Linux 中mysql-5.7.9 64位 RPM 详细安装
- vue学习07--进入/离开&列表过渡
- mybatis原生态开发基本配置文件
- greater<int>()和less<int>()的使用