blob: 596cd3cddb99e863a8ab780e1c209efd39c212d0 [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"
34#include "llvm/ADT/Optional.h"
35#include "llvm/ADT/Statistic.h"
36#include "llvm/CodeGen/MachineValueType.h"
37#include "llvm/Support/CommandLine.h"
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +000038#include "llvm/Support/Error.h"
Daniel Sanders52b4ce72017-03-07 23:20:35 +000039#include "llvm/Support/LowLevelTypeImpl.h"
Pavel Labath52a82e22017-02-21 09:19:41 +000040#include "llvm/Support/ScopedPrinter.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000041#include "llvm/TableGen/Error.h"
42#include "llvm/TableGen/Record.h"
43#include "llvm/TableGen/TableGenBackend.h"
44#include <string>
Daniel Sanders8a4bae92017-03-14 21:32:08 +000045#include <numeric>
Ahmed Bougacha36f70352016-12-21 23:26:20 +000046using namespace llvm;
47
48#define DEBUG_TYPE "gisel-emitter"
49
50STATISTIC(NumPatternTotal, "Total number of patterns");
Daniel Sandersb41ce2b2017-02-20 14:31:27 +000051STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
52STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
Ahmed Bougacha36f70352016-12-21 23:26:20 +000053STATISTIC(NumPatternEmitted, "Number of patterns emitted");
54
55static cl::opt<bool> WarnOnSkippedPatterns(
56 "warn-on-skipped-patterns",
57 cl::desc("Explain why a pattern was skipped for inclusion "
58 "in the GlobalISel selector"),
59 cl::init(false));
60
Daniel Sandersbdfebb82017-03-15 20:18:38 +000061namespace {
Ahmed Bougacha36f70352016-12-21 23:26:20 +000062//===- Helper functions ---------------------------------------------------===//
63
Daniel Sanders52b4ce72017-03-07 23:20:35 +000064/// This class stands in for LLT wherever we want to tablegen-erate an
65/// equivalent at compiler run-time.
66class LLTCodeGen {
67private:
68 LLT Ty;
69
70public:
71 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
72
73 void emitCxxConstructorCall(raw_ostream &OS) const {
74 if (Ty.isScalar()) {
75 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
76 return;
77 }
78 if (Ty.isVector()) {
79 OS << "LLT::vector(" << Ty.getNumElements() << ", " << Ty.getSizeInBits()
80 << ")";
81 return;
82 }
83 llvm_unreachable("Unhandled LLT");
84 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +000085
86 const LLT &get() const { return Ty; }
87};
88
89class InstructionMatcher;
90class OperandPlaceholder {
91private:
92 enum PlaceholderKind {
93 OP_MatchReference,
94 OP_Temporary,
95 } Kind;
96
97 struct MatchReferenceData {
98 InstructionMatcher *InsnMatcher;
99 StringRef InsnVarName;
100 StringRef SymbolicName;
101 };
102
103 struct TemporaryData {
104 unsigned OpIdx;
105 };
106
107 union {
108 struct MatchReferenceData MatchReference;
109 struct TemporaryData Temporary;
110 };
111
112 OperandPlaceholder(PlaceholderKind Kind) : Kind(Kind) {}
113
114public:
115 ~OperandPlaceholder() {}
116
117 static OperandPlaceholder
118 CreateMatchReference(InstructionMatcher *InsnMatcher,
119 const StringRef InsnVarName, const StringRef SymbolicName) {
120 OperandPlaceholder Result(OP_MatchReference);
121 Result.MatchReference.InsnMatcher = InsnMatcher;
122 Result.MatchReference.InsnVarName = InsnVarName;
123 Result.MatchReference.SymbolicName = SymbolicName;
124 return Result;
125 }
126
127 static OperandPlaceholder CreateTemporary(unsigned OpIdx) {
128 OperandPlaceholder Result(OP_Temporary);
129 Result.Temporary.OpIdx = OpIdx;
130 return Result;
131 }
132
133 void emitCxxValueExpr(raw_ostream &OS) const;
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000134};
135
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000136/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
137/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000138static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000139 MVT VT(SVT);
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000140 if (VT.isVector() && VT.getVectorNumElements() != 1)
141 return LLTCodeGen(LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
142 if (VT.isInteger() || VT.isFloatingPoint())
143 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
144 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000145}
146
147static bool isTrivialOperatorNode(const TreePatternNode *N) {
148 return !N->isLeaf() && !N->hasAnyPredicate() && !N->getTransformFn();
149}
150
151//===- Matchers -----------------------------------------------------------===//
152
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000153class MatchAction;
154
155/// Generates code to check that a match rule matches.
156class RuleMatcher {
157 /// A list of matchers that all need to succeed for the current rule to match.
158 /// FIXME: This currently supports a single match position but could be
159 /// extended to support multiple positions to support div/rem fusion or
160 /// load-multiple instructions.
161 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
162
163 /// A list of actions that need to be taken when all predicates in this rule
164 /// have succeeded.
165 std::vector<std::unique_ptr<MatchAction>> Actions;
166
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000167 /// A map of instruction matchers to the local variables created by
168 /// emitCxxCaptureStmts().
169 std::map<const InstructionMatcher *, std::string> InsnVariableNames;
170
171 /// ID for the next instruction variable defined with defineInsnVar()
172 unsigned NextInsnVarID;
173
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000174public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000175 RuleMatcher()
176 : Matchers(), Actions(), InsnVariableNames(), NextInsnVarID(0) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000177 RuleMatcher(RuleMatcher &&Other) = default;
178 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000179
180 InstructionMatcher &addInstructionMatcher();
181
182 template <class Kind, class... Args> Kind &addAction(Args &&... args);
183
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000184 std::string defineInsnVar(raw_ostream &OS, const InstructionMatcher &Matcher,
185 StringRef Value);
186 StringRef getInsnVarName(const InstructionMatcher &InsnMatcher) const;
187
188 void emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr);
189
190 void emit(raw_ostream &OS);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000191
192 /// Compare the priority of this object and B.
193 ///
194 /// Returns true if this object is more important than B.
195 bool isHigherPriorityThan(const RuleMatcher &B) const;
196
197 /// Report the maximum number of temporary operands needed by the rule
198 /// matcher.
199 unsigned countTemporaryOperands() const;
200};
201
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000202template <class PredicateTy> class PredicateListMatcher {
203private:
204 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
205 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000206
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000207public:
208 /// Construct a new operand predicate and add it to the matcher.
209 template <class Kind, class... Args>
210 Kind &addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000211 Predicates.emplace_back(
212 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000213 return *static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000214 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000215
216 typename PredicateVec::const_iterator predicates_begin() const { return Predicates.begin(); }
217 typename PredicateVec::const_iterator predicates_end() const { return Predicates.end(); }
218 iterator_range<typename PredicateVec::const_iterator> predicates() const {
219 return make_range(predicates_begin(), predicates_end());
220 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000221 typename PredicateVec::size_type predicates_size() const { return Predicates.size(); }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000222
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000223 /// Emit a C++ expression that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000224 template <class... Args>
Daniel Sandersf8c804f2017-01-28 11:10:42 +0000225 void emitCxxPredicateListExpr(raw_ostream &OS, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000226 if (Predicates.empty()) {
227 OS << "true";
228 return;
229 }
230
231 StringRef Separator = "";
232 for (const auto &Predicate : predicates()) {
233 OS << Separator << "(";
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000234 Predicate->emitCxxPredicateExpr(OS, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000235 OS << ")";
Ahmed Bougacha905af9f2017-02-04 00:47:02 +0000236 Separator = " &&\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000237 }
238 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000239};
240
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000241/// Generates code to check a predicate of an operand.
242///
243/// Typical predicates include:
244/// * Operand is a particular register.
245/// * Operand is assigned a particular register bank.
246/// * Operand is an MBB.
247class OperandPredicateMatcher {
248public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000249 /// This enum is used for RTTI and also defines the priority that is given to
250 /// the predicate when generating the matcher code. Kinds with higher priority
251 /// must be tested first.
252 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000253 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
254 /// but OPM_Int must have priority over OPM_RegBank since constant integers
255 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000256 enum PredicateKind {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000257 OPM_ComplexPattern,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000258 OPM_Int,
Daniel Sanders759ff412017-02-24 13:58:11 +0000259 OPM_LLT,
260 OPM_RegBank,
261 OPM_MBB,
262 };
263
264protected:
265 PredicateKind Kind;
266
267public:
268 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000269 virtual ~OperandPredicateMatcher() {}
270
Daniel Sanders759ff412017-02-24 13:58:11 +0000271 PredicateKind getKind() const { return Kind; }
272
Daniel Sanderse604ef52017-02-20 15:30:43 +0000273 /// Emit a C++ expression that checks the predicate for the given operand.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000274 virtual void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanderse604ef52017-02-20 15:30:43 +0000275 StringRef OperandExpr) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000276
277 /// Compare the priority of this object and B.
278 ///
279 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000280 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const {
281 return Kind < B.Kind;
Daniel Sanders759ff412017-02-24 13:58:11 +0000282 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000283
284 /// Report the maximum number of temporary operands needed by the predicate
285 /// matcher.
286 virtual unsigned countTemporaryOperands() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000287};
288
289/// Generates code to check that an operand is a particular LLT.
290class LLTOperandMatcher : public OperandPredicateMatcher {
291protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000292 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000293
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000294public:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000295 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders759ff412017-02-24 13:58:11 +0000296 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {}
297
298 static bool classof(const OperandPredicateMatcher *P) {
299 return P->getKind() == OPM_LLT;
300 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000301
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000302 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanderse604ef52017-02-20 15:30:43 +0000303 StringRef OperandExpr) const override {
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000304 OS << "MRI.getType(" << OperandExpr << ".getReg()) == (";
305 Ty.emitCxxConstructorCall(OS);
306 OS << ")";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000307 }
308};
309
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000310/// Generates code to check that an operand is a particular target constant.
311class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
312protected:
313 const Record &TheDef;
314 /// The index of the first temporary operand to allocate to this
315 /// ComplexPattern.
316 unsigned BaseTemporaryID;
317
318 unsigned getNumOperands() const {
319 return TheDef.getValueAsDag("Operands")->getNumArgs();
320 }
321
322public:
323 ComplexPatternOperandMatcher(const Record &TheDef, unsigned BaseTemporaryID)
324 : OperandPredicateMatcher(OPM_ComplexPattern), TheDef(TheDef),
325 BaseTemporaryID(BaseTemporaryID) {}
326
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000327 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000328 StringRef OperandExpr) const override {
329 OS << TheDef.getValueAsString("MatcherFn") << "(" << OperandExpr;
330 for (unsigned I = 0; I < getNumOperands(); ++I) {
331 OS << ", ";
332 OperandPlaceholder::CreateTemporary(BaseTemporaryID + I)
333 .emitCxxValueExpr(OS);
334 }
335 OS << ")";
336 }
337
338 unsigned countTemporaryOperands() const override {
339 return getNumOperands();
340 }
341};
342
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000343/// Generates code to check that an operand is in a particular register bank.
344class RegisterBankOperandMatcher : public OperandPredicateMatcher {
345protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000346 const CodeGenRegisterClass &RC;
347
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000348public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000349 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
350 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
351
352 static bool classof(const OperandPredicateMatcher *P) {
353 return P->getKind() == OPM_RegBank;
354 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000355
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000356 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanderse604ef52017-02-20 15:30:43 +0000357 StringRef OperandExpr) const override {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000358 OS << "(&RBI.getRegBankFromRegClass(" << RC.getQualifiedName()
Daniel Sanderse604ef52017-02-20 15:30:43 +0000359 << "RegClass) == RBI.getRegBank(" << OperandExpr
360 << ".getReg(), MRI, TRI))";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000361 }
362};
363
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000364/// Generates code to check that an operand is a basic block.
365class MBBOperandMatcher : public OperandPredicateMatcher {
366public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000367 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
368
369 static bool classof(const OperandPredicateMatcher *P) {
370 return P->getKind() == OPM_MBB;
371 }
372
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000373 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanderse604ef52017-02-20 15:30:43 +0000374 StringRef OperandExpr) const override {
375 OS << OperandExpr << ".isMBB()";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000376 }
377};
378
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000379/// Generates code to check that an operand is a particular int.
380class IntOperandMatcher : public OperandPredicateMatcher {
381protected:
382 int64_t Value;
383
384public:
385 IntOperandMatcher(int64_t Value)
386 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
387
388 static bool classof(const OperandPredicateMatcher *P) {
389 return P->getKind() == OPM_Int;
390 }
391
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000392 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Simon Pilgrimd0302912017-02-24 17:20:27 +0000393 StringRef OperandExpr) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000394 OS << "isOperandImmEqual(" << OperandExpr << ", " << Value << ", MRI)";
395 }
396};
397
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000398/// Generates code to check that a set of predicates match for a particular
399/// operand.
400class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
401protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000402 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000403 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000404 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000405
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000406public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000407 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
408 const std::string &SymbolicName)
409 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000410
411 bool hasSymbolicName() const { return !SymbolicName.empty(); }
412 const StringRef getSymbolicName() const { return SymbolicName; }
413 unsigned getOperandIndex() const { return OpIdx; }
414
415 std::string getOperandExpr(const StringRef InsnVarName) const {
Pavel Labath52a82e22017-02-21 09:19:41 +0000416 return (InsnVarName + ".getOperand(" + llvm::to_string(OpIdx) + ")").str();
Daniel Sanderse604ef52017-02-20 15:30:43 +0000417 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000418
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000419 InstructionMatcher &getInstructionMatcher() const { return Insn; }
420
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000421 /// Emit a C++ expression that tests whether the instruction named in
422 /// InsnVarName matches all the predicate and all the operands.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000423 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
424 const StringRef InsnVarName) const {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000425 OS << "(/* ";
426 if (SymbolicName.empty())
427 OS << "Operand " << OpIdx;
428 else
429 OS << SymbolicName;
430 OS << " */ ";
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000431 emitCxxPredicateListExpr(OS, Rule, getOperandExpr(InsnVarName));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000432 OS << ")";
433 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000434
435 /// Compare the priority of this object and B.
436 ///
437 /// Returns true if this object is more important than B.
438 bool isHigherPriorityThan(const OperandMatcher &B) const {
439 // Operand matchers involving more predicates have higher priority.
440 if (predicates_size() > B.predicates_size())
441 return true;
442 if (predicates_size() < B.predicates_size())
443 return false;
444
445 // This assumes that predicates are added in a consistent order.
446 for (const auto &Predicate : zip(predicates(), B.predicates())) {
447 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
448 return true;
449 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
450 return false;
451 }
452
453 return false;
454 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000455
456 /// Report the maximum number of temporary operands needed by the operand
457 /// matcher.
458 unsigned countTemporaryOperands() const {
459 return std::accumulate(
460 predicates().begin(), predicates().end(), 0,
461 [](unsigned A,
462 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
463 return A + Predicate->countTemporaryOperands();
464 });
465 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000466};
467
468/// Generates code to check a predicate on an instruction.
469///
470/// Typical predicates include:
471/// * The opcode of the instruction is a particular value.
472/// * The nsw/nuw flag is/isn't set.
473class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +0000474protected:
475 /// This enum is used for RTTI and also defines the priority that is given to
476 /// the predicate when generating the matcher code. Kinds with higher priority
477 /// must be tested first.
478 enum PredicateKind {
479 IPM_Opcode,
480 };
481
482 PredicateKind Kind;
483
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000484public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000485 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000486 virtual ~InstructionPredicateMatcher() {}
487
Daniel Sanders759ff412017-02-24 13:58:11 +0000488 PredicateKind getKind() const { return Kind; }
489
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000490 /// Emit a C++ expression that tests whether the instruction named in
491 /// InsnVarName matches the predicate.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000492 virtual void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000493 StringRef InsnVarName) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000494
495 /// Compare the priority of this object and B.
496 ///
497 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000498 virtual bool isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +0000499 return Kind < B.Kind;
500 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000501
502 /// Report the maximum number of temporary operands needed by the predicate
503 /// matcher.
504 virtual unsigned countTemporaryOperands() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000505};
506
507/// Generates code to check the opcode of an instruction.
508class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
509protected:
510 const CodeGenInstruction *I;
511
512public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000513 InstructionOpcodeMatcher(const CodeGenInstruction *I)
514 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000515
Daniel Sanders759ff412017-02-24 13:58:11 +0000516 static bool classof(const InstructionPredicateMatcher *P) {
517 return P->getKind() == IPM_Opcode;
518 }
519
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000520 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000521 StringRef InsnVarName) const override {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000522 OS << InsnVarName << ".getOpcode() == " << I->Namespace
523 << "::" << I->TheDef->getName();
524 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000525
526 /// Compare the priority of this object and B.
527 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000528 /// Returns true if this object is more important than B.
529 bool isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +0000530 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
531 return true;
532 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
533 return false;
534
535 // Prioritize opcodes for cosmetic reasons in the generated source. Although
536 // this is cosmetic at the moment, we may want to drive a similar ordering
537 // using instruction frequency information to improve compile time.
538 if (const InstructionOpcodeMatcher *BO =
539 dyn_cast<InstructionOpcodeMatcher>(&B))
540 return I->TheDef->getName() < BO->I->TheDef->getName();
541
542 return false;
543 };
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000544};
545
546/// Generates code to check that a set of predicates and operands match for a
547/// particular instruction.
548///
549/// Typical predicates include:
550/// * Has a specific opcode.
551/// * Has an nsw/nuw flag or doesn't.
552class InstructionMatcher
553 : public PredicateListMatcher<InstructionPredicateMatcher> {
554protected:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000555 typedef std::vector<OperandMatcher> OperandVec;
556
557 /// The operands to match. All rendered operands must be present even if the
558 /// condition is always true.
559 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000560
561public:
562 /// Add an operand to the matcher.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000563 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000564 Operands.emplace_back(*this, OpIdx, SymbolicName);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000565 return Operands.back();
566 }
567
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000568 Optional<const OperandMatcher *> getOptionalOperand(StringRef SymbolicName) const {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000569 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
570 const auto &I = std::find_if(Operands.begin(), Operands.end(),
571 [&SymbolicName](const OperandMatcher &X) {
572 return X.getSymbolicName() == SymbolicName;
573 });
574 if (I != Operands.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000575 return &*I;
576 return None;
577 }
578
579 const OperandMatcher &getOperand(const StringRef SymbolicName) const {
580 Optional<const OperandMatcher *>OM = getOptionalOperand(SymbolicName);
581 if (OM.hasValue())
582 return *OM.getValue();
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000583 llvm_unreachable("Failed to lookup operand");
584 }
585
586 unsigned getNumOperands() const { return Operands.size(); }
587 OperandVec::const_iterator operands_begin() const {
588 return Operands.begin();
589 }
590 OperandVec::const_iterator operands_end() const {
591 return Operands.end();
592 }
593 iterator_range<OperandVec::const_iterator> operands() const {
594 return make_range(operands_begin(), operands_end());
595 }
596
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000597 /// Emit C++ statements to check the shape of the match and capture
598 /// instructions into local variables.
599 ///
600 /// TODO: When nested instruction matching is implemented, this function will
601 /// descend into the operands and capture variables.
602 void emitCxxCaptureStmts(raw_ostream &OS, RuleMatcher &Rule, StringRef Expr) {
603 OS << "if (" << Expr << ".getNumOperands() < " << getNumOperands() << ")\n"
604 << " return false;\n";
605 }
606
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000607 /// Emit a C++ expression that tests whether the instruction named in
608 /// InsnVarName matches all the predicates and all the operands.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000609 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
610 StringRef InsnVarName) const {
611 emitCxxPredicateListExpr(OS, Rule, InsnVarName);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000612 for (const auto &Operand : Operands) {
Ahmed Bougacha905af9f2017-02-04 00:47:02 +0000613 OS << " &&\n(";
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000614 Operand.emitCxxPredicateExpr(OS, Rule, InsnVarName);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000615 OS << ")";
616 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000617 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000618
619 /// Compare the priority of this object and B.
620 ///
621 /// Returns true if this object is more important than B.
622 bool isHigherPriorityThan(const InstructionMatcher &B) const {
623 // Instruction matchers involving more operands have higher priority.
624 if (Operands.size() > B.Operands.size())
625 return true;
626 if (Operands.size() < B.Operands.size())
627 return false;
628
629 for (const auto &Predicate : zip(predicates(), B.predicates())) {
630 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
631 return true;
632 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
633 return false;
634 }
635
636 for (const auto &Operand : zip(Operands, B.Operands)) {
637 if (std::get<0>(Operand).isHigherPriorityThan(std::get<1>(Operand)))
638 return true;
639 if (std::get<1>(Operand).isHigherPriorityThan(std::get<0>(Operand)))
640 return false;
641 }
642
643 return false;
644 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000645
646 /// Report the maximum number of temporary operands needed by the instruction
647 /// matcher.
648 unsigned countTemporaryOperands() const {
649 return std::accumulate(predicates().begin(), predicates().end(), 0,
650 [](unsigned A,
651 const std::unique_ptr<InstructionPredicateMatcher>
652 &Predicate) {
653 return A + Predicate->countTemporaryOperands();
654 }) +
655 std::accumulate(Operands.begin(), Operands.end(), 0,
656 [](unsigned A, const OperandMatcher &Operand) {
657 return A + Operand.countTemporaryOperands();
658 });
659 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000660};
661
Daniel Sanders43c882c2017-02-01 10:53:10 +0000662//===- Actions ------------------------------------------------------------===//
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000663void OperandPlaceholder::emitCxxValueExpr(raw_ostream &OS) const {
664 switch (Kind) {
665 case OP_MatchReference:
666 OS << MatchReference.InsnMatcher->getOperand(MatchReference.SymbolicName)
667 .getOperandExpr(MatchReference.InsnVarName);
668 break;
669 case OP_Temporary:
670 OS << "TempOp" << Temporary.OpIdx;
671 break;
672 }
673}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000674
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000675class OperandRenderer {
676public:
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000677 enum RendererKind { OR_Copy, OR_Register, OR_ComplexPattern };
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000678
679protected:
680 RendererKind Kind;
681
682public:
683 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
684 virtual ~OperandRenderer() {}
685
686 RendererKind getKind() const { return Kind; }
687
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000688 virtual void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000689};
690
691/// A CopyRenderer emits code to copy a single operand from an existing
692/// instruction to the one being built.
693class CopyRenderer : public OperandRenderer {
694protected:
695 /// The matcher for the instruction that this operand is copied from.
696 /// This provides the facility for looking up an a operand by it's name so
697 /// that it can be used as a source for the instruction being built.
698 const InstructionMatcher &Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000699 /// The name of the operand.
700 const StringRef SymbolicName;
701
702public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000703 CopyRenderer(const InstructionMatcher &Matched, StringRef SymbolicName)
704 : OperandRenderer(OR_Copy), Matched(Matched), SymbolicName(SymbolicName) {
705 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000706
707 static bool classof(const OperandRenderer *R) {
708 return R->getKind() == OR_Copy;
709 }
710
711 const StringRef getSymbolicName() const { return SymbolicName; }
712
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000713 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
714 const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
715 StringRef InsnVarName =
716 Rule.getInsnVarName(Operand.getInstructionMatcher());
717 std::string OperandExpr = Operand.getOperandExpr(InsnVarName);
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000718 OS << " MIB.add(" << OperandExpr << "/*" << SymbolicName << "*/);\n";
719 }
720};
721
722/// Adds a specific physical register to the instruction being built.
723/// This is typically useful for WZR/XZR on AArch64.
724class AddRegisterRenderer : public OperandRenderer {
725protected:
726 const Record *RegisterDef;
727
728public:
729 AddRegisterRenderer(const Record *RegisterDef)
730 : OperandRenderer(OR_Register), RegisterDef(RegisterDef) {}
731
732 static bool classof(const OperandRenderer *R) {
733 return R->getKind() == OR_Register;
734 }
735
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000736 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000737 OS << " MIB.addReg(" << RegisterDef->getValueAsString("Namespace")
738 << "::" << RegisterDef->getName() << ");\n";
739 }
740};
741
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000742class RenderComplexPatternOperand : public OperandRenderer {
743private:
744 const Record &TheDef;
745 std::vector<OperandPlaceholder> Sources;
746
747 unsigned getNumOperands() const {
748 return TheDef.getValueAsDag("Operands")->getNumArgs();
749 }
750
751public:
752 RenderComplexPatternOperand(const Record &TheDef,
753 const ArrayRef<OperandPlaceholder> Sources)
754 : OperandRenderer(OR_ComplexPattern), TheDef(TheDef), Sources(Sources) {}
755
756 static bool classof(const OperandRenderer *R) {
757 return R->getKind() == OR_ComplexPattern;
758 }
759
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000760 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000761 assert(Sources.size() == getNumOperands() && "Inconsistent number of operands");
762 for (const auto &Source : Sources) {
763 OS << "MIB.add(";
764 Source.emitCxxValueExpr(OS);
765 OS << ");\n";
766 }
767 }
768};
769
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +0000770/// An action taken when all Matcher predicates succeeded for a parent rule.
771///
772/// Typical actions include:
773/// * Changing the opcode of an instruction.
774/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +0000775class MatchAction {
776public:
777 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000778
779 /// Emit the C++ statements to implement the action.
780 ///
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000781 /// \param RecycleVarName If given, it's an instruction to recycle. The
782 /// requirements on the instruction vary from action to
783 /// action.
784 virtual void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
785 StringRef RecycleVarName) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +0000786};
787
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000788/// Generates a comment describing the matched rule being acted upon.
789class DebugCommentAction : public MatchAction {
790private:
791 const PatternToMatch &P;
792
793public:
794 DebugCommentAction(const PatternToMatch &P) : P(P) {}
795
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000796 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
797 StringRef RecycleVarName) const override {
798 OS << "// " << *P.getSrcPattern() << " => " << *P.getDstPattern() << "\n";
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000799 }
800};
801
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000802/// Generates code to build an instruction or mutate an existing instruction
803/// into the desired instruction when this is possible.
804class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +0000805private:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000806 const CodeGenInstruction *I;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000807 const InstructionMatcher &Matched;
808 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
809
810 /// True if the instruction can be built solely by mutating the opcode.
811 bool canMutate() const {
812 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +0000813 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000814 if (Matched.getOperand(Copy->getSymbolicName()).getOperandIndex() !=
Zachary Turner309a0882017-03-13 16:24:10 +0000815 Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000816 return false;
817 } else
818 return false;
819 }
820
821 return true;
822 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000823
Daniel Sanders43c882c2017-02-01 10:53:10 +0000824public:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000825 BuildMIAction(const CodeGenInstruction *I, const InstructionMatcher &Matched)
826 : I(I), Matched(Matched) {}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000827
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000828 template <class Kind, class... Args>
829 Kind &addRenderer(Args&&... args) {
830 OperandRenderers.emplace_back(
831 llvm::make_unique<Kind>(std::forward<Args>(args)...));
832 return *static_cast<Kind *>(OperandRenderers.back().get());
833 }
834
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000835 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
836 StringRef RecycleVarName) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000837 if (canMutate()) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000838 OS << RecycleVarName << ".setDesc(TII.get(" << I->Namespace
839 << "::" << I->TheDef->getName() << "));\n";
840 OS << " MachineInstr &NewI = " << RecycleVarName << ";\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000841 return;
842 }
843
844 // TODO: Simple permutation looks like it could be almost as common as
845 // mutation due to commutative operations.
846
847 OS << "MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, "
848 "I.getDebugLoc(), TII.get("
849 << I->Namespace << "::" << I->TheDef->getName() << "));\n";
850 for (const auto &Renderer : OperandRenderers)
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000851 Renderer->emitCxxRenderStmts(OS, Rule);
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000852 OS << " MIB.setMemRefs(I.memoperands_begin(), I.memoperands_end());\n";
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000853 OS << " " << RecycleVarName << ".eraseFromParent();\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000854 OS << " MachineInstr &NewI = *MIB;\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000855 }
856};
857
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000858InstructionMatcher &RuleMatcher::addInstructionMatcher() {
859 Matchers.emplace_back(new InstructionMatcher());
860 return *Matchers.back();
861}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +0000862
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000863template <class Kind, class... Args>
864Kind &RuleMatcher::addAction(Args &&... args) {
865 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
866 return *static_cast<Kind *>(Actions.back().get());
867}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000868
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000869std::string RuleMatcher::defineInsnVar(raw_ostream &OS,
870 const InstructionMatcher &Matcher,
871 StringRef Value) {
872 std::string InsnVarName = "MI" + llvm::to_string(NextInsnVarID++);
873 OS << "MachineInstr &" << InsnVarName << " = " << Value << ";\n";
874 InsnVariableNames[&Matcher] = InsnVarName;
875 return InsnVarName;
876}
877
878StringRef RuleMatcher::getInsnVarName(const InstructionMatcher &InsnMatcher) const {
879 const auto &I = InsnVariableNames.find(&InsnMatcher);
880 if (I != InsnVariableNames.end())
881 return I->second;
882 llvm_unreachable("Matched Insn was not captured in a local variable");
883}
884
885/// Emit C++ statements to check the shape of the match and capture
886/// instructions into local variables.
887void RuleMatcher::emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr) {
888 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
889 std::string InsnVarName = defineInsnVar(OS, *Matchers.front(), Expr);
890 Matchers.front()->emitCxxCaptureStmts(OS, *this, InsnVarName);
891}
892
893void RuleMatcher::emit(raw_ostream &OS) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000894 if (Matchers.empty())
895 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000896
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000897 // The representation supports rules that require multiple roots such as:
898 // %ptr(p0) = ...
899 // %elt0(s32) = G_LOAD %ptr
900 // %1(p0) = G_ADD %ptr, 4
901 // %elt1(s32) = G_LOAD p0 %1
902 // which could be usefully folded into:
903 // %ptr(p0) = ...
904 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
905 // on some targets but we don't need to make use of that yet.
906 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000907 OS << "if ([&]() {\n";
908
909 emitCxxCaptureStmts(OS, "I");
910
911 OS << " if (";
912 Matchers.front()->emitCxxPredicateExpr(OS, *this,
913 getInsnVarName(*Matchers.front()));
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000914 OS << ") {\n";
915
916 for (const auto &MA : Actions) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000917 MA->emitCxxActionStmts(OS, *this, "I");
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000918 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000919
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000920 OS << " constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);\n";
921 OS << " return true;\n";
922 OS << " }\n";
923 OS << " return false;\n";
924 OS << " }()) { return true; }\n\n";
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000925}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000926
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000927bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
928 // Rules involving more match roots have higher priority.
929 if (Matchers.size() > B.Matchers.size())
930 return true;
931 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +0000932 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000933
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000934 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
935 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
936 return true;
937 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
938 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000939 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000940
941 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +0000942}
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000943
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000944unsigned RuleMatcher::countTemporaryOperands() const {
945 return std::accumulate(
946 Matchers.begin(), Matchers.end(), 0,
947 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
948 return A + Matcher->countTemporaryOperands();
949 });
950}
951
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000952//===- GlobalISelEmitter class --------------------------------------------===//
953
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000954class GlobalISelEmitter {
955public:
956 explicit GlobalISelEmitter(RecordKeeper &RK);
957 void run(raw_ostream &OS);
958
959private:
960 const RecordKeeper &RK;
961 const CodeGenDAGPatterns CGP;
962 const CodeGenTarget &Target;
963
964 /// Keep track of the equivalence between SDNodes and Instruction.
965 /// This is defined using 'GINodeEquiv' in the target description.
966 DenseMap<Record *, const CodeGenInstruction *> NodeEquivs;
967
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000968 /// Keep track of the equivalence between ComplexPattern's and
969 /// GIComplexOperandMatcher. Map entries are specified by subclassing
970 /// GIComplexPatternEquiv.
971 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
972
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000973 void gatherNodeEquivs();
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000974 const CodeGenInstruction *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000975
976 /// Analyze pattern \p P, returning a matcher for it if possible.
977 /// Otherwise, return an Error explaining why we don't support it.
978 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
979};
980
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000981void GlobalISelEmitter::gatherNodeEquivs() {
982 assert(NodeEquivs.empty());
983 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
984 NodeEquivs[Equiv->getValueAsDef("Node")] =
985 &Target.getInstruction(Equiv->getValueAsDef("I"));
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000986
987 assert(ComplexPatternEquivs.empty());
988 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
989 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
990 if (!SelDAGEquiv)
991 continue;
992 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
993 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000994}
995
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000996const CodeGenInstruction *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000997 return NodeEquivs.lookup(N);
998}
999
1000GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
1001 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()) {}
1002
1003//===- Emitter ------------------------------------------------------------===//
1004
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001005/// Helper function to let the emitter report skip reason error messages.
1006static Error failedImport(const Twine &Reason) {
1007 return make_error<StringError>(Reason, inconvertibleErrorCode());
1008}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001009
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001010Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001011 unsigned TempOpIdx = 0;
1012
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001013 // Keep track of the matchers and actions to emit.
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001014 RuleMatcher M;
1015 M.addAction<DebugCommentAction>(P);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001016
1017 // First, analyze the whole pattern.
1018 // If the entire pattern has a predicate (e.g., target features), ignore it.
1019 if (!P.getPredicates()->getValues().empty())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001020 return failedImport("Pattern has a predicate");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001021
1022 // Physreg imp-defs require additional logic. Ignore the pattern.
1023 if (!P.getDstRegs().empty())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001024 return failedImport("Pattern defines a physical register");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001025
1026 // Next, analyze the pattern operators.
1027 TreePatternNode *Src = P.getSrcPattern();
1028 TreePatternNode *Dst = P.getDstPattern();
1029
1030 // If the root of either pattern isn't a simple operator, ignore it.
1031 if (!isTrivialOperatorNode(Dst))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001032 return failedImport("Dst pattern root isn't a trivial operator");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001033 if (!isTrivialOperatorNode(Src))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001034 return failedImport("Src pattern root isn't a trivial operator");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001035
1036 Record *DstOp = Dst->getOperator();
1037 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001038 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001039
1040 auto &DstI = Target.getInstruction(DstOp);
1041
1042 auto SrcGIOrNull = findNodeEquiv(Src->getOperator());
1043 if (!SrcGIOrNull)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001044 return failedImport("Pattern operator lacks an equivalent Instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001045 auto &SrcGI = *SrcGIOrNull;
1046
1047 // The operators look good: match the opcode and mutate it to the new one.
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001048 InstructionMatcher &InsnMatcher = M.addInstructionMatcher();
1049 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001050 auto &DstMIBuilder = M.addAction<BuildMIAction>(&DstI, InsnMatcher);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001051
1052 // Next, analyze the children, only accepting patterns that don't require
1053 // any change to operands.
1054 if (Src->getNumChildren() != Dst->getNumChildren())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001055 return failedImport("Src/dst patterns have a different # of children");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001056
1057 unsigned OpIdx = 0;
1058
1059 // Start with the defined operands (i.e., the results of the root operator).
1060 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001061 return failedImport("Src pattern results and dst MI defs are different");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001062
1063 for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001064 const auto &DstIOperand = DstI.Operands[OpIdx];
1065 Record *DstIOpRec = DstIOperand.Rec;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001066 if (!DstIOpRec->isSubClassOf("RegisterClass"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001067 return failedImport("Dst MI def isn't a register class");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001068
1069 auto OpTyOrNone = MVTToLLT(Ty.getConcrete());
1070 if (!OpTyOrNone)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001071 return failedImport("Dst operand has an unsupported type");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001072
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001073 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx, DstIOperand.Name);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001074 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1075 OM.addPredicate<RegisterBankOperandMatcher>(
1076 Target.getRegisterClass(DstIOpRec));
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001077 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, DstIOperand.Name);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001078 ++OpIdx;
1079 }
1080
1081 // Finally match the used operands (i.e., the children of the root operator).
1082 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
1083 auto *SrcChild = Src->getChild(i);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001084
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001085 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, SrcChild->getName());
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001086
1087 // The only non-leaf child we accept is 'bb': it's an operator because
1088 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1089 if (!SrcChild->isLeaf()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001090 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
1091 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
1092 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001093 OM.addPredicate<MBBOperandMatcher>();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001094 continue;
1095 }
1096 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001097 return failedImport("Src pattern child isn't a leaf node or an MBB");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001098 }
1099
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001100 if (SrcChild->hasAnyPredicate())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001101 return failedImport("Src pattern child has predicate");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001102
1103 ArrayRef<EEVT::TypeSet> ChildTypes = SrcChild->getExtTypes();
1104 if (ChildTypes.size() != 1)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001105 return failedImport("Src pattern child has multiple results");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001106
1107 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1108 if (!OpTyOrNone)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001109 return failedImport("Src operand has an unsupported type");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001110 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001111
1112 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
1113 OM.addPredicate<IntOperandMatcher>(ChildInt->getValue());
1114 continue;
1115 }
1116
1117 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
1118 auto *ChildRec = ChildDefInit->getDef();
1119
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001120 if (ChildRec->isSubClassOf("RegisterClass")) {
1121 OM.addPredicate<RegisterBankOperandMatcher>(
1122 Target.getRegisterClass(ChildRec));
1123 continue;
1124 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001125
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001126 if (ChildRec->isSubClassOf("ComplexPattern")) {
1127 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1128 if (ComplexPattern == ComplexPatternEquivs.end())
1129 return failedImport(
1130 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1131
1132 const auto &Predicate = OM.addPredicate<ComplexPatternOperandMatcher>(
1133 *ComplexPattern->second, TempOpIdx);
1134 TempOpIdx += Predicate.countTemporaryOperands();
1135 continue;
1136 }
1137
1138 return failedImport(
1139 "Src pattern child def is an unsupported tablegen class");
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001140 }
1141
1142 return failedImport("Src pattern child is an unsupported kind");
1143 }
1144
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001145 TempOpIdx = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001146 // Finally render the used operands (i.e., the children of the root operator).
1147 for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
1148 auto *DstChild = Dst->getChild(i);
1149
1150 // The only non-leaf child we accept is 'bb': it's an operator because
1151 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1152 if (!DstChild->isLeaf()) {
1153 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
1154 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
1155 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001156 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher,
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001157 DstChild->getName());
1158 continue;
1159 }
1160 }
1161 return failedImport("Dst pattern child isn't a leaf node or an MBB");
1162 }
1163
1164 // Otherwise, we're looking for a bog-standard RegisterClass operand.
1165 if (DstChild->hasAnyPredicate())
1166 return failedImport("Dst pattern child has predicate");
1167
1168 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
1169 auto *ChildRec = ChildDefInit->getDef();
1170
1171 ArrayRef<EEVT::TypeSet> ChildTypes = DstChild->getExtTypes();
1172 if (ChildTypes.size() != 1)
1173 return failedImport("Dst pattern child has multiple results");
1174
1175 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1176 if (!OpTyOrNone)
1177 return failedImport("Dst operand has an unsupported type");
1178
1179 if (ChildRec->isSubClassOf("Register")) {
1180 DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
1181 continue;
1182 }
1183
1184 if (ChildRec->isSubClassOf("RegisterClass")) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001185 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher,
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001186 DstChild->getName());
1187 continue;
1188 }
1189
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001190 if (ChildRec->isSubClassOf("ComplexPattern")) {
1191 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1192 if (ComplexPattern == ComplexPatternEquivs.end())
1193 return failedImport(
1194 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1195
1196 SmallVector<OperandPlaceholder, 2> RenderedOperands;
1197 for (unsigned I = 0; I < InsnMatcher.getOperand(DstChild->getName())
1198 .countTemporaryOperands();
1199 ++I) {
1200 RenderedOperands.push_back(OperandPlaceholder::CreateTemporary(I));
1201 TempOpIdx++;
1202 }
1203 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
1204 *ComplexPattern->second,
1205 RenderedOperands);
1206 continue;
1207 }
1208
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001209 return failedImport(
1210 "Dst pattern child def is an unsupported tablegen class");
1211 }
1212
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001213 return failedImport("Dst pattern child is an unsupported kind");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001214 }
1215
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001216 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001217 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001218 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001219}
1220
1221void GlobalISelEmitter::run(raw_ostream &OS) {
1222 // Track the GINodeEquiv definitions.
1223 gatherNodeEquivs();
1224
1225 emitSourceFileHeader(("Global Instruction Selector for the " +
1226 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001227 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001228 // Look through the SelectionDAG patterns we found, possibly emitting some.
1229 for (const PatternToMatch &Pat : CGP.ptms()) {
1230 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001231 auto MatcherOrErr = runOnPattern(Pat);
1232
1233 // The pattern analysis can fail, indicating an unsupported pattern.
1234 // Report that if we've been asked to do so.
1235 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001236 if (WarnOnSkippedPatterns) {
1237 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001238 "Skipped pattern: " + toString(std::move(Err)));
1239 } else {
1240 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001241 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001242 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001243 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001244 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001245
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001246 Rules.push_back(std::move(MatcherOrErr.get()));
1247 }
1248
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001249 std::stable_sort(Rules.begin(), Rules.end(),
1250 [&](const RuleMatcher &A, const RuleMatcher &B) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001251 if (A.isHigherPriorityThan(B)) {
1252 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
1253 "and less important at "
1254 "the same time");
1255 return true;
1256 }
1257 return false;
1258 });
1259
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001260 unsigned MaxTemporaries = 0;
1261 for (const auto &Rule : Rules)
1262 MaxTemporaries = std::max(MaxTemporaries, Rule.countTemporaryOperands());
1263
1264 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n";
1265 for (unsigned I = 0; I < MaxTemporaries; ++I)
1266 OS << " mutable MachineOperand TempOp" << I << ";\n";
1267 OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
1268
1269 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n";
1270 for (unsigned I = 0; I < MaxTemporaries; ++I)
1271 OS << ", TempOp" << I << "(MachineOperand::CreatePlaceholder())\n";
1272 OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
1273
1274 OS << "#ifdef GET_GLOBALISEL_IMPL\n"
1275 << "bool " << Target.getName()
1276 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
1277 << " MachineFunction &MF = *I.getParent()->getParent();\n"
1278 << " const MachineRegisterInfo &MRI = MF.getRegInfo();\n";
1279
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001280 for (auto &Rule : Rules) {
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001281 Rule.emit(OS);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001282 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001283 }
1284
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001285 OS << " return false;\n"
1286 << "}\n"
1287 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001288}
1289
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001290} // end anonymous namespace
1291
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001292//===----------------------------------------------------------------------===//
1293
1294namespace llvm {
1295void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
1296 GlobalISelEmitter(RK).run(OS);
1297}
1298} // End llvm namespace