summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2018-04-01 17:08:58 +0000
committerNicolai Haehnle <nhaehnle@gmail.com>2018-04-01 17:08:58 +0000
commit398c0b6701209c2c7fc980463c21456db2114971 (patch)
tree418321060ee7634f82e8c715dd3dabc0e3695b9e
parent24e3a4d6e93cb589d854227a9674acb0ca0c4679 (diff)
downloadbcm5719-llvm-398c0b6701209c2c7fc980463c21456db2114971.tar.gz
bcm5719-llvm-398c0b6701209c2c7fc980463c21456db2114971.zip
TableGen: Support Intrinsic values in SearchableTable
Summary: We will use this in the AMDGPU backend in a subsequent patch in the stack to lookup target-specific per-intrinsic information. The generic CodeGenIntrinsic machinery is used to ensure that, even though we don't calculate actual enum values here, we do get the intrinsics in the right order for the binary search index. Change-Id: If61cd5587963a4c5a1cc53df1e59c5e4dec1f9dc Reviewers: arsenm, rampitec, b-sumner Subscribers: wdng, tpr, llvm-commits Differential Revision: https://reviews.llvm.org/D44935 llvm-svn: 328937
-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