blob: 1d21042e95a8d89bda8749c75faab1b99e81a41f [file] [log] [blame]
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001//===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// This tablegen backend emits code for use by the GlobalISel instruction
12/// selector. See include/llvm/CodeGen/TargetGlobalISel.td.
13///
14/// This file analyzes the patterns recognized by the SelectionDAGISel tablegen
15/// backend, filters out the ones that are unsupported, maps
16/// SelectionDAG-specific constructs to their GlobalISel counterpart
17/// (when applicable: MVT to LLT; SDNode to generic Instruction).
18///
19/// Not all patterns are supported: pass the tablegen invocation
20/// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,
21/// as well as why.
22///
23/// The generated file defines a single method:
24/// bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;
25/// intended to be used in InstructionSelector::select as the first-step
26/// selector for the patterns that don't require complex C++.
27///
28/// FIXME: We'll probably want to eventually define a base
29/// "TargetGenInstructionSelector" class.
30///
31//===----------------------------------------------------------------------===//
32
33#include "CodeGenDAGPatterns.h"
Daniel Sanderse7b0d662017-04-21 15:59:56 +000034#include "SubtargetFeatureInfo.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000035#include "llvm/ADT/Optional.h"
Daniel Sanders0ed28822017-04-12 08:23:08 +000036#include "llvm/ADT/SmallSet.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000037#include "llvm/ADT/Statistic.h"
38#include "llvm/CodeGen/MachineValueType.h"
39#include "llvm/Support/CommandLine.h"
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +000040#include "llvm/Support/Error.h"
Daniel Sanders52b4ce72017-03-07 23:20:35 +000041#include "llvm/Support/LowLevelTypeImpl.h"
Pavel Labath52a82e22017-02-21 09:19:41 +000042#include "llvm/Support/ScopedPrinter.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000043#include "llvm/TableGen/Error.h"
44#include "llvm/TableGen/Record.h"
45#include "llvm/TableGen/TableGenBackend.h"
46#include <string>
Daniel Sanders8a4bae92017-03-14 21:32:08 +000047#include <numeric>
Ahmed Bougacha36f70352016-12-21 23:26:20 +000048using namespace llvm;
49
50#define DEBUG_TYPE "gisel-emitter"
51
52STATISTIC(NumPatternTotal, "Total number of patterns");
Daniel Sandersb41ce2b2017-02-20 14:31:27 +000053STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
54STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
Ahmed Bougacha36f70352016-12-21 23:26:20 +000055STATISTIC(NumPatternEmitted, "Number of patterns emitted");
Daniel Sandersc60abe32017-07-04 15:31:50 +000056/// A unique identifier for a MatchTable.
57static unsigned CurrentMatchTableID = 0;
Ahmed Bougacha36f70352016-12-21 23:26:20 +000058
Daniel Sanders0848b232017-03-27 13:15:13 +000059cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
60
Ahmed Bougacha36f70352016-12-21 23:26:20 +000061static cl::opt<bool> WarnOnSkippedPatterns(
62 "warn-on-skipped-patterns",
63 cl::desc("Explain why a pattern was skipped for inclusion "
64 "in the GlobalISel selector"),
Daniel Sanders0848b232017-03-27 13:15:13 +000065 cl::init(false), cl::cat(GlobalISelEmitterCat));
Ahmed Bougacha36f70352016-12-21 23:26:20 +000066
Daniel Sandersbdfebb82017-03-15 20:18:38 +000067namespace {
Ahmed Bougacha36f70352016-12-21 23:26:20 +000068//===- Helper functions ---------------------------------------------------===//
69
Daniel Sanders52b4ce72017-03-07 23:20:35 +000070/// This class stands in for LLT wherever we want to tablegen-erate an
71/// equivalent at compiler run-time.
72class LLTCodeGen {
73private:
74 LLT Ty;
75
76public:
77 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
78
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000079 void emitCxxEnumValue(raw_ostream &OS) const {
80 if (Ty.isScalar()) {
81 OS << "GILLT_s" << Ty.getSizeInBits();
82 return;
83 }
84 if (Ty.isVector()) {
85 OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
86 return;
87 }
88 llvm_unreachable("Unhandled LLT");
89 }
90
Daniel Sanders52b4ce72017-03-07 23:20:35 +000091 void emitCxxConstructorCall(raw_ostream &OS) const {
92 if (Ty.isScalar()) {
93 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
94 return;
95 }
96 if (Ty.isVector()) {
Daniel Sanders32291982017-06-28 13:50:04 +000097 OS << "LLT::vector(" << Ty.getNumElements() << ", "
98 << Ty.getScalarSizeInBits() << ")";
Daniel Sanders52b4ce72017-03-07 23:20:35 +000099 return;
100 }
101 llvm_unreachable("Unhandled LLT");
102 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000103
104 const LLT &get() const { return Ty; }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000105
106 /// This ordering is used for std::unique() and std::sort(). There's no
107 /// particular logic behind the order.
108 bool operator<(const LLTCodeGen &Other) const {
109 if (!Ty.isValid())
110 return Other.Ty.isValid();
111 if (Ty.isScalar()) {
112 if (!Other.Ty.isValid())
113 return false;
114 if (Other.Ty.isScalar())
115 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
116 return false;
117 }
118 if (Ty.isVector()) {
119 if (!Other.Ty.isValid() || Other.Ty.isScalar())
120 return false;
121 if (Other.Ty.isVector()) {
122 if (Ty.getNumElements() < Other.Ty.getNumElements())
123 return true;
124 if (Ty.getNumElements() > Other.Ty.getNumElements())
125 return false;
126 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
127 }
128 return false;
129 }
130 llvm_unreachable("Unhandled LLT");
131 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000132};
133
134class InstructionMatcher;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000135/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
136/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000137static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000138 MVT VT(SVT);
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000139 if (VT.isVector() && VT.getVectorNumElements() != 1)
Daniel Sanders32291982017-06-28 13:50:04 +0000140 return LLTCodeGen(
141 LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000142 if (VT.isInteger() || VT.isFloatingPoint())
143 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
144 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000145}
146
Daniel Sandersd0656a32017-04-13 09:45:37 +0000147static std::string explainPredicates(const TreePatternNode *N) {
148 std::string Explanation = "";
149 StringRef Separator = "";
150 for (const auto &P : N->getPredicateFns()) {
151 Explanation +=
152 (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
153 if (P.isAlwaysTrue())
154 Explanation += " always-true";
155 if (P.isImmediatePattern())
156 Explanation += " immediate";
157 }
158 return Explanation;
159}
160
Daniel Sandersd0656a32017-04-13 09:45:37 +0000161std::string explainOperator(Record *Operator) {
162 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000163 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000164
165 if (Operator->isSubClassOf("Intrinsic"))
166 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
167
168 return " (Operator not understood)";
169}
170
171/// Helper function to let the emitter report skip reason error messages.
172static Error failedImport(const Twine &Reason) {
173 return make_error<StringError>(Reason, inconvertibleErrorCode());
174}
175
176static Error isTrivialOperatorNode(const TreePatternNode *N) {
177 std::string Explanation = "";
178 std::string Separator = "";
179 if (N->isLeaf()) {
Daniel Sanders3334cc02017-05-23 20:02:48 +0000180 if (isa<IntInit>(N->getLeafValue()))
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000181 return Error::success();
182
Daniel Sandersd0656a32017-04-13 09:45:37 +0000183 Explanation = "Is a leaf";
184 Separator = ", ";
185 }
186
187 if (N->hasAnyPredicate()) {
188 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
189 Separator = ", ";
190 }
191
192 if (N->getTransformFn()) {
193 Explanation += Separator + "Has a transform function";
194 Separator = ", ";
195 }
196
197 if (!N->isLeaf() && !N->hasAnyPredicate() && !N->getTransformFn())
198 return Error::success();
199
200 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000201}
202
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000203static Record *getInitValueAsRegClass(Init *V) {
204 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
205 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
206 return VDefInit->getDef()->getValueAsDef("RegClass");
207 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
208 return VDefInit->getDef();
209 }
210 return nullptr;
211}
212
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000213std::string
214getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
215 std::string Name = "GIFBS";
216 for (const auto &Feature : FeatureBitset)
217 Name += ("_" + Feature->getName()).str();
218 return Name;
219}
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000220//===- Matchers -----------------------------------------------------------===//
221
Daniel Sandersbee57392017-04-04 13:25:23 +0000222class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000223class MatchAction;
224
225/// Generates code to check that a match rule matches.
226class RuleMatcher {
227 /// A list of matchers that all need to succeed for the current rule to match.
228 /// FIXME: This currently supports a single match position but could be
229 /// extended to support multiple positions to support div/rem fusion or
230 /// load-multiple instructions.
231 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
232
233 /// A list of actions that need to be taken when all predicates in this rule
234 /// have succeeded.
235 std::vector<std::unique_ptr<MatchAction>> Actions;
236
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000237 /// A map of instruction matchers to the local variables created by
Daniel Sanders9d662d22017-07-06 10:06:12 +0000238 /// emitCaptureOpcodes().
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000239 std::map<const InstructionMatcher *, unsigned> InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000240
241 /// ID for the next instruction variable defined with defineInsnVar()
242 unsigned NextInsnVarID;
243
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000244 std::vector<Record *> RequiredFeatures;
245
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000246public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000247 RuleMatcher()
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000248 : Matchers(), Actions(), InsnVariableIDs(), NextInsnVarID(0) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000249 RuleMatcher(RuleMatcher &&Other) = default;
250 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000251
252 InstructionMatcher &addInstructionMatcher();
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000253 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000254 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000255
256 template <class Kind, class... Args> Kind &addAction(Args &&... args);
257
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000258 /// Define an instruction without emitting any code to do so.
259 /// This is used for the root of the match.
260 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
261 /// Define an instruction and emit corresponding state-machine opcodes.
262 unsigned defineInsnVar(raw_ostream &OS, const InstructionMatcher &Matcher,
263 unsigned InsnVarID, unsigned OpIdx);
264 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000265
Daniel Sanders9d662d22017-07-06 10:06:12 +0000266 void emitCaptureOpcodes(raw_ostream &OS);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000267
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000268 void emit(raw_ostream &OS);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000269
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000270 /// Compare the priority of this object and B.
271 ///
272 /// Returns true if this object is more important than B.
273 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000274
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000275 /// Report the maximum number of temporary operands needed by the rule
276 /// matcher.
277 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000278
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000279 // FIXME: Remove this as soon as possible
280 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000281};
282
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000283template <class PredicateTy> class PredicateListMatcher {
284private:
285 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
286 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000287
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000288public:
289 /// Construct a new operand predicate and add it to the matcher.
290 template <class Kind, class... Args>
291 Kind &addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000292 Predicates.emplace_back(
293 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000294 return *static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000295 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000296
Daniel Sanders32291982017-06-28 13:50:04 +0000297 typename PredicateVec::const_iterator predicates_begin() const {
298 return Predicates.begin();
299 }
300 typename PredicateVec::const_iterator predicates_end() const {
301 return Predicates.end();
302 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000303 iterator_range<typename PredicateVec::const_iterator> predicates() const {
304 return make_range(predicates_begin(), predicates_end());
305 }
Daniel Sanders32291982017-06-28 13:50:04 +0000306 typename PredicateVec::size_type predicates_size() const {
307 return Predicates.size();
308 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000309
Daniel Sanders9d662d22017-07-06 10:06:12 +0000310 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000311 template <class... Args>
Daniel Sanders9d662d22017-07-06 10:06:12 +0000312 void emitPredicateListOpcodes(raw_ostream &OS, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000313 if (Predicates.empty()) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000314 OS << "// No predicates\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000315 return;
316 }
317
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000318 for (const auto &Predicate : predicates())
Daniel Sanders9d662d22017-07-06 10:06:12 +0000319 Predicate->emitPredicateOpcodes(OS, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000320 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000321};
322
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000323/// Generates code to check a predicate of an operand.
324///
325/// Typical predicates include:
326/// * Operand is a particular register.
327/// * Operand is assigned a particular register bank.
328/// * Operand is an MBB.
329class OperandPredicateMatcher {
330public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000331 /// This enum is used for RTTI and also defines the priority that is given to
332 /// the predicate when generating the matcher code. Kinds with higher priority
333 /// must be tested first.
334 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000335 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
336 /// but OPM_Int must have priority over OPM_RegBank since constant integers
337 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000338 enum PredicateKind {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000339 OPM_ComplexPattern,
Daniel Sandersbee57392017-04-04 13:25:23 +0000340 OPM_Instruction,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000341 OPM_IntrinsicID,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000342 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000343 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000344 OPM_LLT,
345 OPM_RegBank,
346 OPM_MBB,
347 };
348
349protected:
350 PredicateKind Kind;
351
352public:
353 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000354 virtual ~OperandPredicateMatcher() {}
355
Daniel Sanders759ff412017-02-24 13:58:11 +0000356 PredicateKind getKind() const { return Kind; }
357
Daniel Sandersbee57392017-04-04 13:25:23 +0000358 /// Return the OperandMatcher for the specified operand or nullptr if there
359 /// isn't one by that name in this operand predicate matcher.
360 ///
361 /// InstructionOperandMatcher is the only subclass that can return non-null
362 /// for this.
363 virtual Optional<const OperandMatcher *>
Daniel Sandersdb7ed372017-04-04 13:52:00 +0000364 getOptionalOperand(StringRef SymbolicName) const {
Daniel Sandersbee57392017-04-04 13:25:23 +0000365 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
366 return None;
367 }
368
Daniel Sanders9d662d22017-07-06 10:06:12 +0000369 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sandersbee57392017-04-04 13:25:23 +0000370 ///
Daniel Sanders9d662d22017-07-06 10:06:12 +0000371 /// Only InstructionOperandMatcher needs to do anything for this method the
372 /// rest just walk the tree.
373 virtual void emitCaptureOpcodes(raw_ostream &OS, RuleMatcher &Rule,
374 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000375
Daniel Sanders9d662d22017-07-06 10:06:12 +0000376 /// Emit MatchTable opcodes that check the predicate for the given operand.
377 virtual void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000378 unsigned InsnVarID,
379 unsigned OpIdx) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000380
381 /// Compare the priority of this object and B.
382 ///
383 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000384 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const {
385 return Kind < B.Kind;
Daniel Sanders759ff412017-02-24 13:58:11 +0000386 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000387
388 /// Report the maximum number of temporary operands needed by the predicate
389 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000390 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000391};
392
393/// Generates code to check that an operand is a particular LLT.
394class LLTOperandMatcher : public OperandPredicateMatcher {
395protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000396 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000397
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000398public:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000399 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders759ff412017-02-24 13:58:11 +0000400 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {}
401
402 static bool classof(const OperandPredicateMatcher *P) {
403 return P->getKind() == OPM_LLT;
404 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000405
Daniel Sanders9d662d22017-07-06 10:06:12 +0000406 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000407 unsigned InsnVarID, unsigned OpIdx) const override {
408 OS << " GIM_CheckType, /*MI*/" << InsnVarID << ", /*Op*/" << OpIdx
409 << ", /*Type*/";
410 Ty.emitCxxEnumValue(OS);
411 OS << ", \n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000412 }
413};
414
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000415/// Generates code to check that an operand is a particular target constant.
416class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
417protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000418 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000419 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000420
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000421 unsigned getAllocatedTemporariesBaseID() const;
422
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000423public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000424 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
425 const Record &TheDef)
426 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
427 TheDef(TheDef) {}
428
429 static bool classof(const OperandPredicateMatcher *P) {
430 return P->getKind() == OPM_ComplexPattern;
431 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000432
Daniel Sanders9d662d22017-07-06 10:06:12 +0000433 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000434 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000435 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000436 OS << " GIM_CheckComplexPattern, /*MI*/" << InsnVarID << ", /*Op*/"
437 << OpIdx << ", /*Renderer*/" << ID << ", GICP_"
438 << TheDef.getName() << ",\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000439 }
440
Daniel Sanders2deea182017-04-22 15:11:04 +0000441 unsigned countRendererFns() const override {
442 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000443 }
444};
445
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000446/// Generates code to check that an operand is in a particular register bank.
447class RegisterBankOperandMatcher : public OperandPredicateMatcher {
448protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000449 const CodeGenRegisterClass &RC;
450
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000451public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000452 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
453 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
454
455 static bool classof(const OperandPredicateMatcher *P) {
456 return P->getKind() == OPM_RegBank;
457 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000458
Daniel Sanders9d662d22017-07-06 10:06:12 +0000459 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000460 unsigned InsnVarID, unsigned OpIdx) const override {
461 OS << " GIM_CheckRegBankForClass, /*MI*/" << InsnVarID << ", /*Op*/"
462 << OpIdx << ", /*RC*/" << RC.getQualifiedName() << "RegClassID,\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000463 }
464};
465
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000466/// Generates code to check that an operand is a basic block.
467class MBBOperandMatcher : public OperandPredicateMatcher {
468public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000469 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
470
471 static bool classof(const OperandPredicateMatcher *P) {
472 return P->getKind() == OPM_MBB;
473 }
474
Daniel Sanders9d662d22017-07-06 10:06:12 +0000475 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000476 unsigned InsnVarID, unsigned OpIdx) const override {
477 OS << " GIM_CheckIsMBB, /*MI*/" << InsnVarID << ", /*Op*/" << OpIdx << ",\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000478 }
479};
480
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000481/// Generates code to check that an operand is a G_CONSTANT with a particular
482/// int.
483class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000484protected:
485 int64_t Value;
486
487public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000488 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000489 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
490
491 static bool classof(const OperandPredicateMatcher *P) {
492 return P->getKind() == OPM_Int;
493 }
494
Daniel Sanders9d662d22017-07-06 10:06:12 +0000495 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000496 unsigned InsnVarID, unsigned OpIdx) const override {
497 OS << " GIM_CheckConstantInt, /*MI*/" << InsnVarID << ", /*Op*/"
498 << OpIdx << ", " << Value << ",\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000499 }
500};
501
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000502/// Generates code to check that an operand is a raw int (where MO.isImm() or
503/// MO.isCImm() is true).
504class LiteralIntOperandMatcher : public OperandPredicateMatcher {
505protected:
506 int64_t Value;
507
508public:
509 LiteralIntOperandMatcher(int64_t Value)
510 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
511
512 static bool classof(const OperandPredicateMatcher *P) {
513 return P->getKind() == OPM_LiteralInt;
514 }
515
Daniel Sanders9d662d22017-07-06 10:06:12 +0000516 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000517 unsigned InsnVarID, unsigned OpIdx) const override {
518 OS << " GIM_CheckLiteralInt, /*MI*/" << InsnVarID << ", /*Op*/"
519 << OpIdx << ", " << Value << ",\n";
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000520 }
521};
522
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000523/// Generates code to check that an operand is an intrinsic ID.
524class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
525protected:
526 const CodeGenIntrinsic *II;
527
528public:
529 IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
530 : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
531
532 static bool classof(const OperandPredicateMatcher *P) {
533 return P->getKind() == OPM_IntrinsicID;
534 }
535
536 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
537 unsigned InsnVarID, unsigned OpIdx) const override {
538 OS << " GIM_CheckIntrinsicID, /*MI*/" << InsnVarID << ", /*Op*/"
539 << OpIdx << ", Intrinsic::" << II->EnumName << ",\n";
540 }
541};
542
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000543/// Generates code to check that a set of predicates match for a particular
544/// operand.
545class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
546protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000547 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000548 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000549 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000550
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000551 /// The index of the first temporary variable allocated to this operand. The
552 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +0000553 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000554 unsigned AllocatedTemporariesBaseID;
555
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000556public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000557 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000558 const std::string &SymbolicName,
559 unsigned AllocatedTemporariesBaseID)
560 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
561 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000562
563 bool hasSymbolicName() const { return !SymbolicName.empty(); }
564 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +0000565 void setSymbolicName(StringRef Name) {
566 assert(SymbolicName.empty() && "Operand already has a symbolic name");
567 SymbolicName = Name;
568 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000569 unsigned getOperandIndex() const { return OpIdx; }
570
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000571 std::string getOperandExpr(unsigned InsnVarID) const {
572 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
573 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +0000574 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000575
Daniel Sandersbee57392017-04-04 13:25:23 +0000576 Optional<const OperandMatcher *>
577 getOptionalOperand(StringRef DesiredSymbolicName) const {
578 assert(!DesiredSymbolicName.empty() && "Cannot lookup unnamed operand");
579 if (DesiredSymbolicName == SymbolicName)
580 return this;
581 for (const auto &OP : predicates()) {
582 const auto &MaybeOperand = OP->getOptionalOperand(DesiredSymbolicName);
583 if (MaybeOperand.hasValue())
584 return MaybeOperand.getValue();
585 }
586 return None;
587 }
588
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000589 InstructionMatcher &getInstructionMatcher() const { return Insn; }
590
Daniel Sanders9d662d22017-07-06 10:06:12 +0000591 /// Emit MatchTable opcodes to capture instructions into the MIs table.
592 void emitCaptureOpcodes(raw_ostream &OS, RuleMatcher &Rule,
593 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +0000594 for (const auto &Predicate : predicates())
Daniel Sanders9d662d22017-07-06 10:06:12 +0000595 Predicate->emitCaptureOpcodes(OS, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +0000596 }
597
Daniel Sanders9d662d22017-07-06 10:06:12 +0000598 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000599 /// InsnVarID matches all the predicates and all the operands.
Daniel Sanders9d662d22017-07-06 10:06:12 +0000600 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000601 unsigned InsnVarID) const {
602 OS << " // MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000603 if (SymbolicName.empty())
604 OS << "Operand " << OpIdx;
605 else
606 OS << SymbolicName;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000607 OS << "\n";
Daniel Sanders9d662d22017-07-06 10:06:12 +0000608 emitPredicateListOpcodes(OS, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000609 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000610
611 /// Compare the priority of this object and B.
612 ///
613 /// Returns true if this object is more important than B.
614 bool isHigherPriorityThan(const OperandMatcher &B) const {
615 // Operand matchers involving more predicates have higher priority.
616 if (predicates_size() > B.predicates_size())
617 return true;
618 if (predicates_size() < B.predicates_size())
619 return false;
620
621 // This assumes that predicates are added in a consistent order.
622 for (const auto &Predicate : zip(predicates(), B.predicates())) {
623 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
624 return true;
625 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
626 return false;
627 }
628
629 return false;
630 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000631
632 /// Report the maximum number of temporary operands needed by the operand
633 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000634 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000635 return std::accumulate(
636 predicates().begin(), predicates().end(), 0,
637 [](unsigned A,
638 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +0000639 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000640 });
641 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000642
643 unsigned getAllocatedTemporariesBaseID() const {
644 return AllocatedTemporariesBaseID;
645 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000646};
647
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000648unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
649 return Operand.getAllocatedTemporariesBaseID();
650}
651
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000652/// Generates code to check a predicate on an instruction.
653///
654/// Typical predicates include:
655/// * The opcode of the instruction is a particular value.
656/// * The nsw/nuw flag is/isn't set.
657class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +0000658protected:
659 /// This enum is used for RTTI and also defines the priority that is given to
660 /// the predicate when generating the matcher code. Kinds with higher priority
661 /// must be tested first.
662 enum PredicateKind {
663 IPM_Opcode,
664 };
665
666 PredicateKind Kind;
667
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000668public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000669 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000670 virtual ~InstructionPredicateMatcher() {}
671
Daniel Sanders759ff412017-02-24 13:58:11 +0000672 PredicateKind getKind() const { return Kind; }
673
Daniel Sanders9d662d22017-07-06 10:06:12 +0000674 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000675 /// InsnVarID matches the predicate.
Daniel Sanders9d662d22017-07-06 10:06:12 +0000676 virtual void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000677 unsigned InsnVarID) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000678
679 /// Compare the priority of this object and B.
680 ///
681 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +0000682 virtual bool
683 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +0000684 return Kind < B.Kind;
685 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000686
687 /// Report the maximum number of temporary operands needed by the predicate
688 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000689 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000690};
691
692/// Generates code to check the opcode of an instruction.
693class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
694protected:
695 const CodeGenInstruction *I;
696
697public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000698 InstructionOpcodeMatcher(const CodeGenInstruction *I)
699 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000700
Daniel Sanders759ff412017-02-24 13:58:11 +0000701 static bool classof(const InstructionPredicateMatcher *P) {
702 return P->getKind() == IPM_Opcode;
703 }
704
Daniel Sanders9d662d22017-07-06 10:06:12 +0000705 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000706 unsigned InsnVarID) const override {
707 OS << " GIM_CheckOpcode, /*MI*/" << InsnVarID << ", " << I->Namespace
708 << "::" << I->TheDef->getName() << ",\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000709 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000710
711 /// Compare the priority of this object and B.
712 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000713 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +0000714 bool
715 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +0000716 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
717 return true;
718 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
719 return false;
720
721 // Prioritize opcodes for cosmetic reasons in the generated source. Although
722 // this is cosmetic at the moment, we may want to drive a similar ordering
723 // using instruction frequency information to improve compile time.
724 if (const InstructionOpcodeMatcher *BO =
725 dyn_cast<InstructionOpcodeMatcher>(&B))
726 return I->TheDef->getName() < BO->I->TheDef->getName();
727
728 return false;
729 };
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000730};
731
732/// Generates code to check that a set of predicates and operands match for a
733/// particular instruction.
734///
735/// Typical predicates include:
736/// * Has a specific opcode.
737/// * Has an nsw/nuw flag or doesn't.
738class InstructionMatcher
739 : public PredicateListMatcher<InstructionPredicateMatcher> {
740protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000741 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000742
743 /// The operands to match. All rendered operands must be present even if the
744 /// condition is always true.
745 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000746
747public:
748 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000749 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
750 unsigned AllocatedTemporariesBaseID) {
751 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
752 AllocatedTemporariesBaseID));
753 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000754 }
755
Daniel Sandersffc7d582017-03-29 15:37:18 +0000756 OperandMatcher &getOperand(unsigned OpIdx) {
757 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000758 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
759 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +0000760 });
761 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000762 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +0000763 llvm_unreachable("Failed to lookup operand");
764 }
765
Daniel Sandersbee57392017-04-04 13:25:23 +0000766 Optional<const OperandMatcher *>
767 getOptionalOperand(StringRef SymbolicName) const {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000768 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
Daniel Sandersbee57392017-04-04 13:25:23 +0000769 for (const auto &Operand : Operands) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000770 const auto &OM = Operand->getOptionalOperand(SymbolicName);
Daniel Sandersbee57392017-04-04 13:25:23 +0000771 if (OM.hasValue())
772 return OM.getValue();
773 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000774 return None;
775 }
776
Daniel Sandersdb7ed372017-04-04 13:52:00 +0000777 const OperandMatcher &getOperand(StringRef SymbolicName) const {
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000778 Optional<const OperandMatcher *>OM = getOptionalOperand(SymbolicName);
779 if (OM.hasValue())
780 return *OM.getValue();
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000781 llvm_unreachable("Failed to lookup operand");
782 }
783
784 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +0000785 OperandVec::iterator operands_begin() { return Operands.begin(); }
786 OperandVec::iterator operands_end() { return Operands.end(); }
787 iterator_range<OperandVec::iterator> operands() {
788 return make_range(operands_begin(), operands_end());
789 }
Daniel Sandersffc7d582017-03-29 15:37:18 +0000790 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
791 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000792 iterator_range<OperandVec::const_iterator> operands() const {
793 return make_range(operands_begin(), operands_end());
794 }
795
Daniel Sanders9d662d22017-07-06 10:06:12 +0000796 /// Emit MatchTable opcodes to check the shape of the match and capture
797 /// instructions into the MIs table.
798 void emitCaptureOpcodes(raw_ostream &OS, RuleMatcher &Rule,
799 unsigned InsnID) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000800 OS << " GIM_CheckNumOperands, /*MI*/" << InsnID << ", /*Expected*/"
801 << getNumOperands() << ",\n";
802 for (const auto &Operand : Operands)
Daniel Sanders9d662d22017-07-06 10:06:12 +0000803 Operand->emitCaptureOpcodes(OS, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000804 }
805
Daniel Sanders9d662d22017-07-06 10:06:12 +0000806 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000807 /// InsnVarName matches all the predicates and all the operands.
Daniel Sanders9d662d22017-07-06 10:06:12 +0000808 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000809 unsigned InsnVarID) const {
Daniel Sanders9d662d22017-07-06 10:06:12 +0000810 emitPredicateListOpcodes(OS, Rule, InsnVarID);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000811 for (const auto &Operand : Operands)
Daniel Sanders9d662d22017-07-06 10:06:12 +0000812 Operand->emitPredicateOpcodes(OS, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000813 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000814
815 /// Compare the priority of this object and B.
816 ///
817 /// Returns true if this object is more important than B.
818 bool isHigherPriorityThan(const InstructionMatcher &B) const {
819 // Instruction matchers involving more operands have higher priority.
820 if (Operands.size() > B.Operands.size())
821 return true;
822 if (Operands.size() < B.Operands.size())
823 return false;
824
825 for (const auto &Predicate : zip(predicates(), B.predicates())) {
826 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
827 return true;
828 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
829 return false;
830 }
831
832 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000833 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +0000834 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000835 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +0000836 return false;
837 }
838
839 return false;
840 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000841
842 /// Report the maximum number of temporary operands needed by the instruction
843 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000844 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000845 return std::accumulate(predicates().begin(), predicates().end(), 0,
846 [](unsigned A,
847 const std::unique_ptr<InstructionPredicateMatcher>
848 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +0000849 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000850 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000851 std::accumulate(
852 Operands.begin(), Operands.end(), 0,
853 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +0000854 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000855 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000856 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000857};
858
Daniel Sandersbee57392017-04-04 13:25:23 +0000859/// Generates code to check that the operand is a register defined by an
860/// instruction that matches the given instruction matcher.
861///
862/// For example, the pattern:
863/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
864/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
865/// the:
866/// (G_ADD $src1, $src2)
867/// subpattern.
868class InstructionOperandMatcher : public OperandPredicateMatcher {
869protected:
870 std::unique_ptr<InstructionMatcher> InsnMatcher;
871
872public:
873 InstructionOperandMatcher()
874 : OperandPredicateMatcher(OPM_Instruction),
875 InsnMatcher(new InstructionMatcher()) {}
876
877 static bool classof(const OperandPredicateMatcher *P) {
878 return P->getKind() == OPM_Instruction;
879 }
880
881 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
882
883 Optional<const OperandMatcher *>
884 getOptionalOperand(StringRef SymbolicName) const override {
885 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
886 return InsnMatcher->getOptionalOperand(SymbolicName);
887 }
888
Daniel Sanders9d662d22017-07-06 10:06:12 +0000889 void emitCaptureOpcodes(raw_ostream &OS, RuleMatcher &Rule,
890 unsigned InsnID, unsigned OpIdx) const override {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000891 unsigned InsnVarID = Rule.defineInsnVar(OS, *InsnMatcher, InsnID, OpIdx);
Daniel Sanders9d662d22017-07-06 10:06:12 +0000892 InsnMatcher->emitCaptureOpcodes(OS, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +0000893 }
894
Daniel Sanders9d662d22017-07-06 10:06:12 +0000895 void emitPredicateOpcodes(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000896 unsigned InsnVarID_,
897 unsigned OpIdx_) const override {
898 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
Daniel Sanders9d662d22017-07-06 10:06:12 +0000899 InsnMatcher->emitPredicateOpcodes(OS, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +0000900 }
901};
902
Daniel Sanders43c882c2017-02-01 10:53:10 +0000903//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000904class OperandRenderer {
905public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000906 enum RendererKind {
907 OR_Copy,
908 OR_CopySubReg,
909 OR_Imm,
910 OR_Register,
911 OR_ComplexPattern
912 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000913
914protected:
915 RendererKind Kind;
916
917public:
918 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
919 virtual ~OperandRenderer() {}
920
921 RendererKind getKind() const { return Kind; }
922
Daniel Sanders3ae33202017-07-06 10:37:17 +0000923 virtual void emitRenderOpcodes(raw_ostream &OS, RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000924};
925
926/// A CopyRenderer emits code to copy a single operand from an existing
927/// instruction to the one being built.
928class CopyRenderer : public OperandRenderer {
929protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000930 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000931 /// The matcher for the instruction that this operand is copied from.
932 /// This provides the facility for looking up an a operand by it's name so
933 /// that it can be used as a source for the instruction being built.
934 const InstructionMatcher &Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000935 /// The name of the operand.
936 const StringRef SymbolicName;
937
938public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000939 CopyRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
940 StringRef SymbolicName)
941 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID), Matched(Matched),
942 SymbolicName(SymbolicName) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000943
944 static bool classof(const OperandRenderer *R) {
945 return R->getKind() == OR_Copy;
946 }
947
948 const StringRef getSymbolicName() const { return SymbolicName; }
949
Daniel Sanders3ae33202017-07-06 10:37:17 +0000950 void emitRenderOpcodes(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000951 const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000952 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sandersa6cfce62017-07-05 14:50:18 +0000953 OS << " GIR_Copy, /*NewInsnID*/" << NewInsnID << ", /*OldInsnID*/"
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000954 << OldInsnVarID << ", /*OpIdx*/" << Operand.getOperandIndex() << ", // "
955 << SymbolicName << "\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000956 }
957};
958
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000959/// A CopySubRegRenderer emits code to copy a single register operand from an
960/// existing instruction to the one being built and indicate that only a
961/// subregister should be copied.
962class CopySubRegRenderer : public OperandRenderer {
963protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000964 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000965 /// The matcher for the instruction that this operand is copied from.
966 /// This provides the facility for looking up an a operand by it's name so
967 /// that it can be used as a source for the instruction being built.
968 const InstructionMatcher &Matched;
969 /// The name of the operand.
970 const StringRef SymbolicName;
971 /// The subregister to extract.
972 const CodeGenSubRegIndex *SubReg;
973
974public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000975 CopySubRegRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
976 StringRef SymbolicName, const CodeGenSubRegIndex *SubReg)
977 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID), Matched(Matched),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000978 SymbolicName(SymbolicName), SubReg(SubReg) {}
979
980 static bool classof(const OperandRenderer *R) {
981 return R->getKind() == OR_CopySubReg;
982 }
983
984 const StringRef getSymbolicName() const { return SymbolicName; }
985
Daniel Sanders3ae33202017-07-06 10:37:17 +0000986 void emitRenderOpcodes(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000987 const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000988 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sandersa6cfce62017-07-05 14:50:18 +0000989 OS << " GIR_CopySubReg, /*NewInsnID*/" << NewInsnID
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000990 << ", /*OldInsnID*/" << OldInsnVarID << ", /*OpIdx*/"
991 << Operand.getOperandIndex() << ", /*SubRegIdx*/" << SubReg->EnumValue
992 << ", // " << SymbolicName << "\n";
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000993 }
994};
995
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000996/// Adds a specific physical register to the instruction being built.
997/// This is typically useful for WZR/XZR on AArch64.
998class AddRegisterRenderer : public OperandRenderer {
999protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001000 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001001 const Record *RegisterDef;
1002
1003public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001004 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
1005 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
1006 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001007
1008 static bool classof(const OperandRenderer *R) {
1009 return R->getKind() == OR_Register;
1010 }
1011
Daniel Sanders3ae33202017-07-06 10:37:17 +00001012 void emitRenderOpcodes(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001013 OS << " GIR_AddRegister, /*InsnID*/" << InsnID << ", "
1014 << (RegisterDef->getValue("Namespace")
1015 ? RegisterDef->getValueAsString("Namespace")
1016 : "")
1017 << "::" << RegisterDef->getName() << ",\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001018 }
1019};
1020
Daniel Sanders0ed28822017-04-12 08:23:08 +00001021/// Adds a specific immediate to the instruction being built.
1022class ImmRenderer : public OperandRenderer {
1023protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001024 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001025 int64_t Imm;
1026
1027public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001028 ImmRenderer(unsigned InsnID, int64_t Imm)
1029 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001030
1031 static bool classof(const OperandRenderer *R) {
1032 return R->getKind() == OR_Imm;
1033 }
1034
Daniel Sanders3ae33202017-07-06 10:37:17 +00001035 void emitRenderOpcodes(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001036 OS << " GIR_AddImm, /*InsnID*/" << InsnID << ", /*Imm*/" << Imm
1037 << ",\n";
Daniel Sanders0ed28822017-04-12 08:23:08 +00001038 }
1039};
1040
Daniel Sanders2deea182017-04-22 15:11:04 +00001041/// Adds operands by calling a renderer function supplied by the ComplexPattern
1042/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001043class RenderComplexPatternOperand : public OperandRenderer {
1044private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001045 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001046 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001047 /// The name of the operand.
1048 const StringRef SymbolicName;
1049 /// The renderer number. This must be unique within a rule since it's used to
1050 /// identify a temporary variable to hold the renderer function.
1051 unsigned RendererID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001052
1053 unsigned getNumOperands() const {
1054 return TheDef.getValueAsDag("Operands")->getNumArgs();
1055 }
1056
1057public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001058 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
1059 StringRef SymbolicName, unsigned RendererID)
1060 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sanders2deea182017-04-22 15:11:04 +00001061 SymbolicName(SymbolicName), RendererID(RendererID) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001062
1063 static bool classof(const OperandRenderer *R) {
1064 return R->getKind() == OR_ComplexPattern;
1065 }
1066
Daniel Sanders3ae33202017-07-06 10:37:17 +00001067 void emitRenderOpcodes(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001068 OS << " GIR_ComplexRenderer, /*InsnID*/" << InsnID << ", /*RendererID*/"
1069 << RendererID << ",\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001070 }
1071};
1072
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001073/// An action taken when all Matcher predicates succeeded for a parent rule.
1074///
1075/// Typical actions include:
1076/// * Changing the opcode of an instruction.
1077/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001078class MatchAction {
1079public:
1080 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001081
1082 /// Emit the C++ statements to implement the action.
1083 ///
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001084 /// \param RecycleInsnID If given, it's an instruction to recycle. The
1085 /// requirements on the instruction vary from action to
1086 /// action.
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001087 virtual void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001088 unsigned RecycleInsnID) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001089};
1090
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001091/// Generates a comment describing the matched rule being acted upon.
1092class DebugCommentAction : public MatchAction {
1093private:
1094 const PatternToMatch &P;
1095
1096public:
1097 DebugCommentAction(const PatternToMatch &P) : P(P) {}
1098
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001099 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001100 unsigned RecycleInsnID) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001101 OS << " // " << *P.getSrcPattern() << " => " << *P.getDstPattern()
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001102 << "\n";
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001103 }
1104};
1105
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001106/// Generates code to build an instruction or mutate an existing instruction
1107/// into the desired instruction when this is possible.
1108class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001109private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001110 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001111 const CodeGenInstruction *I;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001112 const InstructionMatcher &Matched;
1113 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1114
1115 /// True if the instruction can be built solely by mutating the opcode.
1116 bool canMutate() const {
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001117 if (OperandRenderers.size() != Matched.getNumOperands())
1118 return false;
1119
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001120 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001121 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001122 const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName());
1123 if (&Matched != &OM.getInstructionMatcher() ||
1124 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001125 return false;
1126 } else
1127 return false;
1128 }
1129
1130 return true;
1131 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001132
Daniel Sanders43c882c2017-02-01 10:53:10 +00001133public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001134 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001135 const InstructionMatcher &Matched)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001136 : InsnID(InsnID), I(I), Matched(Matched) {}
Daniel Sanders43c882c2017-02-01 10:53:10 +00001137
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001138 template <class Kind, class... Args>
1139 Kind &addRenderer(Args&&... args) {
1140 OperandRenderers.emplace_back(
1141 llvm::make_unique<Kind>(std::forward<Args>(args)...));
1142 return *static_cast<Kind *>(OperandRenderers.back().get());
1143 }
1144
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001145 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001146 unsigned RecycleInsnID) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001147 if (canMutate()) {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001148 OS << " GIR_MutateOpcode, /*InsnID*/" << InsnID
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001149 << ", /*RecycleInsnID*/ " << RecycleInsnID << ", /*Opcode*/"
1150 << I->Namespace << "::" << I->TheDef->getName() << ",\n";
Tim Northover4340d642017-03-20 21:58:23 +00001151
1152 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001153 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001154 auto Namespace = Def->getValue("Namespace")
1155 ? Def->getValueAsString("Namespace")
1156 : "";
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001157 OS << " GIR_AddImplicitDef, " << InsnID << ", " << Namespace
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001158 << "::" << Def->getName() << ",\n";
Tim Northover4340d642017-03-20 21:58:23 +00001159 }
1160 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001161 auto Namespace = Use->getValue("Namespace")
1162 ? Use->getValueAsString("Namespace")
1163 : "";
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001164 OS << " GIR_AddImplicitUse, " << InsnID << ", " << Namespace
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001165 << "::" << Use->getName() << ",\n";
Tim Northover4340d642017-03-20 21:58:23 +00001166 }
1167 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001168 return;
1169 }
1170
1171 // TODO: Simple permutation looks like it could be almost as common as
1172 // mutation due to commutative operations.
1173
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001174 OS << " GIR_BuildMI, /*InsnID*/" << InsnID << ", /*Opcode*/"
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001175 << I->Namespace << "::" << I->TheDef->getName() << ",\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001176 for (const auto &Renderer : OperandRenderers)
Daniel Sanders3ae33202017-07-06 10:37:17 +00001177 Renderer->emitRenderOpcodes(OS, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001178
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001179 OS << " GIR_MergeMemOperands, /*InsnID*/" << InsnID << ",\n"
1180 << " GIR_EraseFromParent, /*InsnID*/" << RecycleInsnID << ",\n";
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001181 }
1182};
1183
1184/// Generates code to constrain the operands of an output instruction to the
1185/// register classes specified by the definition of that instruction.
1186class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001187 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001188
1189public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001190 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001191
1192 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001193 unsigned RecycleInsnID) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001194 OS << " GIR_ConstrainSelectedInstOperands, /*InsnID*/" << InsnID << ",\n";
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001195 }
1196};
1197
1198/// Generates code to constrain the specified operand of an output instruction
1199/// to the specified register class.
1200class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001201 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001202 unsigned OpIdx;
1203 const CodeGenRegisterClass &RC;
1204
1205public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001206 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001207 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001208 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001209
1210 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001211 unsigned RecycleInsnID) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001212 OS << " GIR_ConstrainOperandRC, /*InsnID*/" << InsnID << ", /*Op*/"
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001213 << OpIdx << ", /*RC " << RC.getName() << "*/ " << RC.EnumValue << ",\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001214 }
1215};
1216
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001217InstructionMatcher &RuleMatcher::addInstructionMatcher() {
1218 Matchers.emplace_back(new InstructionMatcher());
1219 return *Matchers.back();
1220}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001221
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001222void RuleMatcher::addRequiredFeature(Record *Feature) {
1223 RequiredFeatures.push_back(Feature);
1224}
1225
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001226const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
1227 return RequiredFeatures;
1228}
1229
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001230template <class Kind, class... Args>
1231Kind &RuleMatcher::addAction(Args &&... args) {
1232 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1233 return *static_cast<Kind *>(Actions.back().get());
1234}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001235
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001236unsigned
1237RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
1238 unsigned NewInsnVarID = NextInsnVarID++;
1239 InsnVariableIDs[&Matcher] = NewInsnVarID;
1240 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001241}
1242
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001243unsigned RuleMatcher::defineInsnVar(raw_ostream &OS,
1244 const InstructionMatcher &Matcher,
1245 unsigned InsnID, unsigned OpIdx) {
1246 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
1247 OS << " GIM_RecordInsn, /*DefineMI*/" << NewInsnVarID << ", /*MI*/"
1248 << InsnID << ", /*OpIdx*/" << OpIdx << ", // MIs[" << NewInsnVarID
1249 << "]\n";
1250 return NewInsnVarID;
1251}
1252
1253unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
1254 const auto &I = InsnVariableIDs.find(&InsnMatcher);
1255 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001256 return I->second;
1257 llvm_unreachable("Matched Insn was not captured in a local variable");
1258}
1259
Daniel Sanders9d662d22017-07-06 10:06:12 +00001260/// Emit MatchTable opcodes to check the shape of the match and capture
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001261/// instructions into local variables.
Daniel Sanders9d662d22017-07-06 10:06:12 +00001262void RuleMatcher::emitCaptureOpcodes(raw_ostream &OS) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001263 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001264 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
Daniel Sanders9d662d22017-07-06 10:06:12 +00001265 Matchers.front()->emitCaptureOpcodes(OS, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001266}
1267
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001268void RuleMatcher::emit(raw_ostream &OS) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001269 if (Matchers.empty())
1270 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001271
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001272 // The representation supports rules that require multiple roots such as:
1273 // %ptr(p0) = ...
1274 // %elt0(s32) = G_LOAD %ptr
1275 // %1(p0) = G_ADD %ptr, 4
1276 // %elt1(s32) = G_LOAD p0 %1
1277 // which could be usefully folded into:
1278 // %ptr(p0) = ...
1279 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
1280 // on some targets but we don't need to make use of that yet.
1281 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001282
Daniel Sandersc60abe32017-07-04 15:31:50 +00001283 OS << " const static int64_t MatchTable" << CurrentMatchTableID << "[] = {\n";
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001284 if (!RequiredFeatures.empty()) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001285 OS << " GIM_CheckFeatures, " << getNameForFeatureBitset(RequiredFeatures)
1286 << ",\n";
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001287 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001288
Daniel Sanders9d662d22017-07-06 10:06:12 +00001289 emitCaptureOpcodes(OS);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001290
Daniel Sanders9d662d22017-07-06 10:06:12 +00001291 Matchers.front()->emitPredicateOpcodes(OS, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001292 getInsnVarID(*Matchers.front()));
1293
Daniel Sandersbee57392017-04-04 13:25:23 +00001294 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001295 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00001296 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001297 SmallVector<unsigned, 2> InsnIDs;
1298 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001299 // Skip the root node since it isn't moving anywhere. Everything else is
1300 // sinking to meet it.
1301 if (Pair.first == Matchers.front().get())
1302 continue;
1303
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001304 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00001305 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001306 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00001307
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001308 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001309 // Reject the difficult cases until we have a more accurate check.
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001310 OS << " GIM_CheckIsSafeToFold, /*InsnID*/" << InsnID << ",\n";
Daniel Sandersbee57392017-04-04 13:25:23 +00001311
1312 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
1313 // account for unsafe cases.
1314 //
1315 // Example:
1316 // MI1--> %0 = ...
1317 // %1 = ... %0
1318 // MI0--> %2 = ... %0
1319 // It's not safe to erase MI1. We currently handle this by not
1320 // erasing %0 (even when it's dead).
1321 //
1322 // Example:
1323 // MI1--> %0 = load volatile @a
1324 // %1 = load volatile @a
1325 // MI0--> %2 = ... %0
1326 // It's not safe to sink %0's def past %1. We currently handle
1327 // this by rejecting all loads.
1328 //
1329 // Example:
1330 // MI1--> %0 = load @a
1331 // %1 = store @a
1332 // MI0--> %2 = ... %0
1333 // It's not safe to sink %0's def past %1. We currently handle
1334 // this by rejecting all loads.
1335 //
1336 // Example:
1337 // G_CONDBR %cond, @BB1
1338 // BB0:
1339 // MI1--> %0 = load @a
1340 // G_BR @BB1
1341 // BB1:
1342 // MI0--> %2 = ... %0
1343 // It's not always safe to sink %0 across control flow. In this
1344 // case it may introduce a memory fault. We currentl handle this
1345 // by rejecting all loads.
1346 }
1347 }
1348
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001349 for (const auto &MA : Actions)
1350 MA->emitCxxActionStmts(OS, *this, 0);
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001351 OS << " GIR_Done,\n"
1352 << " };\n"
1353 << " State.MIs.resize(1);\n"
1354 << " DEBUG(dbgs() << \"Processing MatchTable" << CurrentMatchTableID
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001355 << "\\n\");\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001356 << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable"
1357 << CurrentMatchTableID << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n"
1358 << " return true;\n"
1359 << " }\n\n";
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001360}
Daniel Sanders43c882c2017-02-01 10:53:10 +00001361
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001362bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
1363 // Rules involving more match roots have higher priority.
1364 if (Matchers.size() > B.Matchers.size())
1365 return true;
1366 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00001367 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001368
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001369 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
1370 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
1371 return true;
1372 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
1373 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001374 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001375
1376 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00001377}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001378
Daniel Sanders2deea182017-04-22 15:11:04 +00001379unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001380 return std::accumulate(
1381 Matchers.begin(), Matchers.end(), 0,
1382 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001383 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001384 });
1385}
1386
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001387//===- GlobalISelEmitter class --------------------------------------------===//
1388
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001389class GlobalISelEmitter {
1390public:
1391 explicit GlobalISelEmitter(RecordKeeper &RK);
1392 void run(raw_ostream &OS);
1393
1394private:
1395 const RecordKeeper &RK;
1396 const CodeGenDAGPatterns CGP;
1397 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001398 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001399
1400 /// Keep track of the equivalence between SDNodes and Instruction.
1401 /// This is defined using 'GINodeEquiv' in the target description.
1402 DenseMap<Record *, const CodeGenInstruction *> NodeEquivs;
1403
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001404 /// Keep track of the equivalence between ComplexPattern's and
1405 /// GIComplexOperandMatcher. Map entries are specified by subclassing
1406 /// GIComplexPatternEquiv.
1407 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
1408
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001409 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001410 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001411
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001412 void gatherNodeEquivs();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001413 const CodeGenInstruction *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001414
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001415 Error importRulePredicates(RuleMatcher &M, ArrayRef<Init *> Predicates);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001416 Expected<InstructionMatcher &>
Daniel Sandersc270c502017-03-30 09:36:33 +00001417 createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher,
1418 const TreePatternNode *Src) const;
1419 Error importChildMatcher(InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001420 const TreePatternNode *SrcChild, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00001421 unsigned &TempOpIdx) const;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001422 Expected<BuildMIAction &>
1423 createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst,
1424 const InstructionMatcher &InsnMatcher);
Daniel Sandersc270c502017-03-30 09:36:33 +00001425 Error importExplicitUseRenderer(BuildMIAction &DstMIBuilder,
1426 TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001427 const InstructionMatcher &InsnMatcher) const;
Diana Picus382602f2017-05-17 08:57:28 +00001428 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
1429 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00001430 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00001431 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
1432 const std::vector<Record *> &ImplicitDefs) const;
1433
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001434 /// Analyze pattern \p P, returning a matcher for it if possible.
1435 /// Otherwise, return an Error explaining why we don't support it.
1436 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001437
1438 void declareSubtargetFeature(Record *Predicate);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001439};
1440
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001441void GlobalISelEmitter::gatherNodeEquivs() {
1442 assert(NodeEquivs.empty());
1443 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
1444 NodeEquivs[Equiv->getValueAsDef("Node")] =
1445 &Target.getInstruction(Equiv->getValueAsDef("I"));
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001446
1447 assert(ComplexPatternEquivs.empty());
1448 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
1449 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
1450 if (!SelDAGEquiv)
1451 continue;
1452 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
1453 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001454}
1455
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001456const CodeGenInstruction *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001457 return NodeEquivs.lookup(N);
1458}
1459
1460GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001461 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()), CGRegs(RK) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001462
1463//===- Emitter ------------------------------------------------------------===//
1464
Daniel Sandersc270c502017-03-30 09:36:33 +00001465Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00001466GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001467 ArrayRef<Init *> Predicates) {
1468 for (const Init *Predicate : Predicates) {
1469 const DefInit *PredicateDef = static_cast<const DefInit *>(Predicate);
1470 declareSubtargetFeature(PredicateDef->getDef());
1471 M.addRequiredFeature(PredicateDef->getDef());
1472 }
1473
Daniel Sandersc270c502017-03-30 09:36:33 +00001474 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001475}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001476
Daniel Sandersc270c502017-03-30 09:36:33 +00001477Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
1478 InstructionMatcher &InsnMatcher, const TreePatternNode *Src) const {
Daniel Sanders85ffd362017-07-06 08:12:20 +00001479 const CodeGenInstruction *SrcGIOrNull = nullptr;
1480
Daniel Sandersffc7d582017-03-29 15:37:18 +00001481 // Start with the defined operands (i.e., the results of the root operator).
1482 if (Src->getExtTypes().size() > 1)
1483 return failedImport("Src pattern has multiple results");
1484
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001485 if (Src->isLeaf()) {
1486 Init *SrcInit = Src->getLeafValue();
Daniel Sanders3334cc02017-05-23 20:02:48 +00001487 if (isa<IntInit>(SrcInit)) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001488 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
1489 &Target.getInstruction(RK.getDef("G_CONSTANT")));
1490 } else
Daniel Sanders32291982017-06-28 13:50:04 +00001491 return failedImport(
1492 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001493 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00001494 SrcGIOrNull = findNodeEquiv(Src->getOperator());
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001495 if (!SrcGIOrNull)
1496 return failedImport("Pattern operator lacks an equivalent Instruction" +
1497 explainOperator(Src->getOperator()));
1498 auto &SrcGI = *SrcGIOrNull;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001499
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001500 // The operators look good: match the opcode
1501 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
1502 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001503
1504 unsigned OpIdx = 0;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001505 unsigned TempOpIdx = 0;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001506 for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
1507 auto OpTyOrNone = MVTToLLT(Ty.getConcrete());
1508
1509 if (!OpTyOrNone)
1510 return failedImport(
1511 "Result of Src pattern operator has an unsupported type");
1512
1513 // Results don't have a name unless they are the root node. The caller will
1514 // set the name if appropriate.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001515 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001516 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1517 }
1518
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001519 if (Src->isLeaf()) {
1520 Init *SrcInit = Src->getLeafValue();
1521 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
1522 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
1523 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
1524 } else
Daniel Sanders32291982017-06-28 13:50:04 +00001525 return failedImport(
1526 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001527 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00001528 assert(SrcGIOrNull &&
1529 "Expected to have already found an equivalent Instruction");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001530 // Match the used operands (i.e. the children of the operator).
1531 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00001532 TreePatternNode *SrcChild = Src->getChild(i);
1533
1534 // For G_INTRINSIC, the operand immediately following the defs is an
1535 // intrinsic ID.
1536 if (SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" && i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001537 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00001538 OperandMatcher &OM =
1539 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001540 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00001541 continue;
1542 }
1543
1544 return failedImport("Expected IntInit containing instrinsic ID)");
1545 }
1546
1547 if (auto Error =
1548 importChildMatcher(InsnMatcher, SrcChild, OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001549 return std::move(Error);
1550 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001551 }
1552
1553 return InsnMatcher;
1554}
1555
Daniel Sandersc270c502017-03-30 09:36:33 +00001556Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001557 const TreePatternNode *SrcChild,
Daniel Sandersc270c502017-03-30 09:36:33 +00001558 unsigned OpIdx,
1559 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001560 OperandMatcher &OM =
1561 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001562
1563 if (SrcChild->hasAnyPredicate())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001564 return failedImport("Src pattern child has predicate (" +
1565 explainPredicates(SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001566
1567 ArrayRef<EEVT::TypeSet> ChildTypes = SrcChild->getExtTypes();
1568 if (ChildTypes.size() != 1)
1569 return failedImport("Src pattern child has multiple results");
1570
1571 // Check MBB's before the type check since they are not a known type.
1572 if (!SrcChild->isLeaf()) {
1573 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
1574 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
1575 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
1576 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00001577 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001578 }
1579 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001580 }
1581
1582 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1583 if (!OpTyOrNone)
Daniel Sanders85ffd362017-07-06 08:12:20 +00001584 return failedImport("Src operand has an unsupported type (" + to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001585 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1586
Daniel Sandersbee57392017-04-04 13:25:23 +00001587 // Check for nested instructions.
1588 if (!SrcChild->isLeaf()) {
1589 // Map the node to a gMIR instruction.
1590 InstructionOperandMatcher &InsnOperand =
1591 OM.addPredicate<InstructionOperandMatcher>();
1592 auto InsnMatcherOrError =
1593 createAndImportSelDAGMatcher(InsnOperand.getInsnMatcher(), SrcChild);
1594 if (auto Error = InsnMatcherOrError.takeError())
1595 return Error;
1596
1597 return Error::success();
1598 }
1599
Daniel Sandersffc7d582017-03-29 15:37:18 +00001600 // Check for constant immediates.
1601 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001602 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00001603 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001604 }
1605
1606 // Check for def's like register classes or ComplexPattern's.
1607 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
1608 auto *ChildRec = ChildDefInit->getDef();
1609
1610 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001611 if (ChildRec->isSubClassOf("RegisterClass") ||
1612 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001613 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001614 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00001615 return Error::success();
1616 }
1617
Daniel Sandersffc7d582017-03-29 15:37:18 +00001618 // Check for ComplexPattern's.
1619 if (ChildRec->isSubClassOf("ComplexPattern")) {
1620 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1621 if (ComplexPattern == ComplexPatternEquivs.end())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001622 return failedImport("SelectionDAG ComplexPattern (" +
1623 ChildRec->getName() + ") not mapped to GlobalISel");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001624
Daniel Sanders2deea182017-04-22 15:11:04 +00001625 OM.addPredicate<ComplexPatternOperandMatcher>(OM,
1626 *ComplexPattern->second);
1627 TempOpIdx++;
Daniel Sandersc270c502017-03-30 09:36:33 +00001628 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001629 }
1630
Daniel Sandersd0656a32017-04-13 09:45:37 +00001631 if (ChildRec->isSubClassOf("ImmLeaf")) {
1632 return failedImport(
1633 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
1634 }
1635
Daniel Sandersffc7d582017-03-29 15:37:18 +00001636 return failedImport(
1637 "Src pattern child def is an unsupported tablegen class");
1638 }
1639
1640 return failedImport("Src pattern child is an unsupported kind");
1641}
1642
Daniel Sandersc270c502017-03-30 09:36:33 +00001643Error GlobalISelEmitter::importExplicitUseRenderer(
Daniel Sandersffc7d582017-03-29 15:37:18 +00001644 BuildMIAction &DstMIBuilder, TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001645 const InstructionMatcher &InsnMatcher) const {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001646 // The only non-leaf child we accept is 'bb': it's an operator because
1647 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1648 if (!DstChild->isLeaf()) {
1649 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
1650 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
1651 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001652 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
Daniel Sandersffc7d582017-03-29 15:37:18 +00001653 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00001654 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001655 }
1656 }
1657 return failedImport("Dst pattern child isn't a leaf node or an MBB");
1658 }
1659
1660 // Otherwise, we're looking for a bog-standard RegisterClass operand.
1661 if (DstChild->hasAnyPredicate())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001662 return failedImport("Dst pattern child has predicate (" +
1663 explainPredicates(DstChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001664
1665 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
1666 auto *ChildRec = ChildDefInit->getDef();
1667
1668 ArrayRef<EEVT::TypeSet> ChildTypes = DstChild->getExtTypes();
1669 if (ChildTypes.size() != 1)
1670 return failedImport("Dst pattern child has multiple results");
1671
1672 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1673 if (!OpTyOrNone)
1674 return failedImport("Dst operand has an unsupported type");
1675
1676 if (ChildRec->isSubClassOf("Register")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001677 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, ChildRec);
Daniel Sandersc270c502017-03-30 09:36:33 +00001678 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001679 }
1680
Daniel Sanders658541f2017-04-22 15:53:21 +00001681 if (ChildRec->isSubClassOf("RegisterClass") ||
1682 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001683 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
1684 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00001685 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001686 }
1687
1688 if (ChildRec->isSubClassOf("ComplexPattern")) {
1689 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1690 if (ComplexPattern == ComplexPatternEquivs.end())
1691 return failedImport(
1692 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1693
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001694 const OperandMatcher &OM = InsnMatcher.getOperand(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00001695 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001696 0, *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00001697 OM.getAllocatedTemporariesBaseID());
Daniel Sandersc270c502017-03-30 09:36:33 +00001698 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001699 }
1700
Daniel Sandersd0656a32017-04-13 09:45:37 +00001701 if (ChildRec->isSubClassOf("SDNodeXForm"))
1702 return failedImport("Dst pattern child def is an unsupported tablegen "
1703 "class (SDNodeXForm)");
1704
Daniel Sandersffc7d582017-03-29 15:37:18 +00001705 return failedImport(
1706 "Dst pattern child def is an unsupported tablegen class");
1707 }
1708
1709 return failedImport("Dst pattern child is an unsupported kind");
1710}
1711
Daniel Sandersc270c502017-03-30 09:36:33 +00001712Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersffc7d582017-03-29 15:37:18 +00001713 RuleMatcher &M, const TreePatternNode *Dst,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001714 const InstructionMatcher &InsnMatcher) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001715 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00001716 if (!DstOp->isSubClassOf("Instruction")) {
1717 if (DstOp->isSubClassOf("ValueType"))
1718 return failedImport(
1719 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001720 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00001721 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001722 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001723
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001724 unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs;
1725 unsigned ExpectedDstINumUses = Dst->getNumChildren();
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001726 bool IsExtractSubReg = false;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001727
1728 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001729 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001730 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") {
1731 DstI = &Target.getInstruction(RK.getDef("COPY"));
1732 DstINumUses--; // Ignore the class constraint.
1733 ExpectedDstINumUses--;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001734 } else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") {
1735 DstI = &Target.getInstruction(RK.getDef("COPY"));
1736 IsExtractSubReg = true;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001737 }
1738
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001739 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001740
1741 // Render the explicit defs.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001742 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
1743 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001744 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001745 }
1746
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001747 // EXTRACT_SUBREG needs to use a subregister COPY.
1748 if (IsExtractSubReg) {
1749 if (!Dst->getChild(0)->isLeaf())
1750 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
1751
Daniel Sanders32291982017-06-28 13:50:04 +00001752 if (DefInit *SubRegInit =
1753 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001754 CodeGenRegisterClass *RC = CGRegs.getRegClass(
1755 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));
1756 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
1757
1758 const auto &SrcRCDstRCPair =
1759 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
1760 if (SrcRCDstRCPair.hasValue()) {
1761 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
1762 if (SrcRCDstRCPair->first != RC)
1763 return failedImport("EXTRACT_SUBREG requires an additional COPY");
1764 }
1765
1766 DstMIBuilder.addRenderer<CopySubRegRenderer>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001767 0, InsnMatcher, Dst->getChild(0)->getName(), SubIdx);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001768 return DstMIBuilder;
1769 }
1770
1771 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
1772 }
1773
Daniel Sandersffc7d582017-03-29 15:37:18 +00001774 // Render the explicit uses.
Daniel Sanders0ed28822017-04-12 08:23:08 +00001775 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00001776 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001777 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001778 const CGIOperandList::OperandInfo &DstIOperand =
1779 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00001780
Diana Picus382602f2017-05-17 08:57:28 +00001781 // If the operand has default values, introduce them now.
1782 // FIXME: Until we have a decent test case that dictates we should do
1783 // otherwise, we're going to assume that operands with default values cannot
1784 // be specified in the patterns. Therefore, adding them will not cause us to
1785 // end up with too many rendered operands.
1786 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00001787 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00001788 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
1789 return std::move(Error);
1790 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001791 continue;
1792 }
1793
1794 if (auto Error = importExplicitUseRenderer(
1795 DstMIBuilder, Dst->getChild(Child), InsnMatcher))
Daniel Sandersffc7d582017-03-29 15:37:18 +00001796 return std::move(Error);
Daniel Sanders0ed28822017-04-12 08:23:08 +00001797 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001798 }
1799
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001800 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00001801 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00001802 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001803 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00001804 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00001805 " default ones");
1806
Daniel Sandersffc7d582017-03-29 15:37:18 +00001807 return DstMIBuilder;
1808}
1809
Diana Picus382602f2017-05-17 08:57:28 +00001810Error GlobalISelEmitter::importDefaultOperandRenderers(
1811 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00001812 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00001813 // Look through ValueType operators.
1814 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
1815 if (const DefInit *DefaultDagOperator =
1816 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
1817 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
1818 DefaultOp = DefaultDagOp->getArg(0);
1819 }
1820 }
1821
1822 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001823 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00001824 continue;
1825 }
1826
1827 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001828 DstMIBuilder.addRenderer<ImmRenderer>(0, DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00001829 continue;
1830 }
1831
1832 return failedImport("Could not add default op");
1833 }
1834
1835 return Error::success();
1836}
1837
Daniel Sandersc270c502017-03-30 09:36:33 +00001838Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00001839 BuildMIAction &DstMIBuilder,
1840 const std::vector<Record *> &ImplicitDefs) const {
1841 if (!ImplicitDefs.empty())
1842 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00001843 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001844}
1845
1846Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001847 // Keep track of the matchers and actions to emit.
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001848 RuleMatcher M;
1849 M.addAction<DebugCommentAction>(P);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001850
Daniel Sandersc270c502017-03-30 09:36:33 +00001851 if (auto Error = importRulePredicates(M, P.getPredicates()->getValues()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00001852 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001853
1854 // Next, analyze the pattern operators.
1855 TreePatternNode *Src = P.getSrcPattern();
1856 TreePatternNode *Dst = P.getDstPattern();
1857
1858 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00001859 if (auto Err = isTrivialOperatorNode(Dst))
1860 return failedImport("Dst pattern root isn't a trivial operator (" +
1861 toString(std::move(Err)) + ")");
1862 if (auto Err = isTrivialOperatorNode(Src))
1863 return failedImport("Src pattern root isn't a trivial operator (" +
1864 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001865
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001866 if (Dst->isLeaf())
1867 return failedImport("Dst pattern root isn't a known leaf");
1868
Daniel Sandersbee57392017-04-04 13:25:23 +00001869 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001870 Record *DstOp = Dst->getOperator();
1871 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001872 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001873
1874 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001875 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001876 return failedImport("Src pattern results and dst MI defs are different (" +
1877 to_string(Src->getExtTypes().size()) + " def(s) vs " +
1878 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001879
Daniel Sandersffc7d582017-03-29 15:37:18 +00001880 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher();
Daniel Sandersc270c502017-03-30 09:36:33 +00001881 auto InsnMatcherOrError = createAndImportSelDAGMatcher(InsnMatcherTemp, Src);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001882 if (auto Error = InsnMatcherOrError.takeError())
1883 return std::move(Error);
1884 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
1885
1886 // The root of the match also has constraints on the register bank so that it
1887 // matches the result instruction.
1888 unsigned OpIdx = 0;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001889 for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001890 (void)Ty;
1891
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001892 const auto &DstIOperand = DstI.Operands[OpIdx];
1893 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001894 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
1895 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
1896
1897 if (DstIOpRec == nullptr)
1898 return failedImport(
1899 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001900 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
1901 if (!Dst->getChild(0)->isLeaf())
1902 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
1903
Daniel Sanders32291982017-06-28 13:50:04 +00001904 // We can assume that a subregister is in the same bank as it's super
1905 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001906 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
1907
1908 if (DstIOpRec == nullptr)
1909 return failedImport(
1910 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001911 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00001912 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001913 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00001914 return failedImport("Dst MI def isn't a register class" +
1915 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001916
Daniel Sandersffc7d582017-03-29 15:37:18 +00001917 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
1918 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001919 OM.addPredicate<RegisterBankOperandMatcher>(
1920 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001921 ++OpIdx;
1922 }
1923
Daniel Sandersc270c502017-03-30 09:36:33 +00001924 auto DstMIBuilderOrError =
1925 createAndImportInstructionRenderer(M, Dst, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001926 if (auto Error = DstMIBuilderOrError.takeError())
1927 return std::move(Error);
1928 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001929
Daniel Sandersffc7d582017-03-29 15:37:18 +00001930 // Render the implicit defs.
1931 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00001932 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00001933 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001934
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001935 // Constrain the registers to classes. This is normally derived from the
1936 // emitted instruction but a few instructions require special handling.
1937 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
1938 // COPY_TO_REGCLASS does not provide operand constraints itself but the
1939 // result is constrained to the class given by the second child.
1940 Record *DstIOpRec =
1941 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
1942
1943 if (DstIOpRec == nullptr)
1944 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
1945
1946 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001947 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001948
1949 // We're done with this pattern! It's eligible for GISel emission; return
1950 // it.
1951 ++NumPatternImported;
1952 return std::move(M);
1953 }
1954
1955 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
1956 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
1957 // instructions, the result register class is controlled by the
1958 // subregisters of the operand. As a result, we must constrain the result
1959 // class rather than check that it's already the right one.
1960 if (!Dst->getChild(0)->isLeaf())
1961 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
1962
Daniel Sanders320390b2017-06-28 15:16:03 +00001963 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
1964 if (!SubRegInit)
1965 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001966
Daniel Sanders320390b2017-06-28 15:16:03 +00001967 // Constrain the result to the same register bank as the operand.
1968 Record *DstIOpRec =
1969 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001970
Daniel Sanders320390b2017-06-28 15:16:03 +00001971 if (DstIOpRec == nullptr)
1972 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001973
Daniel Sanders320390b2017-06-28 15:16:03 +00001974 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001975 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001976
Daniel Sanders320390b2017-06-28 15:16:03 +00001977 // It would be nice to leave this constraint implicit but we're required
1978 // to pick a register class so constrain the result to a register class
1979 // that can hold the correct MVT.
1980 //
1981 // FIXME: This may introduce an extra copy if the chosen class doesn't
1982 // actually contain the subregisters.
1983 assert(Src->getExtTypes().size() == 1 &&
1984 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001985
Daniel Sanders320390b2017-06-28 15:16:03 +00001986 const auto &SrcRCDstRCPair =
1987 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
1988 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001989 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
1990 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
1991
1992 // We're done with this pattern! It's eligible for GISel emission; return
1993 // it.
1994 ++NumPatternImported;
1995 return std::move(M);
1996 }
1997
1998 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001999
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002000 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002001 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002002 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002003}
2004
2005void GlobalISelEmitter::run(raw_ostream &OS) {
2006 // Track the GINodeEquiv definitions.
2007 gatherNodeEquivs();
2008
2009 emitSourceFileHeader(("Global Instruction Selector for the " +
2010 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002011 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002012 // Look through the SelectionDAG patterns we found, possibly emitting some.
2013 for (const PatternToMatch &Pat : CGP.ptms()) {
2014 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002015 auto MatcherOrErr = runOnPattern(Pat);
2016
2017 // The pattern analysis can fail, indicating an unsupported pattern.
2018 // Report that if we've been asked to do so.
2019 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002020 if (WarnOnSkippedPatterns) {
2021 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002022 "Skipped pattern: " + toString(std::move(Err)));
2023 } else {
2024 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002025 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002026 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002027 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002028 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002029
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002030 Rules.push_back(std::move(MatcherOrErr.get()));
2031 }
2032
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002033 std::stable_sort(Rules.begin(), Rules.end(),
2034 [&](const RuleMatcher &A, const RuleMatcher &B) {
Daniel Sanders759ff412017-02-24 13:58:11 +00002035 if (A.isHigherPriorityThan(B)) {
2036 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
2037 "and less important at "
2038 "the same time");
2039 return true;
2040 }
2041 return false;
2042 });
2043
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002044 std::vector<Record *> ComplexPredicates =
2045 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
2046 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
2047 [](const Record *A, const Record *B) {
2048 if (A->getName() < B->getName())
2049 return true;
2050 return false;
2051 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002052 unsigned MaxTemporaries = 0;
2053 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00002054 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002055
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002056 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
2057 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
2058 << ";\n"
2059 << "using PredicateBitset = "
2060 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
2061 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
2062
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002063 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
2064 << " mutable MatcherState State;\n"
2065 << " typedef "
2066 "ComplexRendererFn("
2067 << Target.getName()
2068 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
2069 << "const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
2070 "MatcherInfo;\n"
2071 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002072
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002073 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
2074 << ", State(" << MaxTemporaries << "),\n"
2075 << "MatcherInfo({TypeObjects, FeatureBitsets, {\n"
2076 << " nullptr, // GICP_Invalid\n";
2077 for (const auto &Record : ComplexPredicates)
2078 OS << " &" << Target.getName()
2079 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
2080 << ", // " << Record->getName() << "\n";
2081 OS << "}})\n"
2082 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002083
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002084 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
2085 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
2086 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002087
2088 // Separate subtarget features by how often they must be recomputed.
2089 SubtargetFeatureInfoMap ModuleFeatures;
2090 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
2091 std::inserter(ModuleFeatures, ModuleFeatures.end()),
2092 [](const SubtargetFeatureInfoMap::value_type &X) {
2093 return !X.second.mustRecomputePerFunction();
2094 });
2095 SubtargetFeatureInfoMap FunctionFeatures;
2096 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
2097 std::inserter(FunctionFeatures, FunctionFeatures.end()),
2098 [](const SubtargetFeatureInfoMap::value_type &X) {
2099 return X.second.mustRecomputePerFunction();
2100 });
2101
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002102 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002103 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
2104 ModuleFeatures, OS);
2105 SubtargetFeatureInfo::emitComputeAvailableFeatures(
2106 Target.getName(), "InstructionSelector",
2107 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
2108 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002109
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002110 // Emit a table containing the LLT objects needed by the matcher and an enum
2111 // for the matcher to reference them with.
2112 std::vector<LLTCodeGen> TypeObjects = {
2113 LLT::scalar(8), LLT::scalar(16), LLT::scalar(32),
2114 LLT::scalar(64), LLT::scalar(80), LLT::vector(8, 1),
2115 LLT::vector(16, 1), LLT::vector(32, 1), LLT::vector(64, 1),
2116 LLT::vector(8, 8), LLT::vector(16, 8), LLT::vector(32, 8),
2117 LLT::vector(64, 8), LLT::vector(4, 16), LLT::vector(8, 16),
2118 LLT::vector(16, 16), LLT::vector(32, 16), LLT::vector(2, 32),
2119 LLT::vector(4, 32), LLT::vector(8, 32), LLT::vector(16, 32),
2120 LLT::vector(2, 64), LLT::vector(4, 64), LLT::vector(8, 64),
2121 };
2122 std::sort(TypeObjects.begin(), TypeObjects.end());
2123 OS << "enum {\n";
2124 for (const auto &TypeObject : TypeObjects) {
2125 OS << " ";
2126 TypeObject.emitCxxEnumValue(OS);
2127 OS << ",\n";
2128 }
2129 OS << "};\n"
2130 << "const static LLT TypeObjects[] = {\n";
2131 for (const auto &TypeObject : TypeObjects) {
2132 OS << " ";
2133 TypeObject.emitCxxConstructorCall(OS);
2134 OS << ",\n";
2135 }
2136 OS << "};\n\n";
2137
2138 // Emit a table containing the PredicateBitsets objects needed by the matcher
2139 // and an enum for the matcher to reference them with.
2140 std::vector<std::vector<Record *>> FeatureBitsets;
2141 for (auto &Rule : Rules)
2142 FeatureBitsets.push_back(Rule.getRequiredFeatures());
2143 std::sort(
2144 FeatureBitsets.begin(), FeatureBitsets.end(),
2145 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
2146 if (A.size() < B.size())
2147 return true;
2148 if (A.size() > B.size())
2149 return false;
2150 for (const auto &Pair : zip(A, B)) {
2151 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
2152 return true;
2153 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
2154 return false;
2155 }
2156 return false;
2157 });
2158 FeatureBitsets.erase(
2159 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
2160 FeatureBitsets.end());
2161 OS << "enum {\n"
2162 << " GIFBS_Invalid,\n";
2163 for (const auto &FeatureBitset : FeatureBitsets) {
2164 if (FeatureBitset.empty())
2165 continue;
2166 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
2167 }
2168 OS << "};\n"
2169 << "const static PredicateBitset FeatureBitsets[] {\n"
2170 << " {}, // GIFBS_Invalid\n";
2171 for (const auto &FeatureBitset : FeatureBitsets) {
2172 if (FeatureBitset.empty())
2173 continue;
2174 OS << " {";
2175 for (const auto &Feature : FeatureBitset) {
2176 const auto &I = SubtargetFeatures.find(Feature);
2177 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
2178 OS << I->second.getEnumBitName() << ", ";
2179 }
2180 OS << "},\n";
2181 }
2182 OS << "};\n\n";
2183
2184 // Emit complex predicate table and an enum to reference them with.
2185 OS << "enum {\n"
2186 << " GICP_Invalid,\n";
2187 for (const auto &Record : ComplexPredicates)
2188 OS << " GICP_" << Record->getName() << ",\n";
2189 OS << "};\n"
2190 << "// See constructor for table contents\n\n";
2191
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002192 OS << "bool " << Target.getName()
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002193 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
2194 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002195 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00002196 << " // FIXME: This should be computed on a per-function basis rather "
2197 "than per-insn.\n"
2198 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
2199 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00002200 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
2201 << " NewMIVector OutMIs;\n"
2202 << " State.MIs.clear();\n"
2203 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002204
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002205 for (auto &Rule : Rules) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002206 Rule.emit(OS);
Daniel Sandersc60abe32017-07-04 15:31:50 +00002207 ++CurrentMatchTableID;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002208 ++NumPatternEmitted;
Daniel Sandersc60abe32017-07-04 15:31:50 +00002209 assert(CurrentMatchTableID == NumPatternEmitted &&
2210 "Statistic deviates from number of emitted tables");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002211 }
2212
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002213 OS << " return false;\n"
2214 << "}\n"
2215 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002216
2217 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
2218 << "PredicateBitset AvailableModuleFeatures;\n"
2219 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
2220 << "PredicateBitset getAvailableFeatures() const {\n"
2221 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
2222 << "}\n"
2223 << "PredicateBitset\n"
2224 << "computeAvailableModuleFeatures(const " << Target.getName()
2225 << "Subtarget *Subtarget) const;\n"
2226 << "PredicateBitset\n"
2227 << "computeAvailableFunctionFeatures(const " << Target.getName()
2228 << "Subtarget *Subtarget,\n"
2229 << " const MachineFunction *MF) const;\n"
2230 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
2231
2232 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
2233 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
2234 << "AvailableFunctionFeatures()\n"
2235 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002236}
2237
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002238void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
2239 if (SubtargetFeatures.count(Predicate) == 0)
2240 SubtargetFeatures.emplace(
2241 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
2242}
2243
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002244} // end anonymous namespace
2245
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002246//===----------------------------------------------------------------------===//
2247
2248namespace llvm {
2249void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
2250 GlobalISelEmitter(RK).run(OS);
2251}
2252} // End llvm namespace