aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/DAGISelEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/DAGISelEmitter.cpp')
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp78
1 files changed, 56 insertions, 22 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 3b0d4ea..25afc49 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 <opname>" or "<opname>". 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<ConstantSDNode>(" << 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<ResNo> 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<DefInit*>(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<IntInit*>(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<std::pair<unsigned, TreePatternNode*> > 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<SDOperand, SDOperand>::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<RegisterSDNode>(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<RegisterSDNode>(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"