1 //===- GlobalISelMatchTableExecutorEmitter.h ------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file contains common code related to emitting
11 /// GIMatchTableExecutor-derived classes.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLEEXECUTOREMITTER_H
16 #define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLEEXECUTOREMITTER_H
18 #include "Common/SubtargetFeatureInfo.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
33 /// Abstract base class for TableGen backends that emit a
34 /// `GIMatchTableExecutor`-derived class.
35 class GlobalISelMatchTableExecutorEmitter
{
36 /// Emits logic to check features required by \p Rules using the
38 /// SubtargetFeatures map.
39 void emitSubtargetFeatureBitsetImpl(raw_ostream
&OS
,
40 ArrayRef
<gi::RuleMatcher
> Rules
);
42 /// Emits an enum + an array that stores references to
43 /// \p ComplexOperandMatchers.
44 void emitComplexPredicates(raw_ostream
&OS
,
45 ArrayRef
<const Record
*> ComplexOperandMatchers
);
47 /// Emits an enum + an array that stores references to
48 /// \p CustomOperandRenderers.
49 void emitCustomOperandRenderers(raw_ostream
&OS
,
50 ArrayRef
<StringRef
> CustomOperandRenderers
);
52 /// Emits an enum + an array to reference \p TypeObjects (LLTs) in the match
54 void emitTypeObjects(raw_ostream
&OS
, ArrayRef
<gi::LLTCodeGen
> TypeObjects
);
56 /// Emits the getMatchTable function which contains all of the match table's
58 void emitMatchTable(raw_ostream
&OS
, const gi::MatchTable
&Table
);
60 /// Helper function to emit `test` functions for the executor. This emits both
61 /// an enum to reference predicates in the MatchTable, and a function to
62 /// switch over the enum & execute the predicate's C++ code.
64 /// \tparam PredicateObject An object representing a predicate to emit.
65 /// \param OS Output stream
66 /// \param TypeIdentifier Identifier used for the type of the predicate,
67 /// e.g. `MI` for MachineInstrs.
68 /// \param ArgType Full type of the argument, e.g. `const MachineInstr &`
69 /// \param ArgName Name of the argument, e.g. `MI` for MachineInstrs.
70 /// \param AdditionalArgs Optional additional argument declarations.
71 /// \param AdditionalDeclarations Optional declarations to write at the start
72 /// of the function, before switching over the predicates enum.
73 /// \param Predicates Predicates to emit.
74 /// \param GetPredEnumName Returns an enum name for a given predicate.
75 /// \param GetPredCode Returns the C++ code of a given predicate.
76 /// \param Comment Optional comment for the enum declaration.
77 template <typename PredicateObject
>
78 void emitCxxPredicateFns(
79 raw_ostream
&OS
, StringRef TypeIdentifier
, StringRef ArgType
,
80 StringRef ArgName
, StringRef AdditionalArgs
,
81 StringRef AdditionalDeclarations
, ArrayRef
<PredicateObject
> Predicates
,
82 std::function
<StringRef(PredicateObject
)> GetPredEnumName
,
83 std::function
<StringRef(PredicateObject
)> GetPredCode
,
86 OS
<< "// " << Comment
<< "\n";
87 if (!Predicates
.empty()) {
89 StringRef EnumeratorSeparator
= " = GICXXPred_Invalid + 1,\n";
90 for (const auto &Pred
: Predicates
) {
91 OS
<< " GICXXPred_" << TypeIdentifier
<< "_Predicate_"
92 << GetPredEnumName(Pred
) << EnumeratorSeparator
;
93 EnumeratorSeparator
= ",\n";
98 OS
<< "bool " << getClassName() << "::test" << ArgName
<< "Predicate_"
99 << TypeIdentifier
<< "(unsigned PredicateID, " << ArgType
<< " "
100 << ArgName
<< AdditionalArgs
<< ") const {\n"
101 << AdditionalDeclarations
;
102 if (!AdditionalDeclarations
.empty())
104 if (!Predicates
.empty()) {
105 OS
<< " switch (PredicateID) {\n";
106 for (const auto &Pred
: Predicates
) {
107 // Ensure all code is indented.
108 const auto Code
= join(split(GetPredCode(Pred
).str(), "\n"), "\n ");
109 OS
<< " case GICXXPred_" << TypeIdentifier
<< "_Predicate_"
110 << GetPredEnumName(Pred
) << ": {\n"
111 << " " << Code
<< "\n";
112 if (!StringRef(Code
).ltrim().starts_with("return")) {
113 OS
<< " llvm_unreachable(\"" << GetPredEnumName(Pred
)
114 << " should have returned\");\n";
120 OS
<< " llvm_unreachable(\"Unknown predicate\");\n"
121 << " return false;\n"
126 /// Emits `testMIPredicate_MI`.
127 /// \tparam PredicateObject An object representing a predicate to emit.
128 /// \param OS Output stream
129 /// \param AdditionalDecls Additional C++ variable declarations.
130 /// \param Predicates Predicates to emit.
131 /// \param GetPredEnumName Returns an enum name for a given predicate.
132 /// \param GetPredCode Returns the C++ code of a given predicate.
133 /// \param Comment Optional comment for the enum declaration.
134 template <typename PredicateObject
>
135 void emitMIPredicateFnsImpl(
136 raw_ostream
&OS
, StringRef AdditionalDecls
,
137 ArrayRef
<PredicateObject
> Predicates
,
138 std::function
<StringRef(PredicateObject
)> GetPredEnumName
,
139 std::function
<StringRef(PredicateObject
)> GetPredCode
,
140 StringRef Comment
= "") {
141 return emitCxxPredicateFns(
142 OS
, "MI", "const MachineInstr &", "MI", ", const MatcherState &State",
143 AdditionalDecls
, Predicates
, GetPredEnumName
, GetPredCode
, Comment
);
146 /// Helper function to emit the following executor functions:
147 /// * testImmPredicate_I64 (TypeIdentifier=I64)
148 /// * testImmPredicate_APInt (TypeIdentifier=APInt)
149 /// * testImmPredicate_APFloat (TypeIdentifier=APFloat)
151 /// \tparam PredicateObject An object representing a predicate to emit.
152 /// \param OS Output stream
153 /// \param TypeIdentifier Identifier used for the type of the predicate
154 /// \param ArgType Full type of the argument
155 /// \param Predicates Predicates to emit.
156 /// \param GetPredEnumName Returns an enum name for a given predicate.
157 /// \param GetPredCode Returns the C++ code of a given predicate.
158 /// \param Comment Optional comment for the enum declaration.
159 template <typename PredicateObject
>
160 void emitImmPredicateFnsImpl(
161 raw_ostream
&OS
, StringRef TypeIdentifier
, StringRef ArgType
,
162 ArrayRef
<PredicateObject
> Predicates
,
163 std::function
<StringRef(PredicateObject
)> GetPredEnumName
,
164 std::function
<StringRef(PredicateObject
)> GetPredCode
,
165 StringRef Comment
= "") {
166 return emitCxxPredicateFns(OS
, TypeIdentifier
, ArgType
, "Imm", "", "",
167 Predicates
, GetPredEnumName
, GetPredCode
,
171 GlobalISelMatchTableExecutorEmitter() = default;
174 virtual ~GlobalISelMatchTableExecutorEmitter() = default;
176 virtual const CodeGenTarget
&getTarget() const = 0;
178 /// \returns the name of the class being emitted including any prefixes, e.g.
179 /// `AMDGPUInstructionSelector`.
180 virtual StringRef
getClassName() const = 0;
182 /// Emit additional content in emitExecutorImpl
183 virtual void emitAdditionalImpl(raw_ostream
&OS
) {}
185 /// Emit additional content in emitTemporariesInit.
186 virtual void emitAdditionalTemporariesInit(raw_ostream
&OS
) {}
188 /// Emit the `testMIPredicate_MI` function.
189 /// Note: `emitMIPredicateFnsImpl` can be used to do most of the work.
190 virtual void emitMIPredicateFns(raw_ostream
&OS
) = 0;
192 /// Emit the `testImmPredicate_I64` function.
193 /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.
194 virtual void emitI64ImmPredicateFns(raw_ostream
&OS
) = 0;
196 /// Emit the `testImmPredicate_APFloat` function.
197 /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.
198 virtual void emitAPFloatImmPredicateFns(raw_ostream
&OS
) = 0;
200 /// Emit the `testImmPredicate_APInt` function.
201 /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.
202 virtual void emitAPIntImmPredicateFns(raw_ostream
&OS
) = 0;
203 virtual void emitTestSimplePredicate(raw_ostream
&OS
) = 0;
204 virtual void emitRunCustomAction(raw_ostream
&OS
) = 0;
206 void emitExecutorImpl(raw_ostream
&OS
, const gi::MatchTable
&Table
,
207 ArrayRef
<gi::LLTCodeGen
> TypeObjects
,
208 ArrayRef
<gi::RuleMatcher
> Rules
,
209 ArrayRef
<const Record
*> ComplexOperandMatchers
,
210 ArrayRef
<StringRef
> CustomOperandRenderers
,
211 StringRef IfDefName
);
212 void emitPredicateBitset(raw_ostream
&OS
, StringRef IfDefName
);
213 void emitTemporariesDecl(raw_ostream
&OS
, StringRef IfDefName
);
214 void emitTemporariesInit(raw_ostream
&OS
, unsigned MaxTemporaries
,
215 StringRef IfDefName
);
216 void emitPredicatesDecl(raw_ostream
&OS
, StringRef IfDefName
);
217 void emitPredicatesInit(raw_ostream
&OS
, StringRef IfDefName
);
219 // Map of predicates to their subtarget features.
220 SubtargetFeatureInfoMap SubtargetFeatures
;
222 std::map
<std::string
, unsigned> HwModes
;
226 #endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLEEXECUTOREMITTER_H