llvm.org GIT mirror llvm / 06d6470
- Prevent some functions from being inlined to eliminate the code size bloat introduced by previous commit. - SelectCode now returns a SDNode*. If it is not null, the selected node produces the same number of results as the input node. The seletion loop is responsible for calling ReplaceAllUsesWith() to replace the input node with the output target node. For other cases, e.g. when load is folded, the selection code is responsible for calling ReplaceAllUsesOfValueWith() and SelectCode returns NULL. - Other clean ups. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29602 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
1 changed file(s) with 100 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
23962396 /// EmitResultCode - Emit the action for a pattern. Now that it has matched
23972397 /// we actually have to build a DAG!
23982398 std::pair
2399 EmitResultCode(TreePatternNode *N, bool LikeLeaf = false,
2399 EmitResultCode(TreePatternNode *N, bool &RetSelected, bool LikeLeaf = false,
24002400 bool isRoot = false) {
24012401 // This is something selected from the pattern we matched.
24022402 if (!N->getName().empty()) {
24882488 if (isRoot && N->isLeaf()) {
24892489 emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
24902490 emitCode("Result = Tmp" + utostr(ResNo) + ";");
2491 emitCode("return;");
2491 emitCode("return NULL;");
24922492 }
24932493 }
24942494 }
25892589 for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) {
25902590 unsigned OpOrder = EmitOrder[i].first;
25912591 TreePatternNode *Child = EmitOrder[i].second;
2592 std::pair NumTemp = EmitResultCode(Child);
2592 std::pair NumTemp =
2593 EmitResultCode(Child, RetSelected);
25932594 NumTemps[OpOrder] = NumTemp;
25942595 }
25952596
27022703 if (!isRoot)
27032704 return std::make_pair(1, ResNo);
27042705
2705 for (unsigned i = 0; i < NumResults; i++)
2706 emitCode("ReplaceUses(SDOperand(N.Val, " +
2707 utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));");
2708
2706 bool NeedReplace = false;
27092707 if (NodeHasOutFlag)
27102708 emitCode("InFlag = SDOperand(ResNode, " +
27112709 utostr(NumResults + (unsigned)NodeHasChain) + ");");
27142712 emitCode("ReplaceUses(SDOperand(N.Val, 0), SDOperand(ResNode, 0));");
27152713 NumResults = 1;
27162714 }
2717
2718 if (InputHasChain)
2719 emitCode("ReplaceUses(SDOperand(N.Val, " +
2720 utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " +
2721 ChainName + ".ResNo" + "));");
27222715
27232716 if (FoldedChains.size() > 0) {
27242717 std::string Code;
27272720 FoldedChains[j].first + ".Val, " +
27282721 utostr(FoldedChains[j].second) + "), SDOperand(ResNode, " +
27292722 utostr(NumResults) + "));");
2730 }
2731
2732 if (NodeHasOutFlag)
2723 NeedReplace = true;
2724 }
2725
2726 if (NodeHasOutFlag) {
27332727 emitCode("ReplaceUses(SDOperand(N.Val, " +
27342728 utostr(PatResults + (unsigned)InputHasChain) +"), InFlag);");
2729 NeedReplace = true;
2730 }
2731
2732 if (NeedReplace) {
2733 for (unsigned i = 0; i < NumResults; i++)
2734 emitCode("ReplaceUses(SDOperand(N.Val, " +
2735 utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));");
2736 if (InputHasChain)
2737 emitCode("ReplaceUses(SDOperand(N.Val, " +
2738 utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " +
2739 ChainName + ".ResNo" + "));");
2740 } else {
2741 RetSelected = true;
2742 }
27352743
27362744 // User does not expect the instruction would produce a chain!
2737 bool AddedChain = NodeHasChain && !InputHasChain;
2738 if (AddedChain && NodeHasOutFlag) {
2745 if ((!InputHasChain && NodeHasChain) && NodeHasOutFlag) {
27392746 if (PatResults == 0) {
27402747 emitCode("Result = SDOperand(ResNode, N.ResNo+1);");
27412748 } else {
2742 emitCode("if (N.ResNo < " + utostr(PatResults) + ")");
2743 emitCode(" Result = SDOperand(ResNode, N.ResNo);");
2744 emitCode("else");
2745 emitCode(" Result = SDOperand(ResNode, N.ResNo+1);");
2749 assert(PatResults == 1);
2750 emitCode("Result = (N.ResNo == 0) ? SDOperand(ResNode, 0) :"
2751 " SDOperand(ResNode, 1);");
27462752 }
27472753 } else if (InputHasChain && !NodeHasChain) {
27482754 // One of the inner node produces a chain.
2749 emitCode("if (N.ResNo < " + utostr(PatResults) + ")");
2750 emitCode(" Result = SDOperand(ResNode, N.ResNo);");
27512755 if (NodeHasOutFlag) {
2752 emitCode("else if (N.ResNo > " + utostr(PatResults) + ")");
2753 emitCode(" Result = SDOperand(ResNode, N.ResNo-1);");
2754 }
2755 emitCode("else");
2756 emitCode(" Result = SDOperand(" + ChainName + ".Val, " +
2757 ChainName + ".ResNo);");
2758 } else {
2756 emitCode("Result = (N.ResNo < " + utostr(PatResults) +
2757 ") ? SDOperand(ResNode, N.ResNo) : " +
2758 "(N.ResNo > " + utostr(PatResults) + ") ? " +
2759 "SDOperand(ResNode, N.ResNo-1) : " + ChainName + "));");
2760 emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(PatResults+1) +
2761 "), SDOperand(ResNode, N.ResNo-1));");
2762 } else {
2763 emitCode("Result = (N.ResNo < " + utostr(PatResults) +
2764 ") ? SDOperand(ResNode, N.ResNo) : " +
2765 ChainName + ";");
2766 }
2767 for (unsigned i = 0; i < PatResults; ++i)
2768 emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(i) +
2769 "), SDOperand(ResNode, " + utostr(i) + "));");
2770 emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(PatResults) +
2771 "), " + ChainName + ");");
2772 RetSelected = false;
2773 } else {
27592774 emitCode("Result = SDOperand(ResNode, N.ResNo);");
27602775 }
2776
2777 if (RetSelected)
2778 emitCode("return Result.Val;");
2779 else
2780 emitCode("return NULL;");
27612781 } else {
27622782 // If this instruction is the root, and if there is only one use of it,
27632783 // use SelectNodeTo instead of getTargetNode to avoid an allocation.
27732793 if (NodeHasInFlag || HasImpInputs)
27742794 Code += ", InFlag";
27752795 emitCode(Code + ");");
2796 if (isRoot)
2797 emitCode(" return NULL;");
27762798 emitCode("} else {");
27772799 emitDecl("ResNode", 1);
27782800 Code = " ResNode = CurDAG->getTargetNode(Opc" + utostr(OpcNo);
27882810 if (NodeHasInFlag || HasImpInputs)
27892811 Code += ", InFlag";
27902812 emitCode(Code + ");");
2791 emitCode(" ReplaceUses(N, SDOperand(ResNode, 0));");
27922813 emitCode(" Result = SDOperand(ResNode, 0);");
2814 if (isRoot)
2815 emitCode(" return Result.Val;");
27932816 emitCode("}");
27942817 }
27952818
2796 if (isRoot)
2797 emitCode("return;");
27982819 return std::make_pair(1, ResNo);
27992820 } else if (Op->isSubClassOf("SDNodeXForm")) {
28002821 assert(N->getNumChildren() == 1 && "node xform should have one child!");
28012822 // PatLeaf node - the operand may or may not be a leaf node. But it should
28022823 // behave like one.
2803 unsigned OpVal = EmitResultCode(N->getChild(0), true).second;
2824 unsigned OpVal = EmitResultCode(N->getChild(0), RetSelected, true).second;
28042825 unsigned ResNo = TmpNo++;
28052826 emitDecl("Tmp" + utostr(ResNo));
28062827 emitCode("Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
28072828 + "(Tmp" + utostr(OpVal) + ".Val);");
28082829 if (isRoot) {
2809 emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
2830 //emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
28102831 emitCode("Result = Tmp" + utostr(ResNo) + ";");
2811 emitCode("return;");
2832 emitCode("return Result.Val;");
28122833 }
28132834 return std::make_pair(1, ResNo);
28142835 } else {
29472968
29482969 // Emit the matcher, capturing named arguments in VariableMap.
29492970 bool FoundChain = false;
2950 Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", "", FoundChain);
2971 Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", "",
2972 FoundChain);
29512973
29522974 // TP - Get *SOME* tree pattern, we don't care which.
29532975 TreePattern &TP = *PatternFragments.begin()->second;
29853007 // otherwise we are done.
29863008 } while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N", true));
29873009
2988 Emitter.EmitResultCode(Pattern.getDstPattern(), false, true /*the root*/);
3010 bool RetSelected = false;
3011 Emitter.EmitResultCode(Pattern.getDstPattern(), RetSelected, false, true);
29893012 delete Pat;
29903013 }
29913014
33383361 } else {
33393362 EmitFuncNum = EmitFunctions.size();
33403363 EmitFunctions.insert(std::make_pair(CalleeCode, EmitFuncNum));
3341 OS << "void " << "Emit_" << utostr(EmitFuncNum) << CalleeCode;
3364 OS << "SDNode *Emit_" << utostr(EmitFuncNum) << CalleeCode;
33423365 }
33433366
33443367 // Replace the emission code within selection routines with calls to the
33453368 // emission functions.
3346 CallerCode = "Emit_" + utostr(EmitFuncNum) + CallerCode;
3369 CallerCode = "return Emit_" + utostr(EmitFuncNum) + CallerCode;
33473370 GeneratedCode.push_back(std::make_pair(false, CallerCode));
3348 GeneratedCode.push_back(std::make_pair(false, "return;"));
33493371 }
33503372
33513373 // Print function.
33603382 } else
33613383 OpVTI->second.push_back(OpVTStr);
33623384
3363 OS << "void Select_" << OpName << (OpVTStr != "" ? "_" : "")
3385 OS << "SDNode *Select_" << OpName << (OpVTStr != "" ? "_" : "")
33643386 << OpVTStr << "(SDOperand &Result, const SDOperand &N) {\n";
33653387
33663388 // Print all declarations.
34023424 "Intrinsic::getName((Intrinsic::ID)iid);\n";
34033425 }
34043426 OS << " std::cerr << '\\n';\n"
3405 << " abort();\n";
3427 << " abort();\n"
3428 << " return NULL;\n";
34063429 }
34073430 OS << "}\n\n";
34083431 }
34093432 }
34103433
34113434 // Emit boilerplate.
3412 OS << "void Select_INLINEASM(SDOperand& Result, SDOperand N) {\n"
3435 OS << "SDNode *Select_INLINEASM(SDOperand& Result, SDOperand N) {\n"
34133436 << " std::vector Ops(N.Val->op_begin(), N.Val->op_end());\n"
34143437 << " AddToQueue(Ops[0], N.getOperand(0)); // Select the chain.\n\n"
34153438 << " // Select the flag operand.\n"
34213444 << " VTs.push_back(MVT::Flag);\n"
34223445 << " SDOperand New = CurDAG->getNode(ISD::INLINEASM, VTs, &Ops[0], "
34233446 "Ops.size());\n"
3424 << " ReplaceUses(SDOperand(N.Val, 0), New);\n"
3425 << " ReplaceUses(SDOperand(N.Val, 1), SDOperand(New.Val, 1));\n"
34263447 << " Result = New.getValue(N.ResNo);\n"
3427 << " return;\n"
3448 << " return Result.Val;\n"
34283449 << "}\n\n";
34293450
34303451 OS << "// The main instruction selector code.\n"
3431 << "void SelectCode(SDOperand &Result, SDOperand N) {\n"
3452 << "SDNode *SelectCode(SDOperand &Result, SDOperand N) {\n"
34323453 << " if (N.getOpcode() >= ISD::BUILTIN_OP_END &&\n"
34333454 << " N.getOpcode() < (ISD::BUILTIN_OP_END+" << InstNS
34343455 << "INSTRUCTION_LIST_END)) {\n"
34353456 << " Result = N;\n"
3436 << " return; // Already selected.\n"
3457 << " return NULL; // Already selected.\n"
34373458 << " }\n\n"
34383459 << " switch (N.getOpcode()) {\n"
34393460 << " default: break;\n"
34473468 << " case ISD::TargetJumpTable:\n"
34483469 << " case ISD::TargetGlobalAddress: {\n"
34493470 << " Result = N;\n"
3450 << " return;\n"
3471 << " return NULL;\n"
34513472 << " }\n"
34523473 << " case ISD::AssertSext:\n"
34533474 << " case ISD::AssertZext: {\n"
34543475 << " AddToQueue(Result, N.getOperand(0));\n"
34553476 << " ReplaceUses(N, Result);\n"
3456 << " return;\n"
3477 << " return NULL;\n"
34573478 << " }\n"
34583479 << " case ISD::TokenFactor:\n"
34593480 << " case ISD::CopyFromReg:\n"
34633484 << " AddToQueue(Dummy, N.getOperand(i));\n"
34643485 << " }\n"
34653486 << " Result = N;\n"
3466 << " return;\n"
3487 << " return NULL;\n"
34673488 << " }\n"
3468 << " case ISD::INLINEASM: Select_INLINEASM(Result, N); return;\n";
3489 << " case ISD::INLINEASM: return Select_INLINEASM(Result, N);\n";
34693490
34703491
34713492 // Loop over all of the case statements, emiting a call to each method we
34843505 OS << " case " << OpcodeInfo.getEnumName() << ": {\n";
34853506 if (OpVTs.size() == 1) {
34863507 std::string &VTStr = OpVTs[0];
3487 OS << " Select_" << OpName
3508 OS << " return Select_" << OpName
34883509 << (VTStr != "" ? "_" : "") << VTStr << "(Result, N);\n";
34893510 } else {
34903511 if (OpcodeInfo.getNumResults())
34953516 else
34963517 OS << " MVT::ValueType NVT = (N.getNumOperands() > 0) ?"
34973518 << " N.getOperand(0).Val->getValueType(0) : MVT::isVoid;\n";
3498 int ElseCase = -1;
3499 bool First = true;
3519 int Default = -1;
3520 OS << " switch (NVT) {\n";
35003521 for (unsigned i = 0, e = OpVTs.size(); i < e; ++i) {
35013522 std::string &VTStr = OpVTs[i];
35023523 if (VTStr == "") {
3503 ElseCase = i;
3524 Default = i;
35043525 continue;
35053526 }
3506 OS << (First ? " if" : " else if")
3507 << " (NVT == MVT::" << VTStr << ")\n"
3508 << " Select_" << OpName
3527 OS << " case MVT::" << VTStr << ":\n"
3528 << " return Select_" << OpName
35093529 << "_" << VTStr << "(Result, N);\n";
3510 First = false;
3511 }
3512 if (ElseCase != -1)
3513 OS << " else\n" << " Select_" << OpName << "(Result, N);\n";
3530 }
3531 OS << " default:\n";
3532 if (Default != -1)
3533 OS << " return Select_" << OpName << "(Result, N);\n";
35143534 else
3515 OS << " else\n" << " break;\n";
3516 }
3517 OS << " return;\n";
3535 OS << " break;\n";
3536 OS << " }\n";
3537 OS << " break;\n";
3538 }
35183539 OS << " }\n";
35193540 }
35203541
35323553 << " }\n"
35333554 << " std::cerr << '\\n';\n"
35343555 << " abort();\n"
3556 << " return NULL;\n"
35353557 << "}\n";
35363558 }
35373559
35813603 OS << " return ISelSelected[Id / 8] & (1 << (Id % 8));\n";
35823604 OS << "}\n\n";
35833605
3584 OS << "inline void AddToQueue(SDOperand &Result, SDOperand N) {\n";
3606 OS << "void AddToQueue(SDOperand &Result, SDOperand N) NOINLINE {\n";
35853607 OS << " Result = N;\n";
35863608 OS << " int Id = N.Val->getNodeId();\n";
35873609 OS << " if (Id != -1 && !isQueued(Id)) {\n";
36033625 OS << " }\n";
36043626 OS << "}\n\n";
36053627
3606 OS << "inline void ReplaceUses(SDOperand F, SDOperand T) {\n";
3628 OS << "void ReplaceUses(SDOperand F, SDOperand T) NOINLINE {\n";
36073629 OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, ISelKilled);\n";
36083630 OS << " setSelected(F.Val->getNodeId());\n";
3631 OS << " RemoveKilled();\n";
3632 OS << "}\n";
3633 OS << "inline void ReplaceUses(SDNode *F, SDNode *T) {\n";
3634 OS << " CurDAG->ReplaceAllUsesWith(F, T, &ISelKilled);\n";
3635 OS << " setSelected(F->getNodeId());\n";
36093636 OS << " RemoveKilled();\n";
36103637 OS << "}\n\n";
36113638
36253652 OS << " SDNode *Node = ISelQueue.front();\n";
36263653 OS << " std::pop_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
36273654 OS << " ISelQueue.pop_back();\n";
3628 OS << " if (!isSelected(Node->getNodeId()))\n";
3629 OS << " Select(Tmp, SDOperand(Node, 0));\n";
3655 OS << " if (!isSelected(Node->getNodeId())) {\n";
3656 OS << " SDNode *ResNode = Select(Tmp, SDOperand(Node, 0));\n";
3657 OS << " if (ResNode) ReplaceUses(Node, ResNode);\n";
3658 OS << " }\n";
36303659 OS << " }\n";
36313660 OS << "\n";
36323661 OS << " delete[] ISelQueued;\n";