mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
This ugly patch works around a GCC bug where it is compiling SelectCode to
use too much stack space, overflowing the stack for large functions. Instead of emitting new SDOperands in each match block, we emit some common ones at the top of SelectCode then reuse them when possible. This reduces the stack size of SelectCode from 28K to 21K. Note that GCC compiles it to 512 bytes :-/ I've filed GCC PR 25505 to track this. llvm-svn: 24882
This commit is contained in:
parent
338c0b2011
commit
28cf136707
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user