[llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp DAGISelEmitter.h
Evan Cheng
evan.cheng at apple.com
Fri Aug 25 17:59:18 PDT 2006
Changes in directory llvm/utils/TableGen:
DAGISelEmitter.cpp updated: 1.245 -> 1.246
DAGISelEmitter.h updated: 1.67 -> 1.68
---
Log message:
- Clean up tablegen dag isel generator code.
- Clean up the code generated by tablegen:
* AddToISelQueue now takes one argument.
* ComplexPattern matching condition can now be shared.
* Eliminate passing unnecessary arguments to emit routines.
* Eliminate some unneeded SDOperand declarations in select routines.
* Other minor clean ups.
- This reduces foot print slightly: X86ISelDAGToDAG.o is reduced from 971k
to 823k.
---
Diffs of the changes: (+240 -237)
DAGISelEmitter.cpp | 473 ++++++++++++++++++++++++++---------------------------
DAGISelEmitter.h | 4
2 files changed, 240 insertions(+), 237 deletions(-)
Index: llvm/utils/TableGen/DAGISelEmitter.cpp
diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.245 llvm/utils/TableGen/DAGISelEmitter.cpp:1.246
--- llvm/utils/TableGen/DAGISelEmitter.cpp:1.245 Wed Aug 16 02:25:15 2006
+++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Aug 25 19:59:04 2006
@@ -1909,7 +1909,6 @@
}
}
-
// NodeIsComplexPattern - return true if N is a leaf node and a subclass of
// ComplexPattern.
static bool NodeIsComplexPattern(TreePatternNode *N)
@@ -2120,11 +2119,11 @@
std::vector<std::pair<std::string, unsigned> > FoldedChains;
std::set<std::string> Duplicates;
- /// GeneratedCode - This is the buffer that we emit code to. The first bool
+ /// GeneratedCode - This is the buffer that we emit code to. The first int
/// indicates whether this is an exit predicate (something that should be
- /// tested, and if true, the match fails) [when true] or normal code to emit
- /// [when false].
- std::vector<std::pair<bool, std::string> > &GeneratedCode;
+ /// tested, and if true, the match fails) [when 1], or normal code to emit
+ /// [when 0], or initialization code to emit [when 2].
+ std::vector<std::pair<unsigned, std::string> > &GeneratedCode;
/// GeneratedDecl - This is the set of all SDOperand declarations needed for
/// the set of patterns for each top-level opcode.
std::set<std::pair<unsigned, std::string> > &GeneratedDecl;
@@ -2140,11 +2139,15 @@
void emitCheck(const std::string &S) {
if (!S.empty())
- GeneratedCode.push_back(std::make_pair(true, S));
+ GeneratedCode.push_back(std::make_pair(1, S));
}
void emitCode(const std::string &S) {
if (!S.empty())
- GeneratedCode.push_back(std::make_pair(false, S));
+ GeneratedCode.push_back(std::make_pair(0, S));
+ }
+ void emitInit(const std::string &S) {
+ if (!S.empty())
+ GeneratedCode.push_back(std::make_pair(2, S));
}
void emitDecl(const std::string &S, unsigned T=0) {
assert(!S.empty() && "Invalid declaration");
@@ -2161,12 +2164,13 @@
public:
PatternCodeEmitter(DAGISelEmitter &ise, ListInit *preds,
TreePatternNode *pattern, TreePatternNode *instr,
- std::vector<std::pair<bool, std::string> > &gc,
+ std::vector<std::pair<unsigned, std::string> > &gc,
std::set<std::pair<unsigned, std::string> > &gd,
std::vector<std::string> &to,
std::vector<std::string> &tv)
: ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr),
- GeneratedCode(gc), GeneratedDecl(gd), TargetOpcodes(to), TargetVTs(tv),
+ GeneratedCode(gc), GeneratedDecl(gd),
+ TargetOpcodes(to), TargetVTs(tv),
TmpNo(0), OpcNo(0), VTNo(0) {}
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
@@ -2290,8 +2294,7 @@
else
FoundChain = true;
ChainName = "Chain" + ChainSuffix;
- emitDecl(ChainName);
- emitCode(ChainName + " = " + RootName +
+ emitInit("SDOperand " + ChainName + " = " + RootName +
".getOperand(0);");
}
}
@@ -2312,12 +2315,12 @@
}
}
+ const ComplexPattern *CP;
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
- emitDecl(RootName + utostr(OpNo));
- emitCode(RootName + utostr(OpNo) + " = " +
+ emitInit("SDOperand " + RootName + utostr(OpNo) + " = " +
RootName + ".getOperand(" +utostr(OpNo) + ");");
- TreePatternNode *Child = N->getChild(i);
-
+
+ TreePatternNode *Child = N->getChild(i);
if (!Child->isLeaf()) {
// If it's not a leaf, recursively match.
const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator());
@@ -2354,7 +2357,19 @@
} else if (LeafRec->isSubClassOf("Register")) {
// Handle register references.
} else if (LeafRec->isSubClassOf("ComplexPattern")) {
- // Handle complex pattern. Nothing to do here.
+ // Handle complex pattern.
+ CP = NodeGetComplexPattern(Child, ISE);
+ std::string Fn = CP->getSelectFunc();
+ unsigned NumOps = CP->getNumOperands();
+ for (unsigned i = 0; i < NumOps; ++i) {
+ emitDecl("CPTmp" + utostr(i));
+ emitCode("SDOperand CPTmp" + utostr(i) + ";");
+ }
+
+ std::string Code = Fn + "(" + RootName + utostr(OpNo);
+ for (unsigned i = 0; i < NumOps; i++)
+ Code += ", CPTmp" + utostr(i);
+ emitCheck(Code + ")");
} else if (LeafRec->getName() == "srcvalue") {
// Place holder for SRCVALUE nodes. Nothing to do here.
} else if (LeafRec->isSubClassOf("ValueType")) {
@@ -2389,6 +2404,21 @@
}
}
+ // Handle cases when root is a complex pattern.
+ if (isRoot && N->isLeaf() && (CP = NodeGetComplexPattern(N, ISE))) {
+ std::string Fn = CP->getSelectFunc();
+ unsigned NumOps = CP->getNumOperands();
+ for (unsigned i = 0; i < NumOps; ++i) {
+ emitDecl("CPTmp" + utostr(i));
+ emitCode("SDOperand CPTmp" + utostr(i) + ";");
+ }
+
+ std::string Code = Fn + "(" + RootName;
+ for (unsigned i = 0; i < NumOps; i++)
+ Code += ", CPTmp" + utostr(i);
+ emitCheck(Code + ")");
+ }
+
// If there is a node predicate for this, emit the call.
if (!N->getPredicateFn().empty())
emitCheck(N->getPredicateFn() + "(" + RootName + ".Val)");
@@ -2396,9 +2426,12 @@
/// 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 &RetSelected, bool LikeLeaf = false,
- bool isRoot = false) {
+ std::vector<std::string>
+ EmitResultCode(TreePatternNode *N, bool RetSelected,
+ bool InFlagDecled, bool ResNodeDecled,
+ bool LikeLeaf = false, bool isRoot = false) {
+ // List of arguments of getTargetNode() or SelectNodeTo().
+ std::vector<std::string> NodeOps;
// This is something selected from the pattern we matched.
if (!N->getName().empty()) {
std::string &Val = VariableMap[N->getName()];
@@ -2406,12 +2439,12 @@
"Variable referenced but not defined and not caught earlier!");
if (Val[0] == 'T' && Val[1] == 'm' && Val[2] == 'p') {
// Already selected this operand, just return the tmpval.
- return std::make_pair(1, atoi(Val.c_str()+3));
+ NodeOps.push_back(Val);
+ return NodeOps;
}
const ComplexPattern *CP;
unsigned ResNo = TmpNo++;
- unsigned NumRes = 1;
if (!N->isLeaf() && N->getOperator()->getName() == "imm") {
assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
std::string CastType;
@@ -2423,107 +2456,101 @@
case MVT::i32: CastType = "unsigned"; break;
case MVT::i64: CastType = "uint64_t"; break;
}
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) +
+ emitCode("SDOperand Tmp" + utostr(ResNo) +
" = CurDAG->getTargetConstant(((" + CastType +
") cast<ConstantSDNode>(" + Val + ")->getValue()), " +
getEnumName(N->getTypeNum(0)) + ");");
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = "Tmp"+utostr(ResNo);
} else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
Record *Op = OperatorMap[N->getName()];
// Transform ExternalSymbol to TargetExternalSymbol
if (Op && Op->getName() == "externalsym") {
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = CurDAG->getTarget"
+ emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getTarget"
"ExternalSymbol(cast<ExternalSymbolSDNode>(" +
Val + ")->getSymbol(), " +
getEnumName(N->getTypeNum(0)) + ");");
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = "Tmp"+utostr(ResNo);
} else {
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";");
+ NodeOps.push_back(Val);
}
} else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") {
Record *Op = OperatorMap[N->getName()];
// Transform GlobalAddress to TargetGlobalAddress
if (Op && Op->getName() == "globaladdr") {
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = CurDAG->getTarget"
+ emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getTarget"
"GlobalAddress(cast<GlobalAddressSDNode>(" + Val +
")->getGlobal(), " + getEnumName(N->getTypeNum(0)) +
");");
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = "Tmp"+utostr(ResNo);
} else {
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";");
+ NodeOps.push_back(Val);
}
} else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";");
+ NodeOps.push_back(Val);
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = "Tmp"+utostr(ResNo);
} else if (!N->isLeaf() && N->getOperator()->getName() == "tconstpool") {
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";");
+ NodeOps.push_back(Val);
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = "Tmp"+utostr(ResNo);
} else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, ISE))) {
std::string Fn = CP->getSelectFunc();
- NumRes = CP->getNumOperands();
- for (unsigned i = 0; i < NumRes; ++i)
- emitDecl("CPTmp" + utostr(i+ResNo));
-
- std::string Code = Fn + "(" + Val;
- for (unsigned i = 0; i < NumRes; i++)
- Code += ", CPTmp" + utostr(i + ResNo);
- emitCheck(Code + ")");
-
- for (unsigned i = 0; i < NumRes; ++i) {
- emitDecl("Tmp" + utostr(i+ResNo));
- emitCode("AddToQueue(Tmp" + utostr(i+ResNo) + ", CPTmp" +
- utostr(i+ResNo) + ");");
+ for (unsigned i = 0; i < CP->getNumOperands(); ++i) {
+ emitCode("AddToISelQueue(CPTmp" + utostr(i) + ");");
+ NodeOps.push_back("CPTmp" + utostr(i));
}
-
- TmpNo = ResNo + NumRes;
} else {
- emitDecl("Tmp" + utostr(ResNo));
- // This node, probably wrapped in a SDNodeXForms, behaves like a leaf
+ // This node, probably wrapped in a SDNodeXForm, behaves like a leaf
// node even if it isn't one. Don't select it.
- if (LikeLeaf)
- emitCode("Tmp" + utostr(ResNo) + " = " + Val + ";");
- else {
- emitCode("AddToQueue(Tmp" + utostr(ResNo) + ", " + Val + ");");
+ if (!LikeLeaf) {
+ emitCode("AddToISelQueue(" + Val + ");");
if (isRoot && N->isLeaf()) {
- emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
- emitCode("Result = Tmp" + utostr(ResNo) + ";");
+ emitCode("ReplaceUses(N, " + Val + ");");
+ emitCode("Result = " + Val + ";");
emitCode("return NULL;");
}
}
+ NodeOps.push_back(Val);
}
- // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
- // value if used multiple times by this pattern result.
- Val = "Tmp"+utostr(ResNo);
- return std::make_pair(NumRes, ResNo);
+ return NodeOps;
}
if (N->isLeaf()) {
// If this is an explicit register reference, handle it.
if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
unsigned ResNo = TmpNo++;
if (DI->getDef()->isSubClassOf("Register")) {
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = CurDAG->getRegister(" +
+ emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getRegister(" +
ISE.getQualifiedName(DI->getDef()) + ", " +
getEnumName(N->getTypeNum(0)) + ");");
- return std::make_pair(1, ResNo);
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ return NodeOps;
}
} else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
unsigned ResNo = TmpNo++;
assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) +
+ emitCode("SDOperand Tmp" + utostr(ResNo) +
" = CurDAG->getTargetConstant(" + itostr(II->getValue()) +
", " + getEnumName(N->getTypeNum(0)) + ");");
- return std::make_pair(1, ResNo);
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ return NodeOps;
}
#ifndef NDEBUG
N->dump();
#endif
assert(0 && "Unknown leaf type!");
- return std::make_pair(1, ~0U);
+ return NodeOps;
}
Record *Op = N->getOperator();
@@ -2552,11 +2579,8 @@
bool InputHasChain = isRoot &&
NodeHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE);
- if (NodeHasInFlag || NodeHasOutFlag || NodeHasOptInFlag || HasImpInputs)
- emitDecl("InFlag");
if (NodeHasOptInFlag) {
- emitDecl("HasInFlag", 2);
- emitCode("HasInFlag = "
+ emitCode("bool HasInFlag = "
"(N.getOperand(N.getNumOperands()-1).getValueType() == MVT::Flag);");
}
if (HasVarOps)
@@ -2570,47 +2594,29 @@
PatResults++;
}
- // Determine operand emission order. Complex pattern first.
- std::vector<std::pair<unsigned, TreePatternNode*> > EmitOrder;
- std::vector<std::pair<unsigned, TreePatternNode*> >::iterator OI;
+ std::vector<std::string> AllOps;
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- TreePatternNode *Child = N->getChild(i);
- if (i == 0) {
- EmitOrder.push_back(std::make_pair(i, Child));
- OI = EmitOrder.begin();
- } else if (NodeIsComplexPattern(Child)) {
- OI = EmitOrder.insert(OI, std::make_pair(i, Child));
- } else {
- EmitOrder.push_back(std::make_pair(i, Child));
- }
- }
-
- // Emit all of the operands.
- std::vector<std::pair<unsigned, unsigned> > NumTemps(EmitOrder.size());
- 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, RetSelected);
- NumTemps[OpOrder] = NumTemp;
- }
-
- // List all the operands in the right order.
- std::vector<unsigned> Ops;
- for (unsigned i = 0, e = NumTemps.size(); i != e; i++) {
- for (unsigned j = 0; j < NumTemps[i].first; j++)
- Ops.push_back(NumTemps[i].second + j);
+ std::vector<std::string> Ops = EmitResultCode(N->getChild(i),
+ RetSelected, InFlagDecled, ResNodeDecled);
+ AllOps.insert(AllOps.end(), Ops.begin(), Ops.end());
}
// Emit all the chain and CopyToReg stuff.
bool ChainEmitted = NodeHasChain;
if (NodeHasChain)
- emitCode("AddToQueue(" + ChainName + ", " + ChainName + ");");
+ emitCode("AddToISelQueue(" + ChainName + ");");
if (NodeHasInFlag || HasImpInputs)
- EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true);
+ EmitInFlagSelectCode(Pattern, "N", ChainEmitted,
+ InFlagDecled, ResNodeDecled, true);
if (NodeHasOptInFlag) {
- emitCode("if (HasInFlag)");
- emitCode(" AddToQueue(InFlag, N.getOperand(N.getNumOperands()-1));");
+ if (!InFlagDecled) {
+ emitCode("SDOperand InFlag(0, 0);");
+ InFlagDecled = true;
+ }
+ emitCode("if (HasInFlag) {");
+ emitCode(" InFlag = N.getOperand(N.getNumOperands()-1);");
+ emitCode(" AddToISelQueue(InFlag);");
+ emitCode("}");
}
unsigned NumResults = Inst.getNumResults();
@@ -2622,12 +2628,13 @@
std::string NodeName;
if (!isRoot) {
NodeName = "Tmp" + utostr(ResNo);
- emitDecl(NodeName);
- Code2 = NodeName + " = SDOperand(";
+ Code2 = "SDOperand " + NodeName + " = SDOperand(";
} else {
NodeName = "ResNode";
- emitDecl(NodeName, true);
- Code2 = NodeName + " = ";
+ if (!ResNodeDecled)
+ Code2 = "SDNode *" + NodeName + " = ";
+ else
+ Code2 = NodeName + " = ";
}
Code = "CurDAG->getTargetNode(Opc" + utostr(OpcNo);
emitOpcode(II.Namespace + "::" + II.TheDef->getName());
@@ -2644,12 +2651,14 @@
Code += ", MVT::Flag";
// Inputs.
- for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
+ for (unsigned i = 0, e = AllOps.size(); i != e; ++i) {
+ std::string OpName = AllOps[i];
if (HasVarOps)
- emitCode("Ops.push_back(Tmp" + utostr(Ops[i]) + ");");
+ emitCode("Ops.push_back(" + OpName + ");");
else
- Code += ", Tmp" + utostr(Ops[i]);
+ Code += ", " + OpName;
}
+ //AllOps.clear();
if (HasVarOps) {
if (NodeHasInFlag || HasImpInputs)
@@ -2661,9 +2670,8 @@
else
emitCode("for (unsigned i = 2, e = N.getNumOperands(); "
"i != e; ++i) {");
- emitCode(" SDOperand VarOp(0, 0);");
- emitCode(" AddToQueue(VarOp, N.getOperand(i));");
- emitCode(" Ops.push_back(VarOp);");
+ emitCode(" AddToISelQueue(N.getOperand(i));");
+ emitCode(" Ops.push_back(N.getOperand(i));");
emitCode("}");
}
@@ -2674,19 +2682,28 @@
Code += ", " + ChainName;
}
if (NodeHasInFlag || HasImpInputs) {
- if (HasVarOps)
+ if (!InFlagDecled) {
+ emitCode("SDOperand InFlag(0, 0);");
+ InFlagDecled = true;
+ }
+ if (HasVarOps) {
emitCode("Ops.push_back(InFlag);");
- else
+ } else
Code += ", InFlag";
} else if (NodeHasOptInFlag && HasVarOps) {
+ if (!InFlagDecled) {
+ emitCode("SDOperand InFlag(0, 0);");
+ InFlagDecled = true;
+ }
emitCode("if (HasInFlag)");
emitCode(" Ops.push_back(InFlag);");
}
if (HasVarOps)
Code += ", &Ops[0], Ops.size()";
- else if (NodeHasOptInFlag)
+ else if (NodeHasOptInFlag) {
Code = "HasInFlag ? " + Code + ", InFlag) : " + Code;
+ }
if (!isRoot)
Code += "), 0";
@@ -2701,15 +2718,23 @@
emitCode(ChainName + " = SDOperand(" + NodeName +
", " + utostr(PatResults) + ");");
- if (!isRoot)
- return std::make_pair(1, ResNo);
+ if (!isRoot) {
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ return NodeOps;
+ }
bool NeedReplace = false;
- if (NodeHasOutFlag)
- emitCode("InFlag = SDOperand(ResNode, " +
- utostr(NumResults + (unsigned)NodeHasChain) + ");");
+ if (NodeHasOutFlag) {
+ if (!InFlagDecled) {
+ emitCode("SDOperand InFlag = SDOperand(ResNode, " +
+ utostr(NumResults + (unsigned)NodeHasChain) + ");");
+ InFlagDecled = true;
+ } else
+ emitCode("InFlag = SDOperand(ResNode, " +
+ utostr(NumResults + (unsigned)NodeHasChain) + ");");
+ }
- if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) {
+ if (HasImpResults && EmitCopyFromRegs(N, ResNodeDecled, ChainEmitted)) {
emitCode("ReplaceUses(SDOperand(N.Val, 0), SDOperand(ResNode, 0));");
NumResults = 1;
}
@@ -2780,56 +2805,41 @@
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.
- emitCode("if (N.Val->hasOneUse()) {");
- std::string Code = " Result = CurDAG->SelectNodeTo(N.Val, Opc" +
+ std::string Code = "Result = CurDAG->SelectNodeTo(N.Val, Opc" +
utostr(OpcNo);
if (N->getTypeNum(0) != MVT::isVoid)
Code += ", VT" + utostr(VTNo);
if (NodeHasOutFlag)
Code += ", MVT::Flag";
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- Code += ", Tmp" + utostr(Ops[i]);
+ for (unsigned i = 0, e = AllOps.size(); i != e; ++i)
+ Code += ", " + AllOps[i];
+ //AllOps.clear();
if (NodeHasInFlag || HasImpInputs)
Code += ", InFlag";
emitCode(Code + ");");
- emitCode("} else {");
- emitDecl("ResNode", 1);
- Code = " ResNode = CurDAG->getTargetNode(Opc" + utostr(OpcNo);
+ emitCode("return Result.Val;");
emitOpcode(II.Namespace + "::" + II.TheDef->getName());
- if (N->getTypeNum(0) != MVT::isVoid) {
- Code += ", VT" + utostr(VTNo);
+ if (N->getTypeNum(0) != MVT::isVoid)
emitVT(getEnumName(N->getTypeNum(0)));
- }
- if (NodeHasOutFlag)
- Code += ", MVT::Flag";
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- Code += ", Tmp" + utostr(Ops[i]);
- if (NodeHasInFlag || HasImpInputs)
- Code += ", InFlag";
- emitCode(Code + ");");
- emitCode(" Result = SDOperand(ResNode, 0);");
- emitCode("}");
- emitCode("return Result.Val;");
}
- return std::make_pair(1, ResNo);
+ return NodeOps;
} 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), RetSelected, true).second;
+ std::vector<std::string> Ops =
+ EmitResultCode(N->getChild(0), RetSelected, InFlagDecled,
+ ResNodeDecled, true);
unsigned ResNo = TmpNo++;
- emitDecl("Tmp" + utostr(ResNo));
- emitCode("Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
- + "(Tmp" + utostr(OpVal) + ".Val);");
+ emitCode("SDOperand Tmp" + utostr(ResNo) + " = Transform_" + Op->getName()
+ + "(" + Ops.back() + ".Val);");
+ NodeOps.push_back("Tmp" + utostr(ResNo));
if (isRoot) {
- //emitCode("ReplaceUses(N, Tmp" + utostr(ResNo) + ");");
emitCode("Result = Tmp" + utostr(ResNo) + ";");
emitCode("return Result.Val;");
}
- return std::make_pair(1, ResNo);
+ return NodeOps;
} else {
N->dump();
std::cerr << "\n";
@@ -2867,7 +2877,8 @@
/// EmitInFlagSelectCode - Emit the flag operands for the DAG that is
/// being built.
void EmitInFlagSelectCode(TreePatternNode *N, const std::string &RootName,
- bool &ChainEmitted, bool isRoot = false) {
+ bool &ChainEmitted, bool &InFlagDecled,
+ bool &ResNodeDecled, bool isRoot = false) {
const CodeGenTarget &T = ISE.getTargetInfo();
unsigned OpNo =
(unsigned) NodeHasProperty(N, SDNodeInfo::SDNPHasChain, ISE);
@@ -2875,7 +2886,8 @@
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) {
TreePatternNode *Child = N->getChild(i);
if (!Child->isLeaf()) {
- EmitInFlagSelectCode(Child, RootName + utostr(OpNo), ChainEmitted);
+ EmitInFlagSelectCode(Child, RootName + utostr(OpNo), ChainEmitted,
+ InFlagDecled, ResNodeDecled);
} else {
if (DefInit *DI = dynamic_cast<DefInit*>(Child->getLeafValue())) {
if (!Child->getName().empty()) {
@@ -2889,20 +2901,29 @@
if (RR->isSubClassOf("Register")) {
MVT::ValueType RVT = getRegisterValueType(RR, T);
if (RVT == MVT::Flag) {
- emitCode("AddToQueue(InFlag, " + RootName + utostr(OpNo) + ");");
+ if (!InFlagDecled) {
+ emitCode("SDOperand InFlag = " + RootName + utostr(OpNo) + ";");
+ InFlagDecled = true;
+ } else
+ emitCode("InFlag = " + RootName + utostr(OpNo) + ";");
+ emitCode("AddToISelQueue(InFlag);");
} else {
if (!ChainEmitted) {
- emitDecl("Chain");
- emitCode("Chain = CurDAG->getEntryNode();");
+ emitCode("SDOperand Chain = CurDAG->getEntryNode();");
ChainName = "Chain";
ChainEmitted = true;
}
- emitCode("AddToQueue(" + RootName + utostr(OpNo) + ", " +
- RootName + utostr(OpNo) + ");");
- emitCode("ResNode = CurDAG->getCopyToReg(" + ChainName +
+ emitCode("AddToISelQueue(" + RootName + utostr(OpNo) + ");");
+ if (!InFlagDecled) {
+ emitCode("SDOperand InFlag(0, 0);");
+ InFlagDecled = true;
+ }
+ std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
+ emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" + ChainName +
", CurDAG->getRegister(" + ISE.getQualifiedName(RR) +
", " + getEnumName(RVT) + "), " +
RootName + utostr(OpNo) + ", InFlag).Val;");
+ ResNodeDecled = true;
emitCode(ChainName + " = SDOperand(ResNode, 0);");
emitCode("InFlag = SDOperand(ResNode, 1);");
}
@@ -2911,15 +2932,23 @@
}
}
- if (HasInFlag)
- emitCode("AddToQueue(InFlag, " + RootName +
- ".getOperand(" + utostr(OpNo) + "));");
+ if (HasInFlag) {
+ if (!InFlagDecled) {
+ emitCode("SDOperand InFlag = " + RootName +
+ ".getOperand(" + utostr(OpNo) + ");");
+ InFlagDecled = true;
+ } else
+ emitCode("InFlag = " + RootName +
+ ".getOperand(" + utostr(OpNo) + ");");
+ emitCode("AddToISelQueue(InFlag);");
+ }
}
/// EmitCopyFromRegs - Emit code to copy result to physical registers
/// as specified by the instruction. It returns true if any copy is
/// emitted.
- bool EmitCopyFromRegs(TreePatternNode *N, bool &ChainEmitted) {
+ bool EmitCopyFromRegs(TreePatternNode *N, bool &ResNodeDecled,
+ bool &ChainEmitted) {
bool RetVal = false;
Record *Op = N->getOperator();
if (Op->isSubClassOf("Instruction")) {
@@ -2932,14 +2961,15 @@
MVT::ValueType RVT = getRegisterValueType(RR, CGT);
if (RVT != MVT::Flag) {
if (!ChainEmitted) {
- emitDecl("Chain");
- emitCode("Chain = CurDAG->getEntryNode();");
+ emitCode("SDOperand Chain = CurDAG->getEntryNode();");
ChainEmitted = true;
ChainName = "Chain";
}
- emitCode("ResNode = CurDAG->getCopyFromReg(" + ChainName +
+ std::string Decl = (!ResNodeDecled) ? "SDNode *" : "";
+ emitCode(Decl + "ResNode = CurDAG->getCopyFromReg(" + ChainName +
", " + ISE.getQualifiedName(RR) + ", " + getEnumName(RVT) +
", InFlag).Val;");
+ ResNodeDecled = true;
emitCode(ChainName + " = SDOperand(ResNode, 1);");
emitCode("InFlag = SDOperand(ResNode, 2);");
RetVal = true;
@@ -2955,8 +2985,8 @@
/// stream to match the pattern, and generate the code for the match if it
/// succeeds. Returns true if the pattern is not guaranteed to match.
void DAGISelEmitter::GenerateCodeForPattern(PatternToMatch &Pattern,
- std::vector<std::pair<bool, std::string> > &GeneratedCode,
- std::set<std::pair<unsigned, std::string> > &GeneratedDecl,
+ std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
+ std::set<std::pair<unsigned, std::string> > &GeneratedDecl,
std::vector<std::string> &TargetOpcodes,
std::vector<std::string> &TargetVTs) {
PatternCodeEmitter Emitter(*this, Pattern.getPredicates(),
@@ -3005,8 +3035,8 @@
// otherwise we are done.
} while (Emitter.InsertOneTypeCheck(Pat, Pattern.getSrcPattern(), "N", true));
- bool RetSelected = false;
- Emitter.EmitResultCode(Pattern.getDstPattern(), RetSelected, false, true);
+ Emitter.EmitResultCode(Pattern.getDstPattern(),
+ false, false, false, false, true);
delete Pat;
}
@@ -3014,7 +3044,7 @@
/// a line causes any of them to be empty, remove them and return true when
/// done.
static bool EraseCodeLine(std::vector<std::pair<PatternToMatch*,
- std::vector<std::pair<bool, std::string> > > >
+ std::vector<std::pair<unsigned, std::string> > > >
&Patterns) {
bool ErasedPatterns = false;
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
@@ -3031,10 +3061,10 @@
/// EmitPatterns - Emit code for at least one pattern, but try to group common
/// code together between the patterns.
void DAGISelEmitter::EmitPatterns(std::vector<std::pair<PatternToMatch*,
- std::vector<std::pair<bool, std::string> > > >
+ std::vector<std::pair<unsigned, std::string> > > >
&Patterns, unsigned Indent,
std::ostream &OS) {
- typedef std::pair<bool, std::string> CodeLine;
+ typedef std::pair<unsigned, std::string> CodeLine;
typedef std::vector<CodeLine> CodeList;
typedef std::vector<std::pair<PatternToMatch*, CodeList> > PatternList;
@@ -3070,12 +3100,12 @@
<< " size = "
<< getResultPatternSize(Pattern.getDstPattern(), *this) << "\n";
}
- if (!FirstCodeLine.first) {
+ if (FirstCodeLine.first != 1) {
OS << std::string(Indent, ' ') << "{\n";
Indent += 2;
}
EmitPatterns(Shared, Indent, OS);
- if (!FirstCodeLine.first) {
+ if (FirstCodeLine.first != 1) {
Indent -= 2;
OS << std::string(Indent, ' ') << "}\n";
}
@@ -3102,7 +3132,7 @@
// Remove this code from all of the patterns that share it.
bool ErasedPatterns = EraseCodeLine(Patterns);
- bool isPredicate = FirstCodeLine.first;
+ bool isPredicate = FirstCodeLine.first == 1;
// Otherwise, every pattern in the list has this line. Emit it.
if (!isPredicate) {
@@ -3114,7 +3144,7 @@
// If the next code line is another predicate, and if all of the pattern
// in this group share the same next line, emit it inline now. Do this
// until we run out of common predicates.
- while (!ErasedPatterns && Patterns.back().second.back().first) {
+ while (!ErasedPatterns && Patterns.back().second.back().first == 1) {
// Check that all of fhe patterns in Patterns end with the same predicate.
bool AllEndWithSamePredicate = true;
for (unsigned i = 0, e = Patterns.size(); i != e; ++i)
@@ -3238,14 +3268,13 @@
++II) {
MVT::ValueType OpVT = II->first;
std::vector<PatternToMatch*> &Patterns = II->second;
- typedef std::vector<std::pair<bool, std::string> > CodeList;
- typedef std::vector<std::pair<bool, std::string> >::iterator CodeListI;
+ typedef std::vector<std::pair<unsigned, std::string> > CodeList;
+ typedef std::vector<std::pair<unsigned, std::string> >::iterator CodeListI;
std::vector<std::pair<PatternToMatch*, CodeList> > CodeForPatterns;
std::vector<std::vector<std::string> > PatternOpcodes;
std::vector<std::vector<std::string> > PatternVTs;
std::vector<std::set<std::pair<unsigned, std::string> > > PatternDecls;
- std::set<std::pair<unsigned, std::string> > AllGenDecls;
for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
CodeList GeneratedCode;
std::set<std::pair<unsigned, std::string> > GeneratedDecl;
@@ -3253,9 +3282,6 @@
std::vector<std::string> TargetVTs;
GenerateCodeForPattern(*Patterns[i], GeneratedCode, GeneratedDecl,
TargetOpcodes, TargetVTs);
- for (std::set<std::pair<unsigned, std::string> >::iterator
- si = GeneratedDecl.begin(), se = GeneratedDecl.end(); si!=se; ++si)
- AllGenDecls.insert(*si);
CodeForPatterns.push_back(std::make_pair(Patterns[i], GeneratedCode));
PatternDecls.push_back(GeneratedDecl);
PatternOpcodes.push_back(TargetOpcodes);
@@ -3270,7 +3296,7 @@
mightNotMatch = false;
for (unsigned j = 0, e = GeneratedCode.size(); j != e; ++j) {
- if (GeneratedCode[j].first) { // predicate.
+ if (GeneratedCode[j].first == 1) { // predicate.
mightNotMatch = true;
break;
}
@@ -3280,7 +3306,7 @@
// patterns after it CANNOT ever match. Error out.
if (mightNotMatch == false && i != CodeForPatterns.size()-1) {
std::cerr << "Pattern '";
- CodeForPatterns[i+1].first->getSrcPattern()->print(std::cerr);
+ CodeForPatterns[i].first->getSrcPattern()->print(std::cerr);
std::cerr << "' is impossible to select!\n";
exit(1);
}
@@ -3294,16 +3320,16 @@
std::vector<std::string> &TargetOpcodes = PatternOpcodes[i];
std::vector<std::string> &TargetVTs = PatternVTs[i];
std::set<std::pair<unsigned, std::string> > Decls = PatternDecls[i];
+ std::vector<std::string> AddedInits;
int CodeSize = (int)GeneratedCode.size();
int LastPred = -1;
for (int j = CodeSize-1; j >= 0; --j) {
- if (GeneratedCode[j].first) {
+ if (LastPred == -1 && GeneratedCode[j].first == 1)
LastPred = j;
- break;
- }
+ else if (LastPred != -1 && GeneratedCode[j].first == 2)
+ AddedInits.push_back(GeneratedCode[j].second);
}
- std::string CalleeDecls;
std::string CalleeCode = "(SDOperand &Result, const SDOperand &N";
std::string CallerCode = "(Result, N";
for (unsigned j = 0, e = TargetOpcodes.size(); j != e; ++j) {
@@ -3317,35 +3343,25 @@
for (std::set<std::pair<unsigned, std::string> >::iterator
I = Decls.begin(), E = Decls.end(); I != E; ++I) {
std::string Name = I->second;
- if (I->first == 0) {
- if (Name == "InFlag" ||
- (Name.size() > 3 &&
- Name[0] == 'T' && Name[1] == 'm' && Name[2] == 'p')) {
- CalleeDecls += " SDOperand " + Name + "(0, 0);\n";
- continue;
- }
- CalleeCode += ", SDOperand &" + Name;
- CallerCode += ", " + Name;
- } else if (I->first == 1) {
- if (Name == "ResNode") {
- CalleeDecls += " SDNode *" + Name + " = NULL;\n";
- continue;
- }
- CalleeCode += ", SDNode *" + Name;
- CallerCode += ", " + Name;
- } else {
- CalleeCode += ", bool " + Name;
- CallerCode += ", " + Name;
- }
+ CalleeCode += ", SDOperand &" + Name;
+ CallerCode += ", " + Name;
}
CallerCode += ");";
CalleeCode += ") ";
// Prevent emission routines from being inlined to reduce selection
// routines stack frame sizes.
CalleeCode += "NOINLINE ";
- CalleeCode += "{\n" + CalleeDecls;
- for (int j = LastPred+1; j < CodeSize; ++j)
- CalleeCode += " " + GeneratedCode[j].second + '\n';
+ CalleeCode += "{\n";
+
+ for (std::vector<std::string>::const_reverse_iterator
+ I = AddedInits.rbegin(), E = AddedInits.rend(); I != E; ++I)
+ CalleeCode += " " + *I + "\n";
+
+ for (int j = LastPred+1; j < CodeSize; ++j) {
+ std::string code = GeneratedCode[j].second;
+ // if (!AddedDecls.count(code))
+ CalleeCode += " " + code + "\n";
+ }
for (int j = LastPred+1; j < CodeSize; ++j)
GeneratedCode.pop_back();
CalleeCode += "}\n";
@@ -3383,16 +3399,6 @@
OS << "SDNode *Select_" << OpName << (OpVTStr != "" ? "_" : "")
<< OpVTStr << "(SDOperand &Result, const SDOperand &N) {\n";
- // Print all declarations.
- for (std::set<std::pair<unsigned, std::string> >::iterator
- I = AllGenDecls.begin(), E = AllGenDecls.end(); I != E; ++I)
- if (I->first == 0)
- OS << " SDOperand " << I->second << "(0, 0);\n";
- else if (I->first == 1)
- OS << " SDNode *" << I->second << " = NULL;\n";
- else
- OS << " bool " << I->second << " = false;\n";
-
// Loop through and reverse all of the CodeList vectors, as we will be
// accessing them from their logical front, but accessing the end of a
// vector is more efficient.
@@ -3432,10 +3438,10 @@
// Emit boilerplate.
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"
+ << " AddToISelQueue(N.getOperand(0)); // Select the chain.\n\n"
<< " // Select the flag operand.\n"
<< " if (Ops.back().getValueType() == MVT::Flag)\n"
- << " AddToQueue(Ops.back(), Ops.back());\n"
+ << " AddToISelQueue(Ops.back());\n"
<< " SelectInlineAsmMemoryOperands(Ops, *CurDAG);\n"
<< " std::vector<MVT::ValueType> VTs;\n"
<< " VTs.push_back(MVT::Other);\n"
@@ -3470,17 +3476,15 @@
<< " }\n"
<< " case ISD::AssertSext:\n"
<< " case ISD::AssertZext: {\n"
- << " AddToQueue(Result, N.getOperand(0));\n"
- << " ReplaceUses(N, Result);\n"
+ << " AddToISelQueue(N.getOperand(0));\n"
+ << " ReplaceUses(N, N.getOperand(0));\n"
<< " return NULL;\n"
<< " }\n"
<< " case ISD::TokenFactor:\n"
<< " case ISD::CopyFromReg:\n"
<< " case ISD::CopyToReg: {\n"
- << " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i) {\n"
- << " SDOperand Dummy;\n"
- << " AddToQueue(Dummy, N.getOperand(i));\n"
- << " }\n"
+ << " for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)\n"
+ << " AddToISelQueue(N.getOperand(i));\n"
<< " Result = N;\n"
<< " return NULL;\n"
<< " }\n"
@@ -3601,8 +3605,7 @@
OS << " return ISelSelected[Id / 8] & (1 << (Id % 8));\n";
OS << "}\n\n";
- OS << "void AddToQueue(SDOperand &Result, SDOperand N) NOINLINE {\n";
- OS << " Result = N;\n";
+ OS << "void AddToISelQueue(SDOperand N) NOINLINE {\n";
OS << " int Id = N.Val->getNodeId();\n";
OS << " if (Id != -1 && !isQueued(Id)) {\n";
OS << " ISelQueue.push_back(N.Val);\n";
Index: llvm/utils/TableGen/DAGISelEmitter.h
diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.67 llvm/utils/TableGen/DAGISelEmitter.h:1.68
--- llvm/utils/TableGen/DAGISelEmitter.h:1.67 Mon Aug 7 17:17:58 2006
+++ llvm/utils/TableGen/DAGISelEmitter.h Fri Aug 25 19:59:04 2006
@@ -520,12 +520,12 @@
std::vector<Record*> &InstImpInputs,
std::vector<Record*> &InstImpResults);
void GenerateCodeForPattern(PatternToMatch &Pattern,
- std::vector<std::pair<bool, std::string> > &GeneratedCode,
+ std::vector<std::pair<unsigned, std::string> > &GeneratedCode,
std::set<std::pair<unsigned, std::string> > &GeneratedDecl,
std::vector<std::string> &TargetOpcodes,
std::vector<std::string> &TargetVTs);
void EmitPatterns(std::vector<std::pair<PatternToMatch*,
- std::vector<std::pair<bool, std::string> > > > &Patterns,
+ std::vector<std::pair<unsigned, std::string> > > > &Patterns,
unsigned Indent, std::ostream &OS);
void EmitInstructionSelector(std::ostream &OS);
};
More information about the llvm-commits
mailing list