Added support for variable_ops.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28788 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 459eece..4ffdcf6 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -2500,6 +2500,7 @@
if (InstPatNode && InstPatNode->getOperator()->getName() == "set") {
InstPatNode = InstPatNode->getChild(1);
}
+ bool HasVarOps = isRoot && II.hasVariableNumberOfOperands;
bool HasImpInputs = isRoot && Inst.getNumImpOperands() > 0;
bool HasImpResults = isRoot && Inst.getNumImpResults() > 0;
bool NodeHasOptInFlag = isRoot &&
@@ -2515,10 +2516,11 @@
if (NodeHasInFlag || NodeHasOutFlag || NodeHasOptInFlag || HasImpInputs)
emitDecl("InFlag");
- if (NodeHasOptInFlag) {
- emitCode("bool HasOptInFlag = "
+ if (NodeHasOptInFlag)
+ emitCode("bool HasInFlag = "
"N.getOperand(N.getNumOperands()-1).getValueType() == MVT::Flag;");
- }
+ if (HasVarOps)
+ emitCode("std::vector<SDOperand> Ops;");
// How many results is this pattern expected to produce?
unsigned PatResults = 0;
@@ -2581,7 +2583,7 @@
if (NodeHasInFlag || HasImpInputs)
EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true);
if (NodeHasOptInFlag) {
- emitCode("if (HasOptInFlag)");
+ emitCode("if (HasInFlag)");
emitCode(" Select(InFlag, N.getOperand(N.getNumOperands()-1));");
}
@@ -2596,96 +2598,87 @@
unsigned ResNo = TmpNo++;
if (!isRoot || InputHasChain || NodeHasChain || NodeHasOutFlag ||
NodeHasOptInFlag) {
- if (NodeHasOptInFlag) {
- unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren();
- emitDecl("ResNode", true);
- emitCode("if (HasOptInFlag)");
- std::string Code = " ResNode = CurDAG->getTargetNode(" +
- II.Namespace + "::" + II.TheDef->getName();
-
- // Output order: results, chain, flags
- // Result types.
- if (PatResults > 0) {
- if (N->getTypeNum(0) != MVT::isVoid)
- Code += ", " + getEnumName(N->getTypeNum(0));
- }
- if (NodeHasChain)
- Code += ", MVT::Other";
- if (NodeHasOutFlag)
- Code += ", MVT::Flag";
-
- // Inputs.
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- Code += ", Tmp" + utostr(Ops[i]);
- if (NodeHasChain) Code += ", " + ChainName;
- emitCode(Code + ", InFlag);");
-
- emitCode("else");
- Code = " ResNode = CurDAG->getTargetNode(" + II.Namespace + "::" +
- II.TheDef->getName();
-
- // Output order: results, chain, flags
- // Result types.
- if (PatResults > 0 && N->getTypeNum(0) != MVT::isVoid)
- Code += ", " + getEnumName(N->getTypeNum(0));
- if (NodeHasChain)
- Code += ", MVT::Other";
- if (NodeHasOutFlag)
- Code += ", MVT::Flag";
-
- // Inputs.
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- Code += ", Tmp" + utostr(Ops[i]);
- if (NodeHasChain) Code += ", " + ChainName + ");";
- emitCode(Code);
-
- if (NodeHasChain)
- // Remember which op produces the chain.
- emitCode(ChainName + " = SDOperand(ResNode" +
- ", " + utostr(PatResults) + ");");
+ std::string Code;
+ std::string Code2;
+ std::string NodeName;
+ if (!isRoot) {
+ NodeName = "Tmp" + utostr(ResNo);
+ emitDecl(NodeName);
+ Code2 = NodeName + " = SDOperand(";
} else {
- std::string Code;
- std::string NodeName;
- if (!isRoot) {
- NodeName = "Tmp" + utostr(ResNo);
- emitDecl(NodeName);
- Code = NodeName + " = SDOperand(";
- } else {
- NodeName = "ResNode";
- emitDecl(NodeName, true);
- Code = NodeName + " = ";
- }
- Code += "CurDAG->getTargetNode(" +
- II.Namespace + "::" + II.TheDef->getName();
-
- // Output order: results, chain, flags
- // Result types.
- if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid)
- Code += ", " + getEnumName(N->getTypeNum(0));
- if (NodeHasChain)
- Code += ", MVT::Other";
- if (NodeHasOutFlag)
- Code += ", MVT::Flag";
-
- // Inputs.
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- Code += ", Tmp" + utostr(Ops[i]);
- if (NodeHasChain) Code += ", " + ChainName;
- if (NodeHasInFlag || HasImpInputs) Code += ", InFlag";
- if (!isRoot)
- emitCode(Code + "), 0);");
- else
- emitCode(Code + ");");
-
- if (NodeHasChain)
- // Remember which op produces the chain.
- if (!isRoot)
- emitCode(ChainName + " = SDOperand(" + NodeName +
- ".Val, " + utostr(PatResults) + ");");
- else
- emitCode(ChainName + " = SDOperand(" + NodeName +
- ", " + utostr(PatResults) + ");");
+ NodeName = "ResNode";
+ emitDecl(NodeName, true);
+ Code2 = NodeName + " = ";
}
+ Code = "CurDAG->getTargetNode(" +
+ II.Namespace + "::" + II.TheDef->getName();
+
+ // Output order: results, chain, flags
+ // Result types.
+ if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid)
+ Code += ", " + getEnumName(N->getTypeNum(0));
+ if (NodeHasChain)
+ Code += ", MVT::Other";
+ if (NodeHasOutFlag)
+ Code += ", MVT::Flag";
+
+ // Inputs.
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
+ if (HasVarOps)
+ emitCode("Ops.push_back(Tmp" + utostr(Ops[i]) + ");");
+ else
+ Code += ", Tmp" + utostr(Ops[i]);
+ }
+
+ if (HasVarOps) {
+ if (NodeHasInFlag || HasImpInputs)
+ emitCode("for (unsigned i = 2, e = N.getNumOperands()-1; "
+ "i != e; ++i) {");
+ else if (NodeHasOptInFlag)
+ emitCode("for (unsigned i = 2, e = N.getNumOperands()-HasInFlag; "
+ "i != e; ++i) {");
+ else
+ emitCode("for (unsigned i = 2, e = N.getNumOperands(); "
+ "i != e; ++i) {");
+ emitCode(" SDOperand VarOp(0, 0);");
+ emitCode(" Select(VarOp, N.getOperand(i));");
+ emitCode(" Ops.push_back(VarOp);");
+ emitCode("}");
+ }
+
+ if (NodeHasChain) {
+ if (HasVarOps)
+ emitCode("Ops.push_back(" + ChainName + ");");
+ else
+ Code += ", " + ChainName;
+ }
+ if (NodeHasInFlag || HasImpInputs) {
+ if (HasVarOps)
+ emitCode("Ops.push_back(InFlag);");
+ else
+ Code += ", InFlag";
+ } else if (NodeHasOptInFlag && HasVarOps) {
+ emitCode("if (HasInFlag)");
+ emitCode(" Ops.push_back(InFlag);");
+ }
+
+ if (HasVarOps)
+ Code += ", Ops";
+ else if (NodeHasOptInFlag)
+ Code = "HasInFlag ? " + Code + ", InFlag) : " + Code;
+
+ if (!isRoot)
+ Code += "), 0";
+ emitCode(Code2 + Code + ");");
+
+ if (NodeHasChain)
+ // Remember which op produces the chain.
+ if (!isRoot)
+ emitCode(ChainName + " = SDOperand(" + NodeName +
+ ".Val, " + utostr(PatResults) + ");");
+ else
+ emitCode(ChainName + " = SDOperand(" + NodeName +
+ ", " + utostr(PatResults) + ");");
if (!isRoot)
return std::make_pair(1, ResNo);