From 050a03d0f31ee7033d0459dae3c95b8bf12bff89 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 Feb 2010 07:21:10 +0000 Subject: [PATCH] generate code for node and pattern predicates. Note that this won't build if enabled, it will fail with constness issues. I'll resolve these next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96336 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/DAGISelHeader.h | 28 +++++----- include/llvm/CodeGen/SelectionDAGISel.h | 19 +++++++ utils/TableGen/DAGISelMatcher.h | 3 +- utils/TableGen/DAGISelMatcherEmitter.cpp | 69 ++++++++++++++++++++---- 4 files changed, 93 insertions(+), 26 deletions(-) diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index 831475d9a5a..7fda6f76e1c 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -164,23 +164,29 @@ bool CheckOrImmediate(SDValue V, int64_t Val) { return true; } -static int8_t GetInt1(const unsigned char *MatcherTable, unsigned &Idx) { +// These functions are marked always inline so that Idx doesn't get pinned to +// the stack. +ALWAYS_INLINE static int8_t +GetInt1(const unsigned char *MatcherTable, unsigned &Idx) { return MatcherTable[Idx++]; } -static int16_t GetInt2(const unsigned char *MatcherTable, unsigned &Idx) { +ALWAYS_INLINE static int16_t +GetInt2(const unsigned char *MatcherTable, unsigned &Idx) { int16_t Val = GetInt1(MatcherTable, Idx); Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8; return Val; } -static int32_t GetInt4(const unsigned char *MatcherTable, unsigned &Idx) { +ALWAYS_INLINE static int32_t +GetInt4(const unsigned char *MatcherTable, unsigned &Idx) { int32_t Val = GetInt2(MatcherTable, Idx); Val |= int32_t(GetInt2(MatcherTable, Idx)) << 16; return Val; } -static int64_t GetInt8(const unsigned char *MatcherTable, unsigned &Idx) { +ALWAYS_INLINE static int64_t +GetInt8(const unsigned char *MatcherTable, unsigned &Idx) { int64_t Val = GetInt4(MatcherTable, Idx); Val |= int64_t(GetInt4(MatcherTable, Idx)) << 32; return Val; @@ -308,18 +314,12 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, if (N != RecordedNodes[RecNo]) break; continue; } - case OPC_CheckPatternPredicate: { - unsigned PredNo = MatcherTable[MatcherIndex++]; - (void)PredNo; - // FIXME: CHECK IT. + case OPC_CheckPatternPredicate: + if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break; continue; - } - case OPC_CheckPredicate: { - unsigned PredNo = MatcherTable[MatcherIndex++]; - (void)PredNo; - // FIXME: CHECK IT. + case OPC_CheckPredicate: + if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break; continue; - } case OPC_CheckComplexPat: { unsigned PatNo = MatcherTable[MatcherIndex++]; (void)PatNo; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index ae78c5577b6..0be91b414d0 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -112,6 +112,25 @@ protected: bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const; + + /// CheckPatternPredicate - This function is generated by tblgen in the + /// target. It runs the specified pattern predicate and returns true if it + /// succeeds or false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckPatternPredicate(unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + + /// CheckNodePredicate - This function is generated by tblgen in the + /// target. It runs node predicate #PredNo and returns true if it succeeds or + /// false if it fails. The number is a private implementation + /// detail to the code tblgen produces. + virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const { + assert(0 && "Tblgen should generate the implementation of this!"); + return 0; + } + // Calls to these functions are generated by tblgen. SDNode *Select_INLINEASM(SDNode *N); SDNode *Select_UNDEF(SDNode *N); diff --git a/utils/TableGen/DAGISelMatcher.h b/utils/TableGen/DAGISelMatcher.h index 8699d516ed8..b40fbf9cd0e 100644 --- a/utils/TableGen/DAGISelMatcher.h +++ b/utils/TableGen/DAGISelMatcher.h @@ -10,9 +10,10 @@ #ifndef TBLGEN_DAGISELMATCHER_H #define TBLGEN_DAGISELMATCHER_H +#include "llvm/CodeGen/ValueTypes.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" -#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/Support/Casting.h" namespace llvm { class CodeGenDAGPatterns; diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index 3d2791d22e5..c0ad16934e7 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -14,7 +14,7 @@ #include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/Casting.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/FormattedStream.h" using namespace llvm; @@ -66,12 +66,35 @@ static unsigned EmitInt(int64_t Val, formatted_raw_ostream &OS) { namespace { class MatcherTableEmitter { formatted_raw_ostream &OS; + + StringMap NodePredicateMap, PatternPredicateMap; + std::vector NodePredicates, PatternPredicates; + public: MatcherTableEmitter(formatted_raw_ostream &os) : OS(os) {} unsigned EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent); + + void EmitPredicateFunctions(); private: unsigned EmitMatcher(const MatcherNode *N, unsigned Indent); + + unsigned getNodePredicate(StringRef PredName) { + unsigned &Entry = NodePredicateMap[PredName]; + if (Entry == 0) { + NodePredicates.push_back(PredName.str()); + Entry = NodePredicates.size(); + } + return Entry-1; + } + unsigned getPatternPredicate(StringRef PredName) { + unsigned &Entry = PatternPredicateMap[PredName]; + if (Entry == 0) { + PatternPredicates.push_back(PredName.str()); + Entry = PatternPredicates.size(); + } + return Entry-1; + } }; } // end anonymous namespace. @@ -107,18 +130,19 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) { << cast(N)->getMatchNumber() << ",\n"; return 2; - case MatcherNode::CheckPatternPredicate: - OS << "OPC_CheckPatternPredicate, /*XXX*/0,"; - OS.PadToColumn(CommentIndent) << "// " - << cast(N)->getPredicate() << '\n'; + case MatcherNode::CheckPatternPredicate: { + StringRef Pred = cast(N)->getPredicate(); + OS << "OPC_CheckPatternPredicate, " << getPatternPredicate(Pred) << ','; + OS.PadToColumn(CommentIndent) << "// " << Pred << '\n'; return 2; - - case MatcherNode::CheckPredicate: - OS << "OPC_CheckPredicate, /*XXX*/0,"; - OS.PadToColumn(CommentIndent) << "// " - << cast(N)->getPredicateName() << '\n'; + } + case MatcherNode::CheckPredicate: { + StringRef Pred = cast(N)->getPredicateName(); + OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ','; + OS.PadToColumn(CommentIndent) << "// " << Pred << '\n'; return 2; - + } + case MatcherNode::CheckOpcode: OS << "OPC_CheckOpcode, " << cast(N)->getOpcodeName() << ",\n"; @@ -216,6 +240,25 @@ EmitMatcherAndChildren(const MatcherNode *N, unsigned Indent) { } } +void MatcherTableEmitter::EmitPredicateFunctions() { + OS << "bool CheckPatternPredicate(unsigned PredNo) const {\n"; + OS << " switch (PredNo) {\n"; + OS << " default: assert(0 && \"Invalid predicate in table?\");\n"; + for (unsigned i = 0, e = PatternPredicates.size(); i != e; ++i) + OS << " case " << i << ": return " << PatternPredicates[i] << ";\n"; + OS << " }\n"; + OS << "}\n\n"; + + OS << "bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {\n"; + OS << " switch (PredNo) {\n"; + OS << " default: assert(0 && \"Invalid predicate in table?\");\n"; + for (unsigned i = 0, e = NodePredicates.size(); i != e; ++i) + OS << " case " << i << ": return " << NodePredicates[i] << "(N);\n"; + OS << " }\n"; + OS << "}\n\n"; +} + + void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) { formatted_raw_ostream OS(O); @@ -228,4 +271,8 @@ void llvm::EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &O) { unsigned TotalSize = MatcherEmitter.EmitMatcherAndChildren(Matcher, 2); OS << " 0\n }; // Total Array size is " << (TotalSize+1) << " bytes\n\n"; OS << " return SelectCodeCommon(N, MatcherTable,sizeof(MatcherTable));\n}\n"; + OS << "\n"; + + // Next up, emit the function for node and pattern predicates: + MatcherEmitter.EmitPredicateFunctions(); }