summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/test/TableGen/searchabletables-intrinsic.td85
-rw-r--r--llvm/utils/TableGen/SearchableTableEmitter.cpp41
2 files changed, 122 insertions, 4 deletions
diff --git a/llvm/test/TableGen/searchabletables-intrinsic.td b/llvm/test/TableGen/searchabletables-intrinsic.td
new file mode 100644
index 00000000000..ca0a5787298
--- /dev/null
+++ b/llvm/test/TableGen/searchabletables-intrinsic.td
@@ -0,0 +1,85 @@
+// RUN: llvm-tblgen -gen-searchable-tables -I %p/../../include %s | FileCheck %s
+// XFAIL: vg_leak
+
+include "llvm/TableGen/SearchableTable.td"
+
+class IntrinsicProperty;
+class SDNodeProperty;
+
+class ValueType<int size, int value> {
+ string Namespace = "MVT";
+ int Size = size;
+ int Value = value;
+}
+
+class LLVMType<ValueType vt> {
+ ValueType VT = vt;
+}
+
+class Intrinsic<list<LLVMType> param_types = []> {
+ string LLVMName = "";
+ bit isTarget = 0;
+ string TargetPrefix = "";
+ list<LLVMType> RetTypes = [];
+ list<LLVMType> ParamTypes = param_types;
+ list<IntrinsicProperty> IntrProperties = [];
+ list<SDNodeProperty> Properties = [];
+}
+
+def iAny : ValueType<0, 253>;
+def llvm_anyint_ty : LLVMType<iAny>;
+
+def int_abc : Intrinsic<[llvm_anyint_ty]>;
+def int_xyz : Intrinsic<[llvm_anyint_ty]>;
+
+let isTarget = 1, TargetPrefix = "gtarget" in {
+ def int_gtarget_def : Intrinsic<[llvm_anyint_ty]>;
+ def int_gtarget_defg : Intrinsic<[llvm_anyint_ty]>;
+ def int_gtarget_uvw : Intrinsic<[llvm_anyint_ty]>;
+}
+
+let isTarget = 1, TargetPrefix = "ftarget" in {
+ def int_ftarget_ghi : Intrinsic<[llvm_anyint_ty]>;
+ def int_ftarget_ghi_x : Intrinsic<[llvm_anyint_ty]>;
+ def int_ftarget_rst : Intrinsic<[llvm_anyint_ty]>;
+}
+
+class Table<Intrinsic intr, int payload> : SearchableTable {
+ let SearchableFields = ["Intr"];
+ let EnumNameField = ?;
+
+ Intrinsic Intr = !cast<Intrinsic>(intr);
+ bits<16> Payload = payload;
+}
+
+// CHECK-LABEL: TablesList[] = {
+// CHECK-DAG: { Intrinsic::abc, 0x0},
+// CHECK-DAG: { Intrinsic::xyz, 0x1},
+// CHECK-DAG: { Intrinsic::gtarget_def, 0x10},
+// CHECK-DAG: { Intrinsic::gtarget_defg, 0x11},
+// CHECK-DAG: { Intrinsic::gtarget_uvw, 0x12},
+// CHECK-DAG: { Intrinsic::ftarget_ghi, 0x20},
+// CHECK-DAG: { Intrinsic::ftarget_ghi_x, 0x21},
+// CHECK-DAG: { Intrinsic::ftarget_rst, 0x22},
+
+// Check that the index is in the correct order, consistent with the ordering
+// of enums: alphabetically, but target intrinsics after generic intrinsics
+//
+// CHECK-LABEL: TablesByIntr[] = {
+// CHECK-NEXT: Intrinsic::abc
+// CHECK-NEXT: Intrinsic::xyz
+// CHECK-NEXT: Intrinsic::ftarget_ghi
+// CHECK-NEXT: Intrinsic::ftarget_ghi_x
+// CHECK-NEXT: Intrinsic::ftarget_rst
+// CHECK-NEXT: Intrinsic::gtarget_def
+// CHECK-NEXT: Intrinsic::gtarget_defg
+// CHECK-NEXT: Intrinsic::gtarget_uvw
+
+def : Table<int_abc, 0x0>;
+def : Table<int_xyz, 0x1>;
+def : Table<int_gtarget_def, 0x10>;
+def : Table<int_gtarget_defg, 0x11>;
+def : Table<int_gtarget_uvw, 0x12>;
+def : Table<int_ftarget_ghi, 0x20>;
+def : Table<int_ftarget_ghi_x, 0x21>;
+def : Table<int_ftarget_rst, 0x22>;
diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index 63252e8c039..4c127a0c6f9 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -13,12 +13,14 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
+#include "CodeGenIntrinsics.h"
#include <algorithm>
#include <string>
#include <vector>
@@ -30,6 +32,7 @@ namespace {
class SearchableTableEmitter {
RecordKeeper &Records;
+ DenseMap<Init *, std::unique_ptr<CodeGenIntrinsic>> Intrinsics;
public:
SearchableTableEmitter(RecordKeeper &R) : Records(R) {}
@@ -53,8 +56,11 @@ private:
return "0x" + utohexstr(getAsInt(BI));
else if (BitInit *BI = dyn_cast<BitInit>(I))
return BI->getValue() ? "true" : "false";
- else if (CodeInit *CI = dyn_cast<CodeInit>(I)) {
+ else if (CodeInit *CI = dyn_cast<CodeInit>(I))
return CI->getValue();
+ else if (DefInit *DI = dyn_cast<DefInit>(I)) {
+ if (DI->getDef()->isSubClassOf("Intrinsic"))
+ return "Intrinsic::" + getIntrinsic(I).EnumName;
}
PrintFatalError(SMLoc(),
"invalid field type, expected: string, bits, bit or code");
@@ -67,6 +73,23 @@ private:
return StringRef(PrimaryRep).upper();
}
+ bool isIntrinsic(Init *I) {
+ if (DefInit *DI = dyn_cast<DefInit>(I))
+ return DI->getDef()->isSubClassOf("Intrinsic");
+ return false;
+ }
+
+ CodeGenIntrinsic &getIntrinsic(Init *I) {
+ std::unique_ptr<CodeGenIntrinsic> &Intr = Intrinsics[I];
+ if (!Intr)
+ Intr = make_unique<CodeGenIntrinsic>(cast<DefInit>(I)->getDef());
+ return *Intr;
+ }
+
+ bool isIntegral(Init *I) {
+ return isa<BitsInit>(I) || isIntrinsic(I);
+ }
+
std::string searchableFieldType(Init *I) {
if (isa<StringInit>(I))
return "const char *";
@@ -83,7 +106,8 @@ private:
else
PrintFatalError(SMLoc(), "bitfield too large to search");
return "uint" + utostr(NumBits) + "_t";
- }
+ } else if (isIntrinsic(I))
+ return "unsigned";
PrintFatalError(SMLoc(), "Unknown type to search by");
}
@@ -158,6 +182,15 @@ void SearchableTableEmitter::emitSearchTable(
return getAsInt(cast<BitsInit>(LHS.first)) <
getAsInt(cast<BitsInit>(RHS.first));
});
+ } else if (isIntrinsic(SearchTable[0].first)) {
+ std::stable_sort(SearchTable.begin(), SearchTable.end(),
+ [this](const SearchTableEntry &LHS,
+ const SearchTableEntry &RHS) {
+ CodeGenIntrinsic &LHSi = getIntrinsic(LHS.first);
+ CodeGenIntrinsic &RHSi = getIntrinsic(RHS.first);
+ return std::tie(LHSi.TargetPrefix, LHSi.Name) <
+ std::tie(RHSi.TargetPrefix, RHSi.Name);
+ });
} else {
std::stable_sort(SearchTable.begin(), SearchTable.end(),
[this](const SearchTableEntry &LHS,
@@ -176,7 +209,7 @@ void SearchableTableEmitter::emitSearchTable(
void SearchableTableEmitter::emitLookupFunction(StringRef Name, StringRef Field,
Init *I, raw_ostream &OS) {
- bool IsIntegral = isa<BitsInit>(I);
+ bool IsIntegral = isIntegral(I);
std::string FieldType = searchableFieldType(I);
std::string PairType = "std::pair<" + FieldType + ", int>";
@@ -219,7 +252,7 @@ void SearchableTableEmitter::emitLookupFunction(StringRef Name, StringRef Field,
void SearchableTableEmitter::emitLookupDeclaration(StringRef Name,
StringRef Field, Init *I,
raw_ostream &OS) {
- bool IsIntegral = isa<BitsInit>(I);
+ bool IsIntegral = isIntegral(I);
std::string FieldType = searchableFieldType(I);
OS << "const " << Name << " *"
<< "lookup" << Name << "By" << Field;
OpenPOWER on IntegriCloud