Changes in directory llvm/utils/TableGen:
CodeGenTarget.cpp updated: 1.47 -> 1.48 CodeGenTarget.h updated: 1.21 -> 1.22 DAGISelEmitter.cpp updated: 1.85 -> 1.86 DAGISelEmitter.h updated: 1.39 -> 1.40 --- Log message: Added support for ComplexPattern. These are patterns that require C++ pattern matching code that is not currently auto-generated by tblgen, e.g. X86 addressing mode. Selection routines for complex patterns can return multiple operands, e.g. X86 addressing mode returns 4. --- Diffs of the changes: (+171 -47) CodeGenTarget.cpp | 9 ++ CodeGenTarget.h | 17 +++++ DAGISelEmitter.cpp | 165 ++++++++++++++++++++++++++++++++++++++++------------- DAGISelEmitter.h | 27 +++++--- 4 files changed, 171 insertions(+), 47 deletions(-) Index: llvm/utils/TableGen/CodeGenTarget.cpp diff -u llvm/utils/TableGen/CodeGenTarget.cpp:1.47 llvm/utils/TableGen/CodeGenTarget.cpp:1.48 --- llvm/utils/TableGen/CodeGenTarget.cpp:1.47 Sun Dec 4 02:18:16 2005 +++ llvm/utils/TableGen/CodeGenTarget.cpp Wed Dec 7 20:00:36 2005 @@ -330,3 +330,12 @@ throw "Instruction '" + TheDef->getName() + "' does not have an operand named '$" + Name + "'!"; } + +//===----------------------------------------------------------------------===// +// ComplexPattern implementation +// +ComplexPattern::ComplexPattern(Record *R) { + NumOperands = R->getValueAsInt("NumOperands"); + SelectFunc = R->getValueAsString("SelectFunc"); + MatchingNodes = R->getValueAsListOfDefs("MatchingNodes"); +} Index: llvm/utils/TableGen/CodeGenTarget.h diff -u llvm/utils/TableGen/CodeGenTarget.h:1.21 llvm/utils/TableGen/CodeGenTarget.h:1.22 --- llvm/utils/TableGen/CodeGenTarget.h:1.21 Sun Dec 4 20:35:08 2005 +++ llvm/utils/TableGen/CodeGenTarget.h Wed Dec 7 20:00:36 2005 @@ -157,6 +157,23 @@ bool isLittleEndianEncoding() const; }; +/// ComplexPattern - ComplexPattern info, corresponding to the ComplexPattern +/// tablegen class in TargetSelectionDAG.td +class ComplexPattern { + unsigned NumOperands; + std::string SelectFunc; + std::vector<Record*> MatchingNodes; +public: + ComplexPattern() : NumOperands(0) {}; + ComplexPattern(Record *R); + + unsigned getNumOperands() const { return NumOperands; } + const std::string &getSelectFunc() const { return SelectFunc; } + const std::vector<Record*> &getMatchingNodes() const { + return MatchingNodes; + } +}; + } // End llvm namespace #endif Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.85 llvm/utils/TableGen/DAGISelEmitter.cpp:1.86 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.85 Mon Dec 5 17:08:55 2005 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Dec 7 20:00:36 2005 @@ -477,6 +477,9 @@ } else if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { // Using a VTSDNode or CondCodeSDNode. return MVT::Other; + } else if (R->isSubClassOf("ComplexPattern")) { + const CodeGenTarget &T = TP.getDAGISelEmitter().getTargetInfo(); + return T.getPointerType(); } else if (R->getName() == "node") { // Placeholder. return MVT::isUnknown; @@ -609,7 +612,7 @@ for (unsigned i = 0, e = getNumChildren(); i != e; ++i) if (!getChild(i)->canPatternMatch(Reason, ISE)) return false; - + // If this node is a commutative operator, check that the LHS isn't an // immediate. const SDNodeInfo &NodeInfo = ISE.getSDNodeInfo(getOperator()); @@ -833,6 +836,13 @@ } } +void DAGISelEmitter::ParseComplexPatterns() { + std::vector<Record*> AMs = Records.getAllDerivedDefinitions("ComplexPattern"); + while (!AMs.empty()) { + ComplexPatterns.insert(std::make_pair(AMs.back(), AMs.back())); + AMs.pop_back(); + } +} /// ParsePatternFragments - Parse all of the PatFrag definitions in the .td @@ -1204,9 +1214,10 @@ if (InVal->isLeaf() && dynamic_cast<DefInit*>(InVal->getLeafValue())) { Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef(); - if (CGI.OperandList[i].Rec != InRec) + if (CGI.OperandList[i].Rec != InRec && + !InRec->isSubClassOf("ComplexPattern")) I->error("Operand $" + OpName + - "'s register class disagrees between the operand and pattern"); + "'s register class disagrees between the operand and pattern"); } Operands.push_back(CGI.OperandList[i].Rec); @@ -1586,22 +1597,59 @@ } +// NodeIsComplexPattern - return true if N is a leaf node and a subclass of +// ComplexPattern. +static bool NodeIsComplexPattern(TreePatternNode *N) +{ + return (N->isLeaf() && + dynamic_cast<DefInit*>(N->getLeafValue()) && + static_cast<DefInit*>(N->getLeafValue())->getDef()-> + isSubClassOf("ComplexPattern")); +} + +// NodeGetComplexPattern - return the pointer to the ComplexPattern if N +// is a leaf node and a subclass of ComplexPattern, else it returns NULL. +static const ComplexPattern *NodeGetComplexPattern(TreePatternNode *N, + DAGISelEmitter &ISE) +{ + if (N->isLeaf() && + dynamic_cast<DefInit*>(N->getLeafValue()) && + static_cast<DefInit*>(N->getLeafValue())->getDef()-> + isSubClassOf("ComplexPattern")) { + return &ISE.getComplexPattern(static_cast<DefInit*>(N->getLeafValue()) + ->getDef()); + } + return NULL; +} + /// getPatternSize - Return the 'size' of this pattern. We want to match large /// patterns before small ones. This is used to determine the size of a /// pattern. -static unsigned getPatternSize(TreePatternNode *P) { +static unsigned getPatternSize(TreePatternNode *P, DAGISelEmitter &ISE) { assert(isExtIntegerVT(P->getExtType()) || isExtFloatingPointVT(P->getExtType()) || P->getExtType() == MVT::isVoid && "Not a valid pattern node to size!"); unsigned Size = 1; // The node itself. - + + // FIXME: This is a hack to statically increase the priority of patterns + // which maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. + // Later we can allow complexity / cost for each pattern to be (optionally) + // specified. To get best possible pattern match we'll need to dynamically + // calculate the complexity of all patterns a dag can potentially map to. + const ComplexPattern *AM = NodeGetComplexPattern(P, ISE); + if (AM) + Size += AM->getNumOperands(); + // Count children in the count if they are also nodes. for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { TreePatternNode *Child = P->getChild(i); if (!Child->isLeaf() && Child->getExtType() != MVT::Other) - Size += getPatternSize(Child); - else if (Child->isLeaf() && dynamic_cast<IntInit*>(Child->getLeafValue())) { - ++Size; // Matches a ConstantSDNode. + Size += getPatternSize(Child, ISE); + else if (Child->isLeaf()) { + if (dynamic_cast<IntInit*>(Child->getLeafValue())) + ++Size; // Matches a ConstantSDNode. + else if (NodeIsComplexPattern(Child)) + Size += getPatternSize(Child, ISE); } } @@ -1624,10 +1672,13 @@ // In particular, we want to match maximal patterns first and lowest cost within // a particular complexity first. struct PatternSortingPredicate { + PatternSortingPredicate(DAGISelEmitter &ise) : ISE(ise) {}; + DAGISelEmitter &ISE; + bool operator()(DAGISelEmitter::PatternToMatch *LHS, DAGISelEmitter::PatternToMatch *RHS) { - unsigned LHSSize = getPatternSize(LHS->first); - unsigned RHSSize = getPatternSize(RHS->first); + unsigned LHSSize = getPatternSize(LHS->first, ISE); + unsigned RHSSize = getPatternSize(RHS->first, ISE); if (LHSSize > RHSSize) return true; // LHS -> bigger -> less cost if (LHSSize < RHSSize) return false; @@ -1649,9 +1700,10 @@ << ")->getSignExtended() != " << II->getValue() << ")\n" << " goto P" << PatternNo << "Fail;\n"; return; + } else if (!NodeIsComplexPattern(N)) { + assert(0 && "Cannot match this as a leaf value!"); + abort(); } - assert(0 && "Cannot match this as a leaf value!"); - abort(); } // If this node has a name associated with it, capture it in VarMap. If @@ -1710,6 +1762,8 @@ if (LeafRec->isSubClassOf("RegisterClass") || LeafRec->isSubClassOf("Register")) { // Handle register references. Nothing to do here. + } else if (LeafRec->isSubClassOf("ComplexPattern")) { + // Handle complex pattern. Nothing to do here. } else if (LeafRec->isSubClassOf("ValueType")) { // Make sure this is the specified value type. OS << " if (cast<VTSDNode>(" << RootName << OpNo << ")->getVT() != " @@ -1819,9 +1873,10 @@ /// CodeGenPatternResult - Emit the action for a pattern. Now that it has /// matched, we actually have to build a DAG! -unsigned DAGISelEmitter:: +std::pair<unsigned, unsigned> DAGISelEmitter:: CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, std::map<std::string,std::string> &VariableMap, + unsigned PatternNo, std::ostream &OS, bool &HasChain, bool InFlag, bool isRoot) { // This is something selected from the pattern we matched. @@ -1832,10 +1887,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 atoi(Val.c_str()+3); + return std::make_pair(1, atoi(Val.c_str()+3)); } - + + const ComplexPattern *CP; unsigned ResNo = Ctr++; + unsigned NumRes = 1; if (!N->isLeaf() && N->getOperator()->getName() == "imm") { switch (N->getType()) { default: assert(0 && "Unknown type for constant node!"); @@ -1850,13 +1907,27 @@ << ResNo << "C, MVT::" << getEnumName(N->getType()) << ");\n"; } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") { OS << " SDOperand Tmp" << ResNo << " = " << Val << ";\n"; + } else if (N->isLeaf() && (CP = NodeGetComplexPattern(N, *this))) { + std::string Fn = CP->getSelectFunc(); + NumRes = CP->getNumOperands(); + OS << " SDOperand "; + for (unsigned i = 0; i < NumRes; i++) { + if (i != 0) OS << ", "; + OS << "Tmp" << i + ResNo; + } + OS << ";\n"; + OS << " if (!" << Fn << "(" << Val; + for (unsigned i = 0; i < NumRes; i++) + OS << " , Tmp" << i + ResNo; + OS << ")) goto P" << PatternNo << "Fail;\n"; + Ctr = ResNo + NumRes; } else { OS << " SDOperand Tmp" << ResNo << " = Select(" << Val << ");\n"; } // 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 ResNo; + return std::make_pair(NumRes, ResNo); } if (N->isLeaf()) { @@ -1868,7 +1939,7 @@ << getQualifiedName(DI->getDef()) << ", MVT::" << getEnumName(N->getType()) << ");\n"; - return ResNo; + return std::make_pair(1, ResNo); } } else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) { unsigned ResNo = Ctr++; @@ -1876,21 +1947,26 @@ << II->getValue() << ", MVT::" << getEnumName(N->getType()) << ");\n"; - return ResNo; + return std::make_pair(1, ResNo); } N->dump(); assert(0 && "Unknown leaf type!"); - return ~0U; + return std::make_pair(1, ~0U); } Record *Op = N->getOperator(); if (Op->isSubClassOf("Instruction")) { // Emit all of the operands. std::vector<unsigned> Ops; - for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) - Ops.push_back(CodeGenPatternResult(N->getChild(i), Ctr, - VariableMap, OS, HasChain, InFlag)); + for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) { + TreePatternNode *Child = N->getChild(i); + std::pair<unsigned, unsigned> NOPair = + CodeGenPatternResult(Child, Ctr, + VariableMap, PatternNo, OS, HasChain, InFlag); + for (unsigned j = 0; j < NOPair.first; j++) + Ops.push_back(NOPair.second + j); + } CodeGenInstruction &II = Target.getInstruction(Op->getName()); bool HasCtrlDep = II.hasCtrlDep; @@ -1934,12 +2010,12 @@ OS << " CodeGenMap[N.getValue(0)] = Result;\n"; OS << " CodeGenMap[N.getValue(" << NumResults << ")] = Result.getValue(" << NumResults << ");\n"; - OS << " Chain = CodeGenMap[N].getValue(" << NumResults << ");\n"; + OS << " Chain = Result.getValue(" << NumResults << ");\n"; } if (NumResults == 0) OS << " return Chain;\n"; else - OS << " return (N.ResNo) ? Chain : CodeGenMap[N];\n"; + OS << " return (N.ResNo) ? Chain : Result.getValue(0);\n"; } 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. @@ -1963,11 +2039,12 @@ OS << ");\n"; OS << " }\n"; } - return ResNo; + return std::make_pair(1, ResNo); } else if (Op->isSubClassOf("SDNodeXForm")) { assert(N->getNumChildren() == 1 && "node xform should have one child!"); unsigned OpVal = CodeGenPatternResult(N->getChild(0), Ctr, - VariableMap, OS, HasChain, InFlag); + VariableMap, PatternNo, OS, HasChain, InFlag) + .second; unsigned ResNo = Ctr++; OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName() @@ -1976,11 +2053,11 @@ OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n"; OS << " return Tmp" << ResNo << ";\n"; } - return ResNo; + return std::make_pair(1, ResNo); } else { N->dump(); assert(0 && "Unknown node in result pattern!"); - return ~0U; + return std::make_pair(1, ~0U); } } @@ -2005,10 +2082,13 @@ if (!Pat->hasTypeSet()) { // Move a type over from 'other' to 'pat'. Pat->setType(Other->getType()); - OS << " if (" << Prefix << ".getValueType() != MVT::" + OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; return true; } else if (Pat->isLeaf()) { + if (NodeIsComplexPattern(Pat)) + OS << " if (" << Prefix << ".Val->getValueType(0) != MVT::" + << getName(Pat->getType()) << ") goto P" << PatternNo << "Fail;\n"; return false; } @@ -2038,7 +2118,7 @@ OS << "\n // Emits: "; Pattern.second->print(OS); OS << "\n"; - OS << " // Pattern complexity = " << getPatternSize(Pattern.first) + OS << " // Pattern complexity = " << getPatternSize(Pattern.first, *this) << " cost = " << getResultPatternCost(Pattern.second) << "\n"; // Emit the matcher, capturing named arguments in VariableMap. @@ -2088,7 +2168,7 @@ unsigned TmpNo = 0; CodeGenPatternResult(Pattern.second, - TmpNo, VariableMap, OS, HasChain, InFlag, true /*the root*/); + TmpNo, VariableMap, PatternNo, OS, HasChain, InFlag, true /*the root*/); delete Pat; OS << " }\n P" << PatternNo << "Fail:\n"; @@ -2166,23 +2246,31 @@ // Group the patterns by their top-level opcodes. std::map<Record*, std::vector<PatternToMatch*>, CompareByRecordName> PatternsByOpcode; - for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) - if (!PatternsToMatch[i].first->isLeaf()) { - PatternsByOpcode[PatternsToMatch[i].first->getOperator()] - .push_back(&PatternsToMatch[i]); + for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) { + TreePatternNode *Node = PatternsToMatch[i].first; + if (!Node->isLeaf()) { + PatternsByOpcode[Node->getOperator()].push_back(&PatternsToMatch[i]); } else { + const ComplexPattern *CP; if (IntInit *II = - dynamic_cast<IntInit*>(PatternsToMatch[i].first->getLeafValue())) { + dynamic_cast<IntInit*>(Node->getLeafValue())) { PatternsByOpcode[getSDNodeNamed("imm")].push_back(&PatternsToMatch[i]); + } else if ((CP = NodeGetComplexPattern(Node, *this))) { + std::vector<Record*> OpNodes = CP->getMatchingNodes(); + for (unsigned j = 0, e = OpNodes.size(); j != e; j++) { + PatternsByOpcode[OpNodes[j]].insert(PatternsByOpcode[OpNodes[j]].begin(), + &PatternsToMatch[i]); + } } else { std::cerr << "Unrecognized opcode '"; - PatternsToMatch[i].first->dump(); + Node->dump(); std::cerr << "' on tree pattern '"; std::cerr << PatternsToMatch[i].second->getOperator()->getName(); std::cerr << "'!\n"; exit(1); } } + } // Loop over all of the case statements. for (std::map<Record*, std::vector<PatternToMatch*>, @@ -2197,7 +2285,7 @@ // the matches in order of minimal cost. Sort the patterns so the least // cost one is at the start. std::stable_sort(Patterns.begin(), Patterns.end(), - PatternSortingPredicate()); + PatternSortingPredicate(*this)); for (unsigned i = 0, e = Patterns.size(); i != e; ++i) EmitCodeForPattern(*Patterns[i], OS); @@ -2227,6 +2315,7 @@ ParseNodeInfo(); ParseNodeTransforms(OS); + ParseComplexPatterns(); ParsePatternFragments(OS); ParseInstructions(); ParsePatterns(); Index: llvm/utils/TableGen/DAGISelEmitter.h diff -u llvm/utils/TableGen/DAGISelEmitter.h:1.39 llvm/utils/TableGen/DAGISelEmitter.h:1.40 --- llvm/utils/TableGen/DAGISelEmitter.h:1.39 Sun Dec 4 02:18:16 2005 +++ llvm/utils/TableGen/DAGISelEmitter.h Wed Dec 7 20:00:36 2005 @@ -26,6 +26,7 @@ class TreePattern; class TreePatternNode; class DAGISelEmitter; + class ComplexPattern; /// MVT::DAGISelGenValueType - These are some extended forms of MVT::ValueType /// that we use as lattice values during type inferrence. @@ -365,6 +366,7 @@ std::map<Record*, SDNodeInfo> SDNodes; std::map<Record*, std::pair<Record*, std::string> > SDNodeXForms; + std::map<Record*, ComplexPattern> ComplexPatterns; std::map<Record*, TreePattern*> PatternFragments; std::map<Record*, DAGInstruction> Instructions; @@ -387,15 +389,20 @@ return SDNodes.find(R)->second; } - TreePattern *getPatternFragment(Record *R) const { - assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); - return PatternFragments.find(R)->second; - } - const std::pair<Record*, std::string> &getSDNodeTransform(Record *R) const { assert(SDNodeXForms.count(R) && "Invalid transform!"); return SDNodeXForms.find(R)->second; } + + const ComplexPattern &getComplexPattern(Record *R) const { + assert(ComplexPatterns.count(R) && "Unknown addressing mode!"); + return ComplexPatterns.find(R)->second; + } + + TreePattern *getPatternFragment(Record *R) const { + assert(PatternFragments.count(R) && "Invalid pattern fragment request!"); + return PatternFragments.find(R)->second; + } const DAGInstruction &getInstruction(Record *R) const { assert(Instructions.count(R) && "Unknown instruction!"); @@ -405,6 +412,7 @@ private: void ParseNodeInfo(); void ParseNodeTransforms(std::ostream &OS); + void ParseComplexPatterns(); void ParsePatternFragments(std::ostream &OS); void ParseInstructions(); void ParsePatterns(); @@ -420,10 +428,11 @@ std::ostream &OS, bool &HasChain); void EmitCopyToRegsForPattern(TreePatternNode *N, const std::string &RootName, std::ostream &OS, bool &HasChain, bool &InFlag); - unsigned CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, - std::map<std::string,std::string> &VariableMap, - std::ostream &OS, bool &HasChain, bool InFlag, - bool isRoot = false); + std::pair<unsigned, unsigned> + CodeGenPatternResult(TreePatternNode *N, unsigned &Ctr, + std::map<std::string,std::string> &VariableMap, + unsigned PatternNo, std::ostream &OS, bool &HasChain, + bool InFlag, bool isRoot = false); 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