blob: e396093e4f66ca6822cad9c8a78e16a9670b7c87 [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
Ahmed Bougacha36f70352016-12-21 23:26:20 +000061//===- Helper functions ---------------------------------------------------===//
62
Daniel Sanders52b4ce72017-03-07 23:20:35 +000063/// This class stands in for LLT wherever we want to tablegen-erate an
64/// equivalent at compiler run-time.
65class LLTCodeGen {
66private:
67 LLT Ty;
68
69public:
70 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
71
72 void emitCxxConstructorCall(raw_ostream &OS) const {
73 if (Ty.isScalar()) {
74 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
75 return;
76 }
77 if (Ty.isVector()) {
78 OS << "LLT::vector(" << Ty.getNumElements() << ", " << Ty.getSizeInBits()
79 << ")";
80 return;
81 }
82 llvm_unreachable("Unhandled LLT");
83 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +000084
85 const LLT &get() const { return Ty; }
86};
87
88class InstructionMatcher;
89class OperandPlaceholder {
90private:
91 enum PlaceholderKind {
92 OP_MatchReference,
93 OP_Temporary,
94 } Kind;
95
96 struct MatchReferenceData {
97 InstructionMatcher *InsnMatcher;
98 StringRef InsnVarName;
99 StringRef SymbolicName;
100 };
101
102 struct TemporaryData {
103 unsigned OpIdx;
104 };
105
106 union {
107 struct MatchReferenceData MatchReference;
108 struct TemporaryData Temporary;
109 };
110
111 OperandPlaceholder(PlaceholderKind Kind) : Kind(Kind) {}
112
113public:
114 ~OperandPlaceholder() {}
115
116 static OperandPlaceholder
117 CreateMatchReference(InstructionMatcher *InsnMatcher,
118 const StringRef InsnVarName, const StringRef SymbolicName) {
119 OperandPlaceholder Result(OP_MatchReference);
120 Result.MatchReference.InsnMatcher = InsnMatcher;
121 Result.MatchReference.InsnVarName = InsnVarName;
122 Result.MatchReference.SymbolicName = SymbolicName;
123 return Result;
124 }
125
126 static OperandPlaceholder CreateTemporary(unsigned OpIdx) {
127 OperandPlaceholder Result(OP_Temporary);
128 Result.Temporary.OpIdx = OpIdx;
129 return Result;
130 }
131
132 void emitCxxValueExpr(raw_ostream &OS) const;
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000133};
134
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000135/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
136/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000137static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000138 MVT VT(SVT);
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000139 if (VT.isVector() && VT.getVectorNumElements() != 1)
140 return LLTCodeGen(LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
141 if (VT.isInteger() || VT.isFloatingPoint())
142 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
143 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000144}
145
146static bool isTrivialOperatorNode(const TreePatternNode *N) {
147 return !N->isLeaf() && !N->hasAnyPredicate() && !N->getTransformFn();
148}
149
150//===- Matchers -----------------------------------------------------------===//
151
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000152template <class PredicateTy> class PredicateListMatcher {
153private:
154 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
155 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000156
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000157public:
158 /// Construct a new operand predicate and add it to the matcher.
159 template <class Kind, class... Args>
160 Kind &addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000161 Predicates.emplace_back(
162 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000163 return *static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000164 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000165
166 typename PredicateVec::const_iterator predicates_begin() const { return Predicates.begin(); }
167 typename PredicateVec::const_iterator predicates_end() const { return Predicates.end(); }
168 iterator_range<typename PredicateVec::const_iterator> predicates() const {
169 return make_range(predicates_begin(), predicates_end());
170 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000171 typename PredicateVec::size_type predicates_size() const { return Predicates.size(); }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000172
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000173 /// Emit a C++ expression that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000174 template <class... Args>
Daniel Sandersf8c804f2017-01-28 11:10:42 +0000175 void emitCxxPredicateListExpr(raw_ostream &OS, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000176 if (Predicates.empty()) {
177 OS << "true";
178 return;
179 }
180
181 StringRef Separator = "";
182 for (const auto &Predicate : predicates()) {
183 OS << Separator << "(";
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000184 Predicate->emitCxxPredicateExpr(OS, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000185 OS << ")";
Ahmed Bougacha905af9f2017-02-04 00:47:02 +0000186 Separator = " &&\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000187 }
188 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000189};
190
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000191/// Generates code to check a predicate of an operand.
192///
193/// Typical predicates include:
194/// * Operand is a particular register.
195/// * Operand is assigned a particular register bank.
196/// * Operand is an MBB.
197class OperandPredicateMatcher {
198public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000199 /// This enum is used for RTTI and also defines the priority that is given to
200 /// the predicate when generating the matcher code. Kinds with higher priority
201 /// must be tested first.
202 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000203 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
204 /// but OPM_Int must have priority over OPM_RegBank since constant integers
205 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000206 enum PredicateKind {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000207 OPM_ComplexPattern,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000208 OPM_Int,
Daniel Sanders759ff412017-02-24 13:58:11 +0000209 OPM_LLT,
210 OPM_RegBank,
211 OPM_MBB,
212 };
213
214protected:
215 PredicateKind Kind;
216
217public:
218 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000219 virtual ~OperandPredicateMatcher() {}
220
Daniel Sanders759ff412017-02-24 13:58:11 +0000221 PredicateKind getKind() const { return Kind; }
222
Daniel Sanderse604ef52017-02-20 15:30:43 +0000223 /// Emit a C++ expression that checks the predicate for the given operand.
224 virtual void emitCxxPredicateExpr(raw_ostream &OS,
225 StringRef OperandExpr) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000226
227 /// Compare the priority of this object and B.
228 ///
229 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000230 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const {
231 return Kind < B.Kind;
Daniel Sanders759ff412017-02-24 13:58:11 +0000232 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000233
234 /// Report the maximum number of temporary operands needed by the predicate
235 /// matcher.
236 virtual unsigned countTemporaryOperands() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000237};
238
239/// Generates code to check that an operand is a particular LLT.
240class LLTOperandMatcher : public OperandPredicateMatcher {
241protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000242 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000243
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000244public:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000245 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders759ff412017-02-24 13:58:11 +0000246 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {}
247
248 static bool classof(const OperandPredicateMatcher *P) {
249 return P->getKind() == OPM_LLT;
250 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000251
Daniel Sanderse604ef52017-02-20 15:30:43 +0000252 void emitCxxPredicateExpr(raw_ostream &OS,
253 StringRef OperandExpr) const override {
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000254 OS << "MRI.getType(" << OperandExpr << ".getReg()) == (";
255 Ty.emitCxxConstructorCall(OS);
256 OS << ")";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000257 }
258};
259
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000260/// Generates code to check that an operand is a particular target constant.
261class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
262protected:
263 const Record &TheDef;
264 /// The index of the first temporary operand to allocate to this
265 /// ComplexPattern.
266 unsigned BaseTemporaryID;
267
268 unsigned getNumOperands() const {
269 return TheDef.getValueAsDag("Operands")->getNumArgs();
270 }
271
272public:
273 ComplexPatternOperandMatcher(const Record &TheDef, unsigned BaseTemporaryID)
274 : OperandPredicateMatcher(OPM_ComplexPattern), TheDef(TheDef),
275 BaseTemporaryID(BaseTemporaryID) {}
276
277 void emitCxxPredicateExpr(raw_ostream &OS,
278 StringRef OperandExpr) const override {
279 OS << TheDef.getValueAsString("MatcherFn") << "(" << OperandExpr;
280 for (unsigned I = 0; I < getNumOperands(); ++I) {
281 OS << ", ";
282 OperandPlaceholder::CreateTemporary(BaseTemporaryID + I)
283 .emitCxxValueExpr(OS);
284 }
285 OS << ")";
286 }
287
288 unsigned countTemporaryOperands() const override {
289 return getNumOperands();
290 }
291};
292
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000293/// Generates code to check that an operand is in a particular register bank.
294class RegisterBankOperandMatcher : public OperandPredicateMatcher {
295protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000296 const CodeGenRegisterClass &RC;
297
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000298public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000299 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
300 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
301
302 static bool classof(const OperandPredicateMatcher *P) {
303 return P->getKind() == OPM_RegBank;
304 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000305
Daniel Sanderse604ef52017-02-20 15:30:43 +0000306 void emitCxxPredicateExpr(raw_ostream &OS,
307 StringRef OperandExpr) const override {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000308 OS << "(&RBI.getRegBankFromRegClass(" << RC.getQualifiedName()
Daniel Sanderse604ef52017-02-20 15:30:43 +0000309 << "RegClass) == RBI.getRegBank(" << OperandExpr
310 << ".getReg(), MRI, TRI))";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000311 }
312};
313
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000314/// Generates code to check that an operand is a basic block.
315class MBBOperandMatcher : public OperandPredicateMatcher {
316public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000317 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
318
319 static bool classof(const OperandPredicateMatcher *P) {
320 return P->getKind() == OPM_MBB;
321 }
322
Daniel Sanderse604ef52017-02-20 15:30:43 +0000323 void emitCxxPredicateExpr(raw_ostream &OS,
324 StringRef OperandExpr) const override {
325 OS << OperandExpr << ".isMBB()";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000326 }
327};
328
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000329/// Generates code to check that an operand is a particular int.
330class IntOperandMatcher : public OperandPredicateMatcher {
331protected:
332 int64_t Value;
333
334public:
335 IntOperandMatcher(int64_t Value)
336 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
337
338 static bool classof(const OperandPredicateMatcher *P) {
339 return P->getKind() == OPM_Int;
340 }
341
342 void emitCxxPredicateExpr(raw_ostream &OS,
Simon Pilgrimd0302912017-02-24 17:20:27 +0000343 StringRef OperandExpr) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000344 OS << "isOperandImmEqual(" << OperandExpr << ", " << Value << ", MRI)";
345 }
346};
347
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000348/// Generates code to check that a set of predicates match for a particular
349/// operand.
350class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
351protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000352 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000353 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000354
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000355public:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000356 OperandMatcher(unsigned OpIdx, const std::string &SymbolicName)
357 : OpIdx(OpIdx), SymbolicName(SymbolicName) {}
358
359 bool hasSymbolicName() const { return !SymbolicName.empty(); }
360 const StringRef getSymbolicName() const { return SymbolicName; }
361 unsigned getOperandIndex() const { return OpIdx; }
362
363 std::string getOperandExpr(const StringRef InsnVarName) const {
Pavel Labath52a82e22017-02-21 09:19:41 +0000364 return (InsnVarName + ".getOperand(" + llvm::to_string(OpIdx) + ")").str();
Daniel Sanderse604ef52017-02-20 15:30:43 +0000365 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000366
367 /// Emit a C++ expression that tests whether the instruction named in
368 /// InsnVarName matches all the predicate and all the operands.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000369 void emitCxxPredicateExpr(raw_ostream &OS, const StringRef InsnVarName) const {
370 OS << "(/* ";
371 if (SymbolicName.empty())
372 OS << "Operand " << OpIdx;
373 else
374 OS << SymbolicName;
375 OS << " */ ";
Daniel Sanderse604ef52017-02-20 15:30:43 +0000376 emitCxxPredicateListExpr(OS, getOperandExpr(InsnVarName));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000377 OS << ")";
378 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000379
380 /// Compare the priority of this object and B.
381 ///
382 /// Returns true if this object is more important than B.
383 bool isHigherPriorityThan(const OperandMatcher &B) const {
384 // Operand matchers involving more predicates have higher priority.
385 if (predicates_size() > B.predicates_size())
386 return true;
387 if (predicates_size() < B.predicates_size())
388 return false;
389
390 // This assumes that predicates are added in a consistent order.
391 for (const auto &Predicate : zip(predicates(), B.predicates())) {
392 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
393 return true;
394 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
395 return false;
396 }
397
398 return false;
399 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000400
401 /// Report the maximum number of temporary operands needed by the operand
402 /// matcher.
403 unsigned countTemporaryOperands() const {
404 return std::accumulate(
405 predicates().begin(), predicates().end(), 0,
406 [](unsigned A,
407 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
408 return A + Predicate->countTemporaryOperands();
409 });
410 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000411};
412
413/// Generates code to check a predicate on an instruction.
414///
415/// Typical predicates include:
416/// * The opcode of the instruction is a particular value.
417/// * The nsw/nuw flag is/isn't set.
418class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +0000419protected:
420 /// This enum is used for RTTI and also defines the priority that is given to
421 /// the predicate when generating the matcher code. Kinds with higher priority
422 /// must be tested first.
423 enum PredicateKind {
424 IPM_Opcode,
425 };
426
427 PredicateKind Kind;
428
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000429public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000430 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000431 virtual ~InstructionPredicateMatcher() {}
432
Daniel Sanders759ff412017-02-24 13:58:11 +0000433 PredicateKind getKind() const { return Kind; }
434
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000435 /// Emit a C++ expression that tests whether the instruction named in
436 /// InsnVarName matches the predicate.
437 virtual void emitCxxPredicateExpr(raw_ostream &OS,
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000438 StringRef InsnVarName) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000439
440 /// Compare the priority of this object and B.
441 ///
442 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000443 virtual bool isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +0000444 return Kind < B.Kind;
445 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000446
447 /// Report the maximum number of temporary operands needed by the predicate
448 /// matcher.
449 virtual unsigned countTemporaryOperands() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000450};
451
452/// Generates code to check the opcode of an instruction.
453class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
454protected:
455 const CodeGenInstruction *I;
456
457public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000458 InstructionOpcodeMatcher(const CodeGenInstruction *I)
459 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000460
Daniel Sanders759ff412017-02-24 13:58:11 +0000461 static bool classof(const InstructionPredicateMatcher *P) {
462 return P->getKind() == IPM_Opcode;
463 }
464
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000465 void emitCxxPredicateExpr(raw_ostream &OS,
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000466 StringRef InsnVarName) const override {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000467 OS << InsnVarName << ".getOpcode() == " << I->Namespace
468 << "::" << I->TheDef->getName();
469 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000470
471 /// Compare the priority of this object and B.
472 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000473 /// Returns true if this object is more important than B.
474 bool isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +0000475 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
476 return true;
477 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
478 return false;
479
480 // Prioritize opcodes for cosmetic reasons in the generated source. Although
481 // this is cosmetic at the moment, we may want to drive a similar ordering
482 // using instruction frequency information to improve compile time.
483 if (const InstructionOpcodeMatcher *BO =
484 dyn_cast<InstructionOpcodeMatcher>(&B))
485 return I->TheDef->getName() < BO->I->TheDef->getName();
486
487 return false;
488 };
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000489};
490
491/// Generates code to check that a set of predicates and operands match for a
492/// particular instruction.
493///
494/// Typical predicates include:
495/// * Has a specific opcode.
496/// * Has an nsw/nuw flag or doesn't.
497class InstructionMatcher
498 : public PredicateListMatcher<InstructionPredicateMatcher> {
499protected:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000500 typedef std::vector<OperandMatcher> OperandVec;
501
502 /// The operands to match. All rendered operands must be present even if the
503 /// condition is always true.
504 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000505
506public:
507 /// Add an operand to the matcher.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000508 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName) {
509 Operands.emplace_back(OpIdx, SymbolicName);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000510 return Operands.back();
511 }
512
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000513 const OperandMatcher &getOperand(const StringRef SymbolicName) const {
514 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
515 const auto &I = std::find_if(Operands.begin(), Operands.end(),
516 [&SymbolicName](const OperandMatcher &X) {
517 return X.getSymbolicName() == SymbolicName;
518 });
519 if (I != Operands.end())
520 return *I;
521 llvm_unreachable("Failed to lookup operand");
522 }
523
524 unsigned getNumOperands() const { return Operands.size(); }
525 OperandVec::const_iterator operands_begin() const {
526 return Operands.begin();
527 }
528 OperandVec::const_iterator operands_end() const {
529 return Operands.end();
530 }
531 iterator_range<OperandVec::const_iterator> operands() const {
532 return make_range(operands_begin(), operands_end());
533 }
534
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000535 /// Emit a C++ expression that tests whether the instruction named in
536 /// InsnVarName matches all the predicates and all the operands.
Ahmed Bougacha6a1ac5a2017-02-09 02:50:01 +0000537 void emitCxxPredicateExpr(raw_ostream &OS, StringRef InsnVarName) const {
Daniel Sandersf8c804f2017-01-28 11:10:42 +0000538 emitCxxPredicateListExpr(OS, InsnVarName);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000539 for (const auto &Operand : Operands) {
Ahmed Bougacha905af9f2017-02-04 00:47:02 +0000540 OS << " &&\n(";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000541 Operand.emitCxxPredicateExpr(OS, InsnVarName);
542 OS << ")";
543 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000544 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000545
546 /// Compare the priority of this object and B.
547 ///
548 /// Returns true if this object is more important than B.
549 bool isHigherPriorityThan(const InstructionMatcher &B) const {
550 // Instruction matchers involving more operands have higher priority.
551 if (Operands.size() > B.Operands.size())
552 return true;
553 if (Operands.size() < B.Operands.size())
554 return false;
555
556 for (const auto &Predicate : zip(predicates(), B.predicates())) {
557 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
558 return true;
559 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
560 return false;
561 }
562
563 for (const auto &Operand : zip(Operands, B.Operands)) {
564 if (std::get<0>(Operand).isHigherPriorityThan(std::get<1>(Operand)))
565 return true;
566 if (std::get<1>(Operand).isHigherPriorityThan(std::get<0>(Operand)))
567 return false;
568 }
569
570 return false;
571 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000572
573 /// Report the maximum number of temporary operands needed by the instruction
574 /// matcher.
575 unsigned countTemporaryOperands() const {
576 return std::accumulate(predicates().begin(), predicates().end(), 0,
577 [](unsigned A,
578 const std::unique_ptr<InstructionPredicateMatcher>
579 &Predicate) {
580 return A + Predicate->countTemporaryOperands();
581 }) +
582 std::accumulate(Operands.begin(), Operands.end(), 0,
583 [](unsigned A, const OperandMatcher &Operand) {
584 return A + Operand.countTemporaryOperands();
585 });
586 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000587};
588
Daniel Sanders43c882c2017-02-01 10:53:10 +0000589//===- Actions ------------------------------------------------------------===//
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000590void OperandPlaceholder::emitCxxValueExpr(raw_ostream &OS) const {
591 switch (Kind) {
592 case OP_MatchReference:
593 OS << MatchReference.InsnMatcher->getOperand(MatchReference.SymbolicName)
594 .getOperandExpr(MatchReference.InsnVarName);
595 break;
596 case OP_Temporary:
597 OS << "TempOp" << Temporary.OpIdx;
598 break;
599 }
600}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000601
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000602namespace {
603class OperandRenderer {
604public:
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000605 enum RendererKind { OR_Copy, OR_Register, OR_ComplexPattern };
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000606
607protected:
608 RendererKind Kind;
609
610public:
611 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
612 virtual ~OperandRenderer() {}
613
614 RendererKind getKind() const { return Kind; }
615
616 virtual void emitCxxRenderStmts(raw_ostream &OS) const = 0;
617};
618
619/// A CopyRenderer emits code to copy a single operand from an existing
620/// instruction to the one being built.
621class CopyRenderer : public OperandRenderer {
622protected:
623 /// The matcher for the instruction that this operand is copied from.
624 /// This provides the facility for looking up an a operand by it's name so
625 /// that it can be used as a source for the instruction being built.
626 const InstructionMatcher &Matched;
627 /// The name of the instruction to copy from.
628 const StringRef InsnVarName;
629 /// The name of the operand.
630 const StringRef SymbolicName;
631
632public:
633 CopyRenderer(const InstructionMatcher &Matched, const StringRef InsnVarName,
634 const StringRef SymbolicName)
635 : OperandRenderer(OR_Copy), Matched(Matched), InsnVarName(InsnVarName),
636 SymbolicName(SymbolicName) {}
637
638 static bool classof(const OperandRenderer *R) {
639 return R->getKind() == OR_Copy;
640 }
641
642 const StringRef getSymbolicName() const { return SymbolicName; }
643
644 void emitCxxRenderStmts(raw_ostream &OS) const override {
645 std::string OperandExpr =
646 Matched.getOperand(SymbolicName).getOperandExpr(InsnVarName);
647 OS << " MIB.add(" << OperandExpr << "/*" << SymbolicName << "*/);\n";
648 }
649};
650
651/// Adds a specific physical register to the instruction being built.
652/// This is typically useful for WZR/XZR on AArch64.
653class AddRegisterRenderer : public OperandRenderer {
654protected:
655 const Record *RegisterDef;
656
657public:
658 AddRegisterRenderer(const Record *RegisterDef)
659 : OperandRenderer(OR_Register), RegisterDef(RegisterDef) {}
660
661 static bool classof(const OperandRenderer *R) {
662 return R->getKind() == OR_Register;
663 }
664
665 void emitCxxRenderStmts(raw_ostream &OS) const override {
666 OS << " MIB.addReg(" << RegisterDef->getValueAsString("Namespace")
667 << "::" << RegisterDef->getName() << ");\n";
668 }
669};
670
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000671class RenderComplexPatternOperand : public OperandRenderer {
672private:
673 const Record &TheDef;
674 std::vector<OperandPlaceholder> Sources;
675
676 unsigned getNumOperands() const {
677 return TheDef.getValueAsDag("Operands")->getNumArgs();
678 }
679
680public:
681 RenderComplexPatternOperand(const Record &TheDef,
682 const ArrayRef<OperandPlaceholder> Sources)
683 : OperandRenderer(OR_ComplexPattern), TheDef(TheDef), Sources(Sources) {}
684
685 static bool classof(const OperandRenderer *R) {
686 return R->getKind() == OR_ComplexPattern;
687 }
688
689 void emitCxxRenderStmts(raw_ostream &OS) const override {
690 assert(Sources.size() == getNumOperands() && "Inconsistent number of operands");
691 for (const auto &Source : Sources) {
692 OS << "MIB.add(";
693 Source.emitCxxValueExpr(OS);
694 OS << ");\n";
695 }
696 }
697};
698
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +0000699/// An action taken when all Matcher predicates succeeded for a parent rule.
700///
701/// Typical actions include:
702/// * Changing the opcode of an instruction.
703/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +0000704class MatchAction {
705public:
706 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000707
708 /// Emit the C++ statements to implement the action.
709 ///
710 /// \param InsnVarName If given, it's an instruction to recycle. The
711 /// requirements on the instruction vary from action to
712 /// action.
713 virtual void emitCxxActionStmts(raw_ostream &OS,
714 const StringRef InsnVarName) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +0000715};
716
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000717/// Generates a comment describing the matched rule being acted upon.
718class DebugCommentAction : public MatchAction {
719private:
720 const PatternToMatch &P;
721
722public:
723 DebugCommentAction(const PatternToMatch &P) : P(P) {}
724
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000725 void emitCxxActionStmts(raw_ostream &OS,
726 const StringRef InsnVarName) const override {
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000727 OS << "// " << *P.getSrcPattern() << " => " << *P.getDstPattern();
728 }
729};
730
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000731/// Generates code to build an instruction or mutate an existing instruction
732/// into the desired instruction when this is possible.
733class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +0000734private:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000735 const CodeGenInstruction *I;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000736 const InstructionMatcher &Matched;
737 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
738
739 /// True if the instruction can be built solely by mutating the opcode.
740 bool canMutate() const {
741 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +0000742 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000743 if (Matched.getOperand(Copy->getSymbolicName()).getOperandIndex() !=
Zachary Turner309a0882017-03-13 16:24:10 +0000744 Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000745 return false;
746 } else
747 return false;
748 }
749
750 return true;
751 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000752
Daniel Sanders43c882c2017-02-01 10:53:10 +0000753public:
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000754 BuildMIAction(const CodeGenInstruction *I, const InstructionMatcher &Matched)
755 : I(I), Matched(Matched) {}
Daniel Sanders43c882c2017-02-01 10:53:10 +0000756
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000757 template <class Kind, class... Args>
758 Kind &addRenderer(Args&&... args) {
759 OperandRenderers.emplace_back(
760 llvm::make_unique<Kind>(std::forward<Args>(args)...));
761 return *static_cast<Kind *>(OperandRenderers.back().get());
762 }
763
764 virtual void emitCxxActionStmts(raw_ostream &OS,
765 const StringRef InsnVarName) const {
766 if (canMutate()) {
767 OS << "I.setDesc(TII.get(" << I->Namespace << "::" << I->TheDef->getName()
768 << "));\n";
769 OS << " MachineInstr &NewI = I;\n";
770 return;
771 }
772
773 // TODO: Simple permutation looks like it could be almost as common as
774 // mutation due to commutative operations.
775
776 OS << "MachineInstrBuilder MIB = BuildMI(*I.getParent(), I, "
777 "I.getDebugLoc(), TII.get("
778 << I->Namespace << "::" << I->TheDef->getName() << "));\n";
779 for (const auto &Renderer : OperandRenderers)
780 Renderer->emitCxxRenderStmts(OS);
781 OS << " MIB.setMemRefs(I.memoperands_begin(), I.memoperands_end());\n";
782 OS << " " << InsnVarName << ".eraseFromParent();\n";
783 OS << " MachineInstr &NewI = *MIB;\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000784 }
785};
786
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000787/// Generates code to check that a match rule matches.
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000788class RuleMatcher {
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +0000789 /// A list of matchers that all need to succeed for the current rule to match.
790 /// FIXME: This currently supports a single match position but could be
791 /// extended to support multiple positions to support div/rem fusion or
792 /// load-multiple instructions.
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000793 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +0000794
795 /// A list of actions that need to be taken when all predicates in this rule
796 /// have succeeded.
Daniel Sanders43c882c2017-02-01 10:53:10 +0000797 std::vector<std::unique_ptr<MatchAction>> Actions;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000798
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000799public:
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000800 RuleMatcher() {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000801
802 InstructionMatcher &addInstructionMatcher() {
803 Matchers.emplace_back(new InstructionMatcher());
804 return *Matchers.back();
805 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000806
Daniel Sanders43c882c2017-02-01 10:53:10 +0000807 template <class Kind, class... Args>
808 Kind &addAction(Args&&... args) {
809 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
810 return *static_cast<Kind *>(Actions.back().get());
811 }
812
Daniel Sandersb41ce2b2017-02-20 14:31:27 +0000813 void emit(raw_ostream &OS) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000814 if (Matchers.empty())
815 llvm_unreachable("Unexpected empty matcher!");
816
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000817 // The representation supports rules that require multiple roots such as:
818 // %ptr(p0) = ...
819 // %elt0(s32) = G_LOAD %ptr
820 // %1(p0) = G_ADD %ptr, 4
821 // %elt1(s32) = G_LOAD p0 %1
822 // which could be usefully folded into:
823 // %ptr(p0) = ...
824 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
825 // on some targets but we don't need to make use of that yet.
826 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
827 OS << " if (";
828 Matchers.front()->emitCxxPredicateExpr(OS, "I");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000829 OS << ") {\n";
830
Daniel Sanders43c882c2017-02-01 10:53:10 +0000831 for (const auto &MA : Actions) {
832 OS << " ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000833 MA->emitCxxActionStmts(OS, "I");
Daniel Sanders43c882c2017-02-01 10:53:10 +0000834 OS << "\n";
835 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000836
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000837 OS << " constrainSelectedInstRegOperands(NewI, TII, TRI, RBI);\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000838 OS << " return true;\n";
Ahmed Bougacha905af9f2017-02-04 00:47:02 +0000839 OS << " }\n\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000840 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000841
842 /// Compare the priority of this object and B.
843 ///
844 /// Returns true if this object is more important than B.
845 bool isHigherPriorityThan(const RuleMatcher &B) const {
846 // Rules involving more match roots have higher priority.
847 if (Matchers.size() > B.Matchers.size())
848 return true;
849 if (Matchers.size() < B.Matchers.size())
850 return false;
851
852 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
853 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
854 return true;
855 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
856 return false;
857 }
858
859 return false;
860 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000861
862 /// Report the maximum number of temporary operands needed by the rule
863 /// matcher.
864 unsigned countTemporaryOperands() const {
865 return std::accumulate(Matchers.begin(), Matchers.end(), 0,
866 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
867 return A + Matcher->countTemporaryOperands();
868 });
869 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000870};
871
872//===- GlobalISelEmitter class --------------------------------------------===//
873
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000874class GlobalISelEmitter {
875public:
876 explicit GlobalISelEmitter(RecordKeeper &RK);
877 void run(raw_ostream &OS);
878
879private:
880 const RecordKeeper &RK;
881 const CodeGenDAGPatterns CGP;
882 const CodeGenTarget &Target;
883
884 /// Keep track of the equivalence between SDNodes and Instruction.
885 /// This is defined using 'GINodeEquiv' in the target description.
886 DenseMap<Record *, const CodeGenInstruction *> NodeEquivs;
887
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000888 /// Keep track of the equivalence between ComplexPattern's and
889 /// GIComplexOperandMatcher. Map entries are specified by subclassing
890 /// GIComplexPatternEquiv.
891 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
892
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000893 void gatherNodeEquivs();
894 const CodeGenInstruction *findNodeEquiv(Record *N);
895
896 /// Analyze pattern \p P, returning a matcher for it if possible.
897 /// Otherwise, return an Error explaining why we don't support it.
898 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
899};
900
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000901void GlobalISelEmitter::gatherNodeEquivs() {
902 assert(NodeEquivs.empty());
903 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
904 NodeEquivs[Equiv->getValueAsDef("Node")] =
905 &Target.getInstruction(Equiv->getValueAsDef("I"));
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000906
907 assert(ComplexPatternEquivs.empty());
908 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
909 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
910 if (!SelDAGEquiv)
911 continue;
912 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
913 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000914}
915
916const CodeGenInstruction *GlobalISelEmitter::findNodeEquiv(Record *N) {
917 return NodeEquivs.lookup(N);
918}
919
920GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
921 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()) {}
922
923//===- Emitter ------------------------------------------------------------===//
924
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000925/// Helper function to let the emitter report skip reason error messages.
926static Error failedImport(const Twine &Reason) {
927 return make_error<StringError>(Reason, inconvertibleErrorCode());
928}
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000929
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000930Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000931 unsigned TempOpIdx = 0;
932
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000933 // Keep track of the matchers and actions to emit.
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +0000934 RuleMatcher M;
935 M.addAction<DebugCommentAction>(P);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000936
937 // First, analyze the whole pattern.
938 // If the entire pattern has a predicate (e.g., target features), ignore it.
939 if (!P.getPredicates()->getValues().empty())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000940 return failedImport("Pattern has a predicate");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000941
942 // Physreg imp-defs require additional logic. Ignore the pattern.
943 if (!P.getDstRegs().empty())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000944 return failedImport("Pattern defines a physical register");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000945
946 // Next, analyze the pattern operators.
947 TreePatternNode *Src = P.getSrcPattern();
948 TreePatternNode *Dst = P.getDstPattern();
949
950 // If the root of either pattern isn't a simple operator, ignore it.
951 if (!isTrivialOperatorNode(Dst))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000952 return failedImport("Dst pattern root isn't a trivial operator");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000953 if (!isTrivialOperatorNode(Src))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000954 return failedImport("Src pattern root isn't a trivial operator");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000955
956 Record *DstOp = Dst->getOperator();
957 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000958 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000959
960 auto &DstI = Target.getInstruction(DstOp);
961
962 auto SrcGIOrNull = findNodeEquiv(Src->getOperator());
963 if (!SrcGIOrNull)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000964 return failedImport("Pattern operator lacks an equivalent Instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000965 auto &SrcGI = *SrcGIOrNull;
966
967 // The operators look good: match the opcode and mutate it to the new one.
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000968 InstructionMatcher &InsnMatcher = M.addInstructionMatcher();
969 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000970 auto &DstMIBuilder = M.addAction<BuildMIAction>(&DstI, InsnMatcher);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000971
972 // Next, analyze the children, only accepting patterns that don't require
973 // any change to operands.
974 if (Src->getNumChildren() != Dst->getNumChildren())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000975 return failedImport("Src/dst patterns have a different # of children");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000976
977 unsigned OpIdx = 0;
978
979 // Start with the defined operands (i.e., the results of the root operator).
980 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000981 return failedImport("Src pattern results and dst MI defs are different");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000982
983 for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000984 const auto &DstIOperand = DstI.Operands[OpIdx];
985 Record *DstIOpRec = DstIOperand.Rec;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000986 if (!DstIOpRec->isSubClassOf("RegisterClass"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000987 return failedImport("Dst MI def isn't a register class");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000988
989 auto OpTyOrNone = MVTToLLT(Ty.getConcrete());
990 if (!OpTyOrNone)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +0000991 return failedImport("Dst operand has an unsupported type");
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000992
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000993 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx, DstIOperand.Name);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000994 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
995 OM.addPredicate<RegisterBankOperandMatcher>(
996 Target.getRegisterClass(DstIOpRec));
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000997 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, "I", DstIOperand.Name);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000998 ++OpIdx;
999 }
1000
1001 // Finally match the used operands (i.e., the children of the root operator).
1002 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
1003 auto *SrcChild = Src->getChild(i);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001004
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001005 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, SrcChild->getName());
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001006
1007 // The only non-leaf child we accept is 'bb': it's an operator because
1008 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1009 if (!SrcChild->isLeaf()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001010 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
1011 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
1012 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001013 OM.addPredicate<MBBOperandMatcher>();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001014 continue;
1015 }
1016 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001017 return failedImport("Src pattern child isn't a leaf node or an MBB");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001018 }
1019
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001020 if (SrcChild->hasAnyPredicate())
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001021 return failedImport("Src pattern child has predicate");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001022
1023 ArrayRef<EEVT::TypeSet> ChildTypes = SrcChild->getExtTypes();
1024 if (ChildTypes.size() != 1)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001025 return failedImport("Src pattern child has multiple results");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001026
1027 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1028 if (!OpTyOrNone)
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001029 return failedImport("Src operand has an unsupported type");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001030 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001031
1032 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
1033 OM.addPredicate<IntOperandMatcher>(ChildInt->getValue());
1034 continue;
1035 }
1036
1037 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
1038 auto *ChildRec = ChildDefInit->getDef();
1039
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001040 if (ChildRec->isSubClassOf("RegisterClass")) {
1041 OM.addPredicate<RegisterBankOperandMatcher>(
1042 Target.getRegisterClass(ChildRec));
1043 continue;
1044 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001045
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001046 if (ChildRec->isSubClassOf("ComplexPattern")) {
1047 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1048 if (ComplexPattern == ComplexPatternEquivs.end())
1049 return failedImport(
1050 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1051
1052 const auto &Predicate = OM.addPredicate<ComplexPatternOperandMatcher>(
1053 *ComplexPattern->second, TempOpIdx);
1054 TempOpIdx += Predicate.countTemporaryOperands();
1055 continue;
1056 }
1057
1058 return failedImport(
1059 "Src pattern child def is an unsupported tablegen class");
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001060 }
1061
1062 return failedImport("Src pattern child is an unsupported kind");
1063 }
1064
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001065 TempOpIdx = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001066 // Finally render the used operands (i.e., the children of the root operator).
1067 for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
1068 auto *DstChild = Dst->getChild(i);
1069
1070 // The only non-leaf child we accept is 'bb': it's an operator because
1071 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1072 if (!DstChild->isLeaf()) {
1073 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
1074 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
1075 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
1076 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, "I",
1077 DstChild->getName());
1078 continue;
1079 }
1080 }
1081 return failedImport("Dst pattern child isn't a leaf node or an MBB");
1082 }
1083
1084 // Otherwise, we're looking for a bog-standard RegisterClass operand.
1085 if (DstChild->hasAnyPredicate())
1086 return failedImport("Dst pattern child has predicate");
1087
1088 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
1089 auto *ChildRec = ChildDefInit->getDef();
1090
1091 ArrayRef<EEVT::TypeSet> ChildTypes = DstChild->getExtTypes();
1092 if (ChildTypes.size() != 1)
1093 return failedImport("Dst pattern child has multiple results");
1094
1095 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1096 if (!OpTyOrNone)
1097 return failedImport("Dst operand has an unsupported type");
1098
1099 if (ChildRec->isSubClassOf("Register")) {
1100 DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
1101 continue;
1102 }
1103
1104 if (ChildRec->isSubClassOf("RegisterClass")) {
1105 DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, "I",
1106 DstChild->getName());
1107 continue;
1108 }
1109
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001110 if (ChildRec->isSubClassOf("ComplexPattern")) {
1111 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1112 if (ComplexPattern == ComplexPatternEquivs.end())
1113 return failedImport(
1114 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1115
1116 SmallVector<OperandPlaceholder, 2> RenderedOperands;
1117 for (unsigned I = 0; I < InsnMatcher.getOperand(DstChild->getName())
1118 .countTemporaryOperands();
1119 ++I) {
1120 RenderedOperands.push_back(OperandPlaceholder::CreateTemporary(I));
1121 TempOpIdx++;
1122 }
1123 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
1124 *ComplexPattern->second,
1125 RenderedOperands);
1126 continue;
1127 }
1128
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001129 return failedImport(
1130 "Dst pattern child def is an unsupported tablegen class");
1131 }
1132
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001133 return failedImport("Dst pattern child is an unsupported kind");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001134 }
1135
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001136 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001137 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001138 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001139}
1140
1141void GlobalISelEmitter::run(raw_ostream &OS) {
1142 // Track the GINodeEquiv definitions.
1143 gatherNodeEquivs();
1144
1145 emitSourceFileHeader(("Global Instruction Selector for the " +
1146 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001147 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001148 // Look through the SelectionDAG patterns we found, possibly emitting some.
1149 for (const PatternToMatch &Pat : CGP.ptms()) {
1150 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001151 auto MatcherOrErr = runOnPattern(Pat);
1152
1153 // The pattern analysis can fail, indicating an unsupported pattern.
1154 // Report that if we've been asked to do so.
1155 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001156 if (WarnOnSkippedPatterns) {
1157 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001158 "Skipped pattern: " + toString(std::move(Err)));
1159 } else {
1160 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001161 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001162 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001163 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001164 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001165
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001166 Rules.push_back(std::move(MatcherOrErr.get()));
1167 }
1168
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001169 std::stable_sort(Rules.begin(), Rules.end(),
1170 [&](const RuleMatcher &A, const RuleMatcher &B) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001171 if (A.isHigherPriorityThan(B)) {
1172 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
1173 "and less important at "
1174 "the same time");
1175 return true;
1176 }
1177 return false;
1178 });
1179
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001180 unsigned MaxTemporaries = 0;
1181 for (const auto &Rule : Rules)
1182 MaxTemporaries = std::max(MaxTemporaries, Rule.countTemporaryOperands());
1183
1184 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n";
1185 for (unsigned I = 0; I < MaxTemporaries; ++I)
1186 OS << " mutable MachineOperand TempOp" << I << ";\n";
1187 OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
1188
1189 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n";
1190 for (unsigned I = 0; I < MaxTemporaries; ++I)
1191 OS << ", TempOp" << I << "(MachineOperand::CreatePlaceholder())\n";
1192 OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
1193
1194 OS << "#ifdef GET_GLOBALISEL_IMPL\n"
1195 << "bool " << Target.getName()
1196 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
1197 << " MachineFunction &MF = *I.getParent()->getParent();\n"
1198 << " const MachineRegisterInfo &MRI = MF.getRegInfo();\n";
1199
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001200 for (const auto &Rule : Rules) {
1201 Rule.emit(OS);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001202 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001203 }
1204
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001205 OS << " return false;\n"
1206 << "}\n"
1207 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001208}
1209
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001210} // end anonymous namespace
1211
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001212//===----------------------------------------------------------------------===//
1213
1214namespace llvm {
1215void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
1216 GlobalISelEmitter(RK).run(OS);
1217}
1218} // End llvm namespace