Changes in directory llvm/utils/TableGen:
DAGISelEmitter.cpp updated: 1.111 -> 1.112 DAGISelEmitter.h updated: 1.46 -> 1.47 --- Log message: * Added support for FLAG - a special nameless flag register. Can be used as either an operand or a result. * Fixed some more flag / chain bugs. --- Diffs of the changes: (+68 -65) DAGISelEmitter.cpp | 120 +++++++++++++++++++++++++++++------------------------ DAGISelEmitter.h | 13 ----- 2 files changed, 68 insertions(+), 65 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.111 llvm/utils/TableGen/DAGISelEmitter.cpp:1.112 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.111 Wed Dec 21 14:20:49 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Dec 21 20:24:50 2005 @@ -489,6 +489,9 @@ } else if (R->getName() == "node" || R->getName() == "srcvalue") { // Placeholder. return MVT::isUnknown; + } else if (R->getName() == "FLAG") { + // Some pseudo flag operand. + return MVT::Flag; } TP.error("Unknown node flavor used in pattern: " + R->getName()); @@ -952,17 +955,13 @@ /// HandleUse - Given "Pat" a leaf in the pattern, check to see if it is an /// instruction input. Return true if this is a real use. static bool HandleUse(TreePattern *I, TreePatternNode *Pat, - std::map<std::string, TreePatternNode*> &InstInputs, - std::vector<Record*> &InstImpInputs) { + std::map<std::string, TreePatternNode*> &InstInputs) { // No name -> not interesting. if (Pat->getName().empty()) { if (Pat->isLeaf()) { DefInit *DI = dynamic_cast<DefInit*>(Pat->getLeafValue()); if (DI && DI->getDef()->isSubClassOf("RegisterClass")) I->error("Input " + DI->getDef()->getName() + " must be named!"); - else if (DI && DI->getDef()->isSubClassOf("Register")) { - InstImpInputs.push_back(DI->getDef()); - } } return false; } @@ -1009,10 +1008,9 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, std::map<std::string, TreePatternNode*> &InstInputs, std::map<std::string, Record*> &InstResults, - std::vector<Record*> &InstImpInputs, std::vector<Record*> &InstImpResults) { if (Pat->isLeaf()) { - bool isUse = HandleUse(I, Pat, InstInputs, InstImpInputs); + bool isUse = HandleUse(I, Pat, InstInputs); if (!isUse && Pat->getTransformFn()) I->error("Cannot specify a transform function for a non-input value!"); return; @@ -1023,14 +1021,14 @@ if (Pat->getChild(i)->getExtType() == MVT::isVoid) I->error("Cannot have void nodes inside of patterns!"); FindPatternInputsAndOutputs(I, Pat->getChild(i), InstInputs, InstResults, - InstImpInputs, InstImpResults); + InstImpResults); } // If this is a non-leaf node with no children, treat it basically as if // it were a leaf. This handles nodes like (imm). bool isUse = false; if (Pat->getNumChildren() == 0) - isUse = HandleUse(I, Pat, InstInputs, InstImpInputs); + isUse = HandleUse(I, Pat, InstInputs); if (!isUse && Pat->getTransformFn()) I->error("Cannot specify a transform function for a non-input value!"); @@ -1063,7 +1061,8 @@ if (InstResults.count(Dest->getName())) I->error("cannot set '" + Dest->getName() +"' multiple times"); InstResults[Dest->getName()] = Val->getDef(); - } else if (Val->getDef()->isSubClassOf("Register")) { + } else if (Val->getDef()->isSubClassOf("Register") || + Val->getDef()->getName() == "FLAG") { InstImpResults.push_back(Val->getDef()); } else { I->error("set destination should be a register!"); @@ -1071,7 +1070,7 @@ // Verify and collect info from the computation. FindPatternInputsAndOutputs(I, Pat->getChild(i+NumValues), - InstInputs, InstResults, InstImpInputs, InstImpResults); + InstInputs, InstResults, InstImpResults); } } @@ -1147,8 +1146,7 @@ std::vector<Record*> ImpResults; std::vector<Record*> ImpOperands; Instructions.insert(std::make_pair(Instrs[i], - DAGInstruction(0, Results, Operands, - ImpResults, ImpOperands))); + DAGInstruction(0, Results, Operands, ImpResults))); continue; // no pattern. } @@ -1169,8 +1167,6 @@ // InstResults - Keep track of all the virtual registers that are 'set' // in the instruction, including what reg class they are. std::map<std::string, Record*> InstResults; - - std::vector<Record*> InstImpInputs; std::vector<Record*> InstImpResults; // Verify that the top-level forms in the instruction are of void type, and @@ -1183,7 +1179,7 @@ // Find inputs and outputs, and verify the structure of the uses/defs. FindPatternInputsAndOutputs(I, Pat, InstInputs, InstResults, - InstImpInputs, InstImpResults); + InstImpResults); } // Now that we have inputs and outputs of the pattern, inspect the operands @@ -1272,7 +1268,7 @@ new TreePatternNode(I->getRecord(), ResultNodeOperands); // Create and insert the instruction. - DAGInstruction TheInst(I, Results, Operands, InstImpResults, InstImpInputs); + DAGInstruction TheInst(I, Results, Operands, InstImpResults); Instructions.insert(std::make_pair(I->getRecord(), TheInst)); // Use a temporary tree pattern to infer all types and make sure that the @@ -1346,11 +1342,10 @@ { std::map<std::string, TreePatternNode*> InstInputs; std::map<std::string, Record*> InstResults; - std::vector<Record*> InstImpInputs; std::vector<Record*> InstImpResults; FindPatternInputsAndOutputs(Pattern, Pattern->getOnlyTree(), InstInputs, InstResults, - InstImpInputs, InstImpResults); + InstImpResults); } ListInit *LI = Patterns[i]->getValueAsListInit("ResultInstrs"); @@ -1763,13 +1758,15 @@ std::vector<std::pair<std::string, unsigned> > FoldedChains; bool FoundChain; unsigned TmpNo; + unsigned NumImpInputs; 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), OS(os), FoundChain(false), TmpNo(0) {} + PatternNo(PatNum), OS(os), FoundChain(false), TmpNo(0), + NumImpInputs(0) {} /// isPredeclaredSDOperand - Return true if this is one of the predeclared /// SDOperands. @@ -1904,8 +1901,13 @@ if (LeafRec->isSubClassOf("RegisterClass")) { // Handle register references. Nothing to do here. } else if (LeafRec->isSubClassOf("Register")) { + // Handle register references. + NumImpInputs++; } else if (LeafRec->isSubClassOf("ComplexPattern")) { // Handle complex pattern. Nothing to do here. + } else if (LeafRec->getName() == "FLAG") { + // Handle pseudo FLAG register nodes. + NumImpInputs++; } else if (LeafRec->getName() == "srcvalue") { // Place holder for SRCVALUE nodes. Nothing to do here. } else if (LeafRec->isSubClassOf("ValueType")) { @@ -1920,6 +1922,7 @@ << ") goto P" << PatternNo << "Fail;\n"; } else { Child->dump(); + std::cerr << " "; assert(0 && "Unknown leaf type!"); } } else if (IntInit *II = dynamic_cast<IntInit*>(Child->getLeafValue())) { @@ -2045,11 +2048,8 @@ Record *Op = N->getOperator(); if (Op->isSubClassOf("Instruction")) { const DAGInstruction &Inst = ISE.getInstruction(Op); - unsigned NumImpResults = Inst.getNumImpResults(); - unsigned NumImpOperands = Inst.getNumImpOperands(); - bool InFlag = NumImpOperands > 0; - bool OutFlag = NumImpResults > 0; - bool IsCopyFromReg = false; + bool InFlag = NumImpInputs > 0; + bool OutFlag = Inst.getNumImpResults() > 0; if (InFlag || OutFlag) OS << " InFlag = SDOperand(0, 0);\n"; @@ -2147,41 +2147,50 @@ ValNo++; } - if (II.hasCtrlDep) { + if (II.hasCtrlDep) OS << " Chain = Result.getValue(" << ValNo << ");\n"; - if (OutFlag) - OS << " InFlag = Result.getValue(" << ValNo+1 << ");\n"; - } else if (OutFlag) - OS << " InFlag = Result.getValue(" << ValNo << ");\n"; if (OutFlag) - IsCopyFromReg = EmitCopyFromRegs(N, II.hasCtrlDep); - if (IsCopyFromReg) - OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = Result;\n"; + OS << " InFlag = Result.getValue(" + << ValNo + (unsigned)II.hasCtrlDep << ");\n"; - if (OutFlag) - OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = InFlag;\n"; + unsigned NumCopies = 0; + if (OutFlag) { + NumCopies = EmitCopyFromRegs(N, II.hasCtrlDep); + for (unsigned i = 0; i < NumCopies; i++) { + OS << " CodeGenMap[N.getValue(" << ValNo << ")] = " + << "Result.getValue(" << ValNo << ");\n"; + ValNo++; + } + } + + // User does not expect that I produce a chain! + bool AddedChain = + !NodeHasChain(Pattern, ISE) && (II.hasCtrlDep || NumCopies > 0); - if (IsCopyFromReg || II.hasCtrlDep) { + if (NodeHasChain(Pattern, ISE)) + OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = Chain;\n"; + + if (FoldedChains.size() > 0) { OS << " "; - if (IsCopyFromReg || NodeHasChain(Pattern, ISE)) - OS << "CodeGenMap[N.getValue(" << ValNo << ")] = "; for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) OS << "CodeGenMap[" << FoldedChains[j].first << ".getValue(" << FoldedChains[j].second << ")] = "; OS << "Chain;\n"; } - // FIXME: this only works because (for now) an instruction can either - // produce a single result or a single flag. - if (II.hasCtrlDep && OutFlag) { - if (IsCopyFromReg) - OS << " return (N.ResNo == 0) ? Result : " - << "((N.ResNo == 2) ? Chain : InFlag);" - << " // Chain comes before flag.\n"; - else - OS << " return (N.ResNo) ? Chain : InFlag;" - << " // Chain comes before flag.\n"; + if (OutFlag) + OS << " CodeGenMap[N.getValue(" << ValNo << ")] = InFlag;\n"; + + if (AddedChain && OutFlag) { + if (NumResults == 0) { + OS << " return Result.getValue(N.ResNo+1);\n"; + } else { + OS << " if (N.ResNo < " << NumResults << ")\n"; + OS << " return Result.getValue(N.ResNo);\n"; + OS << " else\n"; + OS << " return Result.getValue(N.ResNo+1);\n"; + } } else { OS << " return Result.getValue(N.ResNo);\n"; } @@ -2295,6 +2304,8 @@ << ", Select(" << RootName << OpNo << "), InFlag).getValue(1);\n"; } + } else if (RR->getName() == "FLAG") { + OS << " InFlag = Select(" << RootName << OpNo << ");\n"; } } } @@ -2302,9 +2313,10 @@ } /// EmitCopyFromRegs - Emit code to copy result to physical registers - /// as specified by the instruction. - bool EmitCopyFromRegs(TreePatternNode *N, bool HasCtrlDep) { - bool RetVal = false; + /// as specified by the instruction. It returns the number of + /// CopyFromRegs emitted. + unsigned EmitCopyFromRegs(TreePatternNode *N, bool HasCtrlDep) { + unsigned NumCopies = 0; Record *Op = N->getOperator(); if (Op->isSubClassOf("Instruction")) { const DAGInstruction &Inst = ISE.getInstruction(Op); @@ -2330,12 +2342,12 @@ OS << " Chain = Result.getValue(1);\n"; OS << " InFlag = Result.getValue(2);\n"; } - RetVal = true; + NumCopies++; } } } } - return RetVal; + return NumCopies; } }; @@ -2555,7 +2567,7 @@ OS << " } // end of big switch.\n\n" << " std::cerr << \"Cannot yet select: \";\n" - << " N.Val->dump();\n" + << " N.Val->dump(CurDAG);\n" << " std::cerr << '\\n';\n" << " abort();\n" << "}\n"; Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.46 llvm/utils/TableGen/DAGISelEmitter.h:1.47 --- llvm/utils/TableGen/DAGISelEmitter.h:1.46 Fri Dec 16 19:19:28 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Dec 21 20:24:50 2005 @@ -328,23 +328,19 @@ std::vector<Record*> Results; std::vector<Record*> Operands; std::vector<Record*> ImpResults; - std::vector<Record*> ImpOperands; TreePatternNode *ResultPattern; public: DAGInstruction(TreePattern *TP, const std::vector<Record*> &results, const std::vector<Record*> &operands, - const std::vector<Record*> &impresults, - const std::vector<Record*> &impoperands) + const std::vector<Record*> &impresults) : Pattern(TP), Results(results), Operands(operands), - ImpResults(impresults), ImpOperands(impoperands), - ResultPattern(0) {} + ImpResults(impresults), ResultPattern(0) {} TreePattern *getPattern() const { return Pattern; } unsigned getNumResults() const { return Results.size(); } unsigned getNumOperands() const { return Operands.size(); } unsigned getNumImpResults() const { return ImpResults.size(); } - unsigned getNumImpOperands() const { return ImpOperands.size(); } void setResultPattern(TreePatternNode *R) { ResultPattern = R; } @@ -363,10 +359,6 @@ return ImpResults[RN]; } - Record *getImpOperand(unsigned ON) const { - assert(ON < ImpOperands.size()); - return ImpOperands[ON]; - } TreePatternNode *getResultPattern() const { return ResultPattern; } }; @@ -452,7 +444,6 @@ std::map<std::string, TreePatternNode*> &InstInputs, std::map<std::string, Record*> &InstResults, - std::vector<Record*> &InstImpInputs, std::vector<Record*> &InstImpResults); void EmitCodeForPattern(PatternToMatch &Pattern, std::ostream &OS); void EmitInstructionSelector(std::ostream &OS); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits