blob: 193bad3e14c4d2c831f101b6d0b233d4b56db741 [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
167public:
168 RuleMatcher() {}
169
170 InstructionMatcher &addInstructionMatcher();
171
172 template <class Kind, class... Args> Kind &addAction(Args &&... args);
173
174 void emit(raw_ostream &OS) const;
175
176 /// Compare the priority of this object and B.
177 ///
178 /// Returns true if this object is more important than B.
179 bool isHigherPriorityThan(const RuleMatcher &B) const;
180
181 /// Report the maximum number of temporary operands needed by the rule
182 /// matcher.
183 unsigned countTemporaryOperands() const;
184};
185
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000186template <class PredicateTy> class PredicateListMatcher {
187private:
188 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
189 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000190
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000191public:
192 /// Construct a new operand predicate and add it to the matcher.
193 template <class Kind, class... Args>
194 Kind &addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000195 Predicates.emplace_back(
196 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000197 return *static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000198 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000199
200 typename PredicateVec::const_iterator predicates_begin() const { return Predicates.begin(); }
201 typename PredicateVec::const_iterator predicates_end() const { return Predicates.end(); }
202 iterator_range<typename PredicateVec::const_iterator> predicates() const {
203 return make_range(predicates_begin(), predicates_end());
204 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000205 typename PredicateVec::size_type predicates_size() const { return Predicates.size(); }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000206
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000207 /// Emit a C++ expression that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000208 template <class... Args>
Daniel Sandersf8c804f2017-01-28 11:10:42 +0000209 void emitCxxPredicateListExpr(raw_ostream &OS, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000210 if (Predicates.empty()) {
211 OS << "true";
212 return;
213 }
214
215 StringRef Separator = "";
216 for (const auto &Predicate : predicates()) {
217 OS << Separator << "(";
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000218 Predicate->emitCxxPredicateExpr(OS, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000219 OS << ")";
Ahmed Bougacha905af9f2017-02-04 00:47:02 +0000220 Separator = " &&\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000221 }
222 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000223};
224
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000225/// Generates code to check a predicate of an operand.
226///
227/// Typical predicates include:
228/// * Operand is a particular register.
229/// * Operand is assigned a particular register bank.
230/// * Operand is an MBB.
231class OperandPredicateMatcher {
232public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000233 /// This enum is used for RTTI and also defines the priority that is given to
234 /// the predicate when generating the matcher code. Kinds with higher priority
235 /// must be tested first.
236 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000237 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
238 /// but OPM_Int must have priority over OPM_RegBank since constant integers
239 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000240 enum PredicateKind {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000241 OPM_ComplexPattern,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000242 OPM_Int,
Daniel Sanders759ff412017-02-24 13:58:11 +0000243 OPM_LLT,
244 OPM_RegBank,
245 OPM_MBB,
246 };
247
248protected:
249 PredicateKind Kind;
250
251public:
252 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000253 virtual ~OperandPredicateMatcher() {}
254
Daniel Sanders759ff412017-02-24 13:58:11 +0000255 PredicateKind getKind() const { return Kind; }
256
Daniel Sanderse604ef52017-02-20 15:30:43 +0000257 /// Emit a C++ expression that checks the predicate for the given operand.
258 virtual void emitCxxPredicateExpr(raw_ostream &OS,
259 StringRef OperandExpr) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000260
261 /// Compare the priority of this object and B.
262 ///
263 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000264 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const {
265 return Kind < B.Kind;
Daniel Sanders759ff412017-02-24 13:58:11 +0000266 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000267
268 /// Report the maximum number of temporary operands needed by the predicate
269 /// matcher.
270 virtual unsigned countTemporaryOperands() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000271};
272
273/// Generates code to check that an operand is a particular LLT.
274class LLTOperandMatcher : public OperandPredicateMatcher {
275protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000276 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000277
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000278public:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000279 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders759ff412017-02-24 13:58:11 +0000280 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {}
281
282 static bool classof(const OperandPredicateMatcher *P) {
283 return P->getKind() == OPM_LLT;
284 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000285
Daniel Sanderse604ef52017-02-20 15:30:43 +0000286 void emitCxxPredicateExpr(raw_ostream &OS,
287 StringRef OperandExpr) const override {
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000288 OS << "MRI.getType(" << OperandExpr << ".getReg()) == (";
289 Ty.emitCxxConstructorCall(OS);
290 OS << ")";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000291 }
292};
293
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000294/// Generates code to check that an operand is a particular target constant.
295class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
296protected:
297 const Record &TheDef;
298 /// The index of the first temporary operand to allocate to this
299 /// ComplexPattern.
300 unsigned BaseTemporaryID;
301
302 unsigned getNumOperands() const {
303 return TheDef.getValueAsDag("Operands")->getNumArgs();
304 }
305
306public:
307 ComplexPatternOperandMatcher(const Record &TheDef, unsigned BaseTemporaryID)
308 : OperandPredicateMatcher(OPM_ComplexPattern), TheDef(TheDef),
309 BaseTemporaryID(BaseTemporaryID) {}
310
311 void emitCxxPredicateExpr(raw_ostream &OS,
312 StringRef OperandExpr) const override {
313 OS << TheDef.getValueAsString("MatcherFn") << "(" << OperandExpr;
314 for (unsigned I = 0; I < getNumOperands(); ++I) {
315 OS << ", ";
316 OperandPlaceholder::CreateTemporary(BaseTemporaryID + I)
317 .emitCxxValueExpr(OS);
318 }
319 OS << ")";
320 }
321
322 unsigned countTemporaryOperands() const override {
323 return getNumOperands();
324 }
325};
326
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000327/// Generates code to check that an operand is in a particular register bank.
328class RegisterBankOperandMatcher : public OperandPredicateMatcher {
329protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000330 const CodeGenRegisterClass &RC;
331
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000332public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000333 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
334 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
335
336 static bool classof(const OperandPredicateMatcher *P) {
337 return P->getKind() == OPM_RegBank;
338 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000339
Daniel Sanderse604ef52017-02-20 15:30:43 +0000340 void emitCxxPredicateExpr(raw_ostream &OS,
341 StringRef OperandExpr) const override {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000342 OS << "(&RBI.getRegBankFromRegClass(" << RC.getQualifiedName()
Daniel Sanderse604ef52017-02-20 15:30:43 +0000343 << "RegClass) == RBI.getRegBank(" << OperandExpr
344 << ".getReg(), MRI, TRI))";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000345 }
346};
347
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000348/// Generates code to check that an operand is a basic block.
349class MBBOperandMatcher : public OperandPredicateMatcher {
350public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000351 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
352
353 static bool classof(const OperandPredicateMatcher *P) {
354 return P->getKind() == OPM_MBB;
355 }
356
Daniel Sanderse604ef52017-02-20 15:30:43 +0000357 void emitCxxPredicateExpr(raw_ostream &OS,
358 StringRef OperandExpr) const override {
359 OS << OperandExpr << ".isMBB()";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000360 }
361};
362
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000363/// Generates code to check that an operand is a particular int.
364class IntOperandMatcher : public OperandPredicateMatcher {
365protected:
366 int64_t Value;
367
368public:
369 IntOperandMatcher(int64_t Value)
370 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
371
372 static bool classof(const OperandPredicateMatcher *P) {
373 return P->getKind() == OPM_Int;
374 }
375
376 void emitCxxPredicateExpr(raw_ostream &OS,
Simon Pilgrimd0302912017-02-24 17:20:27 +0000377 StringRef OperandExpr) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000378 OS << "isOperandImmEqual(" << OperandExpr << ", " << Value << ", MRI)";
379 }
380};
381
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000382/// Generates code to check that a set of predicates match for a particular
383/// operand.
384class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
385protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000386 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000387 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000388
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000389public:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000390 OperandMatcher(unsigned OpIdx, const std::string &SymbolicName)
391 : OpIdx(OpIdx), SymbolicName(SymbolicName) {}
392
393 bool hasSymbolicName() const { return !SymbolicName.empty(); }
394 const StringRef getSymbolicName() const { return SymbolicName; }
395 unsigned getOperandIndex() const { return OpIdx; }
396
397 std::string getOperandExpr(const StringRef InsnVarName) const {
Pavel Labath52a82e22017-02-21 09:19:41 +0000398 return (InsnVarName + ".getOperand(" + llvm::to_string(OpIdx) + ")").str();
Daniel Sanderse604ef52017-02-20 15:30:43 +0000399 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000400
401 /// Emit a C++ expression that tests whether the instruction named in
402 /// InsnVarName matches all the predicate and all the operands.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000403 void emitCxxPredicateExpr(raw_ostream &OS, const StringRef InsnVarName) const {
404 OS << "(/* ";
405 if (SymbolicName.empty())
406 OS << "Operand " << OpIdx;
407 else
408 OS << SymbolicName;
409 OS << " */ ";
Daniel Sanderse604ef52017-02-20 15:30:43 +0000410 emitCxxPredicateListExpr(OS, getOperandExpr(InsnVarName));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000411 OS << ")";
412 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000413
414 /// Compare the priority of this object and B.
415 ///
416 /// Returns true if this object is more important than B.
417 bool isHigherPriorityThan(const OperandMatcher &B) const {
418 // Operand matchers involving more predicates have higher priority.
419 if (predicates_size() > B.predicates_size())
420 return true;
421 if (predicates_size() < B.predicates_size())
422 return false;
423
424 // This assumes that predicates are added in a consistent order.
425 for (const auto &Predicate : zip(predicates(), B.predicates())) {
426 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
427 return true;
428 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
429 return false;
430 }
431
432 return false;
433 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000434
435 /// Report the maximum number of temporary operands needed by the operand
436 /// matcher.
437 unsigned countTemporaryOperands() const {
438 return std::accumulate(
439 predicates().begin(), predicates().end(), 0,
440 [](unsigned A,
441 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
442 return A + Predicate->countTemporaryOperands();
443 });
444 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000445};
446
447/// Generates code to check a predicate on an instruction.
448///
449/// Typical predicates include:
450/// * The opcode of the instruction is a particular value.
451/// * The nsw/nuw flag is/isn't set.
452class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +0000453protected:
454 /// This enum is used for RTTI and also defines the priority that is given to
455 /// the predicate when generating the matcher code. Kinds with higher priority
456 /// must be tested first.
457 enum PredicateKind {
458 IPM_Opcode,
459 };
460
461 PredicateKind Kind;
462
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000463public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000464 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000465 virtual ~InstructionPredicateMatcher() {}
466
Daniel Sanders759ff412017-02-24 13:58:11 +0000467 PredicateKind getKind() const { return Kind; }
468
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000469 /// Emit a C++ expression that tests whether the instruction named in
470 /// InsnVarName matches the predicate.
471 virtual void emitCxxPredicateExpr(raw_ostream &OS,
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000472 StringRef InsnVarName) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000473
474 /// Compare the priority of this object and B.
475 ///
476 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000477 virtual bool isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +0000478 return Kind < B.Kind;
479 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000480
481 /// Report the maximum number of temporary operands needed by the predicate
482 /// matcher.
483 virtual unsigned countTemporaryOperands() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000484};
485
486/// Generates code to check the opcode of an instruction.
487class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
488protected:
489 const CodeGenInstruction *I;
490
491public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000492 InstructionOpcodeMatcher(const CodeGenInstruction *I)
493 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000494
Daniel Sanders759ff412017-02-24 13:58:11 +0000495 static bool classof(const InstructionPredicateMatcher *P) {
496 return P->getKind() == IPM_Opcode;
497 }
498
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000499 void emitCxxPredicateExpr(raw_ostream &OS,
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000500 StringRef InsnVarName) const override {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000501 OS << InsnVarName << ".getOpcode() == " << I->Namespace
502 << "::" << I->TheDef->getName();
503 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000504
505 /// Compare the priority of this object and B.
506 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000507 /// Returns true if this object is more important than B.
508 bool isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +0000509 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
510 return true;
511 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
512 return false;
513
514 // Prioritize opcodes for cosmetic reasons in the generated source. Although
515 // this is cosmetic at the moment, we may want to drive a similar ordering
516 // using instruction frequency information to improve compile time.
517 if (const InstructionOpcodeMatcher *BO =
518 dyn_cast<InstructionOpcodeMatcher>(&B))
519 return I->TheDef->getName() < BO->I->TheDef->getName();
520
521 return false;
522 };
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000523};
524
525/// Generates code to check that a set of predicates and operands match for a
526/// particular instruction.
527///
528/// Typical predicates include:
529/// * Has a specific opcode.
530/// * Has an nsw/nuw flag or doesn't.
531class InstructionMatcher
532 : public PredicateListMatcher<InstructionPredicateMatcher> {
533protected:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000534 typedef std::vector<OperandMatcher> OperandVec;
535
536 /// The operands to match. All rendered operands must be present even if the
537 /// condition is always true.
538 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000539
540public:
541 /// Add an operand to the matcher.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000542 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName) {
543 Operands.emplace_back(OpIdx, SymbolicName);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000544 return Operands.back();
545 }
546
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000547 const OperandMatcher &getOperand(const StringRef SymbolicName) const {
548 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
549 const auto &I = std::find_if(Operands.begin(), Operands.end(),
550 [&SymbolicName](const OperandMatcher &X) {
551 return X.getSymbolicName() == SymbolicName;
552 });
553 if (I != Operands.end())
554 return *I;
555 llvm_unreachable("Failed to lookup operand");
556 }
557
558 unsigned getNumOperands() const { return Operands.size(); }
559 OperandVec::const_iterator operands_begin() const {
560 return Operands.begin();
561 }
562 OperandVec::const_iterator operands_end() const {
563 return Operands.end();
564 }
565 iterator_range<OperandVec::const_iterator> operands() const {
566 return make_range(operands_begin(), operands_end());
567 }
568
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000569 /// Emit a C++ expression that tests whether the instruction named in
570 /// InsnVarName matches all the predicates and all the operands.
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000571 void emitCxxPredicateExpr(raw_ostream &OS, StringRef InsnVarName) const {
Daniel Sandersf8c804f2017-01-28 11:10:42 +0000572 emitCxxPredicateListExpr(OS, InsnVarName);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000573 for (const auto &Operand : Operands) {
Ahmed Bougacha905af9f2017-02-04 00:47:02 +0000574 OS << " &&\n(";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000575 Operand.emitCxxPredicateExpr(OS, InsnVarName);
576 OS << ")";
577 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000578 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000579
580 /// Compare the priority of this object and B.
581 ///
582 /// Returns true if this object is more important than B.
583 bool isHigherPriorityThan(const InstructionMatcher &B) const {
584 // Instruction matchers involving more operands have higher priority.
585 if (Operands.size() > B.Operands.size())
586 return true;
587 if (Operands.size() < B.Operands.size())
588 return false;
589
590 for (const auto &Predicate : zip(predicates(), B.predicates())) {
591 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
592 return true;
593 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
594 return false;
595 }
596
597 for (const auto &Operand : zip(Operands, B.Operands)) {
598 if (std::get<0>(Operand).isHigherPriorityThan(std::get<1>(Operand)))
599 return true;
600 if (std::get<1>(Operand).isHigherPriorityThan(std::get<0>(Operand)))
601 return false;
602 }
603
604 return false;
605 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000606
607 /// Report the maximum number of temporary operands needed by the instruction
608 /// matcher.
609 unsigned countTemporaryOperands() const {
610 return std::accumulate(predicates().begin(), predicates().end(), 0,
611 [](unsigned A,
612 const std::unique_ptr<InstructionPredicateMatcher>
613 &Predicate) {
614 return A + Predicate->countTemporaryOperands();
615 }) +
616 std::accumulate(Operands.begin(), Operands.end(), 0,
617 [](unsigned A, const OperandMatcher &Operand) {
618 return A + Operand.countTemporaryOperands();
619 });
620 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000621};
622
Daniel Sanders43c882c2017-02-01 10:53:10 +0000623//===- Actions ------------------------------------------------------------===//
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000624void OperandPlaceholder::emitCxxValueExpr(raw_ostream &OS) const {
625 switch (Kind) {
626 case OP_MatchReference:
627 OS << MatchReference.InsnMatcher->getOperand(MatchReference.SymbolicName)
628 .getOperandExpr(MatchReference.InsnVarName);
629 break;
630 case OP_Temporary:
631 OS << "TempOp" << Temporary.OpIdx;
632 break;
633 }
634}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000635
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000636class OperandRenderer {
637public:
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000638 enum RendererKind { OR_Copy, OR_Register, OR_ComplexPattern };
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000639
640protected:
641 RendererKind Kind;
642
643public:
644 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
645 virtual ~OperandRenderer() {}
646
647 RendererKind getKind() const { return Kind; }
648
649 virtual void emitCxxRenderStmts(raw_ostream &OS) const = 0;
650};
651
652/// A CopyRenderer emits code to copy a single operand from an existing
653/// instruction to the one being built.
654class CopyRenderer : public OperandRenderer {
655protected:
656 /// The matcher for the instruction that this operand is copied from.
657 /// This provides the facility for looking up an a operand by it's name so
658 /// that it can be used as a source for the instruction being built.
659 const InstructionMatcher &Matched;
660 /// The name of the instruction to copy from.
661 const StringRef InsnVarName;
662 /// The name of the operand.
663 const StringRef SymbolicName;
664
665public:
666 CopyRenderer(const InstructionMatcher &Matched, const StringRef InsnVarName,
667 const StringRef SymbolicName)
668 : OperandRenderer(OR_Copy), Matched(Matched), InsnVarName(InsnVarName),
669 SymbolicName(SymbolicName) {}
670
671 static bool classof(const OperandRenderer *R) {
672 return R->getKind() == OR_Copy;
673 }
674
675 const StringRef getSymbolicName() const { return SymbolicName; }
676
677 void emitCxxRenderStmts(raw_ostream &OS) const override {
678 std::string OperandExpr =
679 Matched.getOperand(SymbolicName).getOperandExpr(InsnVarName);
680 OS << " MIB.add(" << OperandExpr << "/*" << SymbolicName << "*/);\n";
681 }
682};
683
684/// Adds a specific physical register to the instruction being built.
685/// This is typically useful for WZR/XZR on AArch64.
686class AddRegisterRenderer : public OperandRenderer {
687protected:
688 const Record *RegisterDef;
689
690public:
691 AddRegisterRenderer(const Record *RegisterDef)
692 : OperandRenderer(OR_Register), RegisterDef(RegisterDef) {}
693
694 static bool classof(const OperandRenderer *R) {
695 return R->getKind() == OR_Register;
696 }
697
698 void emitCxxRenderStmts(raw_ostream &OS) const override {
699 OS << " MIB.addReg(" << RegisterDef->getValueAsString("Namespace")
700 << "::" << RegisterDef->getName() << ");\n";
701 }
702};
703
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000704class RenderComplexPatternOperand : public OperandRenderer {
705private:
706 const Record &TheDef;
707 std::vector<OperandPlaceholder> Sources;
708
709 unsigned getNumOperands() const {
710 return TheDef.getValueAsDag("Operands")->getNumArgs();
711 }
712
713public:
714 RenderComplexPatternOperand(const Record &TheDef,
715 const ArrayRef<OperandPlaceholder> Sources)
716 : OperandRenderer(OR_ComplexPattern), TheDef(TheDef), Sources(Sources) {}
717
718 static bool classof(const OperandRenderer *R) {
719 return R->getKind() == OR_ComplexPattern;
720 }
721
722 void emitCxxRenderStmts(raw_ostream &OS) const override {
723 assert(Sources.size() == getNumOperands() && "Inconsistent number of operands");
724 for (const auto &Source : Sources) {
725 OS << "MIB.add(";
726 Source.emitCxxValueExpr(OS);
727 OS << ");\n";
728 }
729 }
730};
731
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +0000732/// An action taken when all Matcher predicates succeeded for a parent rule.
733///
734/// Typical actions include:
735/// * Changing the opcode of an instruction.
736/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +0000737class MatchAction {
738public:
739 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000740
741 /// Emit the C++ statements to implement the action.
742 ///
743 /// \param InsnVarName If given, it's an instruction to recycle. The
744 /// requirements on the instruction vary from action to
745 /// action.
746 virtual void emitCxxActionStmts(raw_ostream &OS,
747 const StringRef InsnVarName) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +0000748};
749
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000750/// Generates a comment describing the matched rule being acted upon.
751class DebugCommentAction : public MatchAction {
752private:
753 const PatternToMatch &P;
754
755public:
756 DebugCommentAction(const PatternToMatch &P) : P(P) {}
757
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000758 void emitCxxActionStmts(raw_ostream &OS,
759 const StringRef InsnVarName) const override {
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000760 OS << "// " << *P.getSrcPattern() << " => " << *P.getDstPattern();
761 }
762};
763
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000764/// Generates code to build an instruction or mutate an existing instruction
765/// into the desired instruction when this is possible.
766class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +0000767private:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000768 const CodeGenInstruction *I;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000769 const InstructionMatcher &Matched;
770 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
771
772 /// True if the instruction can be built solely by mutating the opcode.
773 bool canMutate() const {
774 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +0000775 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000776 if (Matched.getOperand(Copy->getSymbolicName()).getOperandIndex() !=
Zachary Turner309a0882017-03-13 16:24:10 +0000777 Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000778 return false;
779 } else
780 return false;
781 }
782
783 return true;
784 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000785
Daniel Sanders43c882c2017-02-01 10:53:10 +0000786public:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000787 BuildMIAction(const CodeGenInstruction *I, const InstructionMatcher &Matched)
788 : I(I), Matched(Matched) {}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000789
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000790 template <class Kind, class... Args>
791 Kind &addRenderer(Args&&... args) {
792 OperandRenderers.emplace_back(
793 llvm::make_unique<Kind>(std::forward<Args>(args)...));
794 return *static_cast<Kind *>(OperandRenderers.back().get());
795 }
796
797 virtual void emitCxxActionStmts(raw_ostream &OS,
798 const StringRef InsnVarName) const {
799 if (canMutate()) {
800 OS << "I.setDesc(TII.get(" << I->Namespace << "::" << I->TheDef->getName()
801 << "));\n";
802 OS << " MachineInstr &NewI = I;\n";
803 return;
804 }
805
806 // TODO: Simple permutation looks like it could be almost as common as
807 // mutation due to commutative operations.
808
809 OS << "MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, "
810 "I.getDebugLoc(), TII.get("
811 << I->Namespace << "::" << I->TheDef->getName() << "));\n";
812 for (const auto &Renderer : OperandRenderers)
813 Renderer->emitCxxRenderStmts(OS);
814 OS << " MIB.setMemRefs(I.memoperands_begin(), I.memoperands_end());\n";
815 OS << " " << InsnVarName << ".eraseFromParent();\n";
816 OS << " MachineInstr &NewI = *MIB;\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000817 }
818};
819
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000820InstructionMatcher &RuleMatcher::addInstructionMatcher() {
821 Matchers.emplace_back(new InstructionMatcher());
822 return *Matchers.back();
823}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +0000824
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000825template <class Kind, class... Args>
826Kind &RuleMatcher::addAction(Args &&... args) {
827 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
828 return *static_cast<Kind *>(Actions.back().get());
829}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000830
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000831void RuleMatcher::emit(raw_ostream &OS) const {
832 if (Matchers.empty())
833 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000834
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000835 // The representation supports rules that require multiple roots such as:
836 // %ptr(p0) = ...
837 // %elt0(s32) = G_LOAD %ptr
838 // %1(p0) = G_ADD %ptr, 4
839 // %elt1(s32) = G_LOAD p0 %1
840 // which could be usefully folded into:
841 // %ptr(p0) = ...
842 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
843 // on some targets but we don't need to make use of that yet.
844 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
845 OS << " if (";
846 Matchers.front()->emitCxxPredicateExpr(OS, "I");
847 OS << ") {\n";
848
849 for (const auto &MA : Actions) {
850 OS << " ";
851 MA->emitCxxActionStmts(OS, "I");
852 OS << "\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000853 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000854
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000855 OS << " constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);\n";
856 OS << " return true;\n";
857 OS << " }\n\n";
858}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000859
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000860bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
861 // Rules involving more match roots have higher priority.
862 if (Matchers.size() > B.Matchers.size())
863 return true;
864 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +0000865 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000866
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000867 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
868 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
869 return true;
870 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
871 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000872 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000873
874 return false;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000875};
876
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000877unsigned RuleMatcher::countTemporaryOperands() const {
878 return std::accumulate(
879 Matchers.begin(), Matchers.end(), 0,
880 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
881 return A + Matcher->countTemporaryOperands();
882 });
883}
884
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000885//===- GlobalISelEmitter class --------------------------------------------===//
886
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000887class GlobalISelEmitter {
888public:
889 explicit GlobalISelEmitter(RecordKeeper &RK);
890 void run(raw_ostream &OS);
891
892private:
893 const RecordKeeper &RK;
894 const CodeGenDAGPatterns CGP;
895 const CodeGenTarget &Target;
896
897 /// Keep track of the equivalence between SDNodes and Instruction.
898 /// This is defined using 'GINodeEquiv' in the target description.
899 DenseMap<Record *, const CodeGenInstruction *> NodeEquivs;
900
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000901 /// Keep track of the equivalence between ComplexPattern's and
902 /// GIComplexOperandMatcher. Map entries are specified by subclassing
903 /// GIComplexPatternEquiv.
904 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
905
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000906 void gatherNodeEquivs();
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000907 const CodeGenInstruction *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000908
909 /// Analyze pattern \p P, returning a matcher for it if possible.
910 /// Otherwise, return an Error explaining why we don't support it.
911 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
912};
913
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000914void GlobalISelEmitter::gatherNodeEquivs() {
915 assert(NodeEquivs.empty());
916 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
917 NodeEquivs[Equiv->getValueAsDef("Node")] =
918 &Target.getInstruction(Equiv->getValueAsDef("I"));
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000919
920 assert(ComplexPatternEquivs.empty());
921 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
922 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
923 if (!SelDAGEquiv)
924 continue;
925 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
926 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000927}
928
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000929const CodeGenInstruction *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000930 return NodeEquivs.lookup(N);
931}
932
933GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
934 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()) {}
935
936//===- Emitter ------------------------------------------------------------===//
937
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000938/// Helper function to let the emitter report skip reason error messages.
939static Error failedImport(const Twine &Reason) {
940 return make_error<StringError>(Reason, inconvertibleErrorCode());
941}
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000942
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000943Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000944 unsigned TempOpIdx = 0;
945
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000946 // Keep track of the matchers and actions to emit.
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000947 RuleMatcher M;
948 M.addAction<DebugCommentAction>(P);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000949
950 // First, analyze the whole pattern.
951 // If the entire pattern has a predicate (e.g., target features), ignore it.
952 if (!P.getPredicates()->getValues().empty())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000953 return failedImport("Pattern has a predicate");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000954
955 // Physreg imp-defs require additional logic. Ignore the pattern.
956 if (!P.getDstRegs().empty())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000957 return failedImport("Pattern defines a physical register");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000958
959 // Next, analyze the pattern operators.
960 TreePatternNode *Src = P.getSrcPattern();
961 TreePatternNode *Dst = P.getDstPattern();
962
963 // If the root of either pattern isn't a simple operator, ignore it.
964 if (!isTrivialOperatorNode(Dst))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000965 return failedImport("Dst pattern root isn't a trivial operator");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000966 if (!isTrivialOperatorNode(Src))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000967 return failedImport("Src pattern root isn't a trivial operator");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000968
969 Record *DstOp = Dst->getOperator();
970 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000971 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000972
973 auto &DstI = Target.getInstruction(DstOp);
974
975 auto SrcGIOrNull = findNodeEquiv(Src->getOperator());
976 if (!SrcGIOrNull)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000977 return failedImport("Pattern operator lacks an equivalent Instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000978 auto &SrcGI = *SrcGIOrNull;
979
980 // The operators look good: match the opcode and mutate it to the new one.
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000981 InstructionMatcher &InsnMatcher = M.addInstructionMatcher();
982 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000983 auto &DstMIBuilder = M.addAction<BuildMIAction>(&DstI, InsnMatcher);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000984
985 // Next, analyze the children, only accepting patterns that don't require
986 // any change to operands.
987 if (Src->getNumChildren() != Dst->getNumChildren())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000988 return failedImport("Src/dst patterns have a different # of children");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000989
990 unsigned OpIdx = 0;
991
992 // Start with the defined operands (i.e., the results of the root operator).
993 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000994 return failedImport("Src pattern results and dst MI defs are different");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000995
996 for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000997 const auto &DstIOperand = DstI.Operands[OpIdx];
998 Record *DstIOpRec = DstIOperand.Rec;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000999 if (!DstIOpRec->isSubClassOf("RegisterClass"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001000 return failedImport("Dst MI def isn't a register class");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001001
1002 auto OpTyOrNone = MVTToLLT(Ty.getConcrete());
1003 if (!OpTyOrNone)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001004 return failedImport("Dst operand has an unsupported type");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001005
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001006 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx, DstIOperand.Name);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001007 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1008 OM.addPredicate<RegisterBankOperandMatcher>(
1009 Target.getRegisterClass(DstIOpRec));
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001010 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, "I", DstIOperand.Name);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001011 ++OpIdx;
1012 }
1013
1014 // Finally match the used operands (i.e., the children of the root operator).
1015 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
1016 auto *SrcChild = Src->getChild(i);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001017
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001018 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, SrcChild->getName());
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001019
1020 // The only non-leaf child we accept is 'bb': it's an operator because
1021 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1022 if (!SrcChild->isLeaf()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001023 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
1024 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
1025 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001026 OM.addPredicate<MBBOperandMatcher>();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001027 continue;
1028 }
1029 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001030 return failedImport("Src pattern child isn't a leaf node or an MBB");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001031 }
1032
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001033 if (SrcChild->hasAnyPredicate())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001034 return failedImport("Src pattern child has predicate");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001035
1036 ArrayRef<EEVT::TypeSet> ChildTypes = SrcChild->getExtTypes();
1037 if (ChildTypes.size() != 1)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001038 return failedImport("Src pattern child has multiple results");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001039
1040 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1041 if (!OpTyOrNone)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001042 return failedImport("Src operand has an unsupported type");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001043 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001044
1045 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
1046 OM.addPredicate<IntOperandMatcher>(ChildInt->getValue());
1047 continue;
1048 }
1049
1050 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
1051 auto *ChildRec = ChildDefInit->getDef();
1052
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001053 if (ChildRec->isSubClassOf("RegisterClass")) {
1054 OM.addPredicate<RegisterBankOperandMatcher>(
1055 Target.getRegisterClass(ChildRec));
1056 continue;
1057 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001058
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001059 if (ChildRec->isSubClassOf("ComplexPattern")) {
1060 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1061 if (ComplexPattern == ComplexPatternEquivs.end())
1062 return failedImport(
1063 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1064
1065 const auto &Predicate = OM.addPredicate<ComplexPatternOperandMatcher>(
1066 *ComplexPattern->second, TempOpIdx);
1067 TempOpIdx += Predicate.countTemporaryOperands();
1068 continue;
1069 }
1070
1071 return failedImport(
1072 "Src pattern child def is an unsupported tablegen class");
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001073 }
1074
1075 return failedImport("Src pattern child is an unsupported kind");
1076 }
1077
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001078 TempOpIdx = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001079 // Finally render the used operands (i.e., the children of the root operator).
1080 for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
1081 auto *DstChild = Dst->getChild(i);
1082
1083 // The only non-leaf child we accept is 'bb': it's an operator because
1084 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1085 if (!DstChild->isLeaf()) {
1086 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
1087 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
1088 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
1089 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, "I",
1090 DstChild->getName());
1091 continue;
1092 }
1093 }
1094 return failedImport("Dst pattern child isn't a leaf node or an MBB");
1095 }
1096
1097 // Otherwise, we're looking for a bog-standard RegisterClass operand.
1098 if (DstChild->hasAnyPredicate())
1099 return failedImport("Dst pattern child has predicate");
1100
1101 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
1102 auto *ChildRec = ChildDefInit->getDef();
1103
1104 ArrayRef<EEVT::TypeSet> ChildTypes = DstChild->getExtTypes();
1105 if (ChildTypes.size() != 1)
1106 return failedImport("Dst pattern child has multiple results");
1107
1108 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1109 if (!OpTyOrNone)
1110 return failedImport("Dst operand has an unsupported type");
1111
1112 if (ChildRec->isSubClassOf("Register")) {
1113 DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
1114 continue;
1115 }
1116
1117 if (ChildRec->isSubClassOf("RegisterClass")) {
1118 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, "I",
1119 DstChild->getName());
1120 continue;
1121 }
1122
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001123 if (ChildRec->isSubClassOf("ComplexPattern")) {
1124 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1125 if (ComplexPattern == ComplexPatternEquivs.end())
1126 return failedImport(
1127 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1128
1129 SmallVector<OperandPlaceholder, 2> RenderedOperands;
1130 for (unsigned I = 0; I < InsnMatcher.getOperand(DstChild->getName())
1131 .countTemporaryOperands();
1132 ++I) {
1133 RenderedOperands.push_back(OperandPlaceholder::CreateTemporary(I));
1134 TempOpIdx++;
1135 }
1136 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
1137 *ComplexPattern->second,
1138 RenderedOperands);
1139 continue;
1140 }
1141
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001142 return failedImport(
1143 "Dst pattern child def is an unsupported tablegen class");
1144 }
1145
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001146 return failedImport("Dst pattern child is an unsupported kind");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001147 }
1148
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001149 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001150 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001151 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001152}
1153
1154void GlobalISelEmitter::run(raw_ostream &OS) {
1155 // Track the GINodeEquiv definitions.
1156 gatherNodeEquivs();
1157
1158 emitSourceFileHeader(("Global Instruction Selector for the " +
1159 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001160 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001161 // Look through the SelectionDAG patterns we found, possibly emitting some.
1162 for (const PatternToMatch &Pat : CGP.ptms()) {
1163 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001164 auto MatcherOrErr = runOnPattern(Pat);
1165
1166 // The pattern analysis can fail, indicating an unsupported pattern.
1167 // Report that if we've been asked to do so.
1168 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001169 if (WarnOnSkippedPatterns) {
1170 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001171 "Skipped pattern: " + toString(std::move(Err)));
1172 } else {
1173 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001174 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001175 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001176 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001177 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001178
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001179 Rules.push_back(std::move(MatcherOrErr.get()));
1180 }
1181
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001182 std::stable_sort(Rules.begin(), Rules.end(),
1183 [&](const RuleMatcher &A, const RuleMatcher &B) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001184 if (A.isHigherPriorityThan(B)) {
1185 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
1186 "and less important at "
1187 "the same time");
1188 return true;
1189 }
1190 return false;
1191 });
1192
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001193 unsigned MaxTemporaries = 0;
1194 for (const auto &Rule : Rules)
1195 MaxTemporaries = std::max(MaxTemporaries, Rule.countTemporaryOperands());
1196
1197 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n";
1198 for (unsigned I = 0; I < MaxTemporaries; ++I)
1199 OS << " mutable MachineOperand TempOp" << I << ";\n";
1200 OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
1201
1202 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n";
1203 for (unsigned I = 0; I < MaxTemporaries; ++I)
1204 OS << ", TempOp" << I << "(MachineOperand::CreatePlaceholder())\n";
1205 OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
1206
1207 OS << "#ifdef GET_GLOBALISEL_IMPL\n"
1208 << "bool " << Target.getName()
1209 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
1210 << " MachineFunction &MF = *I.getParent()->getParent();\n"
1211 << " const MachineRegisterInfo &MRI = MF.getRegInfo();\n";
1212
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001213 for (const auto &Rule : Rules) {
1214 Rule.emit(OS);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001215 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001216 }
1217
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001218 OS << " return false;\n"
1219 << "}\n"
1220 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001221}
1222
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001223} // end anonymous namespace
1224
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001225//===----------------------------------------------------------------------===//
1226
1227namespace llvm {
1228void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
1229 GlobalISelEmitter(RK).run(OS);
1230}
1231} // End llvm namespace