llvm.org GIT mirror llvm / 7bf0a7f
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328937 91177308-0d34-0410-b5e6-96231b3b80d8 Nicolai Haehnle 1 year, 6 months ago
2 changed file(s) with 122 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
0 // RUN: llvm-tblgen -gen-searchable-tables -I %p/../../include %s | FileCheck %s
1 // XFAIL: vg_leak
2
3 include "llvm/TableGen/SearchableTable.td"
4
5 class IntrinsicProperty;
6 class SDNodeProperty;
7
8 class ValueType {
9 string Namespace = "MVT";
10 int Size = size;
11 int Value = value;
12 }
13
14 class LLVMType {
15 ValueType VT = vt;
16 }
17
18 class Intrinsic param_types = []> {
19 string LLVMName = "";
20 bit isTarget = 0;
21 string TargetPrefix = "";
22 list RetTypes = [];
23 list ParamTypes = param_types;
24 list IntrProperties = [];
25 list Properties = [];
26 }
27
28 def iAny : ValueType<0, 253>;
29 def llvm_anyint_ty : LLVMType;
30
31 def int_abc : Intrinsic<[llvm_anyint_ty]>;
32 def int_xyz : Intrinsic<[llvm_anyint_ty]>;
33
34 let isTarget = 1, TargetPrefix = "gtarget" in {
35 def int_gtarget_def : Intrinsic<[llvm_anyint_ty]>;
36 def int_gtarget_defg : Intrinsic<[llvm_anyint_ty]>;
37 def int_gtarget_uvw : Intrinsic<[llvm_anyint_ty]>;
38 }
39
40 let isTarget = 1, TargetPrefix = "ftarget" in {
41 def int_ftarget_ghi : Intrinsic<[llvm_anyint_ty]>;
42 def int_ftarget_ghi_x : Intrinsic<[llvm_anyint_ty]>;
43 def int_ftarget_rst : Intrinsic<[llvm_anyint_ty]>;
44 }
45
46 class Table : SearchableTable {
47 let SearchableFields = ["Intr"];
48 let EnumNameField = ?;
49
50 Intrinsic Intr = !cast(intr);
51 bits<16> Payload = payload;
52 }
53
54 // CHECK-LABEL: TablesList[] = {
55 // CHECK-DAG: { Intrinsic::abc, 0x0},
56 // CHECK-DAG: { Intrinsic::xyz, 0x1},
57 // CHECK-DAG: { Intrinsic::gtarget_def, 0x10},
58 // CHECK-DAG: { Intrinsic::gtarget_defg, 0x11},
59 // CHECK-DAG: { Intrinsic::gtarget_uvw, 0x12},
60 // CHECK-DAG: { Intrinsic::ftarget_ghi, 0x20},
61 // CHECK-DAG: { Intrinsic::ftarget_ghi_x, 0x21},
62 // CHECK-DAG: { Intrinsic::ftarget_rst, 0x22},
63
64 // Check that the index is in the correct order, consistent with the ordering
65 // of enums: alphabetically, but target intrinsics after generic intrinsics
66 //
67 // CHECK-LABEL: TablesByIntr[] = {
68 // CHECK-NEXT: Intrinsic::abc
69 // CHECK-NEXT: Intrinsic::xyz
70 // CHECK-NEXT: Intrinsic::ftarget_ghi
71 // CHECK-NEXT: Intrinsic::ftarget_ghi_x
72 // CHECK-NEXT: Intrinsic::ftarget_rst
73 // CHECK-NEXT: Intrinsic::gtarget_def
74 // CHECK-NEXT: Intrinsic::gtarget_defg
75 // CHECK-NEXT: Intrinsic::gtarget_uvw
76
77 def : Table;
78 def : Table;
79 def : Table;
80 def : Table;
81 def : Table;
82 def : Table;
83 def : Table;
84 def : Table;
1212 //
1313 //===----------------------------------------------------------------------===//
1414
15 #include "llvm/ADT/DenseMap.h"
1516 #include "llvm/ADT/StringExtras.h"
1617 #include "llvm/Support/Format.h"
1718 #include "llvm/Support/MemoryBuffer.h"
1819 #include "llvm/Support/SourceMgr.h"
1920 #include "llvm/TableGen/Error.h"
2021 #include "llvm/TableGen/Record.h"
22 #include "CodeGenIntrinsics.h"
2123 #include
2224 #include
2325 #include
2931
3032 class SearchableTableEmitter {
3133 RecordKeeper &Records;
34 DenseMap> Intrinsics;
3235
3336 public:
3437 SearchableTableEmitter(RecordKeeper &R) : Records(R) {}
5255 return "0x" + utohexstr(getAsInt(BI));
5356 else if (BitInit *BI = dyn_cast(I))
5457 return BI->getValue() ? "true" : "false";
55 else if (CodeInit *CI = dyn_cast(I)) {
58 else if (CodeInit *CI = dyn_cast(I))
5659 return CI->getValue();
60 else if (DefInit *DI = dyn_cast(I)) {
61 if (DI->getDef()->isSubClassOf("Intrinsic"))
62 return "Intrinsic::" + getIntrinsic(I).EnumName;
5763 }
5864 PrintFatalError(SMLoc(),
5965 "invalid field type, expected: string, bits, bit or code");
6470 if (!isa(I))
6571 return PrimaryRep;
6672 return StringRef(PrimaryRep).upper();
73 }
74
75 bool isIntrinsic(Init *I) {
76 if (DefInit *DI = dyn_cast(I))
77 return DI->getDef()->isSubClassOf("Intrinsic");
78 return false;
79 }
80
81 CodeGenIntrinsic &getIntrinsic(Init *I) {
82 std::unique_ptr &Intr = Intrinsics[I];
83 if (!Intr)
84 Intr = make_unique(cast(I)->getDef());
85 return *Intr;
86 }
87
88 bool isIntegral(Init *I) {
89 return isa(I) || isIntrinsic(I);
6790 }
6891
6992 std::string searchableFieldType(Init *I) {
82105 else
83106 PrintFatalError(SMLoc(), "bitfield too large to search");
84107 return "uint" + utostr(NumBits) + "_t";
85 }
108 } else if (isIntrinsic(I))
109 return "unsigned";
86110 PrintFatalError(SMLoc(), "Unknown type to search by");
87111 }
88112
157181 return getAsInt(cast(LHS.first)) <
158182 getAsInt(cast(RHS.first));
159183 });
184 } else if (isIntrinsic(SearchTable[0].first)) {
185 std::stable_sort(SearchTable.begin(), SearchTable.end(),
186 [this](const SearchTableEntry &LHS,
187 const SearchTableEntry &RHS) {
188 CodeGenIntrinsic &LHSi = getIntrinsic(LHS.first);
189 CodeGenIntrinsic &RHSi = getIntrinsic(RHS.first);
190 return std::tie(LHSi.TargetPrefix, LHSi.Name) <
191 std::tie(RHSi.TargetPrefix, RHSi.Name);
192 });
160193 } else {
161194 std::stable_sort(SearchTable.begin(), SearchTable.end(),
162195 [this](const SearchTableEntry &LHS,
175208
176209 void SearchableTableEmitter::emitLookupFunction(StringRef Name, StringRef Field,
177210 Init *I, raw_ostream &OS) {
178 bool IsIntegral = isa(I);
211 bool IsIntegral = isIntegral(I);
179212 std::string FieldType = searchableFieldType(I);
180213 std::string PairType = "std::pair<" + FieldType + ", int>";
181214
218251 void SearchableTableEmitter::emitLookupDeclaration(StringRef Name,
219252 StringRef Field, Init *I,
220253 raw_ostream &OS) {
221 bool IsIntegral = isa(I);
254 bool IsIntegral = isIntegral(I);
222255 std::string FieldType = searchableFieldType(I);
223256 OS << "const " << Name << " *"
224257 << "lookup" << Name << "By" << Field;