summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp163
1 files changed, 96 insertions, 67 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 8a887017c1..bcc192f9ae 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -2397,7 +2397,7 @@ public:
/// EmitResultCode - Emit the action for a pattern. Now that it has matched
/// we actually have to build a DAG!
std::pair<unsigned, unsigned>
- EmitResultCode(TreePatternNode *N, bool LikeLeaf = false,
+ EmitResultCode(TreePatternNode *N, bool &RetSelected, bool LikeLeaf = false,
bool isRoot = false) {
// This is something selected from the pattern we matched.
if (!N->getName().empty()) {
@@ -2489,7 +2489,7 @@ public:
if (isRoot && N->isLeaf()) {
emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
emitCode("Result = Tmp" + utostr(ResNo) + ";");
- emitCode("return;");
+ emitCode("return NULL;");
}
}
}
@@ -2590,7 +2590,8 @@ public:
for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) {
unsigned OpOrder = EmitOrder[i].first;
TreePatternNode *Child = EmitOrder[i].second;
- std::pair<unsigned, unsigned> NumTemp = EmitResultCode(Child);
+ std::pair<unsigned, unsigned> NumTemp =
+ EmitResultCode(Child, RetSelected);
NumTemps[OpOrder] = NumTemp;
}
@@ -2703,10 +2704,7 @@ public:
if (!isRoot)
return std::make_pair(1, ResNo);
- for (unsigned i = 0; i < NumResults; i++)
- emitCode("ReplaceUses(SDOperand(N.Val, " +
- utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));");
-
+ bool NeedReplace = false;
if (NodeHasOutFlag)
emitCode("InFlag = SDOperand(ResNode, " +
utostr(NumResults + (unsigned)NodeHasChain) + ");");
@@ -2716,11 +2714,6 @@ public:
NumResults = 1;
}
- if (InputHasChain)
- emitCode("ReplaceUses(SDOperand(N.Val, " +
- utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " +
- ChainName + ".ResNo" + "));");
-
if (FoldedChains.size() > 0) {
std::string Code;
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++)
@@ -2728,37 +2721,64 @@ public:
FoldedChains[j].first + ".Val, " +
utostr(FoldedChains[j].second) + "), SDOperand(ResNode, " +
utostr(NumResults) + "));");
+ NeedReplace = true;
}
- if (NodeHasOutFlag)
+ if (NodeHasOutFlag) {
emitCode("ReplaceUses(SDOperand(N.Val, " +
utostr(PatResults + (unsigned)InputHasChain) +"), InFlag);");
+ NeedReplace = true;
+ }
+
+ if (NeedReplace) {
+ for (unsigned i = 0; i < NumResults; i++)
+ emitCode("ReplaceUses(SDOperand(N.Val, " +
+ utostr(i) + "), SDOperand(ResNode, " + utostr(i) + "));");
+ if (InputHasChain)
+ emitCode("ReplaceUses(SDOperand(N.Val, " +
+ utostr(PatResults) + "), SDOperand(" + ChainName + ".Val, " +
+ ChainName + ".ResNo" + "));");
+ } else {
+ RetSelected = true;
+ }
// User does not expect the instruction would produce a chain!
- bool AddedChain = NodeHasChain && !InputHasChain;
- if (AddedChain && NodeHasOutFlag) {
+ if ((!InputHasChain && NodeHasChain) && NodeHasOutFlag) {
if (PatResults == 0) {
emitCode("Result = SDOperand(ResNode, N.ResNo+1);");
} else {
- emitCode("if (N.ResNo < " + utostr(PatResults) + ")");
- emitCode(" Result = SDOperand(ResNode, N.ResNo);");
- emitCode("else");
- emitCode(" Result = SDOperand(ResNode, N.ResNo+1);");
+ assert(PatResults == 1);
+ emitCode("Result = (N.ResNo == 0) ? SDOperand(ResNode, 0) :"
+ " SDOperand(ResNode, 1);");
}
} else if (InputHasChain && !NodeHasChain) {
// One of the inner node produces a chain.
- emitCode("if (N.ResNo < " + utostr(PatResults) + ")");
- emitCode(" Result = SDOperand(ResNode, N.ResNo);");
if (NodeHasOutFlag) {
- emitCode("else if (N.ResNo > " + utostr(PatResults) + ")");
- emitCode(" Result = SDOperand(ResNode, N.ResNo-1);");
- }
- emitCode("else");
- emitCode(" Result = SDOperand(" + ChainName + ".Val, " +
- ChainName + ".ResNo);");
- } else {
+ emitCode("Result = (N.ResNo < " + utostr(PatResults) +
+ ") ? SDOperand(ResNode, N.ResNo) : " +
+ "(N.ResNo > " + utostr(PatResults) + ") ? " +
+ "SDOperand(ResNode, N.ResNo-1) : " + ChainName + "));");
+ emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(PatResults+1) +
+ "), SDOperand(ResNode, N.ResNo-1));");
+ } else {
+ emitCode("Result = (N.ResNo < " + utostr(PatResults) +
+ ") ? SDOperand(ResNode, N.ResNo) : " +
+ ChainName + ";");
+ }
+ for (unsigned i = 0; i < PatResults; ++i)
+ emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(i) +
+ "), SDOperand(ResNode, " + utostr(i) + "));");
+ emitCode("ReplaceUses(SDOperand(N.Val, " + utostr(PatResults) +
+ "), " + ChainName + ");");
+ RetSelected = false;
+ } else {
emitCode("Result = SDOperand(ResNode, N.ResNo);");
}
+
+ if (RetSelected)
+ emitCode("return Result.Val;");
+ else
+ emitCode("return NULL;");
} else {
// If this instruction is the root, and if there is only one use of it,
// use SelectNodeTo instead of getTargetNode to avoid an allocation.
@@ -2774,6 +2794,8 @@ public:
if (NodeHasInFlag || HasImpInputs)
Code += ", InFlag";
emitCode(Code + ");");
+ if (isRoot)
+ emitCode(" return NULL;");
emitCode("} else {");
emitDecl("ResNode", 1);
Code = " ResNode = CurDAG->getTargetNode(Opc" + utostr(OpcNo);
@@ -2789,27 +2811,26 @@ public:
if (NodeHasInFlag || HasImpInputs)
Code += ", InFlag";
emitCode(Code + ");");
- emitCode(" ReplaceUses(N, SDOperand(ResNode, 0));");
emitCode(" Result = SDOperand(ResNode, 0);");
+ if (isRoot)
+ emitCode(" return Result.Val;");
emitCode("}");
}
- if (isRoot)
- emitCode("return;");
return std::make_pair(1, ResNo);
} else if (Op->isSubClassOf("SDNodeXForm")) {
assert(N->getNumChildren() == 1 && "node xform should have one child!");
// PatLeaf node - the operand may or may not be a leaf node. But it should
// behave like one.
- unsigned OpVal = EmitResultCode(N->getChild(0), true).second;
+ unsigned OpVal = EmitResultCode(N->getChild(0), RetSelected, true).second;
unsigned ResNo = TmpNo++;
emitDecl("Tmp" + utostr(ResNo));
emitCode("Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
+ "(Tmp" + utostr(OpVal) + ".Val);");
if (isRoot) {
- emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
+ //emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
emitCode("Result = Tmp" + utostr(ResNo) + ";");
- emitCode("return;");
+ emitCode("return Result.Val;");
}
return std::make_pair(1, ResNo);
} else {
@@ -2948,7 +2969,8 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
// Emit the matcher, capturing named arguments in VariableMap.
bool FoundChain = false;
- Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", "", FoundChain);
+ Emitter.EmitMatchCode(Pattern.getSrcPattern(), NULL, "N", "", "",
+ FoundChain);
// TP - Get *SOME* tree pattern, we don't care which.
TreePattern &TP = *PatternFragments.begin()->second;
@@ -2986,7 +3008,8 @@ void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
// otherwise we are done.
} while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N", true));
- Emitter.EmitResultCode(Pattern.getDstPattern(), false, true /*the root*/);
+ bool RetSelected = false;
+ Emitter.EmitResultCode(Pattern.getDstPattern(), RetSelected, false, true);
delete Pat;
}
@@ -3339,14 +3362,13 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
} else {
EmitFuncNum = EmitFunctions.size();
EmitFunctions.insert(std::make_pair(CalleeCode, EmitFuncNum));
- OS << "void " << "Emit_" << utostr(EmitFuncNum) << CalleeCode;
+ OS << "SDNode *Emit_" << utostr(EmitFuncNum) << CalleeCode;
}
// Replace the emission code within selection routines with calls to the
// emission functions.
- CallerCode = "Emit_" + utostr(EmitFuncNum) + CallerCode;
+ CallerCode = "return Emit_" + utostr(EmitFuncNum) + CallerCode;
GeneratedCode.push_back(std::make_pair(false, CallerCode));
- GeneratedCode.push_back(std::make_pair(false, "return;"));
}
// Print function.
@@ -3361,7 +3383,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
} else
OpVTI->second.push_back(OpVTStr);
- OS << "void Select_" << OpName << (OpVTStr != "" ? "_" : "")
+ OS << "SDNode *Select_" << OpName << (OpVTStr != "" ? "_" : "")
<< OpVTStr << "(SDOperand &Result, const SDOperand &N) {\n";
// Print all declarations.
@@ -3403,14 +3425,15 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
"Intrinsic::getName((Intrinsic::ID)iid);\n";
}
OS << " std::cerr << '\\n';\n"
- << " abort();\n";
+ << " abort();\n"
+ << " return NULL;\n";
}
OS << "}\n\n";
}
}
// Emit boilerplate.
- OS << "void Select_INLINEASM(SDOperand& Result, SDOperand N) {\n"
+ OS << "SDNode *Select_INLINEASM(SDOperand& Result, SDOperand N) {\n"
<< " std::vector<SDOperand> Ops(N.Val->op_begin(), N.Val->op_end());\n"
<< " AddToQueue(Ops[0], N.getOperand(0)); // Select the chain.\n\n"
<< " // Select the flag operand.\n"
@@ -3422,19 +3445,17 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
<< " VTs.push_back(MVT::Flag);\n"
<< " SDOperand New = CurDAG->getNode(ISD::INLINEASM, VTs, &Ops[0], "
"Ops.size());\n"
- << " ReplaceUses(SDOperand(N.Val, 0), New);\n"
- << " ReplaceUses(SDOperand(N.Val, 1), SDOperand(New.Val, 1));\n"
<< " Result = New.getValue(N.ResNo);\n"
- << " return;\n"
+ << " return Result.Val;\n"
<< "}\n\n";
OS << "// The main instruction selector code.\n"
- << "void SelectCode(SDOperand &Result, SDOperand N) {\n"
+ << "SDNode *SelectCode(SDOperand &Result, SDOperand N) {\n"
<< " if (N.getOpcode() >= ISD::BUILTIN_OP_END &&\n"
<< " N.getOpcode() < (ISD::BUILTIN_OP_END+" << InstNS
<< "INSTRUCTION_LIST_END)) {\n"
<< " Result = N;\n"
- << " return; // Already selected.\n"
+ << " return NULL; // Already selected.\n"
<< " }\n\n"
<< " switch (N.getOpcode()) {\n"
<< " default: break;\n"
@@ -3448,13 +3469,13 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
<< " case ISD::TargetJumpTable:\n"
<< " case ISD::TargetGlobalAddress: {\n"
<< " Result = N;\n"
- << " return;\n"
+ << " return NULL;\n"
<< " }\n"
<< " case ISD::AssertSext:\n"
<< " case ISD::AssertZext: {\n"
<< " AddToQueue(Result, N.getOperand(0));\n"
<< " ReplaceUses(N, Result);\n"
- << " return;\n"
+ << " return NULL;\n"
<< " }\n"
<< " case ISD::TokenFactor:\n"
<< " case ISD::CopyFromReg:\n"
@@ -3464,9 +3485,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
<< " AddToQueue(Dummy, N.getOperand(i));\n"
<< " }\n"
<< " Result = N;\n"
- << " return;\n"
+ << " return NULL;\n"
<< " }\n"
- << " case ISD::INLINEASM: Select_INLINEASM(Result, N); return;\n";
+ << " case ISD::INLINEASM: return Select_INLINEASM(Result, N);\n";
// Loop over all of the case statements, emiting a call to each method we
@@ -3485,7 +3506,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
OS << " case " << OpcodeInfo.getEnumName() << ": {\n";
if (OpVTs.size() == 1) {
std::string &VTStr = OpVTs[0];
- OS << " Select_" << OpName
+ OS << " return Select_" << OpName
<< (VTStr != "" ? "_" : "") << VTStr << "(Result, N);\n";
} else {
if (OpcodeInfo.getNumResults())
@@ -3496,26 +3517,26 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
else
OS << " MVT::ValueType NVT = (N.getNumOperands() > 0) ?"
<< " N.getOperand(0).Val->getValueType(0) : MVT::isVoid;\n";
- int ElseCase = -1;
- bool First = true;
+ int Default = -1;
+ OS << " switch (NVT) {\n";
for (unsigned i = 0, e = OpVTs.size(); i < e; ++i) {
std::string &VTStr = OpVTs[i];
if (VTStr == "") {
- ElseCase = i;
+ Default = i;
continue;
}
- OS << (First ? " if" : " else if")
- << " (NVT == MVT::" << VTStr << ")\n"
- << " Select_" << OpName
+ OS << " case MVT::" << VTStr << ":\n"
+ << " return Select_" << OpName
<< "_" << VTStr << "(Result, N);\n";
- First = false;
}
- if (ElseCase != -1)
- OS << " else\n" << " Select_" << OpName << "(Result, N);\n";
+ OS << " default:\n";
+ if (Default != -1)
+ OS << " return Select_" << OpName << "(Result, N);\n";
else
- OS << " else\n" << " break;\n";
+ OS << " break;\n";
+ OS << " }\n";
+ OS << " break;\n";
}
- OS << " return;\n";
OS << " }\n";
}
@@ -3533,6 +3554,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
<< " }\n"
<< " std::cerr << '\\n';\n"
<< " abort();\n"
+ << " return NULL;\n"
<< "}\n";
}
@@ -3582,7 +3604,7 @@ void DAGISelEmitter::run(std::ostream &OS) {
OS << " return ISelSelected[Id / 8] & (1 << (Id % 8));\n";
OS << "}\n\n";
- OS << "inline void AddToQueue(SDOperand &Result, SDOperand N) {\n";
+ OS << "void AddToQueue(SDOperand &Result, SDOperand N) NOINLINE {\n";
OS << " Result = N;\n";
OS << " int Id = N.Val->getNodeId();\n";
OS << " if (Id != -1 && !isQueued(Id)) {\n";
@@ -3604,10 +3626,15 @@ OS << " unsigned NumKilled = ISelKilled.size();\n";
OS << " }\n";
OS << "}\n\n";
- OS << "inline void ReplaceUses(SDOperand F, SDOperand T) {\n";
+ OS << "void ReplaceUses(SDOperand F, SDOperand T) NOINLINE {\n";
OS << " CurDAG->ReplaceAllUsesOfValueWith(F, T, ISelKilled);\n";
OS << " setSelected(F.Val->getNodeId());\n";
OS << " RemoveKilled();\n";
+ OS << "}\n";
+ OS << "inline void ReplaceUses(SDNode *F, SDNode *T) {\n";
+ OS << " CurDAG->ReplaceAllUsesWith(F, T, &ISelKilled);\n";
+ OS << " setSelected(F->getNodeId());\n";
+ OS << " RemoveKilled();\n";
OS << "}\n\n";
OS << "// SelectRoot - Top level entry to DAG isel.\n";
@@ -3626,8 +3653,10 @@ OS << " unsigned NumKilled = ISelKilled.size();\n";
OS << " SDNode *Node = ISelQueue.front();\n";
OS << " std::pop_heap(ISelQueue.begin(), ISelQueue.end(), isel_sort());\n";
OS << " ISelQueue.pop_back();\n";
- OS << " if (!isSelected(Node->getNodeId()))\n";
- OS << " Select(Tmp, SDOperand(Node, 0));\n";
+ OS << " if (!isSelected(Node->getNodeId())) {\n";
+ OS << " SDNode *ResNode = Select(Tmp, SDOperand(Node, 0));\n";
+ OS << " if (ResNode) ReplaceUses(Node, ResNode);\n";
+ OS << " }\n";
OS << " }\n";
OS << "\n";
OS << " delete[] ISelQueued;\n";