Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / utils / TableGen / GlobalISelMatchTableExecutorEmitter.h
blob13193ff8cc9fefd8a4d6e902dd4c277e2b7d9fb3
1 //===- GlobalISelMatchTableExecutorEmitter.h ------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// This file contains common code related to emitting
11 /// GIMatchTableExecutor-derived classes.
12 ///
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLEEXECUTOREMITTER_H
16 #define LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLEEXECUTOREMITTER_H
18 #include "SubtargetFeatureInfo.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 #include <functional>
23 #include <vector>
25 namespace llvm {
26 class CodeGenTarget;
28 namespace gi {
29 class RuleMatcher;
30 class LLTCodeGen;
31 class MatchTable;
32 } // namespace gi
34 /// Abstract base class for TableGen backends that emit a
35 /// `GIMatchTableExecutor`-derived class.
36 class GlobalISelMatchTableExecutorEmitter {
37 /// Emits logic to check features required by \p Rules using the
39 /// SubtargetFeatures map.
40 void emitSubtargetFeatureBitsetImpl(raw_ostream &OS,
41 ArrayRef<gi::RuleMatcher> Rules);
43 /// Emits an enum + an array that stores references to
44 /// \p ComplexOperandMatchers.
45 void emitComplexPredicates(raw_ostream &OS,
46 ArrayRef<Record *> ComplexOperandMatchers);
48 /// Emits an enum + an array that stores references to
49 /// \p CustomOperandRenderers.
50 void emitCustomOperandRenderers(raw_ostream &OS,
51 ArrayRef<StringRef> CustomOperandRenderers);
53 /// Emits an enum + an array to reference \p TypeObjects (LLTs) in the match
54 /// table.
55 void emitTypeObjects(raw_ostream &OS, ArrayRef<gi::LLTCodeGen> TypeObjects);
57 /// Emits the getMatchTable function which contains all of the match table's
58 /// opcodes.
59 void emitMatchTable(raw_ostream &OS, const gi::MatchTable &Table);
61 /// Helper function to emit `test` functions for the executor. This emits both
62 /// an enum to reference predicates in the MatchTable, and a function to
63 /// switch over the enum & execute the predicate's C++ code.
64 ///
65 /// \tparam PredicateObject An object representing a predicate to emit.
66 /// \param OS Output stream
67 /// \param TypeIdentifier Identifier used for the type of the predicate,
68 /// e.g. `MI` for MachineInstrs.
69 /// \param ArgType Full type of the argument, e.g. `const MachineInstr &`
70 /// \param ArgName Name of the argument, e.g. `MI` for MachineInstrs.
71 /// \param AdditionalArgs Optional additional argument declarations.
72 /// \param AdditionalDeclarations Optional declarations to write at the start
73 /// of the function, before switching over the predicates enum.
74 /// \param Predicates Predicates to emit.
75 /// \param GetPredEnumName Returns an enum name for a given predicate.
76 /// \param GetPredCode Returns the C++ code of a given predicate.
77 /// \param Comment Optional comment for the enum declaration.
78 template <typename PredicateObject>
79 void emitCxxPredicateFns(
80 raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,
81 StringRef ArgName, StringRef AdditionalArgs,
82 StringRef AdditionalDeclarations, ArrayRef<PredicateObject> Predicates,
83 std::function<StringRef(PredicateObject)> GetPredEnumName,
84 std::function<StringRef(PredicateObject)> GetPredCode,
85 StringRef Comment) {
86 if (!Comment.empty())
87 OS << "// " << Comment << "\n";
88 if (!Predicates.empty()) {
89 OS << "enum {\n";
90 StringRef EnumeratorSeparator = " = GICXXPred_Invalid + 1,\n";
91 for (const auto &Pred : Predicates) {
92 OS << " GICXXPred_" << TypeIdentifier << "_Predicate_"
93 << GetPredEnumName(Pred) << EnumeratorSeparator;
94 EnumeratorSeparator = ",\n";
96 OS << "};\n";
99 OS << "bool " << getClassName() << "::test" << ArgName << "Predicate_"
100 << TypeIdentifier << "(unsigned PredicateID, " << ArgType << " "
101 << ArgName << AdditionalArgs << ") const {\n"
102 << AdditionalDeclarations;
103 if (!AdditionalDeclarations.empty())
104 OS << "\n";
105 if (!Predicates.empty()) {
106 OS << " switch (PredicateID) {\n";
107 for (const auto &Pred : Predicates) {
108 // Ensure all code is indented.
109 const auto Code = join(split(GetPredCode(Pred).str(), "\n"), "\n ");
110 OS << " case GICXXPred_" << TypeIdentifier << "_Predicate_"
111 << GetPredEnumName(Pred) << ": {\n"
112 << " " << Code << "\n";
113 if (!StringRef(Code).ltrim().startswith("return")) {
114 OS << " llvm_unreachable(\"" << GetPredEnumName(Pred)
115 << " should have returned\");\n";
117 OS << " }\n";
119 OS << " }\n";
121 OS << " llvm_unreachable(\"Unknown predicate\");\n"
122 << " return false;\n"
123 << "}\n";
126 protected:
127 /// Emits `testMIPredicate_MI`.
128 /// \tparam PredicateObject An object representing a predicate to emit.
129 /// \param OS Output stream
130 /// \param AdditionalDecls Additional C++ variable declarations.
131 /// \param Predicates Predicates to emit.
132 /// \param GetPredEnumName Returns an enum name for a given predicate.
133 /// \param GetPredCode Returns the C++ code of a given predicate.
134 /// \param Comment Optional comment for the enum declaration.
135 template <typename PredicateObject>
136 void emitMIPredicateFnsImpl(
137 raw_ostream &OS, StringRef AdditionalDecls,
138 ArrayRef<PredicateObject> Predicates,
139 std::function<StringRef(PredicateObject)> GetPredEnumName,
140 std::function<StringRef(PredicateObject)> GetPredCode,
141 StringRef Comment = "") {
142 return emitCxxPredicateFns(
143 OS, "MI", "const MachineInstr &", "MI", ", const MatcherState &State",
144 AdditionalDecls, Predicates, GetPredEnumName, GetPredCode, Comment);
147 /// Helper function to emit the following executor functions:
148 /// * testImmPredicate_I64 (TypeIdentifier=I64)
149 /// * testImmPredicate_APInt (TypeIdentifier=APInt)
150 /// * testImmPredicate_APFloat (TypeIdentifier=APFloat)
152 /// \tparam PredicateObject An object representing a predicate to emit.
153 /// \param OS Output stream
154 /// \param TypeIdentifier Identifier used for the type of the predicate
155 /// \param ArgType Full type of the argument
156 /// \param Predicates Predicates to emit.
157 /// \param GetPredEnumName Returns an enum name for a given predicate.
158 /// \param GetPredCode Returns the C++ code of a given predicate.
159 /// \param Comment Optional comment for the enum declaration.
160 template <typename PredicateObject>
161 void emitImmPredicateFnsImpl(
162 raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,
163 ArrayRef<PredicateObject> Predicates,
164 std::function<StringRef(PredicateObject)> GetPredEnumName,
165 std::function<StringRef(PredicateObject)> GetPredCode,
166 StringRef Comment = "") {
167 return emitCxxPredicateFns(OS, TypeIdentifier, ArgType, "Imm", "", "",
168 Predicates, GetPredEnumName, GetPredCode,
169 Comment);
172 GlobalISelMatchTableExecutorEmitter() = default;
174 public:
175 virtual ~GlobalISelMatchTableExecutorEmitter() = default;
177 virtual const CodeGenTarget &getTarget() const = 0;
179 /// \returns the name of the class being emitted including any prefixes, e.g.
180 /// `AMDGPUInstructionSelector`.
181 virtual StringRef getClassName() const = 0;
183 /// Emit additional content in emitExecutorImpl
184 virtual void emitAdditionalImpl(raw_ostream &OS) {}
186 /// Emit additional content in emitTemporariesDecl.
187 virtual void emitAdditionalTemporariesDecl(raw_ostream &OS,
188 StringRef Indent) {}
190 /// Emit additional content in emitTemporariesInit.
191 virtual void emitAdditionalTemporariesInit(raw_ostream &OS) {}
193 /// Emit the `testMIPredicate_MI` function.
194 /// Note: `emitMIPredicateFnsImpl` can be used to do most of the work.
195 virtual void emitMIPredicateFns(raw_ostream &OS) = 0;
197 /// Emit the `testImmPredicate_I64` function.
198 /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.
199 virtual void emitI64ImmPredicateFns(raw_ostream &OS) = 0;
201 /// Emit the `testImmPredicate_APFloat` function.
202 /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.
203 virtual void emitAPFloatImmPredicateFns(raw_ostream &OS) = 0;
205 /// Emit the `testImmPredicate_APInt` function.
206 /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.
207 virtual void emitAPIntImmPredicateFns(raw_ostream &OS) = 0;
208 virtual void emitTestSimplePredicate(raw_ostream &OS) = 0;
209 virtual void emitRunCustomAction(raw_ostream &OS) = 0;
211 void emitExecutorImpl(raw_ostream &OS, const gi::MatchTable &Table,
212 ArrayRef<gi::LLTCodeGen> TypeObjects,
213 ArrayRef<gi::RuleMatcher> Rules,
214 ArrayRef<Record *> ComplexOperandMatchers,
215 ArrayRef<StringRef> CustomOperandRenderers,
216 StringRef IfDefName);
217 void emitPredicateBitset(raw_ostream &OS, StringRef IfDefName);
218 void emitTemporariesDecl(raw_ostream &OS, StringRef IfDefName);
219 void emitTemporariesInit(raw_ostream &OS, unsigned MaxTemporaries,
220 StringRef IfDefName);
221 void emitPredicatesDecl(raw_ostream &OS, StringRef IfDefName);
222 void emitPredicatesInit(raw_ostream &OS, StringRef IfDefName);
224 // Map of predicates to their subtarget features.
225 SubtargetFeatureInfoMap SubtargetFeatures;
227 std::map<std::string, unsigned> HwModes;
229 } // namespace llvm
231 #endif