aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-02-16 07:21:10 +0000
committerChris Lattner <sabre@nondot.org>2010-02-16 07:21:10 +0000
commit050a03d0f31ee7033d0459dae3c95b8bf12bff89 (patch)
tree157bc005608d2abfe42e321430e647e7895302fa
parente02ea54cfd71dee378ca6b11243710d1760ea7c1 (diff)
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
-rw-r--r--include/llvm/CodeGen/DAGISelHeader.h28
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h19
-rw-r--r--utils/TableGen/DAGISelMatcher.h3
-rw-r--r--utils/TableGen/DAGISelMatcherEmitter.cpp69
4 files changed, 93 insertions, 26 deletions
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h
index 831475d9a5..7fda6f76e1 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 ae78c5577b..0be91b414d 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 8699d516ed..b40fbf9cd0 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 3d2791d22e..c0ad16934e 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<unsigned> NodePredicateMap, PatternPredicateMap;
+ std::vector<std::string> 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<CheckSameMatcherNode>(N)->getMatchNumber() << ",\n";
return 2;
- case MatcherNode::CheckPatternPredicate:
- OS << "OPC_CheckPatternPredicate, /*XXX*/0,";
- OS.PadToColumn(CommentIndent) << "// "
- << cast<CheckPatternPredicateMatcherNode>(N)->getPredicate() << '\n';
+ case MatcherNode::CheckPatternPredicate: {
+ StringRef Pred = cast<CheckPatternPredicateMatcherNode>(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<CheckPredicateMatcherNode>(N)->getPredicateName() << '\n';
+ }
+ case MatcherNode::CheckPredicate: {
+ StringRef Pred = cast<CheckPredicateMatcherNode>(N)->getPredicateName();
+ OS << "OPC_CheckPredicate, " << getNodePredicate(Pred) << ',';
+ OS.PadToColumn(CommentIndent) << "// " << Pred << '\n';
return 2;
-
+ }
+
case MatcherNode::CheckOpcode:
OS << "OPC_CheckOpcode, "
<< cast<CheckOpcodeMatcherNode>(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();
}