From 8a0604b5235ac4f7cdb229b6a7987ff1ec708bf5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 28 Jan 2006 20:31:24 +0000 Subject: [PATCH] Change PatternCodeEmitter to emit code into a buffer instead of emitting it directly to the output file. This makes things simple because the code doesn't have to worry about indentation or the case when there is no goto. It also allows us to indent the code better without touching everything :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25756 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/DAGISelEmitter.cpp | 504 +++++++++++++++--------------- 1 file changed, 246 insertions(+), 258 deletions(-) diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index 8c7f46c5c82..7b931b63f52 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -1830,8 +1830,7 @@ private: // Matched instruction. TreePatternNode *Instruction; unsigned PatternNo; - bool GotosFail; - std::ostream &OS; + // Node to name mapping std::map VariableMap; // Node to operator mapping @@ -1839,16 +1838,30 @@ private: // Names of all the folded nodes which produce chains. std::vector > FoldedChains; std::set Duplicates; - unsigned TmpNo; + /// GeneratedCode - This is the buffer that we emit code to. The first bool + /// 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 > &GeneratedCode; + + unsigned TmpNo; + + void emitCheck(const std::string &S) { + if (!S.empty()) + GeneratedCode.push_back(std::make_pair(true, S)); + } + void emitCode(const std::string &S) { + if (!S.empty()) + GeneratedCode.push_back(std::make_pair(false, S)); + } public: PatternCodeEmitter(DAGISelEmitter &ise, ListInit *preds, TreePatternNode *pattern, TreePatternNode *instr, - unsigned PatNum, std::ostream &os) : - ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr), - PatternNo(PatNum), GotosFail(false), OS(os), TmpNo(0) {} - - bool UsesFailLabel() { return GotosFail; } + unsigned PatNum, + std::vector > &gc) + : ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr), + PatternNo(PatNum), GeneratedCode(gc), TmpNo(0) {} /// 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 @@ -1858,33 +1871,27 @@ public: // Emit instruction predicates. Each predicate is just a string for now. if (isRoot) { + std::string PredicateCheck; for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) { if (DefInit *Pred = dynamic_cast(Predicates->getElement(i))) { Record *Def = Pred->getDef(); - if (Def->isSubClassOf("Predicate")) { - if (i == 0) - OS << " if ("; - else - OS << " && "; - OS << "!(" << Def->getValueAsString("CondString") << ")"; - if (i == e-1) { - OS << ") goto P" << PatternNo << "Fail;\n"; - GotosFail = true; - } - } else { + if (!Def->isSubClassOf("Predicate")) { Def->dump(); assert(0 && "Unknown predicate type!"); } + if (!PredicateCheck.empty()) + PredicateCheck += " && "; + PredicateCheck += "!(" + Def->getValueAsString("CondString") + ")"; } } + + emitCheck(PredicateCheck); } if (N->isLeaf()) { if (IntInit *II = dynamic_cast(N->getLeafValue())) { - OS << " if (cast(" << RootName - << ")->getSignExtended() != " << II->getValue() << ")\n" - << " goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + emitCheck("cast(" + RootName + + ")->getSignExtended() != " + itostr(II->getValue())); return; } else if (!NodeIsComplexPattern(N)) { assert(0 && "Cannot match this as a leaf value!"); @@ -1903,9 +1910,7 @@ public: // we already have checked that the first reference is valid, we don't // have to recursively match it, just check that it's the same as the // previously named thing. - OS << " if (" << VarMapEntry << " != " << RootName - << ") goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + emitCheck(VarMapEntry + " != " + RootName); return; } @@ -1925,35 +1930,27 @@ public: OpNo = 1; if (!isRoot) { const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator()); - OS << " if (!" << RootName << ".hasOneUse()) goto P" - << PatternNo << "Fail; // Multiple uses of actual result?\n"; - GotosFail = true; + // Multiple uses of actual result? + emitCheck("!" + RootName + ".hasOneUse()"); EmittedUseCheck = true; // hasOneUse() check is not strong enough. If the original node has // already been selected, it may have been replaced with another. - for (unsigned j = 0; j < CInfo.getNumResults(); j++) { - OS << " if (CodeGenMap.count(" << RootName - << ".getValue(" << j << "))) goto P" - << PatternNo << "Fail; // Already selected?\n"; - GotosFail = true; - } + for (unsigned j = 0; j != CInfo.getNumResults(); j++) + emitCheck("CodeGenMap.count(" + RootName + ".getValue(" + utostr(j) + + "))"); + EmittedSlctedCheck = true; - if (NodeHasChain) { - OS << " if (CodeGenMap.count(" << RootName - << ".getValue(" << CInfo.getNumResults() << "))) goto P" - << PatternNo << "Fail; // Already selected for a chain use?\n"; - GotosFail = true; - } + if (NodeHasChain) + emitCheck("CodeGenMap.count(" + RootName + ".getValue(" + + utostr(CInfo.getNumResults()) + "))"); } if (NodeHasChain) { if (!FoundChain) { - OS << " SDOperand Chain = " << RootName << ".getOperand(0);\n"; + emitCode("SDOperand Chain = " + RootName + ".getOperand(0);"); FoundChain = true; } else { - OS << " if (Chain.Val == " << RootName << ".Val)\n"; - OS << " Chain = " << RootName << ".getOperand(0);\n"; - OS << " else\n"; - OS << " goto P" << PatternNo << "Fail;\n"; + emitCheck("Chain.Val != " + RootName + ".Val"); + emitCode("Chain = " + RootName + ".getOperand(0);"); } } } @@ -1968,37 +1965,31 @@ public: PatternHasProperty(N, SDNodeInfo::SDNPOutFlag, ISE))) { const SDNodeInfo &CInfo = ISE.getSDNodeInfo(N->getOperator()); if (!EmittedUseCheck) { - OS << " if (!" << RootName << ".hasOneUse()) goto P" - << PatternNo << "Fail; // Multiple uses of actual result?\n"; - GotosFail = true; + // Multiple uses of actual result? + emitCheck("!" + RootName + ".hasOneUse()"); } if (!EmittedSlctedCheck) // hasOneUse() check is not strong enough. If the original node has // already been selected, it may have been replaced with another. - for (unsigned j = 0; j < CInfo.getNumResults(); j++) { - OS << " if (CodeGenMap.count(" << RootName - << ".getValue(" << j << "))) goto P" - << PatternNo << "Fail; // Already selected?\n"; - GotosFail = true; - } + for (unsigned j = 0; j < CInfo.getNumResults(); j++) + emitCheck("CodeGenMap.count(" + RootName + ".getValue(" + utostr(j) + + "))"); } for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, ++OpNo) { - OS << " SDOperand " << RootName << OpNo << " = " - << RootName << ".getOperand(" << OpNo << ");\n"; + emitCode("SDOperand " + RootName + utostr(OpNo) + " = " + + RootName + ".getOperand(" +utostr(OpNo) + ");"); TreePatternNode *Child = N->getChild(i); if (!Child->isLeaf()) { // If it's not a leaf, recursively match. const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator()); - OS << " if (" << RootName << OpNo << ".getOpcode() != " - << CInfo.getEnumName() << ") goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + emitCheck(RootName + utostr(OpNo) + ".getOpcode() != " + + CInfo.getEnumName()); EmitMatchCode(Child, RootName + utostr(OpNo), FoundChain); - if (NodeHasProperty(Child, SDNodeInfo::SDNPHasChain, ISE)) { + if (NodeHasProperty(Child, SDNodeInfo::SDNPHasChain, ISE)) FoldedChains.push_back(std::make_pair(RootName + utostr(OpNo), CInfo.getNumResults())); - } } else { // If this child has a name associated with it, capture it in VarMap. If // we already saw this in the pattern, emit code to verify dagness. @@ -2011,9 +2002,7 @@ public: // Since we already have checked that the first reference is valid, // we don't have to recursively match it, just check that it's the // same as the previously named thing. - OS << " if (" << VarMapEntry << " != " << RootName << OpNo - << ") goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + emitCheck(VarMapEntry + " != " + RootName + utostr(OpNo)); Duplicates.insert(RootName + utostr(OpNo)); continue; } @@ -2032,17 +2021,12 @@ public: // Place holder for SRCVALUE nodes. Nothing to do here. } else if (LeafRec->isSubClassOf("ValueType")) { // Make sure this is the specified value type. - OS << " if (cast(" << RootName << OpNo - << ")->getVT() != " - << "MVT::" << LeafRec->getName() << ") goto P" << PatternNo - << "Fail;\n"; - GotosFail = true; + emitCheck("cast(" + RootName + utostr(OpNo) + + ")->getVT() != MVT::" + LeafRec->getName()); } else if (LeafRec->isSubClassOf("CondCode")) { // Make sure this is the specified cond code. - OS << " if (cast(" << RootName << OpNo - << ")->get() != " << "ISD::" << LeafRec->getName() - << ") goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + emitCheck("cast(" + RootName + utostr(OpNo) + + ")->get() != ISD::" + LeafRec->getName()); } else { Child->dump(); std::cerr << " "; @@ -2050,12 +2034,9 @@ public: } } else if (IntInit *II = dynamic_cast(Child->getLeafValue())) { - OS << " if (!isa(" << RootName << OpNo - << ") ||\n" - << " cast(" << RootName << OpNo - << ")->getSignExtended() != " << II->getValue() << ")\n" - << " goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + emitCheck("!isa(" + RootName + utostr(OpNo) + + ") || cast(" + RootName + utostr(OpNo) + + ")->getSignExtended() != " + itostr(II->getValue())); } else { Child->dump(); assert(0 && "Unknown leaf type!"); @@ -2064,11 +2045,8 @@ public: } // If there is a node predicate for this, emit the call. - if (!N->getPredicateFn().empty()) { - OS << " if (!" << N->getPredicateFn() << "(" << RootName - << ".Val)) goto P" << PatternNo << "Fail;\n"; - GotosFail = true; - } + if (!N->getPredicateFn().empty()) + emitCheck("!" + N->getPredicateFn() + "(" + RootName + ".Val)"); } /// EmitResultCode - Emit the action for a pattern. Now that it has matched @@ -2091,59 +2069,61 @@ public: unsigned NumRes = 1; if (!N->isLeaf() && N->getOperator()->getName() == "imm") { assert(N->getExtTypes().size() == 1 && "Multiple types not handled!"); + const char *Code; switch (N->getTypeNum(0)) { - default: assert(0 && "Unknown type for constant node!"); - case MVT::i1: OS << " bool Tmp"; break; - case MVT::i8: OS << " unsigned char Tmp"; break; - case MVT::i16: OS << " unsigned short Tmp"; break; - case MVT::i32: OS << " unsigned Tmp"; break; - case MVT::i64: OS << " uint64_t Tmp"; break; + default: assert(0 && "Unknown type for constant node!"); + case MVT::i1: Code = "bool Tmp"; break; + case MVT::i8: Code = "unsigned char Tmp"; break; + case MVT::i16: Code = "unsigned short Tmp"; break; + case MVT::i32: Code = "unsigned Tmp"; break; + case MVT::i64: Code = "uint64_t Tmp"; break; } - OS << ResNo << "C = (unsigned)cast(" << Val - << ")->getValue();\n"; - OS << " SDOperand Tmp" << utostr(ResNo) - << " = CurDAG->getTargetConstant(Tmp" - << ResNo << "C, MVT::" << getEnumName(N->getTypeNum(0)) << ");\n"; + emitCode(Code + utostr(ResNo) + "C = (unsigned)cast(" + + Val + ")->getValue();"); + emitCode("SDOperand Tmp" + utostr(ResNo) + + " = CurDAG->getTargetConstant(Tmp" + utostr(ResNo) + + "C, MVT::" + getEnumName(N->getTypeNum(0)) + ");"); } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){ Record *Op = OperatorMap[N->getName()]; // Transform ExternalSymbol to TargetExternalSymbol if (Op && Op->getName() == "externalsym") { - OS << " SDOperand Tmp" << ResNo - << " = CurDAG->getTargetExternalSymbol(cast(" - << Val << ")->getSymbol(), MVT::" << getEnumName(N->getTypeNum(0)) - << ");\n"; - } else - OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getTarget" + "ExternalSymbol(cast(" + + Val + ")->getSymbol(), MVT::" + + getEnumName(N->getTypeNum(0)) + ");"); + } else { + emitCode("SDOperand Tmp" + utostr(ResNo) + " = " + Val + ";"); + } } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { Record *Op = OperatorMap[N->getName()]; // Transform GlobalAddress to TargetGlobalAddress if (Op && Op->getName() == "globaladdr") { - OS << " SDOperand Tmp" << ResNo - << " = CurDAG->getTargetGlobalAddress(cast(" - << Val << ")->getGlobal(), MVT::" << getEnumName(N->getTypeNum(0)) - << ");\n"; - } else - OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getTarget" + "GlobalAddress(cast(" + Val + + ")->getGlobal(), MVT::" + getEnumName(N->getTypeNum(0)) + + ");"); + } else { + emitCode("SDOperand Tmp" + utostr(ResNo) + " = " + Val + ";"); + } } else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){ - OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + " = " + Val + ";"); } else if (!N->isLeaf() && N->getOperator()->getName() == "tconstpool") { - OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + " = " + Val + ";"); } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, ISE))) { std::string Fn = CP->getSelectFunc(); NumRes = CP->getNumOperands(); - OS << " SDOperand "; + std::string Code = "SDOperand "; for (unsigned i = 0; i < NumRes - 1; ++i) - OS << "Tmp" << (i+ResNo) << ","; - OS << "Tmp" << (NumRes - 1 + ResNo) << ";\n"; - - OS << " if (!" << Fn << "(" << Val; + Code += "Tmp" + utostr(i+ResNo) + ", "; + emitCode(Code + "Tmp" + utostr(NumRes - 1 + ResNo) + ";"); + + Code = "!" + Fn + "(" + Val; for (unsigned i = 0; i < NumRes; i++) - OS << ", Tmp" << i + ResNo; - OS << ")) goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + Code += ", Tmp" + utostr(i + ResNo); + emitCheck(Code + ")"); TmpNo = ResNo + NumRes; } else { - OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + " = Select(" + Val + ");"); } // Add Tmp to VariableMap, so that we don't multiply select this // value if used multiple times by this pattern result. @@ -2156,19 +2136,17 @@ public: if (DefInit *DI = dynamic_cast(N->getLeafValue())) { unsigned ResNo = TmpNo++; if (DI->getDef()->isSubClassOf("Register")) { - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getRegister(" - << ISE.getQualifiedName(DI->getDef()) << ", MVT::" - << getEnumName(N->getTypeNum(0)) - << ");\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getRegister(" + + ISE.getQualifiedName(DI->getDef()) + ", MVT::" + + getEnumName(N->getTypeNum(0)) + ");"); return std::make_pair(1, ResNo); } } else if (IntInit *II = dynamic_cast(N->getLeafValue())) { unsigned ResNo = TmpNo++; assert(N->getExtTypes().size() == 1 && "Multiple types not handled!"); - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetConstant(" - << II->getValue() << ", MVT::" - << getEnumName(N->getTypeNum(0)) - << ");\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + + " = CurDAG->getTargetConstant(" + itostr(II->getValue()) + + ", MVT::" + getEnumName(N->getTypeNum(0)) + ");"); return std::make_pair(1, ResNo); } @@ -2196,9 +2174,9 @@ public: (isRoot && PatternHasProperty(Pattern, SDNodeInfo::SDNPHasChain, ISE)); if (HasInFlag || NodeHasOutFlag || HasOptInFlag || HasImpInputs) - OS << " SDOperand InFlag = SDOperand(0, 0);\n"; + emitCode("SDOperand InFlag = SDOperand(0, 0);"); if (HasOptInFlag) - OS << " bool HasOptInFlag = false;\n"; + emitCode("bool HasOptInFlag = false;"); // How many results is this pattern expected to produce? unsigned NumExpectedResults = 0; @@ -2242,176 +2220,172 @@ public: // Emit all the chain and CopyToReg stuff. bool ChainEmitted = HasChain; if (HasChain) - OS << " Chain = Select(Chain);\n"; + emitCode("Chain = Select(Chain);"); if (HasInFlag || HasOptInFlag || HasImpInputs) EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true); unsigned NumResults = Inst.getNumResults(); unsigned ResNo = TmpNo++; if (!isRoot) { - OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName(); + std::string Code = + "SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getTargetNode(" + + II.Namespace + "::" + II.TheDef->getName(); if (N->getTypeNum(0) != MVT::isVoid) - OS << ", MVT::" << getEnumName(N->getTypeNum(0)); + Code += ", MVT::" + getEnumName(N->getTypeNum(0)); if (NodeHasOutFlag) - OS << ", MVT::Flag"; + Code += ", MVT::Flag"; unsigned LastOp = 0; for (unsigned i = 0, e = Ops.size(); i != e; ++i) { LastOp = Ops[i]; - OS << ", Tmp" << LastOp; + Code += ", Tmp" + utostr(LastOp); } - OS << ");\n"; + emitCode(Code + ");"); if (HasChain) { // Must have at least one result - OS << " Chain = Tmp" << LastOp << ".getValue(" - << NumResults << ");\n"; + emitCode("Chain = Tmp" + utostr(LastOp) + ".getValue(" + + utostr(NumResults) + ");"); } } else if (HasChain || NodeHasOutFlag) { if (HasOptInFlag) { - OS << " SDOperand Result = SDOperand(0, 0);\n"; + emitCode("SDOperand Result = SDOperand(0, 0);"); unsigned FlagNo = (unsigned) NodeHasChain + Pattern->getNumChildren(); - OS << " if (HasOptInFlag)\n"; - OS << " Result = CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName(); + emitCode("if (HasOptInFlag)"); + std::string Code = " Result = CurDAG->getTargetNode(" + + II.Namespace + "::" + II.TheDef->getName(); // Output order: results, chain, flags // Result types. if (NumResults > 0) { if (N->getTypeNum(0) != MVT::isVoid) - OS << ", MVT::" << getEnumName(N->getTypeNum(0)); + Code += ", MVT::" + getEnumName(N->getTypeNum(0)); } if (HasChain) - OS << ", MVT::Other"; + Code += ", MVT::Other"; if (NodeHasOutFlag) - OS << ", MVT::Flag"; + Code += ", MVT::Flag"; // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; - if (HasChain) OS << ", Chain"; - OS << ", InFlag);\n"; + Code += ", Tmp" + utostr(Ops[i]); + if (HasChain) Code += ", Chain"; + emitCode(Code + ", InFlag);"); - OS << " else\n"; - OS << " Result = CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName(); + emitCode("else"); + Code = " Result = CurDAG->getTargetNode(" + II.Namespace + "::" + + II.TheDef->getName(); // Output order: results, chain, flags // Result types. - if (NumResults > 0) { - if (N->getTypeNum(0) != MVT::isVoid) - OS << ", MVT::" << getEnumName(N->getTypeNum(0)); - } + if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) + Code += ", MVT::" + getEnumName(N->getTypeNum(0)); if (HasChain) - OS << ", MVT::Other"; + Code += ", MVT::Other"; if (NodeHasOutFlag) - OS << ", MVT::Flag"; + Code += ", MVT::Flag"; // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; - if (HasChain) OS << ", Chain);\n"; + Code += ", Tmp" + utostr(Ops[i]); + if (HasChain) Code += ", Chain);"; + emitCode(Code); } else { - OS << " SDOperand Result = CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName(); + std::string Code = "SDOperand Result = CurDAG->getTargetNode(" + + II.Namespace + "::" + II.TheDef->getName(); // Output order: results, chain, flags // Result types. - if (NumResults > 0) { - if (N->getTypeNum(0) != MVT::isVoid) - OS << ", MVT::" << getEnumName(N->getTypeNum(0)); - } + if (NumResults > 0 && N->getTypeNum(0) != MVT::isVoid) + Code += ", MVT::" + getEnumName(N->getTypeNum(0)); if (HasChain) - OS << ", MVT::Other"; + Code += ", MVT::Other"; if (NodeHasOutFlag) - OS << ", MVT::Flag"; + Code += ", MVT::Flag"; // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; - if (HasChain) OS << ", Chain"; - if (HasInFlag || HasImpInputs) OS << ", InFlag"; - OS << ");\n"; + Code += ", Tmp" + utostr(Ops[i]); + if (HasChain) Code += ", Chain"; + if (HasInFlag || HasImpInputs) Code += ", InFlag"; + emitCode(Code + ");"); } unsigned ValNo = 0; for (unsigned i = 0; i < NumResults; i++) { - OS << " CodeGenMap[N.getValue(" << ValNo << ")] = Result" - << ".getValue(" << ValNo << ");\n"; + emitCode("CodeGenMap[N.getValue(" + utostr(ValNo) + ")] = Result" + ".getValue(" + utostr(ValNo) + ");"); ValNo++; } if (HasChain) - OS << " Chain = Result.getValue(" << ValNo << ");\n"; + emitCode("Chain = Result.getValue(" + utostr(ValNo) + ");"); if (NodeHasOutFlag) - OS << " InFlag = Result.getValue(" - << ValNo + (unsigned)HasChain << ");\n"; + emitCode("InFlag = Result.getValue(" + + utostr(ValNo + (unsigned)HasChain) + ");"); - if (HasImpResults) { - if (EmitCopyFromRegs(N, ChainEmitted)) { - OS << " CodeGenMap[N.getValue(" << ValNo << ")] = " - << "Result.getValue(" << ValNo << ");\n"; - ValNo++; - } + if (HasImpResults && EmitCopyFromRegs(N, ChainEmitted)) { + emitCode("CodeGenMap[N.getValue(" + utostr(ValNo) + ")] = " + "Result.getValue(" + utostr(ValNo) + ");"); + ValNo++; } // User does not expect that the instruction produces a chain! bool AddedChain = HasChain && !NodeHasChain; if (NodeHasChain) - OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = Chain;\n"; + emitCode("CodeGenMap[N.getValue(" + utostr(ValNo++) + ")] = Chain;"); if (FoldedChains.size() > 0) { - OS << " "; + std::string Code; for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) - OS << "CodeGenMap[" << FoldedChains[j].first << ".getValue(" - << FoldedChains[j].second << ")] = "; - OS << "Chain;\n"; + Code += "CodeGenMap[" + FoldedChains[j].first + ".getValue(" + + utostr(FoldedChains[j].second) + ")] = "; + emitCode(Code + "Chain;"); } if (NodeHasOutFlag) - OS << " CodeGenMap[N.getValue(" << ValNo << ")] = InFlag;\n"; + emitCode("CodeGenMap[N.getValue(" + utostr(ValNo) + ")] = InFlag;"); if (AddedChain && NodeHasOutFlag) { if (NumExpectedResults == 0) { - OS << " return Result.getValue(N.ResNo+1);\n"; + emitCode("return Result.getValue(N.ResNo+1);"); } else { - OS << " if (N.ResNo < " << NumExpectedResults << ")\n"; - OS << " return Result.getValue(N.ResNo);\n"; - OS << " else\n"; - OS << " return Result.getValue(N.ResNo+1);\n"; + emitCode("if (N.ResNo < " + utostr(NumExpectedResults) + ")"); + emitCode(" return Result.getValue(N.ResNo);"); + emitCode("else"); + emitCode(" return Result.getValue(N.ResNo+1);"); } } else { - OS << " return Result.getValue(N.ResNo);\n"; + emitCode("return Result.getValue(N.ResNo);"); } } 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. - OS << " if (N.Val->hasOneUse()) {\n"; - OS << " return CurDAG->SelectNodeTo(N.Val, " - << II.Namespace << "::" << II.TheDef->getName(); + emitCode("if (N.Val->hasOneUse()) {"); + std::string Code = " return CurDAG->SelectNodeTo(N.Val, " + + II.Namespace + "::" + II.TheDef->getName(); if (N->getTypeNum(0) != MVT::isVoid) - OS << ", MVT::" << getEnumName(N->getTypeNum(0)); + Code += ", MVT::" + getEnumName(N->getTypeNum(0)); if (NodeHasOutFlag) - OS << ", MVT::Flag"; + Code += ", MVT::Flag"; for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; + Code += ", Tmp" + utostr(Ops[i]); if (HasInFlag || HasImpInputs) - OS << ", InFlag"; - OS << ");\n"; - OS << " } else {\n"; - OS << " return CodeGenMap[N] = CurDAG->getTargetNode(" - << II.Namespace << "::" << II.TheDef->getName(); + Code += ", InFlag"; + emitCode(Code + ");"); + emitCode("} else {"); + Code = " return CodeGenMap[N] = CurDAG->getTargetNode(" + + II.Namespace + "::" + II.TheDef->getName(); if (N->getTypeNum(0) != MVT::isVoid) - OS << ", MVT::" << getEnumName(N->getTypeNum(0)); + Code += ", MVT::" + getEnumName(N->getTypeNum(0)); if (NodeHasOutFlag) - OS << ", MVT::Flag"; + Code += ", MVT::Flag"; for (unsigned i = 0, e = Ops.size(); i != e; ++i) - OS << ", Tmp" << Ops[i]; + Code += ", Tmp" + utostr(Ops[i]); if (HasInFlag || HasImpInputs) - OS << ", InFlag"; - OS << ");\n"; - OS << " }\n"; + Code += ", InFlag"; + emitCode(Code + ");"); + emitCode("}"); } return std::make_pair(1, ResNo); @@ -2419,11 +2393,11 @@ 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() - << "(Tmp" << OpVal << ".Val);\n"; + emitCode("SDOperand Tmp" + utostr(ResNo) + " = Transform_" + Op->getName() + + "(Tmp" + utostr(OpVal) + ".Val);"); if (isRoot) { - OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n"; - OS << " return Tmp" << ResNo << ";\n"; + emitCode("CodeGenMap[N] = Tmp" +utostr(ResNo) + ";"); + emitCode("return Tmp" + utostr(ResNo) + ";"); } return std::make_pair(1, ResNo); } else { @@ -2443,9 +2417,8 @@ public: if (!Pat->hasTypeSet()) { // Move a type over from 'other' to 'pat'. Pat->setTypes(Other->getExtTypes()); - OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" - << getName(Pat->getTypeNum(0)) << ") goto P" << PatternNo << "Fail;\n"; - GotosFail = true; + emitCheck(Prefix + ".Val->getValueType(0) != MVT::" + + getName(Pat->getTypeNum(0))); return true; } @@ -2485,22 +2458,21 @@ private: if (RR->isSubClassOf("Register")) { MVT::ValueType RVT = getRegisterValueType(RR, T); if (RVT == MVT::Flag) { - OS << " InFlag = Select(" << RootName << OpNo << ");\n"; + emitCode("InFlag = Select(" + RootName + utostr(OpNo) + ");"); } else { if (!ChainEmitted) { - OS << " SDOperand Chain = CurDAG->getEntryNode();\n"; + emitCode("SDOperand Chain = CurDAG->getEntryNode();"); ChainEmitted = true; } - OS << " SDOperand " << RootName << "CR" << i << ";\n"; - OS << " " << RootName << "CR" << i - << " = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(" - << ISE.getQualifiedName(RR) << ", MVT::" - << getEnumName(RVT) << ")" - << ", Select(" << RootName << OpNo << "), InFlag);\n"; - OS << " Chain = " << RootName << "CR" << i - << ".getValue(0);\n"; - OS << " InFlag = " << RootName << "CR" << i - << ".getValue(1);\n"; + emitCode("SDOperand " + RootName + "CR" + utostr(i) + ";"); + emitCode(RootName + "CR" + utostr(i) + + " = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(" + + ISE.getQualifiedName(RR) + ", MVT::" + getEnumName(RVT) + + "), Select(" + RootName + utostr(OpNo) + "), InFlag);"); + emitCode("Chain = " + RootName + "CR" + utostr(i) + + ".getValue(0);"); + emitCode("InFlag = " + RootName + "CR" + utostr(i) + + ".getValue(1);"); } } } @@ -2508,16 +2480,17 @@ private: } if (HasInFlag || HasOptInFlag) { + std::string Code; if (HasOptInFlag) { - OS << " if (" << RootName << ".getNumOperands() == " - << OpNo+1 << ") {\n"; - OS << " "; + emitCode("if (" + RootName + ".getNumOperands() == " + utostr(OpNo+1) + + ") {"); + Code = " "; } - OS << " InFlag = Select(" << RootName << ".getOperand(" - << OpNo << "));\n"; + emitCode(Code + "InFlag = Select(" + RootName + ".getOperand(" + + utostr(OpNo) + "));"); if (HasOptInFlag) { - OS << " HasOptInFlag = true;\n"; - OS << " }\n"; + emitCode(" HasOptInFlag = true;"); + emitCode("}"); } } } @@ -2539,14 +2512,14 @@ private: MVT::ValueType RVT = getRegisterValueType(RR, CGT); if (RVT != MVT::Flag) { if (!ChainEmitted) { - OS << " SDOperand Chain = CurDAG->getEntryNode();\n"; + emitCode("SDOperand Chain = CurDAG->getEntryNode();"); ChainEmitted = true; } - OS << " Result = CurDAG->getCopyFromReg(Chain, " - << ISE.getQualifiedName(RR) - << ", MVT::" << getEnumName(RVT) << ", InFlag);\n"; - OS << " Chain = Result.getValue(1);\n"; - OS << " InFlag = Result.getValue(2);\n"; + emitCode("Result = CurDAG->getCopyFromReg(Chain, " + + ISE.getQualifiedName(RR) + ", MVT::" + getEnumName(RVT) + + ", InFlag);"); + emitCode("Chain = Result.getValue(1);"); + emitCode("InFlag = Result.getValue(2);"); RetVal = true; } } @@ -2564,19 +2537,11 @@ bool DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS) { static unsigned PatternCount = 0; unsigned PatternNo = PatternCount++; - OS << " { // Pattern #" << PatternNo << ": "; - Pattern.getSrcPattern()->print(OS); - OS << "\n // Emits: "; - Pattern.getDstPattern()->print(OS); - OS << "\n"; - OS << " // Pattern complexity = " - << getPatternSize(Pattern.getSrcPattern(), *this) - << " cost = " - << getResultPatternCost(Pattern.getDstPattern()) << "\n"; + std::vector > GeneratedCode; PatternCodeEmitter Emitter(*this, Pattern.getPredicates(), Pattern.getSrcPattern(), Pattern.getDstPattern(), - PatternNo, OS); + PatternNo, GeneratedCode); // Emit the matcher, capturing named arguments in VariableMap. bool FoundChain = false; @@ -2623,12 +2588,35 @@ bool DAGISelEmitter::EmitCodeForPattern(PatternToMatch &Pattern, delete Pat; - if (Emitter.UsesFailLabel()) - OS << " }\n P" << PatternNo << "Fail:\n"; - else - OS << " }\n"; + + OS << " { // Pattern #" << PatternNo << ": "; + Pattern.getSrcPattern()->print(OS); + OS << "\n // Emits: "; + Pattern.getDstPattern()->print(OS); + OS << "\n"; + OS << " // Pattern complexity = " + << getPatternSize(Pattern.getSrcPattern(), *this) + << " cost = " + << getResultPatternCost(Pattern.getDstPattern()) << "\n"; + + // Actually output the generated code now. + bool CanFail = false; + for (unsigned i = 0, e = GeneratedCode.size(); i != e; ++i) { + if (!GeneratedCode[i].first) { + // Normal code. + OS << " " << GeneratedCode[i].second << "\n"; + } else { + OS << " if (" << GeneratedCode[i].second << ") goto P" + << PatternNo << "Fail;\n"; + CanFail = true; + } + } + + OS << " }\n"; + if (CanFail) + OS << "P" << PatternNo << "Fail:\n"; - return Emitter.UsesFailLabel(); + return CanFail; }