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
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index c9be40d..ffb9c5e 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -490,6 +490,18 @@
def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
+//===----------------------------------------------------------------------===//
+// PatPred Subclasses.
+//
+// These allow specifying different sorts of predicates that control whether a
+// node is matched.
+//
+class PatPred;
+
+class CodePatPred<code predicate> : PatPred {
+ code PredicateCode = predicate;
+}
+
//===----------------------------------------------------------------------===//
// Selection DAG Pattern Fragments.
@@ -507,7 +519,7 @@
SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
dag Operands = ops;
dag Fragment = frag;
- code Predicate = pred;
+ code PredicateCode = pred;
SDNodeXForm OperandTransform = xform;
}
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 549b288..d181225 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -459,7 +459,7 @@
include "X86InstrFormats.td"
//===----------------------------------------------------------------------===//
-// Pattern fragments...
+// Pattern fragments.
//
// X86 specific condition code. These correspond to CondCode in
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 79cf18a..b74144e 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -580,34 +580,29 @@
/// 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<DefInit*>(N->getLeafValue()) != NULL) {
+ if (dynamic_cast<DefInit*>(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<std::string, int>
+ if (i->second > 1) // std::pair<std::string, int>
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() << "<empty set>");
} else {
@@ -621,6 +616,46 @@
}
#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 @@
}
for (unsigned i = 0, e = PredicateFns.size(); i != e; ++i)
- OS << "<<P:" << PredicateFns[i] << ">>";
+ OS << "<<P:" << PredicateFns[i].getFnName() << ">>";
if (TransformFn)
OS << "<<X:" << TransformFn->getName() << ">>";
if (!getName().empty())
@@ -1150,9 +1185,9 @@
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 @@
// 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 946dcee..2624495 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -239,6 +239,45 @@
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 @@
/// 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<std::string> PredicateFns;
+ std::vector<TreePredicateFn> 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 @@
return false;
}
- const std::vector<std::string> &getPredicateFns() const {return PredicateFns;}
+ bool hasAnyPredicate() const { return !PredicateFns.empty(); }
+
+ const std::vector<TreePredicateFn> &getPredicateFns() const {
+ return PredicateFns;
+ }
void clearPredicateFns() { PredicateFns.clear(); }
- void setPredicateFns(const std::vector<std::string> &Fns) {
+ void setPredicateFns(const std::vector<TreePredicateFn> &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 2afa2b9..b12e101 100644
--- a/utils/TableGen/DAGISelMatcher.cpp
+++ b/utils/TableGen/DAGISelMatcher.cpp
@@ -83,6 +83,15 @@
}
+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 @@
}
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 CheckPredicateMatcher::getHashImpl() const {
- return HashString(PredName);
+ return HashString(getPredicate().getFnName());
}
unsigned CheckOpcodeMatcher::getHashImpl() const {
@@ -301,7 +310,6 @@
Opcode.getEnumName();
}
-
bool EmitNodeMatcherCommon::isEqualImpl(const Matcher *m) const {
const EmitNodeMatcherCommon *M = cast<EmitNodeMatcherCommon>(m);
return M->OpcodeName == OpcodeName && M->VTs == VTs &&
diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h
index 8ffe412..dcb8da7 100644
--- a/utils/TableGen/DAGISelMatcher.h
+++ b/utils/TableGen/DAGISelMatcher.h
@@ -25,6 +25,8 @@
class ComplexPattern;
class Record;
class SDNodeInfo;
+ class TreePredicateFn;
+ class TreePattern;
Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
const CodeGenDAGPatterns &CGP);
@@ -419,12 +421,11 @@
/// 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 @@
private:
virtual void printImpl(raw_ostream &OS, unsigned indent) const;
virtual bool isEqualImpl(const Matcher *M) const {
- return cast<CheckPredicateMatcher>(M)->PredName == PredName;
+ return cast<CheckPredicateMatcher>(M)->Pred == Pred;
}
virtual unsigned getHashImpl() const;
};
diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp
index 0b69af4..acb0135 100644
--- a/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -33,8 +33,12 @@
namespace {
class MatcherTableEmitter {
const CodeGenDAGPatterns &CGP;
- StringMap<unsigned> NodePredicateMap, PatternPredicateMap;
- std::vector<std::string> NodePredicates, PatternPredicates;
+
+ DenseMap<TreePattern *, unsigned> NodePredicateMap;
+ std::vector<TreePredicateFn> NodePredicates;
+
+ StringMap<unsigned> PatternPredicateMap;
+ std::vector<std::string> PatternPredicates;
DenseMap<const ComplexPattern*, unsigned> ComplexPatternMap;
std::vector<const ComplexPattern*> ComplexPatterns;
@@ -57,14 +61,15 @@
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 @@
}
return Entry-1;
}
-
unsigned getComplexPat(const ComplexPattern &P) {
unsigned &Entry = ComplexPatternMap[&P];
if (Entry == 0) {
@@ -239,7 +243,7 @@
return 2;
case Matcher::CheckPatternPredicate: {
- StringRef Pred = cast<CheckPatternPredicateMatcher>(N)->getPredicate();
+ StringRef Pred =cast<CheckPatternPredicateMatcher>(N)->getPredicate();
OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ',';
if (!OmitComments)
OS.PadToColumn(CommentIndent) << "// " << Pred;
@@ -247,10 +251,10 @@
return 2;
}
case Matcher::CheckPredicate: {
- StringRef Pred = cast<CheckPredicateMatcher>(N)->getPredicateName();
+ TreePredicateFn Pred = cast<CheckPredicateMatcher>(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 @@
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";