blob: daa958e211f65f1e9bb4d490075374da63d123fc [file] [log] [blame]
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001//===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// This tablegen backend emits code for use by the GlobalISel instruction
12/// selector. See include/llvm/CodeGen/TargetGlobalISel.td.
13///
14/// This file analyzes the patterns recognized by the SelectionDAGISel tablegen
15/// backend, filters out the ones that are unsupported, maps
16/// SelectionDAG-specific constructs to their GlobalISel counterpart
17/// (when applicable: MVT to LLT; SDNode to generic Instruction).
18///
19/// Not all patterns are supported: pass the tablegen invocation
20/// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,
21/// as well as why.
22///
23/// The generated file defines a single method:
24/// bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;
25/// intended to be used in InstructionSelector::select as the first-step
26/// selector for the patterns that don't require complex C++.
27///
28/// FIXME: We'll probably want to eventually define a base
29/// "TargetGenInstructionSelector" class.
30///
31//===----------------------------------------------------------------------===//
32
33#include "CodeGenDAGPatterns.h"
Daniel Sanderse7b0d662017-04-21 15:59:56 +000034#include "SubtargetFeatureInfo.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000035#include "llvm/ADT/Optional.h"
Daniel Sanders0ed28822017-04-12 08:23:08 +000036#include "llvm/ADT/SmallSet.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000037#include "llvm/ADT/Statistic.h"
38#include "llvm/CodeGen/MachineValueType.h"
39#include "llvm/Support/CommandLine.h"
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +000040#include "llvm/Support/Error.h"
Daniel Sanders52b4ce72017-03-07 23:20:35 +000041#include "llvm/Support/LowLevelTypeImpl.h"
Pavel Labath52a82e22017-02-21 09:19:41 +000042#include "llvm/Support/ScopedPrinter.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000043#include "llvm/TableGen/Error.h"
44#include "llvm/TableGen/Record.h"
45#include "llvm/TableGen/TableGenBackend.h"
46#include <string>
Daniel Sanders8a4bae92017-03-14 21:32:08 +000047#include <numeric>
Ahmed Bougacha36f70352016-12-21 23:26:20 +000048using namespace llvm;
49
50#define DEBUG_TYPE "gisel-emitter"
51
52STATISTIC(NumPatternTotal, "Total number of patterns");
Daniel Sandersb41ce2b2017-02-20 14:31:27 +000053STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
54STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
Ahmed Bougacha36f70352016-12-21 23:26:20 +000055STATISTIC(NumPatternEmitted, "Number of patterns emitted");
56
Daniel Sanders0848b232017-03-27 13:15:13 +000057cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
58
Ahmed Bougacha36f70352016-12-21 23:26:20 +000059static cl::opt<bool> WarnOnSkippedPatterns(
60 "warn-on-skipped-patterns",
61 cl::desc("Explain why a pattern was skipped for inclusion "
62 "in the GlobalISel selector"),
Daniel Sanders0848b232017-03-27 13:15:13 +000063 cl::init(false), cl::cat(GlobalISelEmitterCat));
Ahmed Bougacha36f70352016-12-21 23:26:20 +000064
Daniel Sandersbdfebb82017-03-15 20:18:38 +000065namespace {
Ahmed Bougacha36f70352016-12-21 23:26:20 +000066//===- Helper functions ---------------------------------------------------===//
67
Daniel Sanders11300ce2017-10-13 21:28:03 +000068
69/// Get the name of the enum value used to number the predicate function.
70std::string getEnumNameForPredicate(const TreePredicateFn &Predicate) {
Simon Pilgrim6ecae9f2017-10-14 21:27:53 +000071 return "GIPFP_" + Predicate.getImmTypeIdentifier().str() + "_" +
Daniel Sanders11300ce2017-10-13 21:28:03 +000072 Predicate.getFnName();
73}
74
75/// Get the opcode used to check this predicate.
76std::string getMatchOpcodeForPredicate(const TreePredicateFn &Predicate) {
Simon Pilgrim6ecae9f2017-10-14 21:27:53 +000077 return "GIM_Check" + Predicate.getImmTypeIdentifier().str() + "ImmPredicate";
Daniel Sanders11300ce2017-10-13 21:28:03 +000078}
79
Daniel Sanders52b4ce72017-03-07 23:20:35 +000080/// This class stands in for LLT wherever we want to tablegen-erate an
81/// equivalent at compiler run-time.
82class LLTCodeGen {
83private:
84 LLT Ty;
85
86public:
87 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
88
Daniel Sanders7aac7cc2017-07-20 09:25:44 +000089 std::string getCxxEnumValue() const {
90 std::string Str;
91 raw_string_ostream OS(Str);
92
93 emitCxxEnumValue(OS);
94 return OS.str();
95 }
96
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000097 void emitCxxEnumValue(raw_ostream &OS) const {
98 if (Ty.isScalar()) {
99 OS << "GILLT_s" << Ty.getSizeInBits();
100 return;
101 }
102 if (Ty.isVector()) {
103 OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
104 return;
105 }
Daniel Sandersa71f4542017-10-16 00:56:30 +0000106 if (Ty.isPointer()) {
107 OS << "GILLT_p" << Ty.getAddressSpace();
108 if (Ty.getSizeInBits() > 0)
109 OS << "s" << Ty.getSizeInBits();
110 return;
111 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000112 llvm_unreachable("Unhandled LLT");
113 }
114
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000115 void emitCxxConstructorCall(raw_ostream &OS) const {
116 if (Ty.isScalar()) {
117 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
118 return;
119 }
120 if (Ty.isVector()) {
Daniel Sanders32291982017-06-28 13:50:04 +0000121 OS << "LLT::vector(" << Ty.getNumElements() << ", "
122 << Ty.getScalarSizeInBits() << ")";
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000123 return;
124 }
Daniel Sandersa71f4542017-10-16 00:56:30 +0000125 if (Ty.isPointer() && Ty.getSizeInBits() > 0) {
126 OS << "LLT::pointer(" << Ty.getAddressSpace() << ", "
127 << Ty.getSizeInBits() << ")";
128 return;
129 }
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000130 llvm_unreachable("Unhandled LLT");
131 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000132
133 const LLT &get() const { return Ty; }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000134
135 /// This ordering is used for std::unique() and std::sort(). There's no
Daniel Sanders032e7f22017-08-17 13:18:35 +0000136 /// particular logic behind the order but either A < B or B < A must be
137 /// true if A != B.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000138 bool operator<(const LLTCodeGen &Other) const {
Daniel Sanders032e7f22017-08-17 13:18:35 +0000139 if (Ty.isValid() != Other.Ty.isValid())
140 return Ty.isValid() < Other.Ty.isValid();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000141 if (!Ty.isValid())
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000142 return false;
Daniel Sanders032e7f22017-08-17 13:18:35 +0000143
144 if (Ty.isVector() != Other.Ty.isVector())
145 return Ty.isVector() < Other.Ty.isVector();
146 if (Ty.isScalar() != Other.Ty.isScalar())
147 return Ty.isScalar() < Other.Ty.isScalar();
148 if (Ty.isPointer() != Other.Ty.isPointer())
149 return Ty.isPointer() < Other.Ty.isPointer();
150
151 if (Ty.isPointer() && Ty.getAddressSpace() != Other.Ty.getAddressSpace())
152 return Ty.getAddressSpace() < Other.Ty.getAddressSpace();
153
154 if (Ty.isVector() && Ty.getNumElements() != Other.Ty.getNumElements())
155 return Ty.getNumElements() < Other.Ty.getNumElements();
156
157 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000158 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000159};
160
161class InstructionMatcher;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000162/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
163/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000164static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000165 MVT VT(SVT);
Daniel Sandersa71f4542017-10-16 00:56:30 +0000166
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000167 if (VT.isVector() && VT.getVectorNumElements() != 1)
Daniel Sanders32291982017-06-28 13:50:04 +0000168 return LLTCodeGen(
169 LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
Daniel Sandersa71f4542017-10-16 00:56:30 +0000170
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000171 if (VT.isInteger() || VT.isFloatingPoint())
172 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
173 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000174}
175
Daniel Sandersd0656a32017-04-13 09:45:37 +0000176static std::string explainPredicates(const TreePatternNode *N) {
177 std::string Explanation = "";
178 StringRef Separator = "";
179 for (const auto &P : N->getPredicateFns()) {
180 Explanation +=
181 (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
182 if (P.isAlwaysTrue())
183 Explanation += " always-true";
184 if (P.isImmediatePattern())
185 Explanation += " immediate";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000186
187 if (P.isUnindexed())
188 Explanation += " unindexed";
189
190 if (P.isNonExtLoad())
191 Explanation += " non-extload";
192 if (P.isAnyExtLoad())
193 Explanation += " extload";
194 if (P.isSignExtLoad())
195 Explanation += " sextload";
196 if (P.isZeroExtLoad())
197 Explanation += " zextload";
198
199 if (P.isNonTruncStore())
200 Explanation += " non-truncstore";
201 if (P.isTruncStore())
202 Explanation += " truncstore";
203
204 if (Record *VT = P.getMemoryVT())
205 Explanation += (" MemVT=" + VT->getName()).str();
206 if (Record *VT = P.getScalarMemoryVT())
207 Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000208 }
209 return Explanation;
210}
211
Daniel Sandersd0656a32017-04-13 09:45:37 +0000212std::string explainOperator(Record *Operator) {
213 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000214 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000215
216 if (Operator->isSubClassOf("Intrinsic"))
217 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
218
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000219 if (Operator->isSubClassOf("ComplexPattern"))
220 return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
221 ")")
222 .str();
223
224 return (" (Operator " + Operator->getName() + " not understood)").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000225}
226
227/// Helper function to let the emitter report skip reason error messages.
228static Error failedImport(const Twine &Reason) {
229 return make_error<StringError>(Reason, inconvertibleErrorCode());
230}
231
232static Error isTrivialOperatorNode(const TreePatternNode *N) {
233 std::string Explanation = "";
234 std::string Separator = "";
Daniel Sanders2c269f62017-08-24 09:11:20 +0000235
236 bool HasUnsupportedPredicate = false;
237 for (const auto &Predicate : N->getPredicateFns()) {
238 if (Predicate.isAlwaysTrue())
239 continue;
240
241 if (Predicate.isImmediatePattern())
242 continue;
243
Daniel Sandersa71f4542017-10-16 00:56:30 +0000244 if (Predicate.isLoad() && Predicate.isUnindexed())
245 continue;
246
247 if (Predicate.isNonExtLoad())
248 continue;
Daniel Sandersd66e0902017-10-23 18:19:24 +0000249
250 if (Predicate.isStore() && Predicate.isUnindexed())
251 continue;
252
253 if (Predicate.isNonTruncStore())
254 continue;
255
Daniel Sanders2c269f62017-08-24 09:11:20 +0000256 HasUnsupportedPredicate = true;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000257 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
258 Separator = ", ";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000259 Explanation += (Separator + "first-failing:" +
260 Predicate.getOrigPatFragRecord()->getRecord()->getName())
261 .str();
Daniel Sanders2c269f62017-08-24 09:11:20 +0000262 break;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000263 }
264
265 if (N->getTransformFn()) {
266 Explanation += Separator + "Has a transform function";
267 Separator = ", ";
268 }
269
Daniel Sanders2c269f62017-08-24 09:11:20 +0000270 if (!HasUnsupportedPredicate && !N->getTransformFn())
Daniel Sandersd0656a32017-04-13 09:45:37 +0000271 return Error::success();
272
273 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000274}
275
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000276static Record *getInitValueAsRegClass(Init *V) {
277 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
278 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
279 return VDefInit->getDef()->getValueAsDef("RegClass");
280 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
281 return VDefInit->getDef();
282 }
283 return nullptr;
284}
285
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000286std::string
287getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
288 std::string Name = "GIFBS";
289 for (const auto &Feature : FeatureBitset)
290 Name += ("_" + Feature->getName()).str();
291 return Name;
292}
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000293
294//===- MatchTable Helpers -------------------------------------------------===//
295
296class MatchTable;
297
298/// A record to be stored in a MatchTable.
299///
300/// This class represents any and all output that may be required to emit the
301/// MatchTable. Instances are most often configured to represent an opcode or
302/// value that will be emitted to the table with some formatting but it can also
303/// represent commas, comments, and other formatting instructions.
304struct MatchTableRecord {
305 enum RecordFlagsBits {
306 MTRF_None = 0x0,
307 /// Causes EmitStr to be formatted as comment when emitted.
308 MTRF_Comment = 0x1,
309 /// Causes the record value to be followed by a comma when emitted.
310 MTRF_CommaFollows = 0x2,
311 /// Causes the record value to be followed by a line break when emitted.
312 MTRF_LineBreakFollows = 0x4,
313 /// Indicates that the record defines a label and causes an additional
314 /// comment to be emitted containing the index of the label.
315 MTRF_Label = 0x8,
316 /// Causes the record to be emitted as the index of the label specified by
317 /// LabelID along with a comment indicating where that label is.
318 MTRF_JumpTarget = 0x10,
319 /// Causes the formatter to add a level of indentation before emitting the
320 /// record.
321 MTRF_Indent = 0x20,
322 /// Causes the formatter to remove a level of indentation after emitting the
323 /// record.
324 MTRF_Outdent = 0x40,
325 };
326
327 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
328 /// reference or define.
329 unsigned LabelID;
330 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
331 /// value, a label name.
332 std::string EmitStr;
333
334private:
335 /// The number of MatchTable elements described by this record. Comments are 0
336 /// while values are typically 1. Values >1 may occur when we need to emit
337 /// values that exceed the size of a MatchTable element.
338 unsigned NumElements;
339
340public:
341 /// A bitfield of RecordFlagsBits flags.
342 unsigned Flags;
343
344 MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
345 unsigned NumElements, unsigned Flags)
346 : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
347 EmitStr(EmitStr), NumElements(NumElements), Flags(Flags) {
348 assert((!LabelID_.hasValue() || LabelID != ~0u) &&
349 "This value is reserved for non-labels");
350 }
351
352 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
353 const MatchTable &Table) const;
354 unsigned size() const { return NumElements; }
355};
356
357/// Holds the contents of a generated MatchTable to enable formatting and the
358/// necessary index tracking needed to support GIM_Try.
359class MatchTable {
360 /// An unique identifier for the table. The generated table will be named
361 /// MatchTable${ID}.
362 unsigned ID;
363 /// The records that make up the table. Also includes comments describing the
364 /// values being emitted and line breaks to format it.
365 std::vector<MatchTableRecord> Contents;
366 /// The currently defined labels.
367 DenseMap<unsigned, unsigned> LabelMap;
368 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
369 unsigned CurrentSize;
370
Daniel Sanders8e82af22017-07-27 11:03:45 +0000371 /// A unique identifier for a MatchTable label.
372 static unsigned CurrentLabelID;
373
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000374public:
375 static MatchTableRecord LineBreak;
376 static MatchTableRecord Comment(StringRef Comment) {
377 return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
378 }
379 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
380 unsigned ExtraFlags = 0;
381 if (IndentAdjust > 0)
382 ExtraFlags |= MatchTableRecord::MTRF_Indent;
383 if (IndentAdjust < 0)
384 ExtraFlags |= MatchTableRecord::MTRF_Outdent;
385
386 return MatchTableRecord(None, Opcode, 1,
387 MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
388 }
389 static MatchTableRecord NamedValue(StringRef NamedValue) {
390 return MatchTableRecord(None, NamedValue, 1,
391 MatchTableRecord::MTRF_CommaFollows);
392 }
393 static MatchTableRecord NamedValue(StringRef Namespace,
394 StringRef NamedValue) {
395 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
396 MatchTableRecord::MTRF_CommaFollows);
397 }
398 static MatchTableRecord IntValue(int64_t IntValue) {
399 return MatchTableRecord(None, llvm::to_string(IntValue), 1,
400 MatchTableRecord::MTRF_CommaFollows);
401 }
402 static MatchTableRecord Label(unsigned LabelID) {
403 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
404 MatchTableRecord::MTRF_Label |
405 MatchTableRecord::MTRF_Comment |
406 MatchTableRecord::MTRF_LineBreakFollows);
407 }
408 static MatchTableRecord JumpTarget(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000409 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000410 MatchTableRecord::MTRF_JumpTarget |
411 MatchTableRecord::MTRF_Comment |
412 MatchTableRecord::MTRF_CommaFollows);
413 }
414
415 MatchTable(unsigned ID) : ID(ID), CurrentSize(0) {}
416
417 void push_back(const MatchTableRecord &Value) {
418 if (Value.Flags & MatchTableRecord::MTRF_Label)
419 defineLabel(Value.LabelID);
420 Contents.push_back(Value);
421 CurrentSize += Value.size();
422 }
423
Daniel Sanders8e82af22017-07-27 11:03:45 +0000424 unsigned allocateLabelID() const { return CurrentLabelID++; }
425
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000426 void defineLabel(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000427 LabelMap.insert(std::make_pair(LabelID, CurrentSize));
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000428 }
429
430 unsigned getLabelIndex(unsigned LabelID) const {
431 const auto I = LabelMap.find(LabelID);
432 assert(I != LabelMap.end() && "Use of undeclared label");
433 return I->second;
434 }
435
Daniel Sanders8e82af22017-07-27 11:03:45 +0000436 void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
437
438 void emitDeclaration(raw_ostream &OS) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000439 unsigned Indentation = 4;
Daniel Sanderscbbbfe42017-07-27 12:47:31 +0000440 OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000441 LineBreak.emit(OS, true, *this);
442 OS << std::string(Indentation, ' ');
443
444 for (auto I = Contents.begin(), E = Contents.end(); I != E;
445 ++I) {
446 bool LineBreakIsNext = false;
447 const auto &NextI = std::next(I);
448
449 if (NextI != E) {
450 if (NextI->EmitStr == "" &&
451 NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
452 LineBreakIsNext = true;
453 }
454
455 if (I->Flags & MatchTableRecord::MTRF_Indent)
456 Indentation += 2;
457
458 I->emit(OS, LineBreakIsNext, *this);
459 if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
460 OS << std::string(Indentation, ' ');
461
462 if (I->Flags & MatchTableRecord::MTRF_Outdent)
463 Indentation -= 2;
464 }
465 OS << "};\n";
466 }
467};
468
Daniel Sanders8e82af22017-07-27 11:03:45 +0000469unsigned MatchTable::CurrentLabelID = 0;
470
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000471MatchTableRecord MatchTable::LineBreak = {
472 None, "" /* Emit String */, 0 /* Elements */,
473 MatchTableRecord::MTRF_LineBreakFollows};
474
475void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
476 const MatchTable &Table) const {
477 bool UseLineComment =
478 LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
479 if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
480 UseLineComment = false;
481
482 if (Flags & MTRF_Comment)
483 OS << (UseLineComment ? "// " : "/*");
484
485 OS << EmitStr;
486 if (Flags & MTRF_Label)
487 OS << ": @" << Table.getLabelIndex(LabelID);
488
489 if (Flags & MTRF_Comment && !UseLineComment)
490 OS << "*/";
491
492 if (Flags & MTRF_JumpTarget) {
493 if (Flags & MTRF_Comment)
494 OS << " ";
495 OS << Table.getLabelIndex(LabelID);
496 }
497
498 if (Flags & MTRF_CommaFollows) {
499 OS << ",";
500 if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
501 OS << " ";
502 }
503
504 if (Flags & MTRF_LineBreakFollows)
505 OS << "\n";
506}
507
508MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
509 Table.push_back(Value);
510 return Table;
511}
512
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000513//===- Matchers -----------------------------------------------------------===//
514
Daniel Sandersbee57392017-04-04 13:25:23 +0000515class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000516class MatchAction;
517
518/// Generates code to check that a match rule matches.
519class RuleMatcher {
520 /// A list of matchers that all need to succeed for the current rule to match.
521 /// FIXME: This currently supports a single match position but could be
522 /// extended to support multiple positions to support div/rem fusion or
523 /// load-multiple instructions.
524 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
525
526 /// A list of actions that need to be taken when all predicates in this rule
527 /// have succeeded.
528 std::vector<std::unique_ptr<MatchAction>> Actions;
529
Daniel Sandersa7b75262017-10-31 18:50:24 +0000530 using DefinedInsnVariablesMap =
531 std::map<const InstructionMatcher *, unsigned>;
532
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000533 /// A map of instruction matchers to the local variables created by
Daniel Sanders9d662d22017-07-06 10:06:12 +0000534 /// emitCaptureOpcodes().
Daniel Sanders078572b2017-08-02 11:03:36 +0000535 DefinedInsnVariablesMap InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000536
Daniel Sandersa7b75262017-10-31 18:50:24 +0000537 using MutatableInsnSet = SmallPtrSet<const InstructionMatcher *, 4>;
538
539 // The set of instruction matchers that have not yet been claimed for mutation
540 // by a BuildMI.
541 MutatableInsnSet MutatableInsns;
542
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000543 /// A map of named operands defined by the matchers that may be referenced by
544 /// the renderers.
545 StringMap<OperandMatcher *> DefinedOperands;
546
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000547 /// ID for the next instruction variable defined with defineInsnVar()
548 unsigned NextInsnVarID;
549
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000550 std::vector<Record *> RequiredFeatures;
551
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000552 ArrayRef<SMLoc> SrcLoc;
553
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000554 typedef std::tuple<Record *, unsigned, unsigned>
555 DefinedComplexPatternSubOperand;
556 typedef StringMap<DefinedComplexPatternSubOperand>
557 DefinedComplexPatternSubOperandMap;
558 /// A map of Symbolic Names to ComplexPattern sub-operands.
559 DefinedComplexPatternSubOperandMap ComplexSubOperands;
560
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000561public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000562 RuleMatcher(ArrayRef<SMLoc> SrcLoc)
Daniel Sandersa7b75262017-10-31 18:50:24 +0000563 : Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(),
564 DefinedOperands(), NextInsnVarID(0), SrcLoc(SrcLoc),
565 ComplexSubOperands() {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000566 RuleMatcher(RuleMatcher &&Other) = default;
567 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000568
Daniel Sanders05540042017-08-08 10:44:31 +0000569 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000570 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000571 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000572
573 template <class Kind, class... Args> Kind &addAction(Args &&... args);
574
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000575 /// Define an instruction without emitting any code to do so.
576 /// This is used for the root of the match.
577 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
578 /// Define an instruction and emit corresponding state-machine opcodes.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000579 unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000580 unsigned InsnVarID, unsigned OpIdx);
581 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sanders078572b2017-08-02 11:03:36 +0000582 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
583 return InsnVariableIDs.begin();
584 }
585 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
586 return InsnVariableIDs.end();
587 }
588 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
589 defined_insn_vars() const {
590 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
591 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000592
Daniel Sandersa7b75262017-10-31 18:50:24 +0000593 MutatableInsnSet::const_iterator mutatable_insns_begin() const {
594 return MutatableInsns.begin();
595 }
596 MutatableInsnSet::const_iterator mutatable_insns_end() const {
597 return MutatableInsns.end();
598 }
599 iterator_range<typename MutatableInsnSet::const_iterator>
600 mutatable_insns() const {
601 return make_range(mutatable_insns_begin(), mutatable_insns_end());
602 }
603 void reserveInsnMatcherForMutation(const InstructionMatcher *InsnMatcher) {
604 bool R = MutatableInsns.erase(InsnMatcher);
605 assert(R && "Reserving a mutatable insn that isn't available");
606 (void)R;
607 }
608
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000609 void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
610
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000611 void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
612 unsigned RendererID, unsigned SubOperandID) {
613 assert(ComplexSubOperands.count(SymbolicName) == 0 && "Already defined");
614 ComplexSubOperands[SymbolicName] =
615 std::make_tuple(ComplexPattern, RendererID, SubOperandID);
616 }
617 Optional<DefinedComplexPatternSubOperand>
618 getComplexSubOperand(StringRef SymbolicName) const {
619 const auto &I = ComplexSubOperands.find(SymbolicName);
620 if (I == ComplexSubOperands.end())
621 return None;
622 return I->second;
623 }
624
Daniel Sanders05540042017-08-08 10:44:31 +0000625 const InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000626 const OperandMatcher &getOperandMatcher(StringRef Name) const;
Daniel Sanders05540042017-08-08 10:44:31 +0000627
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000628 void emitCaptureOpcodes(MatchTable &Table);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000629
Daniel Sanders8e82af22017-07-27 11:03:45 +0000630 void emit(MatchTable &Table);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000631
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000632 /// Compare the priority of this object and B.
633 ///
634 /// Returns true if this object is more important than B.
635 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000636
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000637 /// Report the maximum number of temporary operands needed by the rule
638 /// matcher.
639 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000640
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000641 // FIXME: Remove this as soon as possible
642 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000643};
644
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000645template <class PredicateTy> class PredicateListMatcher {
646private:
647 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
648 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000649
Daniel Sanders2c269f62017-08-24 09:11:20 +0000650 /// Template instantiations should specialize this to return a string to use
651 /// for the comment emitted when there are no predicates.
652 std::string getNoPredicateComment() const;
653
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000654public:
655 /// Construct a new operand predicate and add it to the matcher.
656 template <class Kind, class... Args>
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000657 Optional<Kind *> addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000658 Predicates.emplace_back(
659 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000660 return static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000661 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000662
Daniel Sanders32291982017-06-28 13:50:04 +0000663 typename PredicateVec::const_iterator predicates_begin() const {
664 return Predicates.begin();
665 }
666 typename PredicateVec::const_iterator predicates_end() const {
667 return Predicates.end();
668 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000669 iterator_range<typename PredicateVec::const_iterator> predicates() const {
670 return make_range(predicates_begin(), predicates_end());
671 }
Daniel Sanders32291982017-06-28 13:50:04 +0000672 typename PredicateVec::size_type predicates_size() const {
673 return Predicates.size();
674 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000675
Daniel Sanders9d662d22017-07-06 10:06:12 +0000676 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000677 template <class... Args>
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000678 void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000679 if (Predicates.empty()) {
Daniel Sanders2c269f62017-08-24 09:11:20 +0000680 Table << MatchTable::Comment(getNoPredicateComment())
681 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000682 return;
683 }
684
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000685 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000686 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000687 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000688};
689
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000690/// Generates code to check a predicate of an operand.
691///
692/// Typical predicates include:
693/// * Operand is a particular register.
694/// * Operand is assigned a particular register bank.
695/// * Operand is an MBB.
696class OperandPredicateMatcher {
697public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000698 /// This enum is used for RTTI and also defines the priority that is given to
699 /// the predicate when generating the matcher code. Kinds with higher priority
700 /// must be tested first.
701 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000702 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
703 /// but OPM_Int must have priority over OPM_RegBank since constant integers
704 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000705 enum PredicateKind {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000706 OPM_SameOperand,
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000707 OPM_ComplexPattern,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000708 OPM_IntrinsicID,
Daniel Sanders05540042017-08-08 10:44:31 +0000709 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000710 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000711 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000712 OPM_LLT,
Daniel Sandersa71f4542017-10-16 00:56:30 +0000713 OPM_PointerToAny,
Daniel Sanders759ff412017-02-24 13:58:11 +0000714 OPM_RegBank,
715 OPM_MBB,
716 };
717
718protected:
719 PredicateKind Kind;
720
721public:
722 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000723 virtual ~OperandPredicateMatcher() {}
724
Daniel Sanders759ff412017-02-24 13:58:11 +0000725 PredicateKind getKind() const { return Kind; }
726
Daniel Sanders9d662d22017-07-06 10:06:12 +0000727 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sandersbee57392017-04-04 13:25:23 +0000728 ///
Daniel Sanders9d662d22017-07-06 10:06:12 +0000729 /// Only InstructionOperandMatcher needs to do anything for this method the
730 /// rest just walk the tree.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000731 virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +0000732 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000733
Daniel Sanders9d662d22017-07-06 10:06:12 +0000734 /// Emit MatchTable opcodes that check the predicate for the given operand.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000735 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000736 unsigned InsnVarID,
737 unsigned OpIdx) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000738
739 /// Compare the priority of this object and B.
740 ///
741 /// Returns true if this object is more important than B.
Daniel Sanders05540042017-08-08 10:44:31 +0000742 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000743
744 /// Report the maximum number of temporary operands needed by the predicate
745 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000746 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000747};
748
Daniel Sanders2c269f62017-08-24 09:11:20 +0000749template <>
750std::string
751PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
752 return "No operand predicates";
753}
754
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000755/// Generates code to check that a register operand is defined by the same exact
756/// one as another.
757class SameOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000758 std::string MatchingName;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000759
760public:
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000761 SameOperandMatcher(StringRef MatchingName)
762 : OperandPredicateMatcher(OPM_SameOperand), MatchingName(MatchingName) {}
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000763
764 static bool classof(const OperandPredicateMatcher *P) {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000765 return P->getKind() == OPM_SameOperand;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000766 }
767
768 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
769 unsigned InsnVarID, unsigned OpIdx) const override;
770};
771
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000772/// Generates code to check that an operand is a particular LLT.
773class LLTOperandMatcher : public OperandPredicateMatcher {
774protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000775 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000776
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000777public:
Daniel Sanders032e7f22017-08-17 13:18:35 +0000778 static std::set<LLTCodeGen> KnownTypes;
779
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000780 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders032e7f22017-08-17 13:18:35 +0000781 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {
782 KnownTypes.insert(Ty);
783 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000784
785 static bool classof(const OperandPredicateMatcher *P) {
786 return P->getKind() == OPM_LLT;
787 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000788
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000789 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000790 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000791 Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
792 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
793 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
794 << MatchTable::NamedValue(Ty.getCxxEnumValue())
795 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000796 }
797};
798
Daniel Sanders032e7f22017-08-17 13:18:35 +0000799std::set<LLTCodeGen> LLTOperandMatcher::KnownTypes;
800
Daniel Sandersa71f4542017-10-16 00:56:30 +0000801/// Generates code to check that an operand is a pointer to any address space.
802///
803/// In SelectionDAG, the types did not describe pointers or address spaces. As a
804/// result, iN is used to describe a pointer of N bits to any address space and
805/// PatFrag predicates are typically used to constrain the address space. There's
806/// no reliable means to derive the missing type information from the pattern so
807/// imported rules must test the components of a pointer separately.
808///
Daniel Sandersea8711b2017-10-16 03:36:29 +0000809/// If SizeInBits is zero, then the pointer size will be obtained from the
810/// subtarget.
Daniel Sandersa71f4542017-10-16 00:56:30 +0000811class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
812protected:
813 unsigned SizeInBits;
814
815public:
816 PointerToAnyOperandMatcher(unsigned SizeInBits)
817 : OperandPredicateMatcher(OPM_PointerToAny), SizeInBits(SizeInBits) {}
818
819 static bool classof(const OperandPredicateMatcher *P) {
820 return P->getKind() == OPM_PointerToAny;
821 }
822
823 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
824 unsigned InsnVarID, unsigned OpIdx) const override {
825 Table << MatchTable::Opcode("GIM_CheckPointerToAny") << MatchTable::Comment("MI")
826 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
827 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("SizeInBits")
828 << MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
829 }
830};
831
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000832/// Generates code to check that an operand is a particular target constant.
833class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
834protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000835 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000836 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000837
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000838 unsigned getAllocatedTemporariesBaseID() const;
839
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000840public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000841 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
842 const Record &TheDef)
843 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
844 TheDef(TheDef) {}
845
846 static bool classof(const OperandPredicateMatcher *P) {
847 return P->getKind() == OPM_ComplexPattern;
848 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000849
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000850 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000851 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000852 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000853 Table << MatchTable::Opcode("GIM_CheckComplexPattern")
854 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
855 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
856 << MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
857 << MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
858 << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000859 }
860
Daniel Sanders2deea182017-04-22 15:11:04 +0000861 unsigned countRendererFns() const override {
862 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000863 }
864};
865
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000866/// Generates code to check that an operand is in a particular register bank.
867class RegisterBankOperandMatcher : public OperandPredicateMatcher {
868protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000869 const CodeGenRegisterClass &RC;
870
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000871public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000872 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
873 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
874
875 static bool classof(const OperandPredicateMatcher *P) {
876 return P->getKind() == OPM_RegBank;
877 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000878
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000879 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000880 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000881 Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
882 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
883 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
884 << MatchTable::Comment("RC")
885 << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
886 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000887 }
888};
889
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000890/// Generates code to check that an operand is a basic block.
891class MBBOperandMatcher : public OperandPredicateMatcher {
892public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000893 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
894
895 static bool classof(const OperandPredicateMatcher *P) {
896 return P->getKind() == OPM_MBB;
897 }
898
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000899 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000900 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000901 Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
902 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
903 << MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000904 }
905};
906
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000907/// Generates code to check that an operand is a G_CONSTANT with a particular
908/// int.
909class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000910protected:
911 int64_t Value;
912
913public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000914 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000915 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
916
917 static bool classof(const OperandPredicateMatcher *P) {
918 return P->getKind() == OPM_Int;
919 }
920
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000921 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000922 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000923 Table << MatchTable::Opcode("GIM_CheckConstantInt")
924 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
925 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
926 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000927 }
928};
929
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000930/// Generates code to check that an operand is a raw int (where MO.isImm() or
931/// MO.isCImm() is true).
932class LiteralIntOperandMatcher : public OperandPredicateMatcher {
933protected:
934 int64_t Value;
935
936public:
937 LiteralIntOperandMatcher(int64_t Value)
938 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
939
940 static bool classof(const OperandPredicateMatcher *P) {
941 return P->getKind() == OPM_LiteralInt;
942 }
943
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000944 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000945 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000946 Table << MatchTable::Opcode("GIM_CheckLiteralInt")
947 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
948 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
949 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000950 }
951};
952
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000953/// Generates code to check that an operand is an intrinsic ID.
954class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
955protected:
956 const CodeGenIntrinsic *II;
957
958public:
959 IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
960 : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
961
962 static bool classof(const OperandPredicateMatcher *P) {
963 return P->getKind() == OPM_IntrinsicID;
964 }
965
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000966 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000967 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000968 Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
969 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
970 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
971 << MatchTable::NamedValue("Intrinsic::" + II->EnumName)
972 << MatchTable::LineBreak;
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000973 }
974};
975
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000976/// Generates code to check that a set of predicates match for a particular
977/// operand.
978class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
979protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000980 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000981 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000982 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000983
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000984 /// The index of the first temporary variable allocated to this operand. The
985 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +0000986 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000987 unsigned AllocatedTemporariesBaseID;
988
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000989public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000990 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000991 const std::string &SymbolicName,
992 unsigned AllocatedTemporariesBaseID)
993 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
994 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000995
996 bool hasSymbolicName() const { return !SymbolicName.empty(); }
997 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +0000998 void setSymbolicName(StringRef Name) {
999 assert(SymbolicName.empty() && "Operand already has a symbolic name");
1000 SymbolicName = Name;
1001 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001002 unsigned getOperandIndex() const { return OpIdx; }
1003
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001004 std::string getOperandExpr(unsigned InsnVarID) const {
1005 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
1006 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +00001007 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001008
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001009 InstructionMatcher &getInstructionMatcher() const { return Insn; }
1010
Daniel Sandersa71f4542017-10-16 00:56:30 +00001011 Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001012 bool OperandIsAPointer);
Daniel Sandersa71f4542017-10-16 00:56:30 +00001013
Daniel Sanders9d662d22017-07-06 10:06:12 +00001014 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001015 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001016 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +00001017 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001018 Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00001019 }
1020
Daniel Sanders9d662d22017-07-06 10:06:12 +00001021 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001022 /// InsnVarID matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001023 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001024 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001025 std::string Comment;
1026 raw_string_ostream CommentOS(Comment);
1027 CommentOS << "MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001028 if (SymbolicName.empty())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001029 CommentOS << "Operand " << OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001030 else
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001031 CommentOS << SymbolicName;
1032 Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
1033
1034 emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001035 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001036
1037 /// Compare the priority of this object and B.
1038 ///
1039 /// Returns true if this object is more important than B.
1040 bool isHigherPriorityThan(const OperandMatcher &B) const {
1041 // Operand matchers involving more predicates have higher priority.
1042 if (predicates_size() > B.predicates_size())
1043 return true;
1044 if (predicates_size() < B.predicates_size())
1045 return false;
1046
1047 // This assumes that predicates are added in a consistent order.
1048 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1049 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1050 return true;
1051 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1052 return false;
1053 }
1054
1055 return false;
1056 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001057
1058 /// Report the maximum number of temporary operands needed by the operand
1059 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001060 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001061 return std::accumulate(
1062 predicates().begin(), predicates().end(), 0,
1063 [](unsigned A,
1064 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001065 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001066 });
1067 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001068
1069 unsigned getAllocatedTemporariesBaseID() const {
1070 return AllocatedTemporariesBaseID;
1071 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001072
1073 bool isSameAsAnotherOperand() const {
1074 for (const auto &Predicate : predicates())
1075 if (isa<SameOperandMatcher>(Predicate))
1076 return true;
1077 return false;
1078 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001079};
1080
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001081// Specialize OperandMatcher::addPredicate() to refrain from adding redundant
1082// predicates.
1083template <>
1084template <class Kind, class... Args>
1085Optional<Kind *>
1086PredicateListMatcher<OperandPredicateMatcher>::addPredicate(Args &&... args) {
1087 if (static_cast<OperandMatcher *>(this)->isSameAsAnotherOperand())
1088 return None;
1089 Predicates.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1090 return static_cast<Kind *>(Predicates.back().get());
1091}
1092
1093Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
1094 bool OperandIsAPointer) {
1095 if (!VTy.isMachineValueType())
1096 return failedImport("unsupported typeset");
1097
1098 if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
1099 addPredicate<PointerToAnyOperandMatcher>(0);
1100 return Error::success();
1101 }
1102
1103 auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
1104 if (!OpTyOrNone)
1105 return failedImport("unsupported type");
1106
1107 if (OperandIsAPointer)
1108 addPredicate<PointerToAnyOperandMatcher>(OpTyOrNone->get().getSizeInBits());
1109 else
1110 addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1111 return Error::success();
1112}
1113
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001114unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
1115 return Operand.getAllocatedTemporariesBaseID();
1116}
1117
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001118/// Generates code to check a predicate on an instruction.
1119///
1120/// Typical predicates include:
1121/// * The opcode of the instruction is a particular value.
1122/// * The nsw/nuw flag is/isn't set.
1123class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +00001124protected:
1125 /// This enum is used for RTTI and also defines the priority that is given to
1126 /// the predicate when generating the matcher code. Kinds with higher priority
1127 /// must be tested first.
1128 enum PredicateKind {
1129 IPM_Opcode,
Daniel Sanders2c269f62017-08-24 09:11:20 +00001130 IPM_ImmPredicate,
Daniel Sanders39690bd2017-10-15 02:41:12 +00001131 IPM_NonAtomicMMO,
Daniel Sanders759ff412017-02-24 13:58:11 +00001132 };
1133
1134 PredicateKind Kind;
1135
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001136public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001137 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001138 virtual ~InstructionPredicateMatcher() {}
1139
Daniel Sanders759ff412017-02-24 13:58:11 +00001140 PredicateKind getKind() const { return Kind; }
1141
Daniel Sanders9d662d22017-07-06 10:06:12 +00001142 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001143 /// InsnVarID matches the predicate.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001144 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001145 unsigned InsnVarID) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +00001146
1147 /// Compare the priority of this object and B.
1148 ///
1149 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001150 virtual bool
1151 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +00001152 return Kind < B.Kind;
1153 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001154
1155 /// Report the maximum number of temporary operands needed by the predicate
1156 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001157 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001158};
1159
Daniel Sanders2c269f62017-08-24 09:11:20 +00001160template <>
1161std::string
1162PredicateListMatcher<InstructionPredicateMatcher>::getNoPredicateComment() const {
1163 return "No instruction predicates";
1164}
1165
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001166/// Generates code to check the opcode of an instruction.
1167class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1168protected:
1169 const CodeGenInstruction *I;
1170
1171public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001172 InstructionOpcodeMatcher(const CodeGenInstruction *I)
1173 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001174
Daniel Sanders759ff412017-02-24 13:58:11 +00001175 static bool classof(const InstructionPredicateMatcher *P) {
1176 return P->getKind() == IPM_Opcode;
1177 }
1178
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001179 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001180 unsigned InsnVarID) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001181 Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
1182 << MatchTable::IntValue(InsnVarID)
1183 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1184 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001185 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001186
1187 /// Compare the priority of this object and B.
1188 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001189 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001190 bool
1191 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +00001192 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
1193 return true;
1194 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
1195 return false;
1196
1197 // Prioritize opcodes for cosmetic reasons in the generated source. Although
1198 // this is cosmetic at the moment, we may want to drive a similar ordering
1199 // using instruction frequency information to improve compile time.
1200 if (const InstructionOpcodeMatcher *BO =
1201 dyn_cast<InstructionOpcodeMatcher>(&B))
1202 return I->TheDef->getName() < BO->I->TheDef->getName();
1203
1204 return false;
1205 };
Daniel Sanders05540042017-08-08 10:44:31 +00001206
1207 bool isConstantInstruction() const {
1208 return I->TheDef->getName() == "G_CONSTANT";
1209 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001210};
1211
Daniel Sanders2c269f62017-08-24 09:11:20 +00001212/// Generates code to check that this instruction is a constant whose value
1213/// meets an immediate predicate.
1214///
1215/// Immediates are slightly odd since they are typically used like an operand
1216/// but are represented as an operator internally. We typically write simm8:$src
1217/// in a tablegen pattern, but this is just syntactic sugar for
1218/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1219/// that will be matched and the predicate (which is attached to the imm
1220/// operator) that will be tested. In SelectionDAG this describes a
1221/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
1222///
1223/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1224/// this representation, the immediate could be tested with an
1225/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1226/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1227/// there are two implementation issues with producing that matcher
1228/// configuration from the SelectionDAG pattern:
1229/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1230/// were we to sink the immediate predicate to the operand we would have to
1231/// have two partial implementations of PatFrag support, one for immediates
1232/// and one for non-immediates.
1233/// * At the point we handle the predicate, the OperandMatcher hasn't been
1234/// created yet. If we were to sink the predicate to the OperandMatcher we
1235/// would also have to complicate (or duplicate) the code that descends and
1236/// creates matchers for the subtree.
1237/// Overall, it's simpler to handle it in the place it was found.
1238class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1239protected:
1240 TreePredicateFn Predicate;
1241
1242public:
1243 InstructionImmPredicateMatcher(const TreePredicateFn &Predicate)
1244 : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {}
1245
1246 static bool classof(const InstructionPredicateMatcher *P) {
1247 return P->getKind() == IPM_ImmPredicate;
1248 }
1249
1250 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1251 unsigned InsnVarID) const override {
Daniel Sanders11300ce2017-10-13 21:28:03 +00001252 Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001253 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1254 << MatchTable::Comment("Predicate")
Daniel Sanders11300ce2017-10-13 21:28:03 +00001255 << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001256 << MatchTable::LineBreak;
1257 }
1258};
1259
Daniel Sanders39690bd2017-10-15 02:41:12 +00001260/// Generates code to check that a memory instruction has a non-atomic MachineMemoryOperand.
1261class NonAtomicMMOPredicateMatcher : public InstructionPredicateMatcher {
1262public:
1263 NonAtomicMMOPredicateMatcher()
1264 : InstructionPredicateMatcher(IPM_NonAtomicMMO) {}
1265
1266 static bool classof(const InstructionPredicateMatcher *P) {
1267 return P->getKind() == IPM_NonAtomicMMO;
1268 }
1269
1270 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1271 unsigned InsnVarID) const override {
1272 Table << MatchTable::Opcode("GIM_CheckNonAtomic")
1273 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1274 << MatchTable::LineBreak;
1275 }
1276};
1277
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001278/// Generates code to check that a set of predicates and operands match for a
1279/// particular instruction.
1280///
1281/// Typical predicates include:
1282/// * Has a specific opcode.
1283/// * Has an nsw/nuw flag or doesn't.
1284class InstructionMatcher
1285 : public PredicateListMatcher<InstructionPredicateMatcher> {
1286protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001287 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001288
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001289 RuleMatcher &Rule;
1290
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001291 /// The operands to match. All rendered operands must be present even if the
1292 /// condition is always true.
1293 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001294
Daniel Sanders05540042017-08-08 10:44:31 +00001295 std::string SymbolicName;
1296
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001297public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001298 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
1299 : Rule(Rule), SymbolicName(SymbolicName) {}
1300
1301 RuleMatcher &getRuleMatcher() const { return Rule; }
Daniel Sanders05540042017-08-08 10:44:31 +00001302
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001303 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001304 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1305 unsigned AllocatedTemporariesBaseID) {
1306 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
1307 AllocatedTemporariesBaseID));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001308 if (!SymbolicName.empty())
1309 Rule.defineOperand(SymbolicName, *Operands.back());
1310
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001311 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001312 }
1313
Daniel Sandersffc7d582017-03-29 15:37:18 +00001314 OperandMatcher &getOperand(unsigned OpIdx) {
1315 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001316 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
1317 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001318 });
1319 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001320 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001321 llvm_unreachable("Failed to lookup operand");
1322 }
1323
Daniel Sanders05540042017-08-08 10:44:31 +00001324 StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001325 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +00001326 OperandVec::iterator operands_begin() { return Operands.begin(); }
1327 OperandVec::iterator operands_end() { return Operands.end(); }
1328 iterator_range<OperandVec::iterator> operands() {
1329 return make_range(operands_begin(), operands_end());
1330 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001331 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1332 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001333 iterator_range<OperandVec::const_iterator> operands() const {
1334 return make_range(operands_begin(), operands_end());
1335 }
1336
Daniel Sanders9d662d22017-07-06 10:06:12 +00001337 /// Emit MatchTable opcodes to check the shape of the match and capture
1338 /// instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001339 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001340 unsigned InsnID) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001341 Table << MatchTable::Opcode("GIM_CheckNumOperands")
1342 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1343 << MatchTable::Comment("Expected")
1344 << MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001345 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001346 Operand->emitCaptureOpcodes(Table, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001347 }
1348
Daniel Sanders9d662d22017-07-06 10:06:12 +00001349 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001350 /// InsnVarName matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001351 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001352 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001353 emitPredicateListOpcodes(Table, Rule, InsnVarID);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001354 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001355 Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001356 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001357
1358 /// Compare the priority of this object and B.
1359 ///
1360 /// Returns true if this object is more important than B.
1361 bool isHigherPriorityThan(const InstructionMatcher &B) const {
1362 // Instruction matchers involving more operands have higher priority.
1363 if (Operands.size() > B.Operands.size())
1364 return true;
1365 if (Operands.size() < B.Operands.size())
1366 return false;
1367
1368 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1369 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1370 return true;
1371 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1372 return false;
1373 }
1374
1375 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001376 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001377 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001378 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001379 return false;
1380 }
1381
1382 return false;
1383 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001384
1385 /// Report the maximum number of temporary operands needed by the instruction
1386 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001387 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001388 return std::accumulate(predicates().begin(), predicates().end(), 0,
1389 [](unsigned A,
1390 const std::unique_ptr<InstructionPredicateMatcher>
1391 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001392 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001393 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001394 std::accumulate(
1395 Operands.begin(), Operands.end(), 0,
1396 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001397 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001398 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001399 }
Daniel Sanders05540042017-08-08 10:44:31 +00001400
1401 bool isConstantInstruction() const {
1402 for (const auto &P : predicates())
1403 if (const InstructionOpcodeMatcher *Opcode =
1404 dyn_cast<InstructionOpcodeMatcher>(P.get()))
1405 return Opcode->isConstantInstruction();
1406 return false;
1407 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001408};
1409
Daniel Sandersbee57392017-04-04 13:25:23 +00001410/// Generates code to check that the operand is a register defined by an
1411/// instruction that matches the given instruction matcher.
1412///
1413/// For example, the pattern:
1414/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1415/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1416/// the:
1417/// (G_ADD $src1, $src2)
1418/// subpattern.
1419class InstructionOperandMatcher : public OperandPredicateMatcher {
1420protected:
1421 std::unique_ptr<InstructionMatcher> InsnMatcher;
1422
1423public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001424 InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName)
Daniel Sandersbee57392017-04-04 13:25:23 +00001425 : OperandPredicateMatcher(OPM_Instruction),
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001426 InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {}
Daniel Sandersbee57392017-04-04 13:25:23 +00001427
1428 static bool classof(const OperandPredicateMatcher *P) {
1429 return P->getKind() == OPM_Instruction;
1430 }
1431
1432 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1433
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001434 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001435 unsigned InsnID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001436 unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
1437 InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001438 }
1439
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001440 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001441 unsigned InsnVarID_,
1442 unsigned OpIdx_) const override {
1443 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001444 InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001445 }
1446};
1447
Daniel Sanders43c882c2017-02-01 10:53:10 +00001448//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001449class OperandRenderer {
1450public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001451 enum RendererKind {
1452 OR_Copy,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001453 OR_CopyOrAddZeroReg,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001454 OR_CopySubReg,
Daniel Sanders05540042017-08-08 10:44:31 +00001455 OR_CopyConstantAsImm,
Daniel Sanders11300ce2017-10-13 21:28:03 +00001456 OR_CopyFConstantAsFPImm,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001457 OR_Imm,
1458 OR_Register,
1459 OR_ComplexPattern
1460 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001461
1462protected:
1463 RendererKind Kind;
1464
1465public:
1466 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1467 virtual ~OperandRenderer() {}
1468
1469 RendererKind getKind() const { return Kind; }
1470
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001471 virtual void emitRenderOpcodes(MatchTable &Table,
1472 RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001473};
1474
1475/// A CopyRenderer emits code to copy a single operand from an existing
1476/// instruction to the one being built.
1477class CopyRenderer : public OperandRenderer {
1478protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001479 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001480 /// The name of the operand.
1481 const StringRef SymbolicName;
1482
1483public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001484 CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
1485 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
Daniel Sanders05540042017-08-08 10:44:31 +00001486 SymbolicName(SymbolicName) {
1487 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1488 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001489
1490 static bool classof(const OperandRenderer *R) {
1491 return R->getKind() == OR_Copy;
1492 }
1493
1494 const StringRef getSymbolicName() const { return SymbolicName; }
1495
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001496 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001497 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001498 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001499 Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
1500 << MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
1501 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1502 << MatchTable::IntValue(Operand.getOperandIndex())
1503 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001504 }
1505};
1506
Daniel Sandersd66e0902017-10-23 18:19:24 +00001507/// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1508/// existing instruction to the one being built. If the operand turns out to be
1509/// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1510class CopyOrAddZeroRegRenderer : public OperandRenderer {
1511protected:
1512 unsigned NewInsnID;
1513 /// The name of the operand.
1514 const StringRef SymbolicName;
1515 const Record *ZeroRegisterDef;
1516
1517public:
1518 CopyOrAddZeroRegRenderer(unsigned NewInsnID,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001519 StringRef SymbolicName, Record *ZeroRegisterDef)
1520 : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
1521 SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
1522 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1523 }
1524
1525 static bool classof(const OperandRenderer *R) {
1526 return R->getKind() == OR_CopyOrAddZeroReg;
1527 }
1528
1529 const StringRef getSymbolicName() const { return SymbolicName; }
1530
1531 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1532 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
1533 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
1534 Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg")
1535 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1536 << MatchTable::Comment("OldInsnID")
1537 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1538 << MatchTable::IntValue(Operand.getOperandIndex())
1539 << MatchTable::NamedValue(
1540 (ZeroRegisterDef->getValue("Namespace")
1541 ? ZeroRegisterDef->getValueAsString("Namespace")
1542 : ""),
1543 ZeroRegisterDef->getName())
1544 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1545 }
1546};
1547
Daniel Sanders05540042017-08-08 10:44:31 +00001548/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1549/// an extended immediate operand.
1550class CopyConstantAsImmRenderer : public OperandRenderer {
1551protected:
1552 unsigned NewInsnID;
1553 /// The name of the operand.
1554 const std::string SymbolicName;
1555 bool Signed;
1556
1557public:
1558 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1559 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
1560 SymbolicName(SymbolicName), Signed(true) {}
1561
1562 static bool classof(const OperandRenderer *R) {
1563 return R->getKind() == OR_CopyConstantAsImm;
1564 }
1565
1566 const StringRef getSymbolicName() const { return SymbolicName; }
1567
1568 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1569 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1570 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1571 Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
1572 : "GIR_CopyConstantAsUImm")
1573 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1574 << MatchTable::Comment("OldInsnID")
1575 << MatchTable::IntValue(OldInsnVarID)
1576 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1577 }
1578};
1579
Daniel Sanders11300ce2017-10-13 21:28:03 +00001580/// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1581/// instruction to an extended immediate operand.
1582class CopyFConstantAsFPImmRenderer : public OperandRenderer {
1583protected:
1584 unsigned NewInsnID;
1585 /// The name of the operand.
1586 const std::string SymbolicName;
1587
1588public:
1589 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1590 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
1591 SymbolicName(SymbolicName) {}
1592
1593 static bool classof(const OperandRenderer *R) {
1594 return R->getKind() == OR_CopyFConstantAsFPImm;
1595 }
1596
1597 const StringRef getSymbolicName() const { return SymbolicName; }
1598
1599 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1600 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1601 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1602 Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
1603 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1604 << MatchTable::Comment("OldInsnID")
1605 << MatchTable::IntValue(OldInsnVarID)
1606 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1607 }
1608};
1609
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001610/// A CopySubRegRenderer emits code to copy a single register operand from an
1611/// existing instruction to the one being built and indicate that only a
1612/// subregister should be copied.
1613class CopySubRegRenderer : public OperandRenderer {
1614protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001615 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001616 /// The name of the operand.
1617 const StringRef SymbolicName;
1618 /// The subregister to extract.
1619 const CodeGenSubRegIndex *SubReg;
1620
1621public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001622 CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
1623 const CodeGenSubRegIndex *SubReg)
1624 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001625 SymbolicName(SymbolicName), SubReg(SubReg) {}
1626
1627 static bool classof(const OperandRenderer *R) {
1628 return R->getKind() == OR_CopySubReg;
1629 }
1630
1631 const StringRef getSymbolicName() const { return SymbolicName; }
1632
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001633 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001634 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001635 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001636 Table << MatchTable::Opcode("GIR_CopySubReg")
1637 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1638 << MatchTable::Comment("OldInsnID")
1639 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1640 << MatchTable::IntValue(Operand.getOperandIndex())
1641 << MatchTable::Comment("SubRegIdx")
1642 << MatchTable::IntValue(SubReg->EnumValue)
1643 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001644 }
1645};
1646
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001647/// Adds a specific physical register to the instruction being built.
1648/// This is typically useful for WZR/XZR on AArch64.
1649class AddRegisterRenderer : public OperandRenderer {
1650protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001651 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001652 const Record *RegisterDef;
1653
1654public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001655 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
1656 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
1657 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001658
1659 static bool classof(const OperandRenderer *R) {
1660 return R->getKind() == OR_Register;
1661 }
1662
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001663 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1664 Table << MatchTable::Opcode("GIR_AddRegister")
1665 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1666 << MatchTable::NamedValue(
1667 (RegisterDef->getValue("Namespace")
1668 ? RegisterDef->getValueAsString("Namespace")
1669 : ""),
1670 RegisterDef->getName())
1671 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001672 }
1673};
1674
Daniel Sanders0ed28822017-04-12 08:23:08 +00001675/// Adds a specific immediate to the instruction being built.
1676class ImmRenderer : public OperandRenderer {
1677protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001678 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001679 int64_t Imm;
1680
1681public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001682 ImmRenderer(unsigned InsnID, int64_t Imm)
1683 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001684
1685 static bool classof(const OperandRenderer *R) {
1686 return R->getKind() == OR_Imm;
1687 }
1688
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001689 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1690 Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
1691 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
1692 << MatchTable::IntValue(Imm) << MatchTable::LineBreak;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001693 }
1694};
1695
Daniel Sanders2deea182017-04-22 15:11:04 +00001696/// Adds operands by calling a renderer function supplied by the ComplexPattern
1697/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001698class RenderComplexPatternOperand : public OperandRenderer {
1699private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001700 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001701 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001702 /// The name of the operand.
1703 const StringRef SymbolicName;
1704 /// The renderer number. This must be unique within a rule since it's used to
1705 /// identify a temporary variable to hold the renderer function.
1706 unsigned RendererID;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001707 /// When provided, this is the suboperand of the ComplexPattern operand to
1708 /// render. Otherwise all the suboperands will be rendered.
1709 Optional<unsigned> SubOperand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001710
1711 unsigned getNumOperands() const {
1712 return TheDef.getValueAsDag("Operands")->getNumArgs();
1713 }
1714
1715public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001716 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001717 StringRef SymbolicName, unsigned RendererID,
1718 Optional<unsigned> SubOperand = None)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001719 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001720 SymbolicName(SymbolicName), RendererID(RendererID),
1721 SubOperand(SubOperand) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001722
1723 static bool classof(const OperandRenderer *R) {
1724 return R->getKind() == OR_ComplexPattern;
1725 }
1726
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001727 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001728 Table << MatchTable::Opcode(SubOperand.hasValue() ? "GIR_ComplexSubOperandRenderer"
1729 : "GIR_ComplexRenderer")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001730 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1731 << MatchTable::Comment("RendererID")
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001732 << MatchTable::IntValue(RendererID);
1733 if (SubOperand.hasValue())
1734 Table << MatchTable::Comment("SubOperand")
1735 << MatchTable::IntValue(SubOperand.getValue());
1736 Table << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001737 }
1738};
1739
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001740/// An action taken when all Matcher predicates succeeded for a parent rule.
1741///
1742/// Typical actions include:
1743/// * Changing the opcode of an instruction.
1744/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001745class MatchAction {
1746public:
1747 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001748
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001749 /// Emit the MatchTable opcodes to implement the action.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001750 virtual void emitActionOpcodes(MatchTable &Table,
1751 RuleMatcher &Rule) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001752};
1753
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001754/// Generates a comment describing the matched rule being acted upon.
1755class DebugCommentAction : public MatchAction {
1756private:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001757 std::string S;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001758
1759public:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001760 DebugCommentAction(StringRef S) : S(S) {}
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001761
Daniel Sandersa7b75262017-10-31 18:50:24 +00001762 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001763 Table << MatchTable::Comment(S) << MatchTable::LineBreak;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001764 }
1765};
1766
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001767/// Generates code to build an instruction or mutate an existing instruction
1768/// into the desired instruction when this is possible.
1769class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001770private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001771 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001772 const CodeGenInstruction *I;
Daniel Sanders64f745c2017-10-24 17:08:43 +00001773 const InstructionMatcher *Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001774 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1775
1776 /// True if the instruction can be built solely by mutating the opcode.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001777 bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const {
1778 if (!Insn)
Daniel Sandersab1d1192017-10-24 18:11:54 +00001779 return false;
1780
Daniel Sandersa7b75262017-10-31 18:50:24 +00001781 if (OperandRenderers.size() != Insn->getNumOperands())
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001782 return false;
1783
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001784 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001785 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001786 const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
Daniel Sandersa7b75262017-10-31 18:50:24 +00001787 if (Insn != &OM.getInstructionMatcher() ||
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001788 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001789 return false;
1790 } else
1791 return false;
1792 }
1793
1794 return true;
1795 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001796
Daniel Sanders43c882c2017-02-01 10:53:10 +00001797public:
Daniel Sandersa7b75262017-10-31 18:50:24 +00001798 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
1799 : InsnID(InsnID), I(I), Matched(nullptr) {}
1800
1801 void chooseInsnToMutate(RuleMatcher &Rule) {
1802 for (const auto *MutateCandidate : Rule.mutatable_insns()) {
1803 if (canMutate(Rule, MutateCandidate)) {
1804 // Take the first one we're offered that we're able to mutate.
1805 Rule.reserveInsnMatcherForMutation(MutateCandidate);
1806 Matched = MutateCandidate;
1807 return;
1808 }
1809 }
1810 }
Daniel Sanders43c882c2017-02-01 10:53:10 +00001811
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001812 template <class Kind, class... Args>
1813 Kind &addRenderer(Args&&... args) {
1814 OperandRenderers.emplace_back(
1815 llvm::make_unique<Kind>(std::forward<Args>(args)...));
1816 return *static_cast<Kind *>(OperandRenderers.back().get());
1817 }
1818
Daniel Sandersa7b75262017-10-31 18:50:24 +00001819 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1820 if (Matched) {
1821 assert(canMutate(Rule, Matched) &&
1822 "Arranged to mutate an insn that isn't mutatable");
1823
1824 unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001825 Table << MatchTable::Opcode("GIR_MutateOpcode")
1826 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1827 << MatchTable::Comment("RecycleInsnID")
1828 << MatchTable::IntValue(RecycleInsnID)
1829 << MatchTable::Comment("Opcode")
1830 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1831 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001832
1833 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001834 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001835 auto Namespace = Def->getValue("Namespace")
1836 ? Def->getValueAsString("Namespace")
1837 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001838 Table << MatchTable::Opcode("GIR_AddImplicitDef")
1839 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1840 << MatchTable::NamedValue(Namespace, Def->getName())
1841 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001842 }
1843 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001844 auto Namespace = Use->getValue("Namespace")
1845 ? Use->getValueAsString("Namespace")
1846 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001847 Table << MatchTable::Opcode("GIR_AddImplicitUse")
1848 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1849 << MatchTable::NamedValue(Namespace, Use->getName())
1850 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001851 }
1852 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001853 return;
1854 }
1855
1856 // TODO: Simple permutation looks like it could be almost as common as
1857 // mutation due to commutative operations.
1858
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001859 Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
1860 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
1861 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1862 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001863 for (const auto &Renderer : OperandRenderers)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001864 Renderer->emitRenderOpcodes(Table, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001865
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001866 if (I->mayLoad || I->mayStore) {
1867 Table << MatchTable::Opcode("GIR_MergeMemOperands")
1868 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1869 << MatchTable::Comment("MergeInsnID's");
1870 // Emit the ID's for all the instructions that are matched by this rule.
1871 // TODO: Limit this to matched instructions that mayLoad/mayStore or have
1872 // some other means of having a memoperand. Also limit this to
1873 // emitted instructions that expect to have a memoperand too. For
1874 // example, (G_SEXT (G_LOAD x)) that results in separate load and
1875 // sign-extend instructions shouldn't put the memoperand on the
1876 // sign-extend since it has no effect there.
1877 std::vector<unsigned> MergeInsnIDs;
1878 for (const auto &IDMatcherPair : Rule.defined_insn_vars())
1879 MergeInsnIDs.push_back(IDMatcherPair.second);
1880 std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end());
1881 for (const auto &MergeInsnID : MergeInsnIDs)
1882 Table << MatchTable::IntValue(MergeInsnID);
Daniel Sanders05540042017-08-08 10:44:31 +00001883 Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
1884 << MatchTable::LineBreak;
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001885 }
1886
1887 Table << MatchTable::Opcode("GIR_EraseFromParent")
Daniel Sandersa7b75262017-10-31 18:50:24 +00001888 << MatchTable::Comment("InsnID") << MatchTable::IntValue(0)
1889 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001890 }
1891};
1892
1893/// Generates code to constrain the operands of an output instruction to the
1894/// register classes specified by the definition of that instruction.
1895class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001896 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001897
1898public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001899 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001900
Daniel Sandersa7b75262017-10-31 18:50:24 +00001901 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001902 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
1903 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1904 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001905 }
1906};
1907
1908/// Generates code to constrain the specified operand of an output instruction
1909/// to the specified register class.
1910class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001911 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001912 unsigned OpIdx;
1913 const CodeGenRegisterClass &RC;
1914
1915public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001916 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001917 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001918 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001919
Daniel Sandersa7b75262017-10-31 18:50:24 +00001920 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001921 Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
1922 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1923 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1924 << MatchTable::Comment("RC " + RC.getName())
1925 << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001926 }
1927};
1928
Daniel Sanders05540042017-08-08 10:44:31 +00001929InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001930 Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
Daniel Sandersa7b75262017-10-31 18:50:24 +00001931 MutatableInsns.insert(Matchers.back().get());
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001932 return *Matchers.back();
1933}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001934
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001935void RuleMatcher::addRequiredFeature(Record *Feature) {
1936 RequiredFeatures.push_back(Feature);
1937}
1938
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001939const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
1940 return RequiredFeatures;
1941}
1942
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001943template <class Kind, class... Args>
1944Kind &RuleMatcher::addAction(Args &&... args) {
1945 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1946 return *static_cast<Kind *>(Actions.back().get());
1947}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001948
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001949unsigned
1950RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
1951 unsigned NewInsnVarID = NextInsnVarID++;
1952 InsnVariableIDs[&Matcher] = NewInsnVarID;
1953 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001954}
1955
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001956unsigned RuleMatcher::defineInsnVar(MatchTable &Table,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001957 const InstructionMatcher &Matcher,
1958 unsigned InsnID, unsigned OpIdx) {
1959 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001960 Table << MatchTable::Opcode("GIM_RecordInsn")
1961 << MatchTable::Comment("DefineMI") << MatchTable::IntValue(NewInsnVarID)
1962 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1963 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
1964 << MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
1965 << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001966 return NewInsnVarID;
1967}
1968
1969unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
1970 const auto &I = InsnVariableIDs.find(&InsnMatcher);
1971 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001972 return I->second;
1973 llvm_unreachable("Matched Insn was not captured in a local variable");
1974}
1975
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001976void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
1977 if (DefinedOperands.find(SymbolicName) == DefinedOperands.end()) {
1978 DefinedOperands[SymbolicName] = &OM;
1979 return;
1980 }
1981
1982 // If the operand is already defined, then we must ensure both references in
1983 // the matcher have the exact same node.
1984 OM.addPredicate<SameOperandMatcher>(OM.getSymbolicName());
1985}
1986
Daniel Sanders05540042017-08-08 10:44:31 +00001987const InstructionMatcher &
1988RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
1989 for (const auto &I : InsnVariableIDs)
1990 if (I.first->getSymbolicName() == SymbolicName)
1991 return *I.first;
1992 llvm_unreachable(
1993 ("Failed to lookup instruction " + SymbolicName).str().c_str());
1994}
1995
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001996const OperandMatcher &
1997RuleMatcher::getOperandMatcher(StringRef Name) const {
1998 const auto &I = DefinedOperands.find(Name);
1999
2000 if (I == DefinedOperands.end())
2001 PrintFatalError(SrcLoc, "Operand " + Name + " was not declared in matcher");
2002
2003 return *I->second;
2004}
2005
Daniel Sanders9d662d22017-07-06 10:06:12 +00002006/// Emit MatchTable opcodes to check the shape of the match and capture
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002007/// instructions into local variables.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002008void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002009 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002010 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002011 Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002012}
2013
Daniel Sanders8e82af22017-07-27 11:03:45 +00002014void RuleMatcher::emit(MatchTable &Table) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002015 if (Matchers.empty())
2016 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002017
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002018 // The representation supports rules that require multiple roots such as:
2019 // %ptr(p0) = ...
2020 // %elt0(s32) = G_LOAD %ptr
2021 // %1(p0) = G_ADD %ptr, 4
2022 // %elt1(s32) = G_LOAD p0 %1
2023 // which could be usefully folded into:
2024 // %ptr(p0) = ...
2025 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
2026 // on some targets but we don't need to make use of that yet.
2027 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002028
Daniel Sanders8e82af22017-07-27 11:03:45 +00002029 unsigned LabelID = Table.allocateLabelID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002030 Table << MatchTable::Opcode("GIM_Try", +1)
Daniel Sanders8e82af22017-07-27 11:03:45 +00002031 << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(LabelID)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002032 << MatchTable::LineBreak;
2033
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002034 if (!RequiredFeatures.empty()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002035 Table << MatchTable::Opcode("GIM_CheckFeatures")
2036 << MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
2037 << MatchTable::LineBreak;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002038 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002039
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002040 emitCaptureOpcodes(Table);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002041
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002042 Matchers.front()->emitPredicateOpcodes(Table, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002043 getInsnVarID(*Matchers.front()));
2044
Daniel Sandersbee57392017-04-04 13:25:23 +00002045 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002046 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00002047 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002048 SmallVector<unsigned, 2> InsnIDs;
2049 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002050 // Skip the root node since it isn't moving anywhere. Everything else is
2051 // sinking to meet it.
2052 if (Pair.first == Matchers.front().get())
2053 continue;
2054
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002055 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00002056 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002057 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00002058
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002059 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002060 // Reject the difficult cases until we have a more accurate check.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002061 Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
2062 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2063 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00002064
2065 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
2066 // account for unsafe cases.
2067 //
2068 // Example:
2069 // MI1--> %0 = ...
2070 // %1 = ... %0
2071 // MI0--> %2 = ... %0
2072 // It's not safe to erase MI1. We currently handle this by not
2073 // erasing %0 (even when it's dead).
2074 //
2075 // Example:
2076 // MI1--> %0 = load volatile @a
2077 // %1 = load volatile @a
2078 // MI0--> %2 = ... %0
2079 // It's not safe to sink %0's def past %1. We currently handle
2080 // this by rejecting all loads.
2081 //
2082 // Example:
2083 // MI1--> %0 = load @a
2084 // %1 = store @a
2085 // MI0--> %2 = ... %0
2086 // It's not safe to sink %0's def past %1. We currently handle
2087 // this by rejecting all loads.
2088 //
2089 // Example:
2090 // G_CONDBR %cond, @BB1
2091 // BB0:
2092 // MI1--> %0 = load @a
2093 // G_BR @BB1
2094 // BB1:
2095 // MI0--> %2 = ... %0
2096 // It's not always safe to sink %0 across control flow. In this
2097 // case it may introduce a memory fault. We currentl handle this
2098 // by rejecting all loads.
2099 }
2100 }
2101
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002102 for (const auto &MA : Actions)
Daniel Sandersa7b75262017-10-31 18:50:24 +00002103 MA->emitActionOpcodes(Table, *this);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002104 Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
Daniel Sanders8e82af22017-07-27 11:03:45 +00002105 << MatchTable::Label(LabelID);
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002106}
Daniel Sanders43c882c2017-02-01 10:53:10 +00002107
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002108bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
2109 // Rules involving more match roots have higher priority.
2110 if (Matchers.size() > B.Matchers.size())
2111 return true;
2112 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00002113 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002114
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002115 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
2116 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
2117 return true;
2118 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
2119 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002120 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002121
2122 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00002123}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002124
Daniel Sanders2deea182017-04-22 15:11:04 +00002125unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002126 return std::accumulate(
2127 Matchers.begin(), Matchers.end(), 0,
2128 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00002129 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002130 });
2131}
2132
Daniel Sanders05540042017-08-08 10:44:31 +00002133bool OperandPredicateMatcher::isHigherPriorityThan(
2134 const OperandPredicateMatcher &B) const {
2135 // Generally speaking, an instruction is more important than an Int or a
2136 // LiteralInt because it can cover more nodes but theres an exception to
2137 // this. G_CONSTANT's are less important than either of those two because they
2138 // are more permissive.
Daniel Sandersedd07842017-08-17 09:26:14 +00002139
2140 const InstructionOperandMatcher *AOM =
2141 dyn_cast<InstructionOperandMatcher>(this);
2142 const InstructionOperandMatcher *BOM =
2143 dyn_cast<InstructionOperandMatcher>(&B);
2144 bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
2145 bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
2146
2147 if (AOM && BOM) {
2148 // The relative priorities between a G_CONSTANT and any other instruction
2149 // don't actually matter but this code is needed to ensure a strict weak
2150 // ordering. This is particularly important on Windows where the rules will
2151 // be incorrectly sorted without it.
2152 if (AIsConstantInsn != BIsConstantInsn)
2153 return AIsConstantInsn < BIsConstantInsn;
2154 return false;
Daniel Sanders05540042017-08-08 10:44:31 +00002155 }
Daniel Sandersedd07842017-08-17 09:26:14 +00002156
2157 if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
2158 return false;
2159 if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
2160 return true;
Daniel Sanders05540042017-08-08 10:44:31 +00002161
2162 return Kind < B.Kind;
Daniel Sanders75b84fc2017-08-08 13:21:26 +00002163}
Daniel Sanders05540042017-08-08 10:44:31 +00002164
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002165void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
2166 RuleMatcher &Rule,
2167 unsigned InsnVarID,
2168 unsigned OpIdx) const {
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002169 const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002170 unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
2171
2172 Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
2173 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
2174 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2175 << MatchTable::Comment("OtherMI")
2176 << MatchTable::IntValue(OtherInsnVarID)
2177 << MatchTable::Comment("OtherOpIdx")
2178 << MatchTable::IntValue(OtherOM.getOperandIndex())
2179 << MatchTable::LineBreak;
2180}
2181
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002182//===- GlobalISelEmitter class --------------------------------------------===//
2183
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002184class GlobalISelEmitter {
2185public:
2186 explicit GlobalISelEmitter(RecordKeeper &RK);
2187 void run(raw_ostream &OS);
2188
2189private:
2190 const RecordKeeper &RK;
2191 const CodeGenDAGPatterns CGP;
2192 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002193 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002194
Daniel Sanders39690bd2017-10-15 02:41:12 +00002195 /// Keep track of the equivalence between SDNodes and Instruction by mapping
2196 /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
2197 /// check for attributes on the relation such as CheckMMOIsNonAtomic.
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002198 /// This is defined using 'GINodeEquiv' in the target description.
Daniel Sanders39690bd2017-10-15 02:41:12 +00002199 DenseMap<Record *, Record *> NodeEquivs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002200
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002201 /// Keep track of the equivalence between ComplexPattern's and
2202 /// GIComplexOperandMatcher. Map entries are specified by subclassing
2203 /// GIComplexPatternEquiv.
2204 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
2205
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002206 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002207 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002208
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002209 void gatherNodeEquivs();
Daniel Sanders39690bd2017-10-15 02:41:12 +00002210 Record *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002211
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002212 Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002213 Expected<InstructionMatcher &> createAndImportSelDAGMatcher(
2214 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2215 const TreePatternNode *Src, unsigned &TempOpIdx) const;
2216 Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
2217 unsigned &TempOpIdx) const;
2218 Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002219 const TreePatternNode *SrcChild,
2220 bool OperandIsAPointer, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00002221 unsigned &TempOpIdx) const;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002222 Expected<BuildMIAction &>
Daniel Sandersa7b75262017-10-31 18:50:24 +00002223 createAndImportInstructionRenderer(RuleMatcher &M,
2224 const TreePatternNode *Dst);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002225 Error importExplicitUseRenderer(RuleMatcher &Rule,
2226 BuildMIAction &DstMIBuilder,
Daniel Sandersa7b75262017-10-31 18:50:24 +00002227 TreePatternNode *DstChild) const;
Diana Picus382602f2017-05-17 08:57:28 +00002228 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
2229 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00002230 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002231 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
2232 const std::vector<Record *> &ImplicitDefs) const;
2233
Daniel Sanders11300ce2017-10-13 21:28:03 +00002234 void emitImmPredicates(raw_ostream &OS, StringRef TypeIdentifier,
2235 StringRef Type,
Daniel Sanders649c5852017-10-13 20:42:18 +00002236 std::function<bool(const Record *R)> Filter);
2237
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002238 /// Analyze pattern \p P, returning a matcher for it if possible.
2239 /// Otherwise, return an Error explaining why we don't support it.
2240 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002241
2242 void declareSubtargetFeature(Record *Predicate);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002243};
2244
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002245void GlobalISelEmitter::gatherNodeEquivs() {
2246 assert(NodeEquivs.empty());
2247 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
Daniel Sanders39690bd2017-10-15 02:41:12 +00002248 NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002249
2250 assert(ComplexPatternEquivs.empty());
2251 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
2252 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
2253 if (!SelDAGEquiv)
2254 continue;
2255 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
2256 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002257}
2258
Daniel Sanders39690bd2017-10-15 02:41:12 +00002259Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002260 return NodeEquivs.lookup(N);
2261}
2262
2263GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002264 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()),
2265 CGRegs(RK, Target.getHwModes()) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002266
2267//===- Emitter ------------------------------------------------------------===//
2268
Daniel Sandersc270c502017-03-30 09:36:33 +00002269Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002270GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002271 ArrayRef<Predicate> Predicates) {
2272 for (const Predicate &P : Predicates) {
2273 if (!P.Def)
2274 continue;
2275 declareSubtargetFeature(P.Def);
2276 M.addRequiredFeature(P.Def);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002277 }
2278
Daniel Sandersc270c502017-03-30 09:36:33 +00002279 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002280}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002281
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002282Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
2283 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2284 const TreePatternNode *Src, unsigned &TempOpIdx) const {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002285 Record *SrcGIEquivOrNull = nullptr;
Daniel Sanders85ffd362017-07-06 08:12:20 +00002286 const CodeGenInstruction *SrcGIOrNull = nullptr;
2287
Daniel Sandersffc7d582017-03-29 15:37:18 +00002288 // Start with the defined operands (i.e., the results of the root operator).
2289 if (Src->getExtTypes().size() > 1)
2290 return failedImport("Src pattern has multiple results");
2291
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002292 if (Src->isLeaf()) {
2293 Init *SrcInit = Src->getLeafValue();
Daniel Sanders3334cc02017-05-23 20:02:48 +00002294 if (isa<IntInit>(SrcInit)) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002295 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
2296 &Target.getInstruction(RK.getDef("G_CONSTANT")));
2297 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002298 return failedImport(
2299 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002300 } else {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002301 SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
2302 if (!SrcGIEquivOrNull)
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002303 return failedImport("Pattern operator lacks an equivalent Instruction" +
2304 explainOperator(Src->getOperator()));
Daniel Sanders39690bd2017-10-15 02:41:12 +00002305 SrcGIOrNull = &Target.getInstruction(SrcGIEquivOrNull->getValueAsDef("I"));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002306
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002307 // The operators look good: match the opcode
Daniel Sanders39690bd2017-10-15 02:41:12 +00002308 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002309 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002310
2311 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002312 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002313 // Results don't have a name unless they are the root node. The caller will
2314 // set the name if appropriate.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002315 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002316 if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
2317 return failedImport(toString(std::move(Error)) +
2318 " for result of Src pattern operator");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002319 }
2320
Daniel Sanders2c269f62017-08-24 09:11:20 +00002321 for (const auto &Predicate : Src->getPredicateFns()) {
2322 if (Predicate.isAlwaysTrue())
2323 continue;
2324
2325 if (Predicate.isImmediatePattern()) {
2326 InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
2327 continue;
2328 }
2329
Daniel Sandersa71f4542017-10-16 00:56:30 +00002330 // No check required. A G_LOAD is an unindexed load.
2331 if (Predicate.isLoad() && Predicate.isUnindexed())
2332 continue;
2333
2334 // No check required. G_LOAD by itself is a non-extending load.
2335 if (Predicate.isNonExtLoad())
2336 continue;
2337
2338 if (Predicate.isLoad() && Predicate.getMemoryVT() != nullptr) {
2339 Optional<LLTCodeGen> MemTyOrNone =
2340 MVTToLLT(getValueType(Predicate.getMemoryVT()));
2341
2342 if (!MemTyOrNone)
2343 return failedImport("MemVT could not be converted to LLT");
2344
2345 InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue());
2346 continue;
2347 }
2348
Daniel Sandersd66e0902017-10-23 18:19:24 +00002349 // No check required. A G_STORE is an unindexed store.
2350 if (Predicate.isStore() && Predicate.isUnindexed())
2351 continue;
2352
2353 // No check required. G_STORE by itself is a non-extending store.
2354 if (Predicate.isNonTruncStore())
2355 continue;
2356
2357 if (Predicate.isStore() && Predicate.getMemoryVT() != nullptr) {
2358 Optional<LLTCodeGen> MemTyOrNone =
2359 MVTToLLT(getValueType(Predicate.getMemoryVT()));
2360
2361 if (!MemTyOrNone)
2362 return failedImport("MemVT could not be converted to LLT");
2363
2364 InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue());
2365 continue;
2366 }
2367
Daniel Sanders2c269f62017-08-24 09:11:20 +00002368 return failedImport("Src pattern child has predicate (" +
2369 explainPredicates(Src) + ")");
2370 }
Daniel Sanders39690bd2017-10-15 02:41:12 +00002371 if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
2372 InsnMatcher.addPredicate<NonAtomicMMOPredicateMatcher>();
Daniel Sanders2c269f62017-08-24 09:11:20 +00002373
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002374 if (Src->isLeaf()) {
2375 Init *SrcInit = Src->getLeafValue();
2376 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002377 OperandMatcher &OM =
2378 InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002379 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
2380 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002381 return failedImport(
2382 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002383 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002384 assert(SrcGIOrNull &&
2385 "Expected to have already found an equivalent Instruction");
Daniel Sanders11300ce2017-10-13 21:28:03 +00002386 if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
2387 SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
2388 // imm/fpimm still have operands but we don't need to do anything with it
Daniel Sanders05540042017-08-08 10:44:31 +00002389 // here since we don't support ImmLeaf predicates yet. However, we still
2390 // need to note the hidden operand to get GIM_CheckNumOperands correct.
2391 InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2392 return InsnMatcher;
2393 }
2394
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002395 // Match the used operands (i.e. the children of the operator).
2396 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002397 TreePatternNode *SrcChild = Src->getChild(i);
2398
Daniel Sandersa71f4542017-10-16 00:56:30 +00002399 // SelectionDAG allows pointers to be represented with iN since it doesn't
2400 // distinguish between pointers and integers but they are different types in GlobalISel.
2401 // Coerce integers to pointers to address space 0 if the context indicates a pointer.
2402 // TODO: Find a better way to do this, SDTCisPtrTy?
2403 bool OperandIsAPointer =
Daniel Sandersd66e0902017-10-23 18:19:24 +00002404 (SrcGIOrNull->TheDef->getName() == "G_LOAD" && i == 0) ||
2405 (SrcGIOrNull->TheDef->getName() == "G_STORE" && i == 1);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002406
Daniel Sanders28887fe2017-09-19 12:56:36 +00002407 // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
2408 // following the defs is an intrinsic ID.
2409 if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
2410 SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
2411 i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002412 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002413 OperandMatcher &OM =
2414 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002415 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00002416 continue;
2417 }
2418
2419 return failedImport("Expected IntInit containing instrinsic ID)");
2420 }
2421
Daniel Sandersa71f4542017-10-16 00:56:30 +00002422 if (auto Error =
2423 importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
2424 OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002425 return std::move(Error);
2426 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002427 }
2428
2429 return InsnMatcher;
2430}
2431
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002432Error GlobalISelEmitter::importComplexPatternOperandMatcher(
2433 OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
2434 const auto &ComplexPattern = ComplexPatternEquivs.find(R);
2435 if (ComplexPattern == ComplexPatternEquivs.end())
2436 return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
2437 ") not mapped to GlobalISel");
2438
2439 OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
2440 TempOpIdx++;
2441 return Error::success();
2442}
2443
2444Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
2445 InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002446 const TreePatternNode *SrcChild,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002447 bool OperandIsAPointer,
Daniel Sandersc270c502017-03-30 09:36:33 +00002448 unsigned OpIdx,
2449 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002450 OperandMatcher &OM =
2451 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002452 if (OM.isSameAsAnotherOperand())
2453 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002454
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002455 ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002456 if (ChildTypes.size() != 1)
2457 return failedImport("Src pattern child has multiple results");
2458
2459 // Check MBB's before the type check since they are not a known type.
2460 if (!SrcChild->isLeaf()) {
2461 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
2462 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
2463 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
2464 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00002465 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002466 }
2467 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002468 }
2469
Daniel Sandersa71f4542017-10-16 00:56:30 +00002470 if (auto Error =
2471 OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
2472 return failedImport(toString(std::move(Error)) + " for Src operand (" +
2473 to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002474
Daniel Sandersbee57392017-04-04 13:25:23 +00002475 // Check for nested instructions.
2476 if (!SrcChild->isLeaf()) {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002477 if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
2478 // When a ComplexPattern is used as an operator, it should do the same
2479 // thing as when used as a leaf. However, the children of the operator
2480 // name the sub-operands that make up the complex operand and we must
2481 // prepare to reference them in the renderer too.
2482 unsigned RendererID = TempOpIdx;
2483 if (auto Error = importComplexPatternOperandMatcher(
2484 OM, SrcChild->getOperator(), TempOpIdx))
2485 return Error;
2486
2487 for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
2488 auto *SubOperand = SrcChild->getChild(i);
2489 if (!SubOperand->getName().empty())
2490 Rule.defineComplexSubOperand(SubOperand->getName(),
2491 SrcChild->getOperator(), RendererID, i);
2492 }
2493
2494 return Error::success();
2495 }
2496
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002497 auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
2498 InsnMatcher.getRuleMatcher(), SrcChild->getName());
2499 if (!MaybeInsnOperand.hasValue()) {
2500 // This isn't strictly true. If the user were to provide exactly the same
2501 // matchers as the original operand then we could allow it. However, it's
2502 // simpler to not permit the redundant specification.
2503 return failedImport("Nested instruction cannot be the same as another operand");
2504 }
2505
Daniel Sandersbee57392017-04-04 13:25:23 +00002506 // Map the node to a gMIR instruction.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002507 InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
Daniel Sanders57938df2017-07-11 10:40:18 +00002508 auto InsnMatcherOrError = createAndImportSelDAGMatcher(
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002509 Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00002510 if (auto Error = InsnMatcherOrError.takeError())
2511 return Error;
2512
2513 return Error::success();
2514 }
2515
Daniel Sandersffc7d582017-03-29 15:37:18 +00002516 // Check for constant immediates.
2517 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002518 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00002519 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002520 }
2521
2522 // Check for def's like register classes or ComplexPattern's.
2523 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
2524 auto *ChildRec = ChildDefInit->getDef();
2525
2526 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002527 if (ChildRec->isSubClassOf("RegisterClass") ||
2528 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002529 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002530 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00002531 return Error::success();
2532 }
2533
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002534 // Check for ValueType.
2535 if (ChildRec->isSubClassOf("ValueType")) {
2536 // We already added a type check as standard practice so this doesn't need
2537 // to do anything.
2538 return Error::success();
2539 }
2540
Daniel Sandersffc7d582017-03-29 15:37:18 +00002541 // Check for ComplexPattern's.
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002542 if (ChildRec->isSubClassOf("ComplexPattern"))
2543 return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002544
Daniel Sandersd0656a32017-04-13 09:45:37 +00002545 if (ChildRec->isSubClassOf("ImmLeaf")) {
2546 return failedImport(
2547 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
2548 }
2549
Daniel Sandersffc7d582017-03-29 15:37:18 +00002550 return failedImport(
2551 "Src pattern child def is an unsupported tablegen class");
2552 }
2553
2554 return failedImport("Src pattern child is an unsupported kind");
2555}
2556
Daniel Sandersc270c502017-03-30 09:36:33 +00002557Error GlobalISelEmitter::importExplicitUseRenderer(
Daniel Sandersa7b75262017-10-31 18:50:24 +00002558 RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
2559 TreePatternNode *DstChild) const {
Daniel Sanders2c269f62017-08-24 09:11:20 +00002560 if (DstChild->getTransformFn() != nullptr) {
2561 return failedImport("Dst pattern child has transform fn " +
2562 DstChild->getTransformFn()->getName());
2563 }
2564
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002565 const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
2566 if (SubOperand.hasValue()) {
2567 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
2568 0, *std::get<0>(*SubOperand), DstChild->getName(),
2569 std::get<1>(*SubOperand), std::get<2>(*SubOperand));
2570 return Error::success();
2571 }
2572
Daniel Sandersffc7d582017-03-29 15:37:18 +00002573 if (!DstChild->isLeaf()) {
Daniel Sanders05540042017-08-08 10:44:31 +00002574 // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
2575 // inline, but in MI it's just another operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002576 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
2577 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
2578 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002579 DstMIBuilder.addRenderer<CopyRenderer>(0, DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00002580 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002581 }
2582 }
Daniel Sanders05540042017-08-08 10:44:31 +00002583
2584 // Similarly, imm is an operator in TreePatternNode's view but must be
2585 // rendered as operands.
2586 // FIXME: The target should be able to choose sign-extended when appropriate
2587 // (e.g. on Mips).
2588 if (DstChild->getOperator()->getName() == "imm") {
2589 DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(0,
2590 DstChild->getName());
2591 return Error::success();
Daniel Sanders11300ce2017-10-13 21:28:03 +00002592 } else if (DstChild->getOperator()->getName() == "fpimm") {
2593 DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
2594 0, DstChild->getName());
2595 return Error::success();
Daniel Sanders05540042017-08-08 10:44:31 +00002596 }
2597
Daniel Sanders2c269f62017-08-24 09:11:20 +00002598 return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002599 }
2600
2601 // Otherwise, we're looking for a bog-standard RegisterClass operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002602 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
2603 auto *ChildRec = ChildDefInit->getDef();
2604
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002605 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002606 if (ChildTypes.size() != 1)
2607 return failedImport("Dst pattern child has multiple results");
2608
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002609 Optional<LLTCodeGen> OpTyOrNone = None;
2610 if (ChildTypes.front().isMachineValueType())
2611 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002612 if (!OpTyOrNone)
2613 return failedImport("Dst operand has an unsupported type");
2614
2615 if (ChildRec->isSubClassOf("Register")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002616 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, ChildRec);
Daniel Sandersc270c502017-03-30 09:36:33 +00002617 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002618 }
2619
Daniel Sanders658541f2017-04-22 15:53:21 +00002620 if (ChildRec->isSubClassOf("RegisterClass") ||
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002621 ChildRec->isSubClassOf("RegisterOperand") ||
2622 ChildRec->isSubClassOf("ValueType")) {
Daniel Sandersd66e0902017-10-23 18:19:24 +00002623 if (ChildRec->isSubClassOf("RegisterOperand") &&
2624 !ChildRec->isValueUnset("GIZeroRegister")) {
2625 DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002626 0, DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
Daniel Sandersd66e0902017-10-23 18:19:24 +00002627 return Error::success();
2628 }
2629
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002630 DstMIBuilder.addRenderer<CopyRenderer>(0, DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00002631 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002632 }
2633
2634 if (ChildRec->isSubClassOf("ComplexPattern")) {
2635 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
2636 if (ComplexPattern == ComplexPatternEquivs.end())
2637 return failedImport(
2638 "SelectionDAG ComplexPattern not mapped to GlobalISel");
2639
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002640 const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002641 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002642 0, *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00002643 OM.getAllocatedTemporariesBaseID());
Daniel Sandersc270c502017-03-30 09:36:33 +00002644 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002645 }
2646
Daniel Sandersd0656a32017-04-13 09:45:37 +00002647 if (ChildRec->isSubClassOf("SDNodeXForm"))
2648 return failedImport("Dst pattern child def is an unsupported tablegen "
2649 "class (SDNodeXForm)");
2650
Daniel Sandersffc7d582017-03-29 15:37:18 +00002651 return failedImport(
2652 "Dst pattern child def is an unsupported tablegen class");
2653 }
2654
2655 return failedImport("Dst pattern child is an unsupported kind");
2656}
2657
Daniel Sandersc270c502017-03-30 09:36:33 +00002658Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersa7b75262017-10-31 18:50:24 +00002659 RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002660 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00002661 if (!DstOp->isSubClassOf("Instruction")) {
2662 if (DstOp->isSubClassOf("ValueType"))
2663 return failedImport(
2664 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002665 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00002666 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002667 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002668
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002669 unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs;
2670 unsigned ExpectedDstINumUses = Dst->getNumChildren();
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002671 bool IsExtractSubReg = false;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002672
2673 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002674 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002675 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") {
2676 DstI = &Target.getInstruction(RK.getDef("COPY"));
2677 DstINumUses--; // Ignore the class constraint.
2678 ExpectedDstINumUses--;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002679 } else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") {
2680 DstI = &Target.getInstruction(RK.getDef("COPY"));
2681 IsExtractSubReg = true;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002682 }
2683
Daniel Sandersa7b75262017-10-31 18:50:24 +00002684 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002685
2686 // Render the explicit defs.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002687 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
2688 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002689 DstMIBuilder.addRenderer<CopyRenderer>(0, DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002690 }
2691
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002692 // EXTRACT_SUBREG needs to use a subregister COPY.
2693 if (IsExtractSubReg) {
2694 if (!Dst->getChild(0)->isLeaf())
2695 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2696
Daniel Sanders32291982017-06-28 13:50:04 +00002697 if (DefInit *SubRegInit =
2698 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002699 CodeGenRegisterClass *RC = CGRegs.getRegClass(
2700 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));
2701 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
2702
2703 const auto &SrcRCDstRCPair =
2704 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2705 if (SrcRCDstRCPair.hasValue()) {
2706 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
2707 if (SrcRCDstRCPair->first != RC)
2708 return failedImport("EXTRACT_SUBREG requires an additional COPY");
2709 }
2710
2711 DstMIBuilder.addRenderer<CopySubRegRenderer>(
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002712 0, Dst->getChild(0)->getName(), SubIdx);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002713 return DstMIBuilder;
2714 }
2715
2716 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
2717 }
2718
Daniel Sandersffc7d582017-03-29 15:37:18 +00002719 // Render the explicit uses.
Daniel Sanders0ed28822017-04-12 08:23:08 +00002720 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00002721 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002722 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002723 const CGIOperandList::OperandInfo &DstIOperand =
2724 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00002725
Diana Picus382602f2017-05-17 08:57:28 +00002726 // If the operand has default values, introduce them now.
2727 // FIXME: Until we have a decent test case that dictates we should do
2728 // otherwise, we're going to assume that operands with default values cannot
2729 // be specified in the patterns. Therefore, adding them will not cause us to
2730 // end up with too many rendered operands.
2731 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00002732 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00002733 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
2734 return std::move(Error);
2735 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002736 continue;
2737 }
2738
Daniel Sandersa7b75262017-10-31 18:50:24 +00002739 if (auto Error =
2740 importExplicitUseRenderer(M, DstMIBuilder, Dst->getChild(Child)))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002741 return std::move(Error);
Daniel Sanders0ed28822017-04-12 08:23:08 +00002742 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002743 }
2744
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002745 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00002746 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00002747 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002748 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00002749 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00002750 " default ones");
2751
Daniel Sandersffc7d582017-03-29 15:37:18 +00002752 return DstMIBuilder;
2753}
2754
Diana Picus382602f2017-05-17 08:57:28 +00002755Error GlobalISelEmitter::importDefaultOperandRenderers(
2756 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00002757 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00002758 // Look through ValueType operators.
2759 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
2760 if (const DefInit *DefaultDagOperator =
2761 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
2762 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
2763 DefaultOp = DefaultDagOp->getArg(0);
2764 }
2765 }
2766
2767 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002768 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00002769 continue;
2770 }
2771
2772 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002773 DstMIBuilder.addRenderer<ImmRenderer>(0, DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00002774 continue;
2775 }
2776
2777 return failedImport("Could not add default op");
2778 }
2779
2780 return Error::success();
2781}
2782
Daniel Sandersc270c502017-03-30 09:36:33 +00002783Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00002784 BuildMIAction &DstMIBuilder,
2785 const std::vector<Record *> &ImplicitDefs) const {
2786 if (!ImplicitDefs.empty())
2787 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00002788 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002789}
2790
2791Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002792 // Keep track of the matchers and actions to emit.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002793 RuleMatcher M(P.getSrcRecord()->getLoc());
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00002794 M.addAction<DebugCommentAction>(llvm::to_string(*P.getSrcPattern()) +
2795 " => " +
2796 llvm::to_string(*P.getDstPattern()));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002797
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002798 if (auto Error = importRulePredicates(M, P.getPredicates()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002799 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002800
2801 // Next, analyze the pattern operators.
2802 TreePatternNode *Src = P.getSrcPattern();
2803 TreePatternNode *Dst = P.getDstPattern();
2804
2805 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00002806 if (auto Err = isTrivialOperatorNode(Dst))
2807 return failedImport("Dst pattern root isn't a trivial operator (" +
2808 toString(std::move(Err)) + ")");
2809 if (auto Err = isTrivialOperatorNode(Src))
2810 return failedImport("Src pattern root isn't a trivial operator (" +
2811 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002812
Daniel Sandersedd07842017-08-17 09:26:14 +00002813 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
2814 unsigned TempOpIdx = 0;
2815 auto InsnMatcherOrError =
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002816 createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
Daniel Sandersedd07842017-08-17 09:26:14 +00002817 if (auto Error = InsnMatcherOrError.takeError())
2818 return std::move(Error);
2819 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
2820
2821 if (Dst->isLeaf()) {
2822 Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
2823
2824 const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
2825 if (RCDef) {
2826 // We need to replace the def and all its uses with the specified
2827 // operand. However, we must also insert COPY's wherever needed.
2828 // For now, emit a copy and let the register allocator clean up.
2829 auto &DstI = Target.getInstruction(RK.getDef("COPY"));
2830 const auto &DstIOperand = DstI.Operands[0];
2831
2832 OperandMatcher &OM0 = InsnMatcher.getOperand(0);
2833 OM0.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002834 M.defineOperand(OM0.getSymbolicName(), OM0);
Daniel Sandersedd07842017-08-17 09:26:14 +00002835 OM0.addPredicate<RegisterBankOperandMatcher>(RC);
2836
Daniel Sandersa7b75262017-10-31 18:50:24 +00002837 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI);
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002838 DstMIBuilder.addRenderer<CopyRenderer>(0, DstIOperand.Name);
2839 DstMIBuilder.addRenderer<CopyRenderer>(0, Dst->getName());
Daniel Sandersedd07842017-08-17 09:26:14 +00002840 M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
2841
2842 // We're done with this pattern! It's eligible for GISel emission; return
2843 // it.
2844 ++NumPatternImported;
2845 return std::move(M);
2846 }
2847
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002848 return failedImport("Dst pattern root isn't a known leaf");
Daniel Sandersedd07842017-08-17 09:26:14 +00002849 }
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002850
Daniel Sandersbee57392017-04-04 13:25:23 +00002851 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002852 Record *DstOp = Dst->getOperator();
2853 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002854 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002855
2856 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002857 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00002858 return failedImport("Src pattern results and dst MI defs are different (" +
2859 to_string(Src->getExtTypes().size()) + " def(s) vs " +
2860 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002861
Daniel Sandersffc7d582017-03-29 15:37:18 +00002862 // The root of the match also has constraints on the register bank so that it
2863 // matches the result instruction.
2864 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002865 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
2866 (void)VTy;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002867
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002868 const auto &DstIOperand = DstI.Operands[OpIdx];
2869 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002870 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
2871 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
2872
2873 if (DstIOpRec == nullptr)
2874 return failedImport(
2875 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002876 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
2877 if (!Dst->getChild(0)->isLeaf())
2878 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
2879
Daniel Sanders32291982017-06-28 13:50:04 +00002880 // We can assume that a subregister is in the same bank as it's super
2881 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002882 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
2883
2884 if (DstIOpRec == nullptr)
2885 return failedImport(
2886 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002887 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00002888 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002889 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00002890 return failedImport("Dst MI def isn't a register class" +
2891 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002892
Daniel Sandersffc7d582017-03-29 15:37:18 +00002893 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
2894 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002895 M.defineOperand(OM.getSymbolicName(), OM);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002896 OM.addPredicate<RegisterBankOperandMatcher>(
2897 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002898 ++OpIdx;
2899 }
2900
Daniel Sandersa7b75262017-10-31 18:50:24 +00002901 auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002902 if (auto Error = DstMIBuilderOrError.takeError())
2903 return std::move(Error);
2904 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002905
Daniel Sandersffc7d582017-03-29 15:37:18 +00002906 // Render the implicit defs.
2907 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00002908 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002909 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002910
Daniel Sandersa7b75262017-10-31 18:50:24 +00002911 DstMIBuilder.chooseInsnToMutate(M);
2912
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002913 // Constrain the registers to classes. This is normally derived from the
2914 // emitted instruction but a few instructions require special handling.
2915 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
2916 // COPY_TO_REGCLASS does not provide operand constraints itself but the
2917 // result is constrained to the class given by the second child.
2918 Record *DstIOpRec =
2919 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
2920
2921 if (DstIOpRec == nullptr)
2922 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
2923
2924 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002925 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002926
2927 // We're done with this pattern! It's eligible for GISel emission; return
2928 // it.
2929 ++NumPatternImported;
2930 return std::move(M);
2931 }
2932
2933 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
2934 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
2935 // instructions, the result register class is controlled by the
2936 // subregisters of the operand. As a result, we must constrain the result
2937 // class rather than check that it's already the right one.
2938 if (!Dst->getChild(0)->isLeaf())
2939 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2940
Daniel Sanders320390b2017-06-28 15:16:03 +00002941 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
2942 if (!SubRegInit)
2943 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002944
Daniel Sanders320390b2017-06-28 15:16:03 +00002945 // Constrain the result to the same register bank as the operand.
2946 Record *DstIOpRec =
2947 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002948
Daniel Sanders320390b2017-06-28 15:16:03 +00002949 if (DstIOpRec == nullptr)
2950 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002951
Daniel Sanders320390b2017-06-28 15:16:03 +00002952 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002953 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002954
Daniel Sanders320390b2017-06-28 15:16:03 +00002955 // It would be nice to leave this constraint implicit but we're required
2956 // to pick a register class so constrain the result to a register class
2957 // that can hold the correct MVT.
2958 //
2959 // FIXME: This may introduce an extra copy if the chosen class doesn't
2960 // actually contain the subregisters.
2961 assert(Src->getExtTypes().size() == 1 &&
2962 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002963
Daniel Sanders320390b2017-06-28 15:16:03 +00002964 const auto &SrcRCDstRCPair =
2965 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2966 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002967 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
2968 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
2969
2970 // We're done with this pattern! It's eligible for GISel emission; return
2971 // it.
2972 ++NumPatternImported;
2973 return std::move(M);
2974 }
2975
2976 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002977
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002978 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002979 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002980 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002981}
2982
Daniel Sanders649c5852017-10-13 20:42:18 +00002983// Emit imm predicate table and an enum to reference them with.
2984// The 'Predicate_' part of the name is redundant but eliminating it is more
2985// trouble than it's worth.
2986void GlobalISelEmitter::emitImmPredicates(
Daniel Sanders11300ce2017-10-13 21:28:03 +00002987 raw_ostream &OS, StringRef TypeIdentifier, StringRef Type,
2988 std::function<bool(const Record *R)> Filter) {
Daniel Sanders649c5852017-10-13 20:42:18 +00002989 std::vector<const Record *> MatchedRecords;
2990 const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
2991 std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
2992 [&](Record *Record) {
2993 return !Record->getValueAsString("ImmediateCode").empty() &&
2994 Filter(Record);
2995 });
2996
Daniel Sanders11300ce2017-10-13 21:28:03 +00002997 if (!MatchedRecords.empty()) {
2998 OS << "// PatFrag predicates.\n"
2999 << "enum {\n";
Daniel Sanders2fed4ff2017-10-13 21:51:20 +00003000 std::string EnumeratorSeparator =
Daniel Sanders11300ce2017-10-13 21:28:03 +00003001 (" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str();
3002 for (const auto *Record : MatchedRecords) {
3003 OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName()
3004 << EnumeratorSeparator;
3005 EnumeratorSeparator = ",\n";
3006 }
3007 OS << "};\n";
Daniel Sanders649c5852017-10-13 20:42:18 +00003008 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00003009
Daniel Sanders649c5852017-10-13 20:42:18 +00003010 for (const auto *Record : MatchedRecords)
Daniel Sanders11300ce2017-10-13 21:28:03 +00003011 OS << "static bool Predicate_" << Record->getName() << "(" << Type
3012 << " Imm) {" << Record->getValueAsString("ImmediateCode") << "}\n";
3013
3014 OS << "static InstructionSelector::" << TypeIdentifier
3015 << "ImmediatePredicateFn " << TypeIdentifier << "ImmPredicateFns[] = {\n"
Daniel Sanders649c5852017-10-13 20:42:18 +00003016 << " nullptr,\n";
3017 for (const auto *Record : MatchedRecords)
3018 OS << " Predicate_" << Record->getName() << ",\n";
3019 OS << "};\n";
3020}
3021
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003022void GlobalISelEmitter::run(raw_ostream &OS) {
3023 // Track the GINodeEquiv definitions.
3024 gatherNodeEquivs();
3025
3026 emitSourceFileHeader(("Global Instruction Selector for the " +
3027 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003028 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003029 // Look through the SelectionDAG patterns we found, possibly emitting some.
3030 for (const PatternToMatch &Pat : CGP.ptms()) {
3031 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003032 auto MatcherOrErr = runOnPattern(Pat);
3033
3034 // The pattern analysis can fail, indicating an unsupported pattern.
3035 // Report that if we've been asked to do so.
3036 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003037 if (WarnOnSkippedPatterns) {
3038 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003039 "Skipped pattern: " + toString(std::move(Err)));
3040 } else {
3041 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003042 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003043 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003044 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003045 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003046
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003047 Rules.push_back(std::move(MatcherOrErr.get()));
3048 }
3049
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00003050 std::stable_sort(Rules.begin(), Rules.end(),
3051 [&](const RuleMatcher &A, const RuleMatcher &B) {
3052 if (A.isHigherPriorityThan(B)) {
3053 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
3054 "and less important at "
3055 "the same time");
3056 return true;
3057 }
3058 return false;
3059 });
Daniel Sanders759ff412017-02-24 13:58:11 +00003060
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003061 std::vector<Record *> ComplexPredicates =
3062 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
3063 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
3064 [](const Record *A, const Record *B) {
3065 if (A->getName() < B->getName())
3066 return true;
3067 return false;
3068 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003069 unsigned MaxTemporaries = 0;
3070 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00003071 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003072
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003073 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
3074 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
3075 << ";\n"
3076 << "using PredicateBitset = "
3077 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
3078 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
3079
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003080 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
3081 << " mutable MatcherState State;\n"
3082 << " typedef "
Daniel Sanders1e4569f2017-10-20 20:55:29 +00003083 "ComplexRendererFns("
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003084 << Target.getName()
3085 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003086 << " const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003087 "MatcherInfo;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003088 << " static " << Target.getName()
3089 << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003090 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003091
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003092 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
3093 << ", State(" << MaxTemporaries << "),\n"
Daniel Sanders11300ce2017-10-13 21:28:03 +00003094 << "MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, "
Daniel Sandersea8711b2017-10-16 03:36:29 +00003095 "APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003096 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003097
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003098 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
3099 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
3100 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003101
3102 // Separate subtarget features by how often they must be recomputed.
3103 SubtargetFeatureInfoMap ModuleFeatures;
3104 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3105 std::inserter(ModuleFeatures, ModuleFeatures.end()),
3106 [](const SubtargetFeatureInfoMap::value_type &X) {
3107 return !X.second.mustRecomputePerFunction();
3108 });
3109 SubtargetFeatureInfoMap FunctionFeatures;
3110 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3111 std::inserter(FunctionFeatures, FunctionFeatures.end()),
3112 [](const SubtargetFeatureInfoMap::value_type &X) {
3113 return X.second.mustRecomputePerFunction();
3114 });
3115
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003116 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003117 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
3118 ModuleFeatures, OS);
3119 SubtargetFeatureInfo::emitComputeAvailableFeatures(
3120 Target.getName(), "InstructionSelector",
3121 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
3122 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003123
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003124 // Emit a table containing the LLT objects needed by the matcher and an enum
3125 // for the matcher to reference them with.
Daniel Sanders032e7f22017-08-17 13:18:35 +00003126 std::vector<LLTCodeGen> TypeObjects;
3127 for (const auto &Ty : LLTOperandMatcher::KnownTypes)
3128 TypeObjects.push_back(Ty);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003129 std::sort(TypeObjects.begin(), TypeObjects.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003130 OS << "// LLT Objects.\n"
3131 << "enum {\n";
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003132 for (const auto &TypeObject : TypeObjects) {
3133 OS << " ";
3134 TypeObject.emitCxxEnumValue(OS);
3135 OS << ",\n";
3136 }
3137 OS << "};\n"
3138 << "const static LLT TypeObjects[] = {\n";
3139 for (const auto &TypeObject : TypeObjects) {
3140 OS << " ";
3141 TypeObject.emitCxxConstructorCall(OS);
3142 OS << ",\n";
3143 }
3144 OS << "};\n\n";
3145
3146 // Emit a table containing the PredicateBitsets objects needed by the matcher
3147 // and an enum for the matcher to reference them with.
3148 std::vector<std::vector<Record *>> FeatureBitsets;
3149 for (auto &Rule : Rules)
3150 FeatureBitsets.push_back(Rule.getRequiredFeatures());
3151 std::sort(
3152 FeatureBitsets.begin(), FeatureBitsets.end(),
3153 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
3154 if (A.size() < B.size())
3155 return true;
3156 if (A.size() > B.size())
3157 return false;
3158 for (const auto &Pair : zip(A, B)) {
3159 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
3160 return true;
3161 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
3162 return false;
3163 }
3164 return false;
3165 });
3166 FeatureBitsets.erase(
3167 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
3168 FeatureBitsets.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003169 OS << "// Feature bitsets.\n"
3170 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003171 << " GIFBS_Invalid,\n";
3172 for (const auto &FeatureBitset : FeatureBitsets) {
3173 if (FeatureBitset.empty())
3174 continue;
3175 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
3176 }
3177 OS << "};\n"
3178 << "const static PredicateBitset FeatureBitsets[] {\n"
3179 << " {}, // GIFBS_Invalid\n";
3180 for (const auto &FeatureBitset : FeatureBitsets) {
3181 if (FeatureBitset.empty())
3182 continue;
3183 OS << " {";
3184 for (const auto &Feature : FeatureBitset) {
3185 const auto &I = SubtargetFeatures.find(Feature);
3186 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
3187 OS << I->second.getEnumBitName() << ", ";
3188 }
3189 OS << "},\n";
3190 }
3191 OS << "};\n\n";
3192
3193 // Emit complex predicate table and an enum to reference them with.
Daniel Sanders49980702017-08-23 10:09:25 +00003194 OS << "// ComplexPattern predicates.\n"
3195 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003196 << " GICP_Invalid,\n";
3197 for (const auto &Record : ComplexPredicates)
3198 OS << " GICP_" << Record->getName() << ",\n";
3199 OS << "};\n"
3200 << "// See constructor for table contents\n\n";
3201
Daniel Sanders11300ce2017-10-13 21:28:03 +00003202 emitImmPredicates(OS, "I64", "int64_t", [](const Record *R) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003203 bool Unset;
3204 return !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
3205 !R->getValueAsBit("IsAPInt");
3206 });
Daniel Sanders11300ce2017-10-13 21:28:03 +00003207 emitImmPredicates(OS, "APFloat", "const APFloat &", [](const Record *R) {
3208 bool Unset;
3209 return R->getValueAsBitOrUnset("IsAPFloat", Unset);
3210 });
3211 emitImmPredicates(OS, "APInt", "const APInt &", [](const Record *R) {
3212 return R->getValueAsBit("IsAPInt");
3213 });
Daniel Sandersea8711b2017-10-16 03:36:29 +00003214 OS << "\n";
3215
3216 OS << Target.getName() << "InstructionSelector::ComplexMatcherMemFn\n"
3217 << Target.getName() << "InstructionSelector::ComplexPredicateFns[] = {\n"
3218 << " nullptr, // GICP_Invalid\n";
3219 for (const auto &Record : ComplexPredicates)
3220 OS << " &" << Target.getName()
3221 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
3222 << ", // " << Record->getName() << "\n";
3223 OS << "};\n\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00003224
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003225 OS << "bool " << Target.getName()
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003226 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
3227 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003228 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00003229 << " // FIXME: This should be computed on a per-function basis rather "
3230 "than per-insn.\n"
3231 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
3232 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00003233 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
3234 << " NewMIVector OutMIs;\n"
3235 << " State.MIs.clear();\n"
3236 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003237
Daniel Sanders8e82af22017-07-27 11:03:45 +00003238 MatchTable Table(0);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00003239 for (auto &Rule : Rules) {
Daniel Sanders8e82af22017-07-27 11:03:45 +00003240 Rule.emit(Table);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003241 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003242 }
Daniel Sanders8e82af22017-07-27 11:03:45 +00003243 Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
3244 Table.emitDeclaration(OS);
3245 OS << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, ";
3246 Table.emitUse(OS);
3247 OS << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n"
3248 << " return true;\n"
3249 << " }\n\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003250
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003251 OS << " return false;\n"
3252 << "}\n"
3253 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003254
3255 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
3256 << "PredicateBitset AvailableModuleFeatures;\n"
3257 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
3258 << "PredicateBitset getAvailableFeatures() const {\n"
3259 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
3260 << "}\n"
3261 << "PredicateBitset\n"
3262 << "computeAvailableModuleFeatures(const " << Target.getName()
3263 << "Subtarget *Subtarget) const;\n"
3264 << "PredicateBitset\n"
3265 << "computeAvailableFunctionFeatures(const " << Target.getName()
3266 << "Subtarget *Subtarget,\n"
3267 << " const MachineFunction *MF) const;\n"
3268 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
3269
3270 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
3271 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
3272 << "AvailableFunctionFeatures()\n"
3273 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003274}
3275
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003276void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
3277 if (SubtargetFeatures.count(Predicate) == 0)
3278 SubtargetFeatures.emplace(
3279 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
3280}
3281
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003282} // end anonymous namespace
3283
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003284//===----------------------------------------------------------------------===//
3285
3286namespace llvm {
3287void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
3288 GlobalISelEmitter(RK).run(OS);
3289}
3290} // End llvm namespace