diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 3b0d4eac122..25afc49dd76 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -1772,6 +1772,21 @@ public: ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr), PatternNo(PatNum), OS(os), FoundChain(false), TmpNo(0) {}; + /// DeclareSDOperand - Emit "SDOperand " or "". This works + /// around an ugly GCC bug where SelectCode is using too much stack space + void DeclareSDOperand(const std::string &OpName) const { + // If it's one of the common cases declared at the top of SelectCode, just + // use the existing declaration. + if (OpName == "N0" || OpName == "N1" || OpName == "N2" || + OpName == "N00" || OpName == "N01" || + OpName == "N10" || OpName == "N11" || + OpName == "Tmp0" || OpName == "Tmp1" || + OpName == "Tmp2" || OpName == "Tmp3") + OS << OpName; + else + OS << "SDOperand " << OpName; + } + /// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo /// if the match fails. At this point, we already know that the opcode for N /// matches, and the SDNode for the result has the RootName specified name. @@ -1845,8 +1860,9 @@ public: } for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { - OS << " SDOperand " << RootName << OpNo <<" = " << RootName - << ".getOperand(" << OpNo << ");\n"; + OS << " "; + DeclareSDOperand(RootName+utostr(OpNo)); + OS << " = " << RootName << ".getOperand(" << OpNo << ");\n"; TreePatternNode *Child = N->getChild(i); if (!Child->isLeaf()) { @@ -1915,7 +1931,7 @@ public: if (HasChain) { if (!FoundChain) { - OS << " SDOperand Chain = " << RootName << ".getOperand(0);\n"; + OS << " Chain = " << RootName << ".getOperand(0);\n"; FoundChain = true; } } @@ -1954,28 +1970,35 @@ public: case MVT::i64: OS << " uint64_t Tmp"; break; } OS << ResNo << "C = cast(" << Val << ")->getValue();\n"; - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(Tmp" + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = CurDAG->getTargetConstant(Tmp" << ResNo << "C, MVT::" << getEnumName(N->getType()) << ");\n"; } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { - OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = " << Val << ";\n"; } else if (!N->isLeaf() && N->getOperator()->getName() == "tconstpool") { - OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = " << Val << ";\n"; } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, ISE))) { std::string Fn = CP->getSelectFunc(); NumRes = CP->getNumOperands(); - OS << " SDOperand "; - for (unsigned i = 0; i < NumRes; i++) { - if (i != 0) OS << ", "; - OS << "Tmp" << i + ResNo; + for (unsigned i = 0; i != NumRes; ++i) { + OS << " "; + DeclareSDOperand("Tmp" + utostr(i+ResNo)); + OS << ";\n"; } - OS << ";\n"; OS << " if (!" << Fn << "(" << Val; for (unsigned i = 0; i < NumRes; i++) OS << ", Tmp" << i + ResNo; OS << ")) goto P" << PatternNo << "Fail;\n"; TmpNo = ResNo + NumRes; } else { - OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = Select(" << Val << ");\n"; } // Add Tmp to VariableMap, so that we don't multiply select this // value if used multiple times by this pattern result. @@ -1988,7 +2011,9 @@ public: if (DefInit *DI = dynamic_cast(N->getLeafValue())) { unsigned ResNo = TmpNo++; if (DI->getDef()->isSubClassOf("Register")) { - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getRegister(" + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = CurDAG->getRegister(" << ISE.getQualifiedName(DI->getDef()) << ", MVT::" << getEnumName(N->getType()) << ");\n"; @@ -1996,7 +2021,9 @@ public: } } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { unsigned ResNo = TmpNo++; - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(" + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = CurDAG->getTargetConstant(" << II->getValue() << ", MVT::" << getEnumName(N->getType()) << ");\n"; @@ -2018,7 +2045,7 @@ public: bool IsCopyFromReg = false; if (InFlag || OutFlag) - OS << " SDOperand InFlag = SDOperand(0,0);\n"; + OS << " InFlag = SDOperand(0, 0);\n"; // Determine operand emission order. Complex pattern first. std::vector > EmitOrder; @@ -2063,7 +2090,9 @@ public: unsigned NumResults = Inst.getNumResults(); unsigned ResNo = TmpNo++; if (!isRoot) { - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetNode(" + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = CurDAG->getTargetNode(" << II.Namespace << "::" << II.TheDef->getName(); if (N->getType() != MVT::isVoid) OS << ", MVT::" << getEnumName(N->getType()); @@ -2082,7 +2111,7 @@ public: << NumResults << ");\n"; } } else if (II.hasCtrlDep || OutFlag) { - OS << " SDOperand Result = CurDAG->getTargetNode(" + OS << " Result = CurDAG->getTargetNode(" << II.Namespace << "::" << II.TheDef->getName(); // Output order: results, chain, flags @@ -2184,7 +2213,9 @@ public: assert(N->getNumChildren() == 1 && "node xform should have one child!"); unsigned OpVal = EmitResultCode(N->getChild(0)).second; unsigned ResNo = TmpNo++; - OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName() + OS << " "; + DeclareSDOperand("Tmp"+utostr(ResNo)); + OS << " = Transform_" << Op->getName() << "(Tmp" << OpVal << ".Val);\n"; if (isRoot) { OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n"; @@ -2285,7 +2316,7 @@ private: OS << " Chain = Result.getValue(1);\n"; OS << " InFlag = Result.getValue(2);\n"; } else { - OS << " SDOperand Chain;\n"; + OS << " Chain;\n"; OS << " Result = CurDAG->getCopyFromReg(" << "CurDAG->getEntryNode(), ISE.getQualifiedName(RR)" << ", MVT::" << getEnumName(RVT) << ", InFlag);\n"; @@ -2394,6 +2425,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " return N; // Already selected.\n\n" << " std::map::iterator CGMI = CodeGenMap.find(N);\n" << " if (CGMI != CodeGenMap.end()) return CGMI->second;\n" + << " // Work arounds for GCC stack overflow bugs.\n" + << " SDOperand N0, N1, N2, N00, N01, N10, N11, Tmp0, Tmp1, Tmp2, Tmp3;\n" + << " SDOperand Chain, InFlag, Result;\n" << " switch (N.getOpcode()) {\n" << " default: break;\n" << " case ISD::EntryToken: // These leaves remain the same.\n" @@ -2419,7 +2453,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);\n" << " }\n" << " case ISD::CopyFromReg: {\n" - << " SDOperand Chain = Select(N.getOperand(0));\n" + << " Chain = Select(N.getOperand(0));\n" << " unsigned Reg = cast(N.getOperand(1))->getReg();\n" << " MVT::ValueType VT = N.Val->getValueType(0);\n" << " if (N.Val->getNumValues() == 2) {\n" @@ -2442,10 +2476,10 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { << " }\n" << " }\n" << " case ISD::CopyToReg: {\n" - << " SDOperand Chain = Select(N.getOperand(0));\n" + << " Chain = Select(N.getOperand(0));\n" << " unsigned Reg = cast(N.getOperand(1))->getReg();\n" << " SDOperand Val = Select(N.getOperand(2));\n" - << " SDOperand Result = N;\n" + << " Result = N;\n" << " if (N.Val->getNumValues() == 1) {\n" << " if (Chain != N.getOperand(0) || Val != N.getOperand(2))\n" << " Result = CurDAG->getCopyToReg(Chain, Reg, Val);\n"