From 543790673c747ab2793fc657e239ce5f78419dc0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 17 Apr 2011 21:38:24 +0000 Subject: Rework our internal representation of node predicates to expose more structure and fix some fixmes. We now have a TreePredicateFn class that handles all of the decoding of these things. This is an internal cleanup that has no impact on the code generated by tblgen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129670 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 75 +++++++++++++++++++++++--------- utils/TableGen/CodeGenDAGPatterns.h | 53 +++++++++++++++++++--- utils/TableGen/DAGISelMatcher.cpp | 14 ++++-- utils/TableGen/DAGISelMatcher.h | 11 ++--- utils/TableGen/DAGISelMatcherEmitter.cpp | 46 ++++++++------------ 5 files changed, 139 insertions(+), 60 deletions(-) (limited to 'utils/TableGen') diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 79cf18a4d7..b74144ebfd 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -580,34 +580,29 @@ typedef std::map DepVarMap; /// Const iterator shorthand for DepVarMap typedef DepVarMap::const_iterator DepVarMap_citer; -namespace { -void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) { +static void FindDepVarsOf(TreePatternNode *N, DepVarMap &DepMap) { if (N->isLeaf()) { - if (dynamic_cast(N->getLeafValue()) != NULL) { + if (dynamic_cast(N->getLeafValue()) != NULL) DepMap[N->getName()]++; - } } else { for (size_t i = 0, e = N->getNumChildren(); i != e; ++i) FindDepVarsOf(N->getChild(i), DepMap); } } - -//! Find dependent variables within child patterns -/*! - */ -void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) { + +/// Find dependent variables within child patterns +static void FindDepVars(TreePatternNode *N, MultipleUseVarSet &DepVars) { DepVarMap depcounts; FindDepVarsOf(N, depcounts); for (DepVarMap_citer i = depcounts.begin(); i != depcounts.end(); ++i) { - if (i->second > 1) { // std::pair + if (i->second > 1) // std::pair DepVars.insert(i->first); - } } } -//! Dump the dependent variable set: #ifndef NDEBUG -void DumpDepVars(MultipleUseVarSet &DepVars) { +/// Dump the dependent variable set: +static void DumpDepVars(MultipleUseVarSet &DepVars) { if (DepVars.empty()) { DEBUG(errs() << ""); } else { @@ -621,6 +616,46 @@ void DumpDepVars(MultipleUseVarSet &DepVars) { } #endif + +//===----------------------------------------------------------------------===// +// TreePredicateFn Implementation +//===----------------------------------------------------------------------===// + +std::string TreePredicateFn::getPredCode() const { + return PatFragRec->getRecord()->getValueAsCode("PredicateCode"); +} + + +/// isAlwaysTrue - Return true if this is a noop predicate. +bool TreePredicateFn::isAlwaysTrue() const { + return getPredCode().empty(); +} + +/// Return the name to use in the generated code to reference this, this is +/// "Predicate_foo" if from a pattern fragment "foo". +std::string TreePredicateFn::getFnName() const { + return "Predicate_" + PatFragRec->getRecord()->getName(); +} + +/// getCodeToRunOnSDNode - Return the code for the function body that +/// evaluates this predicate. The argument is expected to be in "Node", +/// not N. This handles casting and conversion to a concrete node type as +/// appropriate. +std::string TreePredicateFn::getCodeToRunOnSDNode() const { + std::string ClassName; + if (PatFragRec->getOnlyTree()->isLeaf()) + ClassName = "SDNode"; + else { + Record *Op = PatFragRec->getOnlyTree()->getOperator(); + ClassName = PatFragRec->getDAGPatterns().getSDNodeInfo(Op).getSDClassName(); + } + std::string Result; + if (ClassName == "SDNode") + Result = " SDNode *N = Node;\n"; + else + Result = " " + ClassName + "*N = cast<" + ClassName + ">(Node);\n"; + + return Result + getPredCode(); } //===----------------------------------------------------------------------===// @@ -1015,7 +1050,7 @@ void TreePatternNode::print(raw_ostream &OS) const { } for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i) - OS << "<>"; + OS << "<>"; if (TransformFn) OS << "<getName() << ">>"; if (!getName().empty()) @@ -1150,9 +1185,9 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { TreePatternNode *FragTree = Frag->getOnlyTree()->clone(); - std::string Code = Op->getValueAsCode("Predicate"); - if (!Code.empty()) - FragTree->addPredicateFn("Predicate_"+Op->getName()); + TreePredicateFn PredFn(Frag); + if (!PredFn.isAlwaysTrue()) + FragTree->addPredicateFn(PredFn); // Resolve formal arguments to their actual value. if (Frag->getNumArgs()) { @@ -2063,9 +2098,9 @@ void CodeGenDAGPatterns::ParsePatternFragments() { // If there is a code init for this fragment, keep track of the fact that // this fragment uses it. - std::string Code = Fragments[i]->getValueAsCode("Predicate"); - if (!Code.empty()) - P->getOnlyTree()->addPredicateFn("Predicate_"+Fragments[i]->getName()); + TreePredicateFn PredFn(P); + if (!PredFn.isAlwaysTrue()) + P->getOnlyTree()->addPredicateFn(PredFn); // If there is a node transformation corresponding to this, keep track of // it. diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index 946dceed66..2624495a8d 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -239,6 +239,45 @@ public: return MadeChange; } }; + +/// TreePredicateFn - This is an abstraction that represents the predicates on +/// a PatFrag node. This is a simple one-word wrapper around a pointer to +/// provide nice accessors. +class TreePredicateFn { + /// PatFragRec - This is the TreePattern for the PatFrag that we + /// originally came from. + TreePattern *PatFragRec; +public: + /// TreePredicateFn constructor. Here 'N' is a subclass of PatFrag. + TreePredicateFn(TreePattern *N) : PatFragRec(N) {} + + + TreePattern *getOrigPatFragRecord() const { return PatFragRec; } + + /// isAlwaysTrue - Return true if this is a noop predicate. + bool isAlwaysTrue() const; + + + bool operator==(const TreePredicateFn &RHS) const { + return PatFragRec == RHS.PatFragRec; + } + + bool operator!=(const TreePredicateFn &RHS) const { return !(*this == RHS); } + + /// Return the name to use in the generated code to reference this, this is + /// "Predicate_foo" if from a pattern fragment "foo". + std::string getFnName() const; + + /// getCodeToRunOnSDNode - Return the code for the function body that + /// evaluates this predicate. The argument is expected to be in "Node", + /// not N. This handles casting and conversion to a concrete node type as + /// appropriate. + std::string getCodeToRunOnSDNode() const; + +private: + std::string getPredCode() const; +}; + /// FIXME: TreePatternNode's can be shared in some cases (due to dag-shaped /// patterns), and as such should be ref counted. We currently just leak all @@ -263,7 +302,7 @@ class TreePatternNode { /// PredicateFns - The predicate functions to execute on this node to check /// for a match. If this list is empty, no predicate is involved. - std::vector PredicateFns; + std::vector PredicateFns; /// TransformFn - The transformation function to execute on this node before /// it can be substituted into the resulting instruction on a pattern match. @@ -323,14 +362,18 @@ public: return false; } - const std::vector &getPredicateFns() const {return PredicateFns;} + bool hasAnyPredicate() const { return !PredicateFns.empty(); } + + const std::vector &getPredicateFns() const { + return PredicateFns; + } void clearPredicateFns() { PredicateFns.clear(); } - void setPredicateFns(const std::vector &Fns) { + void setPredicateFns(const std::vector &Fns) { assert(PredicateFns.empty() && "Overwriting non-empty predicate list!"); PredicateFns = Fns; } - void addPredicateFn(const std::string &Fn) { - assert(!Fn.empty() && "Empty predicate string!"); + void addPredicateFn(const TreePredicateFn &Fn) { + assert(!Fn.isAlwaysTrue() && "Empty predicate string!"); if (std::find(PredicateFns.begin(), PredicateFns.end(), Fn) == PredicateFns.end()) PredicateFns.push_back(Fn); diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp index 2afa2b907b..b12e1015c3 100644 --- a/utils/TableGen/DAGISelMatcher.cpp +++ b/utils/TableGen/DAGISelMatcher.cpp @@ -83,6 +83,15 @@ ScopeMatcher::~ScopeMatcher() { } +CheckPredicateMatcher::CheckPredicateMatcher(const TreePredicateFn &pred) + : Matcher(CheckPredicate), Pred(pred.getOrigPatFragRecord()) {} + +TreePredicateFn CheckPredicateMatcher::getPredicate() const { + return TreePredicateFn(Pred); +} + + + // printImpl methods. void ScopeMatcher::printImpl(raw_ostream &OS, unsigned indent) const { @@ -129,7 +138,7 @@ printImpl(raw_ostream &OS, unsigned indent) const { } void CheckPredicateMatcher::printImpl(raw_ostream &OS, unsigned indent) const { - OS.indent(indent) << "CheckPredicate " << PredName << '\n'; + OS.indent(indent) << "CheckPredicate " << getPredicate().getFnName() << '\n'; } void CheckOpcodeMatcher::printImpl(raw_ostream &OS, unsigned indent) const { @@ -263,7 +272,7 @@ unsigned CheckPatternPredicateMatcher::getHashImpl() const { } unsigned CheckPredicateMatcher::getHashImpl() const { - return HashString(PredName); + return HashString(getPredicate().getFnName()); } unsigned CheckOpcodeMatcher::getHashImpl() const { @@ -301,7 +310,6 @@ bool CheckOpcodeMatcher::isEqualImpl(const Matcher *M) const { Opcode.getEnumName(); } - bool EmitNodeMatcherCommon::isEqualImpl(const Matcher *m) const { const EmitNodeMatcherCommon *M = cast(m); return M->OpcodeName == OpcodeName && M->VTs == VTs && diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h index 8ffe412aca..dcb8da7108 100644 --- a/utils/TableGen/DAGISelMatcher.h +++ b/utils/TableGen/DAGISelMatcher.h @@ -25,6 +25,8 @@ namespace llvm { class ComplexPattern; class Record; class SDNodeInfo; + class TreePredicateFn; + class TreePattern; Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant, const CodeGenDAGPatterns &CGP); @@ -419,12 +421,11 @@ private: /// CheckPredicateMatcher - This checks the target-specific predicate to /// see if the node is acceptable. class CheckPredicateMatcher : public Matcher { - StringRef PredName; + TreePattern *Pred; public: - CheckPredicateMatcher(StringRef predname) - : Matcher(CheckPredicate), PredName(predname) {} + CheckPredicateMatcher(const TreePredicateFn &pred); - StringRef getPredicateName() const { return PredName; } + TreePredicateFn getPredicate() const; static inline bool classof(const Matcher *N) { return N->getKind() == CheckPredicate; @@ -436,7 +437,7 @@ public: private: virtual void printImpl(raw_ostream &OS, unsigned indent) const; virtual bool isEqualImpl(const Matcher *M) const { - return cast(M)->PredName == PredName; + return cast(M)->Pred == Pred; } virtual unsigned getHashImpl() const; }; diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index 0b69af4870..acb0135422 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -33,8 +33,12 @@ OmitComments("omit-comments", cl::desc("Do not generate comments"), namespace { class MatcherTableEmitter { const CodeGenDAGPatterns &CGP; - StringMap NodePredicateMap, PatternPredicateMap; - std::vector NodePredicates, PatternPredicates; + + DenseMap NodePredicateMap; + std::vector NodePredicates; + + StringMap PatternPredicateMap; + std::vector PatternPredicates; DenseMap ComplexPatternMap; std::vector ComplexPatterns; @@ -57,14 +61,15 @@ private: unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, formatted_raw_ostream &OS); - unsigned getNodePredicate(StringRef PredName) { - unsigned &Entry = NodePredicateMap[PredName]; + unsigned getNodePredicate(TreePredicateFn Pred) { + unsigned &Entry = NodePredicateMap[Pred.getOrigPatFragRecord()]; if (Entry == 0) { - NodePredicates.push_back(PredName.str()); + NodePredicates.push_back(Pred); Entry = NodePredicates.size(); } return Entry-1; } + unsigned getPatternPredicate(StringRef PredName) { unsigned &Entry = PatternPredicateMap[PredName]; if (Entry == 0) { @@ -73,7 +78,6 @@ private: } return Entry-1; } - unsigned getComplexPat(const ComplexPattern &P) { unsigned &Entry = ComplexPatternMap[&P]; if (Entry == 0) { @@ -239,7 +243,7 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, return 2; case Matcher::CheckPatternPredicate: { - StringRef Pred = cast(N)->getPredicate(); + StringRef Pred =cast(N)->getPredicate(); OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ','; if (!OmitComments) OS.PadToColumn(CommentIndent) << "// " << Pred; @@ -247,10 +251,10 @@ EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, return 2; } case Matcher::CheckPredicate: { - StringRef Pred = cast(N)->getPredicateName(); + TreePredicateFn Pred = cast(N)->getPredicate(); OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ','; if (!OmitComments) - OS.PadToColumn(CommentIndent) << "// " << Pred; + OS.PadToColumn(CommentIndent) << "// " << Pred.getFnName(); OS << '\n'; return 2; } @@ -617,25 +621,13 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) { OS << " switch (PredNo) {\n"; OS << " default: assert(0 && \"Invalid predicate in table?\");\n"; for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) { - // FIXME: Storing this by name is horrible. - TreePattern *P =PFsByName[NodePredicates[i].substr(strlen("Predicate_"))]; - assert(P && "Unknown name?"); - // Emit the predicate code corresponding to this pattern. - std::string Code = P->getRecord()->getValueAsCode("Predicate"); - assert(!Code.empty() && "No code in this predicate"); - OS << " case " << i << ": { // " << NodePredicates[i] << '\n'; - std::string ClassName; - if (P->getOnlyTree()->isLeaf()) - ClassName = "SDNode"; - else - ClassName = - CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName(); - if (ClassName == "SDNode") - OS << " SDNode *N = Node;\n"; - else - OS << " " << ClassName << "*N = cast<" << ClassName << ">(Node);\n"; - OS << Code << "\n }\n"; + TreePredicateFn PredFn = NodePredicates[i]; + + assert(!PredFn.isAlwaysTrue() && "No code in this predicate"); + OS << " case " << i << ": { // " << NodePredicates[i].getFnName() <<'\n'; + + OS << PredFn.getCodeToRunOnSDNode() << "\n }\n"; } OS << " }\n"; OS << "}\n\n"; -- cgit v1.2.3