blob: aa11d8e886ea9c5e3146c10895dbc1ab51f88dc7 [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 Sanders2c269f62017-08-24 09:11:20 +0000249 HasUnsupportedPredicate = true;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000250 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
251 Separator = ", ";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000252 Explanation += (Separator + "first-failing:" +
253 Predicate.getOrigPatFragRecord()->getRecord()->getName())
254 .str();
Daniel Sanders2c269f62017-08-24 09:11:20 +0000255 break;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000256 }
257
258 if (N->getTransformFn()) {
259 Explanation += Separator + "Has a transform function";
260 Separator = ", ";
261 }
262
Daniel Sanders2c269f62017-08-24 09:11:20 +0000263 if (!HasUnsupportedPredicate && !N->getTransformFn())
Daniel Sandersd0656a32017-04-13 09:45:37 +0000264 return Error::success();
265
266 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000267}
268
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000269static Record *getInitValueAsRegClass(Init *V) {
270 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
271 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
272 return VDefInit->getDef()->getValueAsDef("RegClass");
273 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
274 return VDefInit->getDef();
275 }
276 return nullptr;
277}
278
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000279std::string
280getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
281 std::string Name = "GIFBS";
282 for (const auto &Feature : FeatureBitset)
283 Name += ("_" + Feature->getName()).str();
284 return Name;
285}
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000286
287//===- MatchTable Helpers -------------------------------------------------===//
288
289class MatchTable;
290
291/// A record to be stored in a MatchTable.
292///
293/// This class represents any and all output that may be required to emit the
294/// MatchTable. Instances are most often configured to represent an opcode or
295/// value that will be emitted to the table with some formatting but it can also
296/// represent commas, comments, and other formatting instructions.
297struct MatchTableRecord {
298 enum RecordFlagsBits {
299 MTRF_None = 0x0,
300 /// Causes EmitStr to be formatted as comment when emitted.
301 MTRF_Comment = 0x1,
302 /// Causes the record value to be followed by a comma when emitted.
303 MTRF_CommaFollows = 0x2,
304 /// Causes the record value to be followed by a line break when emitted.
305 MTRF_LineBreakFollows = 0x4,
306 /// Indicates that the record defines a label and causes an additional
307 /// comment to be emitted containing the index of the label.
308 MTRF_Label = 0x8,
309 /// Causes the record to be emitted as the index of the label specified by
310 /// LabelID along with a comment indicating where that label is.
311 MTRF_JumpTarget = 0x10,
312 /// Causes the formatter to add a level of indentation before emitting the
313 /// record.
314 MTRF_Indent = 0x20,
315 /// Causes the formatter to remove a level of indentation after emitting the
316 /// record.
317 MTRF_Outdent = 0x40,
318 };
319
320 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
321 /// reference or define.
322 unsigned LabelID;
323 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
324 /// value, a label name.
325 std::string EmitStr;
326
327private:
328 /// The number of MatchTable elements described by this record. Comments are 0
329 /// while values are typically 1. Values >1 may occur when we need to emit
330 /// values that exceed the size of a MatchTable element.
331 unsigned NumElements;
332
333public:
334 /// A bitfield of RecordFlagsBits flags.
335 unsigned Flags;
336
337 MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
338 unsigned NumElements, unsigned Flags)
339 : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
340 EmitStr(EmitStr), NumElements(NumElements), Flags(Flags) {
341 assert((!LabelID_.hasValue() || LabelID != ~0u) &&
342 "This value is reserved for non-labels");
343 }
344
345 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
346 const MatchTable &Table) const;
347 unsigned size() const { return NumElements; }
348};
349
350/// Holds the contents of a generated MatchTable to enable formatting and the
351/// necessary index tracking needed to support GIM_Try.
352class MatchTable {
353 /// An unique identifier for the table. The generated table will be named
354 /// MatchTable${ID}.
355 unsigned ID;
356 /// The records that make up the table. Also includes comments describing the
357 /// values being emitted and line breaks to format it.
358 std::vector<MatchTableRecord> Contents;
359 /// The currently defined labels.
360 DenseMap<unsigned, unsigned> LabelMap;
361 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
362 unsigned CurrentSize;
363
Daniel Sanders8e82af22017-07-27 11:03:45 +0000364 /// A unique identifier for a MatchTable label.
365 static unsigned CurrentLabelID;
366
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000367public:
368 static MatchTableRecord LineBreak;
369 static MatchTableRecord Comment(StringRef Comment) {
370 return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
371 }
372 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
373 unsigned ExtraFlags = 0;
374 if (IndentAdjust > 0)
375 ExtraFlags |= MatchTableRecord::MTRF_Indent;
376 if (IndentAdjust < 0)
377 ExtraFlags |= MatchTableRecord::MTRF_Outdent;
378
379 return MatchTableRecord(None, Opcode, 1,
380 MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
381 }
382 static MatchTableRecord NamedValue(StringRef NamedValue) {
383 return MatchTableRecord(None, NamedValue, 1,
384 MatchTableRecord::MTRF_CommaFollows);
385 }
386 static MatchTableRecord NamedValue(StringRef Namespace,
387 StringRef NamedValue) {
388 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
389 MatchTableRecord::MTRF_CommaFollows);
390 }
391 static MatchTableRecord IntValue(int64_t IntValue) {
392 return MatchTableRecord(None, llvm::to_string(IntValue), 1,
393 MatchTableRecord::MTRF_CommaFollows);
394 }
395 static MatchTableRecord Label(unsigned LabelID) {
396 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
397 MatchTableRecord::MTRF_Label |
398 MatchTableRecord::MTRF_Comment |
399 MatchTableRecord::MTRF_LineBreakFollows);
400 }
401 static MatchTableRecord JumpTarget(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000402 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000403 MatchTableRecord::MTRF_JumpTarget |
404 MatchTableRecord::MTRF_Comment |
405 MatchTableRecord::MTRF_CommaFollows);
406 }
407
408 MatchTable(unsigned ID) : ID(ID), CurrentSize(0) {}
409
410 void push_back(const MatchTableRecord &Value) {
411 if (Value.Flags & MatchTableRecord::MTRF_Label)
412 defineLabel(Value.LabelID);
413 Contents.push_back(Value);
414 CurrentSize += Value.size();
415 }
416
Daniel Sanders8e82af22017-07-27 11:03:45 +0000417 unsigned allocateLabelID() const { return CurrentLabelID++; }
418
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000419 void defineLabel(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000420 LabelMap.insert(std::make_pair(LabelID, CurrentSize));
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000421 }
422
423 unsigned getLabelIndex(unsigned LabelID) const {
424 const auto I = LabelMap.find(LabelID);
425 assert(I != LabelMap.end() && "Use of undeclared label");
426 return I->second;
427 }
428
Daniel Sanders8e82af22017-07-27 11:03:45 +0000429 void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
430
431 void emitDeclaration(raw_ostream &OS) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000432 unsigned Indentation = 4;
Daniel Sanderscbbbfe42017-07-27 12:47:31 +0000433 OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000434 LineBreak.emit(OS, true, *this);
435 OS << std::string(Indentation, ' ');
436
437 for (auto I = Contents.begin(), E = Contents.end(); I != E;
438 ++I) {
439 bool LineBreakIsNext = false;
440 const auto &NextI = std::next(I);
441
442 if (NextI != E) {
443 if (NextI->EmitStr == "" &&
444 NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
445 LineBreakIsNext = true;
446 }
447
448 if (I->Flags & MatchTableRecord::MTRF_Indent)
449 Indentation += 2;
450
451 I->emit(OS, LineBreakIsNext, *this);
452 if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
453 OS << std::string(Indentation, ' ');
454
455 if (I->Flags & MatchTableRecord::MTRF_Outdent)
456 Indentation -= 2;
457 }
458 OS << "};\n";
459 }
460};
461
Daniel Sanders8e82af22017-07-27 11:03:45 +0000462unsigned MatchTable::CurrentLabelID = 0;
463
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000464MatchTableRecord MatchTable::LineBreak = {
465 None, "" /* Emit String */, 0 /* Elements */,
466 MatchTableRecord::MTRF_LineBreakFollows};
467
468void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
469 const MatchTable &Table) const {
470 bool UseLineComment =
471 LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
472 if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
473 UseLineComment = false;
474
475 if (Flags & MTRF_Comment)
476 OS << (UseLineComment ? "// " : "/*");
477
478 OS << EmitStr;
479 if (Flags & MTRF_Label)
480 OS << ": @" << Table.getLabelIndex(LabelID);
481
482 if (Flags & MTRF_Comment && !UseLineComment)
483 OS << "*/";
484
485 if (Flags & MTRF_JumpTarget) {
486 if (Flags & MTRF_Comment)
487 OS << " ";
488 OS << Table.getLabelIndex(LabelID);
489 }
490
491 if (Flags & MTRF_CommaFollows) {
492 OS << ",";
493 if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
494 OS << " ";
495 }
496
497 if (Flags & MTRF_LineBreakFollows)
498 OS << "\n";
499}
500
501MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
502 Table.push_back(Value);
503 return Table;
504}
505
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000506//===- Matchers -----------------------------------------------------------===//
507
Daniel Sandersbee57392017-04-04 13:25:23 +0000508class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000509class MatchAction;
510
511/// Generates code to check that a match rule matches.
512class RuleMatcher {
513 /// A list of matchers that all need to succeed for the current rule to match.
514 /// FIXME: This currently supports a single match position but could be
515 /// extended to support multiple positions to support div/rem fusion or
516 /// load-multiple instructions.
517 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
518
519 /// A list of actions that need to be taken when all predicates in this rule
520 /// have succeeded.
521 std::vector<std::unique_ptr<MatchAction>> Actions;
522
Daniel Sanders078572b2017-08-02 11:03:36 +0000523 typedef std::map<const InstructionMatcher *, unsigned>
524 DefinedInsnVariablesMap;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000525 /// A map of instruction matchers to the local variables created by
Daniel Sanders9d662d22017-07-06 10:06:12 +0000526 /// emitCaptureOpcodes().
Daniel Sanders078572b2017-08-02 11:03:36 +0000527 DefinedInsnVariablesMap InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000528
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000529 /// A map of named operands defined by the matchers that may be referenced by
530 /// the renderers.
531 StringMap<OperandMatcher *> DefinedOperands;
532
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000533 /// ID for the next instruction variable defined with defineInsnVar()
534 unsigned NextInsnVarID;
535
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000536 std::vector<Record *> RequiredFeatures;
537
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000538 ArrayRef<SMLoc> SrcLoc;
539
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000540 typedef std::tuple<Record *, unsigned, unsigned>
541 DefinedComplexPatternSubOperand;
542 typedef StringMap<DefinedComplexPatternSubOperand>
543 DefinedComplexPatternSubOperandMap;
544 /// A map of Symbolic Names to ComplexPattern sub-operands.
545 DefinedComplexPatternSubOperandMap ComplexSubOperands;
546
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000547public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000548 RuleMatcher(ArrayRef<SMLoc> SrcLoc)
549 : Matchers(), Actions(), InsnVariableIDs(), DefinedOperands(),
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000550 NextInsnVarID(0), SrcLoc(SrcLoc), ComplexSubOperands() {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000551 RuleMatcher(RuleMatcher &&Other) = default;
552 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000553
Daniel Sanders05540042017-08-08 10:44:31 +0000554 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000555 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000556 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000557
558 template <class Kind, class... Args> Kind &addAction(Args &&... args);
559
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000560 /// Define an instruction without emitting any code to do so.
561 /// This is used for the root of the match.
562 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
563 /// Define an instruction and emit corresponding state-machine opcodes.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000564 unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000565 unsigned InsnVarID, unsigned OpIdx);
566 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sanders078572b2017-08-02 11:03:36 +0000567 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
568 return InsnVariableIDs.begin();
569 }
570 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
571 return InsnVariableIDs.end();
572 }
573 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
574 defined_insn_vars() const {
575 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
576 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000577
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000578 void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
579
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000580 void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
581 unsigned RendererID, unsigned SubOperandID) {
582 assert(ComplexSubOperands.count(SymbolicName) == 0 && "Already defined");
583 ComplexSubOperands[SymbolicName] =
584 std::make_tuple(ComplexPattern, RendererID, SubOperandID);
585 }
586 Optional<DefinedComplexPatternSubOperand>
587 getComplexSubOperand(StringRef SymbolicName) const {
588 const auto &I = ComplexSubOperands.find(SymbolicName);
589 if (I == ComplexSubOperands.end())
590 return None;
591 return I->second;
592 }
593
Daniel Sanders05540042017-08-08 10:44:31 +0000594 const InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000595 const OperandMatcher &getOperandMatcher(StringRef Name) const;
Daniel Sanders05540042017-08-08 10:44:31 +0000596
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000597 void emitCaptureOpcodes(MatchTable &Table);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000598
Daniel Sanders8e82af22017-07-27 11:03:45 +0000599 void emit(MatchTable &Table);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000600
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000601 /// Compare the priority of this object and B.
602 ///
603 /// Returns true if this object is more important than B.
604 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000605
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000606 /// Report the maximum number of temporary operands needed by the rule
607 /// matcher.
608 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000609
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000610 // FIXME: Remove this as soon as possible
611 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000612};
613
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000614template <class PredicateTy> class PredicateListMatcher {
615private:
616 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
617 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000618
Daniel Sanders2c269f62017-08-24 09:11:20 +0000619 /// Template instantiations should specialize this to return a string to use
620 /// for the comment emitted when there are no predicates.
621 std::string getNoPredicateComment() const;
622
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000623public:
624 /// Construct a new operand predicate and add it to the matcher.
625 template <class Kind, class... Args>
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000626 Optional<Kind *> addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000627 Predicates.emplace_back(
628 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000629 return static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000630 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000631
Daniel Sanders32291982017-06-28 13:50:04 +0000632 typename PredicateVec::const_iterator predicates_begin() const {
633 return Predicates.begin();
634 }
635 typename PredicateVec::const_iterator predicates_end() const {
636 return Predicates.end();
637 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000638 iterator_range<typename PredicateVec::const_iterator> predicates() const {
639 return make_range(predicates_begin(), predicates_end());
640 }
Daniel Sanders32291982017-06-28 13:50:04 +0000641 typename PredicateVec::size_type predicates_size() const {
642 return Predicates.size();
643 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000644
Daniel Sanders9d662d22017-07-06 10:06:12 +0000645 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000646 template <class... Args>
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000647 void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000648 if (Predicates.empty()) {
Daniel Sanders2c269f62017-08-24 09:11:20 +0000649 Table << MatchTable::Comment(getNoPredicateComment())
650 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000651 return;
652 }
653
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000654 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000655 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000656 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000657};
658
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000659/// Generates code to check a predicate of an operand.
660///
661/// Typical predicates include:
662/// * Operand is a particular register.
663/// * Operand is assigned a particular register bank.
664/// * Operand is an MBB.
665class OperandPredicateMatcher {
666public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000667 /// This enum is used for RTTI and also defines the priority that is given to
668 /// the predicate when generating the matcher code. Kinds with higher priority
669 /// must be tested first.
670 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000671 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
672 /// but OPM_Int must have priority over OPM_RegBank since constant integers
673 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000674 enum PredicateKind {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000675 OPM_Tie,
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000676 OPM_ComplexPattern,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000677 OPM_IntrinsicID,
Daniel Sanders05540042017-08-08 10:44:31 +0000678 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000679 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000680 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000681 OPM_LLT,
Daniel Sandersa71f4542017-10-16 00:56:30 +0000682 OPM_PointerToAny,
Daniel Sanders759ff412017-02-24 13:58:11 +0000683 OPM_RegBank,
684 OPM_MBB,
685 };
686
687protected:
688 PredicateKind Kind;
689
690public:
691 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000692 virtual ~OperandPredicateMatcher() {}
693
Daniel Sanders759ff412017-02-24 13:58:11 +0000694 PredicateKind getKind() const { return Kind; }
695
Daniel Sanders9d662d22017-07-06 10:06:12 +0000696 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sandersbee57392017-04-04 13:25:23 +0000697 ///
Daniel Sanders9d662d22017-07-06 10:06:12 +0000698 /// Only InstructionOperandMatcher needs to do anything for this method the
699 /// rest just walk the tree.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000700 virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +0000701 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000702
Daniel Sanders9d662d22017-07-06 10:06:12 +0000703 /// Emit MatchTable opcodes that check the predicate for the given operand.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000704 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000705 unsigned InsnVarID,
706 unsigned OpIdx) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000707
708 /// Compare the priority of this object and B.
709 ///
710 /// Returns true if this object is more important than B.
Daniel Sanders05540042017-08-08 10:44:31 +0000711 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000712
713 /// Report the maximum number of temporary operands needed by the predicate
714 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000715 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000716};
717
Daniel Sanders2c269f62017-08-24 09:11:20 +0000718template <>
719std::string
720PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
721 return "No operand predicates";
722}
723
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000724/// Generates code to check that a register operand is defined by the same exact
725/// one as another.
726class SameOperandMatcher : public OperandPredicateMatcher {
727 std::string TiedTo;
728
729public:
730 SameOperandMatcher(StringRef TiedTo)
731 : OperandPredicateMatcher(OPM_Tie), TiedTo(TiedTo) {}
732
733 static bool classof(const OperandPredicateMatcher *P) {
734 return P->getKind() == OPM_Tie;
735 }
736
737 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
738 unsigned InsnVarID, unsigned OpIdx) const override;
739};
740
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000741/// Generates code to check that an operand is a particular LLT.
742class LLTOperandMatcher : public OperandPredicateMatcher {
743protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000744 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000745
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000746public:
Daniel Sanders032e7f22017-08-17 13:18:35 +0000747 static std::set<LLTCodeGen> KnownTypes;
748
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000749 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders032e7f22017-08-17 13:18:35 +0000750 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {
751 KnownTypes.insert(Ty);
752 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000753
754 static bool classof(const OperandPredicateMatcher *P) {
755 return P->getKind() == OPM_LLT;
756 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000757
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000758 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000759 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000760 Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
761 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
762 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
763 << MatchTable::NamedValue(Ty.getCxxEnumValue())
764 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000765 }
766};
767
Daniel Sanders032e7f22017-08-17 13:18:35 +0000768std::set<LLTCodeGen> LLTOperandMatcher::KnownTypes;
769
Daniel Sandersa71f4542017-10-16 00:56:30 +0000770/// Generates code to check that an operand is a pointer to any address space.
771///
772/// In SelectionDAG, the types did not describe pointers or address spaces. As a
773/// result, iN is used to describe a pointer of N bits to any address space and
774/// PatFrag predicates are typically used to constrain the address space. There's
775/// no reliable means to derive the missing type information from the pattern so
776/// imported rules must test the components of a pointer separately.
777///
Daniel Sandersea8711b2017-10-16 03:36:29 +0000778/// If SizeInBits is zero, then the pointer size will be obtained from the
779/// subtarget.
Daniel Sandersa71f4542017-10-16 00:56:30 +0000780class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
781protected:
782 unsigned SizeInBits;
783
784public:
785 PointerToAnyOperandMatcher(unsigned SizeInBits)
786 : OperandPredicateMatcher(OPM_PointerToAny), SizeInBits(SizeInBits) {}
787
788 static bool classof(const OperandPredicateMatcher *P) {
789 return P->getKind() == OPM_PointerToAny;
790 }
791
792 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
793 unsigned InsnVarID, unsigned OpIdx) const override {
794 Table << MatchTable::Opcode("GIM_CheckPointerToAny") << MatchTable::Comment("MI")
795 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
796 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("SizeInBits")
797 << MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
798 }
799};
800
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000801/// Generates code to check that an operand is a particular target constant.
802class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
803protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000804 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000805 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000806
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000807 unsigned getAllocatedTemporariesBaseID() const;
808
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000809public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000810 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
811 const Record &TheDef)
812 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
813 TheDef(TheDef) {}
814
815 static bool classof(const OperandPredicateMatcher *P) {
816 return P->getKind() == OPM_ComplexPattern;
817 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000818
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000819 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000820 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000821 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000822 Table << MatchTable::Opcode("GIM_CheckComplexPattern")
823 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
824 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
825 << MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
826 << MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
827 << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000828 }
829
Daniel Sanders2deea182017-04-22 15:11:04 +0000830 unsigned countRendererFns() const override {
831 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000832 }
833};
834
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000835/// Generates code to check that an operand is in a particular register bank.
836class RegisterBankOperandMatcher : public OperandPredicateMatcher {
837protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000838 const CodeGenRegisterClass &RC;
839
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000840public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000841 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
842 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
843
844 static bool classof(const OperandPredicateMatcher *P) {
845 return P->getKind() == OPM_RegBank;
846 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000847
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000848 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000849 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000850 Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
851 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
852 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
853 << MatchTable::Comment("RC")
854 << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
855 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000856 }
857};
858
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000859/// Generates code to check that an operand is a basic block.
860class MBBOperandMatcher : public OperandPredicateMatcher {
861public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000862 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
863
864 static bool classof(const OperandPredicateMatcher *P) {
865 return P->getKind() == OPM_MBB;
866 }
867
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000868 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000869 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000870 Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
871 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
872 << MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000873 }
874};
875
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000876/// Generates code to check that an operand is a G_CONSTANT with a particular
877/// int.
878class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000879protected:
880 int64_t Value;
881
882public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000883 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000884 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
885
886 static bool classof(const OperandPredicateMatcher *P) {
887 return P->getKind() == OPM_Int;
888 }
889
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000890 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000891 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000892 Table << MatchTable::Opcode("GIM_CheckConstantInt")
893 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
894 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
895 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000896 }
897};
898
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000899/// Generates code to check that an operand is a raw int (where MO.isImm() or
900/// MO.isCImm() is true).
901class LiteralIntOperandMatcher : public OperandPredicateMatcher {
902protected:
903 int64_t Value;
904
905public:
906 LiteralIntOperandMatcher(int64_t Value)
907 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
908
909 static bool classof(const OperandPredicateMatcher *P) {
910 return P->getKind() == OPM_LiteralInt;
911 }
912
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000913 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000914 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000915 Table << MatchTable::Opcode("GIM_CheckLiteralInt")
916 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
917 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
918 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000919 }
920};
921
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000922/// Generates code to check that an operand is an intrinsic ID.
923class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
924protected:
925 const CodeGenIntrinsic *II;
926
927public:
928 IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
929 : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
930
931 static bool classof(const OperandPredicateMatcher *P) {
932 return P->getKind() == OPM_IntrinsicID;
933 }
934
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000935 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000936 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000937 Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
938 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
939 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
940 << MatchTable::NamedValue("Intrinsic::" + II->EnumName)
941 << MatchTable::LineBreak;
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000942 }
943};
944
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000945/// Generates code to check that a set of predicates match for a particular
946/// operand.
947class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
948protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000949 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000950 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000951 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000952
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000953 /// The index of the first temporary variable allocated to this operand. The
954 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +0000955 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000956 unsigned AllocatedTemporariesBaseID;
957
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000958public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000959 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000960 const std::string &SymbolicName,
961 unsigned AllocatedTemporariesBaseID)
962 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
963 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000964
965 bool hasSymbolicName() const { return !SymbolicName.empty(); }
966 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +0000967 void setSymbolicName(StringRef Name) {
968 assert(SymbolicName.empty() && "Operand already has a symbolic name");
969 SymbolicName = Name;
970 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000971 unsigned getOperandIndex() const { return OpIdx; }
972
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000973 std::string getOperandExpr(unsigned InsnVarID) const {
974 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
975 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +0000976 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000977
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000978 InstructionMatcher &getInstructionMatcher() const { return Insn; }
979
Daniel Sandersa71f4542017-10-16 00:56:30 +0000980 Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
981 bool OperandIsAPointer) {
Daniel Sandersea8711b2017-10-16 03:36:29 +0000982 if (!VTy.isMachineValueType())
983 return failedImport("unsupported typeset");
984
985 if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
986 addPredicate<PointerToAnyOperandMatcher>(0);
987 return Error::success();
988 }
989
990 auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
Daniel Sandersa71f4542017-10-16 00:56:30 +0000991 if (!OpTyOrNone)
992 return failedImport("unsupported type");
993
994 if (OperandIsAPointer)
995 addPredicate<PointerToAnyOperandMatcher>(
996 OpTyOrNone->get().getSizeInBits());
997 else
998 addPredicate<LLTOperandMatcher>(*OpTyOrNone);
999 return Error::success();
1000 }
1001
Daniel Sanders9d662d22017-07-06 10:06:12 +00001002 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001003 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001004 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +00001005 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001006 Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00001007 }
1008
Daniel Sanders9d662d22017-07-06 10:06:12 +00001009 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001010 /// InsnVarID matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001011 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001012 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001013 std::string Comment;
1014 raw_string_ostream CommentOS(Comment);
1015 CommentOS << "MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001016 if (SymbolicName.empty())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001017 CommentOS << "Operand " << OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001018 else
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001019 CommentOS << SymbolicName;
1020 Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
1021
1022 emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001023 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001024
1025 /// Compare the priority of this object and B.
1026 ///
1027 /// Returns true if this object is more important than B.
1028 bool isHigherPriorityThan(const OperandMatcher &B) const {
1029 // Operand matchers involving more predicates have higher priority.
1030 if (predicates_size() > B.predicates_size())
1031 return true;
1032 if (predicates_size() < B.predicates_size())
1033 return false;
1034
1035 // This assumes that predicates are added in a consistent order.
1036 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1037 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1038 return true;
1039 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1040 return false;
1041 }
1042
1043 return false;
1044 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001045
1046 /// Report the maximum number of temporary operands needed by the operand
1047 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001048 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001049 return std::accumulate(
1050 predicates().begin(), predicates().end(), 0,
1051 [](unsigned A,
1052 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001053 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001054 });
1055 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001056
1057 unsigned getAllocatedTemporariesBaseID() const {
1058 return AllocatedTemporariesBaseID;
1059 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001060
1061 bool isSameAsAnotherOperand() const {
1062 for (const auto &Predicate : predicates())
1063 if (isa<SameOperandMatcher>(Predicate))
1064 return true;
1065 return false;
1066 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001067};
1068
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001069// Specialize OperandMatcher::addPredicate() to refrain from adding redundant
1070// predicates.
1071template <>
1072template <class Kind, class... Args>
1073Optional<Kind *>
1074PredicateListMatcher<OperandPredicateMatcher>::addPredicate(Args &&... args) {
1075 if (static_cast<OperandMatcher *>(this)->isSameAsAnotherOperand())
1076 return None;
1077 Predicates.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1078 return static_cast<Kind *>(Predicates.back().get());
1079}
1080
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001081unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
1082 return Operand.getAllocatedTemporariesBaseID();
1083}
1084
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001085/// Generates code to check a predicate on an instruction.
1086///
1087/// Typical predicates include:
1088/// * The opcode of the instruction is a particular value.
1089/// * The nsw/nuw flag is/isn't set.
1090class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +00001091protected:
1092 /// This enum is used for RTTI and also defines the priority that is given to
1093 /// the predicate when generating the matcher code. Kinds with higher priority
1094 /// must be tested first.
1095 enum PredicateKind {
1096 IPM_Opcode,
Daniel Sanders2c269f62017-08-24 09:11:20 +00001097 IPM_ImmPredicate,
Daniel Sanders39690bd2017-10-15 02:41:12 +00001098 IPM_NonAtomicMMO,
Daniel Sanders759ff412017-02-24 13:58:11 +00001099 };
1100
1101 PredicateKind Kind;
1102
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001103public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001104 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001105 virtual ~InstructionPredicateMatcher() {}
1106
Daniel Sanders759ff412017-02-24 13:58:11 +00001107 PredicateKind getKind() const { return Kind; }
1108
Daniel Sanders9d662d22017-07-06 10:06:12 +00001109 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001110 /// InsnVarID matches the predicate.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001111 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001112 unsigned InsnVarID) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +00001113
1114 /// Compare the priority of this object and B.
1115 ///
1116 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001117 virtual bool
1118 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +00001119 return Kind < B.Kind;
1120 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001121
1122 /// Report the maximum number of temporary operands needed by the predicate
1123 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001124 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001125};
1126
Daniel Sanders2c269f62017-08-24 09:11:20 +00001127template <>
1128std::string
1129PredicateListMatcher<InstructionPredicateMatcher>::getNoPredicateComment() const {
1130 return "No instruction predicates";
1131}
1132
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001133/// Generates code to check the opcode of an instruction.
1134class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1135protected:
1136 const CodeGenInstruction *I;
1137
1138public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001139 InstructionOpcodeMatcher(const CodeGenInstruction *I)
1140 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001141
Daniel Sanders759ff412017-02-24 13:58:11 +00001142 static bool classof(const InstructionPredicateMatcher *P) {
1143 return P->getKind() == IPM_Opcode;
1144 }
1145
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001146 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001147 unsigned InsnVarID) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001148 Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
1149 << MatchTable::IntValue(InsnVarID)
1150 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1151 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001152 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001153
1154 /// Compare the priority of this object and B.
1155 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001156 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001157 bool
1158 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +00001159 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
1160 return true;
1161 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
1162 return false;
1163
1164 // Prioritize opcodes for cosmetic reasons in the generated source. Although
1165 // this is cosmetic at the moment, we may want to drive a similar ordering
1166 // using instruction frequency information to improve compile time.
1167 if (const InstructionOpcodeMatcher *BO =
1168 dyn_cast<InstructionOpcodeMatcher>(&B))
1169 return I->TheDef->getName() < BO->I->TheDef->getName();
1170
1171 return false;
1172 };
Daniel Sanders05540042017-08-08 10:44:31 +00001173
1174 bool isConstantInstruction() const {
1175 return I->TheDef->getName() == "G_CONSTANT";
1176 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001177};
1178
Daniel Sanders2c269f62017-08-24 09:11:20 +00001179/// Generates code to check that this instruction is a constant whose value
1180/// meets an immediate predicate.
1181///
1182/// Immediates are slightly odd since they are typically used like an operand
1183/// but are represented as an operator internally. We typically write simm8:$src
1184/// in a tablegen pattern, but this is just syntactic sugar for
1185/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1186/// that will be matched and the predicate (which is attached to the imm
1187/// operator) that will be tested. In SelectionDAG this describes a
1188/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
1189///
1190/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1191/// this representation, the immediate could be tested with an
1192/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1193/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1194/// there are two implementation issues with producing that matcher
1195/// configuration from the SelectionDAG pattern:
1196/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1197/// were we to sink the immediate predicate to the operand we would have to
1198/// have two partial implementations of PatFrag support, one for immediates
1199/// and one for non-immediates.
1200/// * At the point we handle the predicate, the OperandMatcher hasn't been
1201/// created yet. If we were to sink the predicate to the OperandMatcher we
1202/// would also have to complicate (or duplicate) the code that descends and
1203/// creates matchers for the subtree.
1204/// Overall, it's simpler to handle it in the place it was found.
1205class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1206protected:
1207 TreePredicateFn Predicate;
1208
1209public:
1210 InstructionImmPredicateMatcher(const TreePredicateFn &Predicate)
1211 : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {}
1212
1213 static bool classof(const InstructionPredicateMatcher *P) {
1214 return P->getKind() == IPM_ImmPredicate;
1215 }
1216
1217 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1218 unsigned InsnVarID) const override {
Daniel Sanders11300ce2017-10-13 21:28:03 +00001219 Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001220 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1221 << MatchTable::Comment("Predicate")
Daniel Sanders11300ce2017-10-13 21:28:03 +00001222 << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001223 << MatchTable::LineBreak;
1224 }
1225};
1226
Daniel Sanders39690bd2017-10-15 02:41:12 +00001227/// Generates code to check that a memory instruction has a non-atomic MachineMemoryOperand.
1228class NonAtomicMMOPredicateMatcher : public InstructionPredicateMatcher {
1229public:
1230 NonAtomicMMOPredicateMatcher()
1231 : InstructionPredicateMatcher(IPM_NonAtomicMMO) {}
1232
1233 static bool classof(const InstructionPredicateMatcher *P) {
1234 return P->getKind() == IPM_NonAtomicMMO;
1235 }
1236
1237 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1238 unsigned InsnVarID) const override {
1239 Table << MatchTable::Opcode("GIM_CheckNonAtomic")
1240 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1241 << MatchTable::LineBreak;
1242 }
1243};
1244
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001245/// Generates code to check that a set of predicates and operands match for a
1246/// particular instruction.
1247///
1248/// Typical predicates include:
1249/// * Has a specific opcode.
1250/// * Has an nsw/nuw flag or doesn't.
1251class InstructionMatcher
1252 : public PredicateListMatcher<InstructionPredicateMatcher> {
1253protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001254 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001255
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001256 RuleMatcher &Rule;
1257
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001258 /// The operands to match. All rendered operands must be present even if the
1259 /// condition is always true.
1260 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001261
Daniel Sanders05540042017-08-08 10:44:31 +00001262 std::string SymbolicName;
1263
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001264public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001265 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
1266 : Rule(Rule), SymbolicName(SymbolicName) {}
1267
1268 RuleMatcher &getRuleMatcher() const { return Rule; }
Daniel Sanders05540042017-08-08 10:44:31 +00001269
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001270 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001271 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1272 unsigned AllocatedTemporariesBaseID) {
1273 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
1274 AllocatedTemporariesBaseID));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001275 if (!SymbolicName.empty())
1276 Rule.defineOperand(SymbolicName, *Operands.back());
1277
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001278 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001279 }
1280
Daniel Sandersffc7d582017-03-29 15:37:18 +00001281 OperandMatcher &getOperand(unsigned OpIdx) {
1282 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001283 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
1284 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001285 });
1286 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001287 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001288 llvm_unreachable("Failed to lookup operand");
1289 }
1290
Daniel Sanders05540042017-08-08 10:44:31 +00001291 StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001292 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +00001293 OperandVec::iterator operands_begin() { return Operands.begin(); }
1294 OperandVec::iterator operands_end() { return Operands.end(); }
1295 iterator_range<OperandVec::iterator> operands() {
1296 return make_range(operands_begin(), operands_end());
1297 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001298 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1299 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001300 iterator_range<OperandVec::const_iterator> operands() const {
1301 return make_range(operands_begin(), operands_end());
1302 }
1303
Daniel Sanders9d662d22017-07-06 10:06:12 +00001304 /// Emit MatchTable opcodes to check the shape of the match and capture
1305 /// instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001306 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001307 unsigned InsnID) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001308 Table << MatchTable::Opcode("GIM_CheckNumOperands")
1309 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1310 << MatchTable::Comment("Expected")
1311 << MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001312 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001313 Operand->emitCaptureOpcodes(Table, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001314 }
1315
Daniel Sanders9d662d22017-07-06 10:06:12 +00001316 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001317 /// InsnVarName matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001318 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001319 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001320 emitPredicateListOpcodes(Table, Rule, InsnVarID);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001321 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001322 Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001323 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001324
1325 /// Compare the priority of this object and B.
1326 ///
1327 /// Returns true if this object is more important than B.
1328 bool isHigherPriorityThan(const InstructionMatcher &B) const {
1329 // Instruction matchers involving more operands have higher priority.
1330 if (Operands.size() > B.Operands.size())
1331 return true;
1332 if (Operands.size() < B.Operands.size())
1333 return false;
1334
1335 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1336 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1337 return true;
1338 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1339 return false;
1340 }
1341
1342 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001343 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001344 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001345 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001346 return false;
1347 }
1348
1349 return false;
1350 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001351
1352 /// Report the maximum number of temporary operands needed by the instruction
1353 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001354 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001355 return std::accumulate(predicates().begin(), predicates().end(), 0,
1356 [](unsigned A,
1357 const std::unique_ptr<InstructionPredicateMatcher>
1358 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001359 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001360 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001361 std::accumulate(
1362 Operands.begin(), Operands.end(), 0,
1363 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001364 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001365 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001366 }
Daniel Sanders05540042017-08-08 10:44:31 +00001367
1368 bool isConstantInstruction() const {
1369 for (const auto &P : predicates())
1370 if (const InstructionOpcodeMatcher *Opcode =
1371 dyn_cast<InstructionOpcodeMatcher>(P.get()))
1372 return Opcode->isConstantInstruction();
1373 return false;
1374 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001375};
1376
Daniel Sandersbee57392017-04-04 13:25:23 +00001377/// Generates code to check that the operand is a register defined by an
1378/// instruction that matches the given instruction matcher.
1379///
1380/// For example, the pattern:
1381/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1382/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1383/// the:
1384/// (G_ADD $src1, $src2)
1385/// subpattern.
1386class InstructionOperandMatcher : public OperandPredicateMatcher {
1387protected:
1388 std::unique_ptr<InstructionMatcher> InsnMatcher;
1389
1390public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001391 InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName)
Daniel Sandersbee57392017-04-04 13:25:23 +00001392 : OperandPredicateMatcher(OPM_Instruction),
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001393 InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {}
Daniel Sandersbee57392017-04-04 13:25:23 +00001394
1395 static bool classof(const OperandPredicateMatcher *P) {
1396 return P->getKind() == OPM_Instruction;
1397 }
1398
1399 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1400
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001401 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001402 unsigned InsnID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001403 unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
1404 InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001405 }
1406
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001407 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001408 unsigned InsnVarID_,
1409 unsigned OpIdx_) const override {
1410 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001411 InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001412 }
1413};
1414
Daniel Sanders43c882c2017-02-01 10:53:10 +00001415//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001416class OperandRenderer {
1417public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001418 enum RendererKind {
1419 OR_Copy,
1420 OR_CopySubReg,
Daniel Sanders05540042017-08-08 10:44:31 +00001421 OR_CopyConstantAsImm,
Daniel Sanders11300ce2017-10-13 21:28:03 +00001422 OR_CopyFConstantAsFPImm,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001423 OR_Imm,
1424 OR_Register,
1425 OR_ComplexPattern
1426 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001427
1428protected:
1429 RendererKind Kind;
1430
1431public:
1432 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1433 virtual ~OperandRenderer() {}
1434
1435 RendererKind getKind() const { return Kind; }
1436
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001437 virtual void emitRenderOpcodes(MatchTable &Table,
1438 RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001439};
1440
1441/// A CopyRenderer emits code to copy a single operand from an existing
1442/// instruction to the one being built.
1443class CopyRenderer : public OperandRenderer {
1444protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001445 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001446 /// The matcher for the instruction that this operand is copied from.
1447 /// This provides the facility for looking up an a operand by it's name so
1448 /// that it can be used as a source for the instruction being built.
1449 const InstructionMatcher &Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001450 /// The name of the operand.
1451 const StringRef SymbolicName;
1452
1453public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001454 CopyRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
1455 StringRef SymbolicName)
1456 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID), Matched(Matched),
Daniel Sanders05540042017-08-08 10:44:31 +00001457 SymbolicName(SymbolicName) {
1458 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1459 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001460
1461 static bool classof(const OperandRenderer *R) {
1462 return R->getKind() == OR_Copy;
1463 }
1464
1465 const StringRef getSymbolicName() const { return SymbolicName; }
1466
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001467 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001468 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001469 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001470 Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
1471 << MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
1472 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1473 << MatchTable::IntValue(Operand.getOperandIndex())
1474 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001475 }
1476};
1477
Daniel Sanders05540042017-08-08 10:44:31 +00001478/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1479/// an extended immediate operand.
1480class CopyConstantAsImmRenderer : public OperandRenderer {
1481protected:
1482 unsigned NewInsnID;
1483 /// The name of the operand.
1484 const std::string SymbolicName;
1485 bool Signed;
1486
1487public:
1488 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1489 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
1490 SymbolicName(SymbolicName), Signed(true) {}
1491
1492 static bool classof(const OperandRenderer *R) {
1493 return R->getKind() == OR_CopyConstantAsImm;
1494 }
1495
1496 const StringRef getSymbolicName() const { return SymbolicName; }
1497
1498 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1499 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1500 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1501 Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
1502 : "GIR_CopyConstantAsUImm")
1503 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1504 << MatchTable::Comment("OldInsnID")
1505 << MatchTable::IntValue(OldInsnVarID)
1506 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1507 }
1508};
1509
Daniel Sanders11300ce2017-10-13 21:28:03 +00001510/// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1511/// instruction to an extended immediate operand.
1512class CopyFConstantAsFPImmRenderer : public OperandRenderer {
1513protected:
1514 unsigned NewInsnID;
1515 /// The name of the operand.
1516 const std::string SymbolicName;
1517
1518public:
1519 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1520 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
1521 SymbolicName(SymbolicName) {}
1522
1523 static bool classof(const OperandRenderer *R) {
1524 return R->getKind() == OR_CopyFConstantAsFPImm;
1525 }
1526
1527 const StringRef getSymbolicName() const { return SymbolicName; }
1528
1529 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1530 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1531 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1532 Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
1533 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1534 << MatchTable::Comment("OldInsnID")
1535 << MatchTable::IntValue(OldInsnVarID)
1536 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1537 }
1538};
1539
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001540/// A CopySubRegRenderer emits code to copy a single register operand from an
1541/// existing instruction to the one being built and indicate that only a
1542/// subregister should be copied.
1543class CopySubRegRenderer : public OperandRenderer {
1544protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001545 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001546 /// The matcher for the instruction that this operand is copied from.
1547 /// This provides the facility for looking up an a operand by it's name so
1548 /// that it can be used as a source for the instruction being built.
1549 const InstructionMatcher &Matched;
1550 /// The name of the operand.
1551 const StringRef SymbolicName;
1552 /// The subregister to extract.
1553 const CodeGenSubRegIndex *SubReg;
1554
1555public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001556 CopySubRegRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
1557 StringRef SymbolicName, const CodeGenSubRegIndex *SubReg)
1558 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID), Matched(Matched),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001559 SymbolicName(SymbolicName), SubReg(SubReg) {}
1560
1561 static bool classof(const OperandRenderer *R) {
1562 return R->getKind() == OR_CopySubReg;
1563 }
1564
1565 const StringRef getSymbolicName() const { return SymbolicName; }
1566
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001567 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001568 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001569 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001570 Table << MatchTable::Opcode("GIR_CopySubReg")
1571 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1572 << MatchTable::Comment("OldInsnID")
1573 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1574 << MatchTable::IntValue(Operand.getOperandIndex())
1575 << MatchTable::Comment("SubRegIdx")
1576 << MatchTable::IntValue(SubReg->EnumValue)
1577 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001578 }
1579};
1580
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001581/// Adds a specific physical register to the instruction being built.
1582/// This is typically useful for WZR/XZR on AArch64.
1583class AddRegisterRenderer : public OperandRenderer {
1584protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001585 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001586 const Record *RegisterDef;
1587
1588public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001589 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
1590 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
1591 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001592
1593 static bool classof(const OperandRenderer *R) {
1594 return R->getKind() == OR_Register;
1595 }
1596
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001597 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1598 Table << MatchTable::Opcode("GIR_AddRegister")
1599 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1600 << MatchTable::NamedValue(
1601 (RegisterDef->getValue("Namespace")
1602 ? RegisterDef->getValueAsString("Namespace")
1603 : ""),
1604 RegisterDef->getName())
1605 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001606 }
1607};
1608
Daniel Sanders0ed28822017-04-12 08:23:08 +00001609/// Adds a specific immediate to the instruction being built.
1610class ImmRenderer : public OperandRenderer {
1611protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001612 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001613 int64_t Imm;
1614
1615public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001616 ImmRenderer(unsigned InsnID, int64_t Imm)
1617 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001618
1619 static bool classof(const OperandRenderer *R) {
1620 return R->getKind() == OR_Imm;
1621 }
1622
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001623 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1624 Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
1625 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
1626 << MatchTable::IntValue(Imm) << MatchTable::LineBreak;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001627 }
1628};
1629
Daniel Sanders2deea182017-04-22 15:11:04 +00001630/// Adds operands by calling a renderer function supplied by the ComplexPattern
1631/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001632class RenderComplexPatternOperand : public OperandRenderer {
1633private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001634 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001635 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001636 /// The name of the operand.
1637 const StringRef SymbolicName;
1638 /// The renderer number. This must be unique within a rule since it's used to
1639 /// identify a temporary variable to hold the renderer function.
1640 unsigned RendererID;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001641 /// When provided, this is the suboperand of the ComplexPattern operand to
1642 /// render. Otherwise all the suboperands will be rendered.
1643 Optional<unsigned> SubOperand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001644
1645 unsigned getNumOperands() const {
1646 return TheDef.getValueAsDag("Operands")->getNumArgs();
1647 }
1648
1649public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001650 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001651 StringRef SymbolicName, unsigned RendererID,
1652 Optional<unsigned> SubOperand = None)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001653 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001654 SymbolicName(SymbolicName), RendererID(RendererID),
1655 SubOperand(SubOperand) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001656
1657 static bool classof(const OperandRenderer *R) {
1658 return R->getKind() == OR_ComplexPattern;
1659 }
1660
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001661 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001662 Table << MatchTable::Opcode(SubOperand.hasValue() ? "GIR_ComplexSubOperandRenderer"
1663 : "GIR_ComplexRenderer")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001664 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1665 << MatchTable::Comment("RendererID")
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001666 << MatchTable::IntValue(RendererID);
1667 if (SubOperand.hasValue())
1668 Table << MatchTable::Comment("SubOperand")
1669 << MatchTable::IntValue(SubOperand.getValue());
1670 Table << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001671 }
1672};
1673
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001674/// An action taken when all Matcher predicates succeeded for a parent rule.
1675///
1676/// Typical actions include:
1677/// * Changing the opcode of an instruction.
1678/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001679class MatchAction {
1680public:
1681 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001682
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001683 /// Emit the MatchTable opcodes to implement the action.
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001684 ///
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001685 /// \param RecycleInsnID If given, it's an instruction to recycle. The
1686 /// requirements on the instruction vary from action to
1687 /// action.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001688 virtual void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1689 unsigned RecycleInsnID) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001690};
1691
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001692/// Generates a comment describing the matched rule being acted upon.
1693class DebugCommentAction : public MatchAction {
1694private:
1695 const PatternToMatch &P;
1696
1697public:
1698 DebugCommentAction(const PatternToMatch &P) : P(P) {}
1699
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001700 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1701 unsigned RecycleInsnID) const override {
1702 Table << MatchTable::Comment(llvm::to_string(*P.getSrcPattern()) + " => " +
1703 llvm::to_string(*P.getDstPattern()))
1704 << MatchTable::LineBreak;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001705 }
1706};
1707
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001708/// Generates code to build an instruction or mutate an existing instruction
1709/// into the desired instruction when this is possible.
1710class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001711private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001712 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001713 const CodeGenInstruction *I;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001714 const InstructionMatcher &Matched;
1715 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1716
1717 /// True if the instruction can be built solely by mutating the opcode.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001718 bool canMutate(RuleMatcher &Rule) const {
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001719 if (OperandRenderers.size() != Matched.getNumOperands())
1720 return false;
1721
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001722 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001723 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001724 const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001725 if (&Matched != &OM.getInstructionMatcher() ||
1726 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001727 return false;
1728 } else
1729 return false;
1730 }
1731
1732 return true;
1733 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001734
Daniel Sanders43c882c2017-02-01 10:53:10 +00001735public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001736 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001737 const InstructionMatcher &Matched)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001738 : InsnID(InsnID), I(I), Matched(Matched) {}
Daniel Sanders43c882c2017-02-01 10:53:10 +00001739
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001740 template <class Kind, class... Args>
1741 Kind &addRenderer(Args&&... args) {
1742 OperandRenderers.emplace_back(
1743 llvm::make_unique<Kind>(std::forward<Args>(args)...));
1744 return *static_cast<Kind *>(OperandRenderers.back().get());
1745 }
1746
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001747 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1748 unsigned RecycleInsnID) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001749 if (canMutate(Rule)) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001750 Table << MatchTable::Opcode("GIR_MutateOpcode")
1751 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1752 << MatchTable::Comment("RecycleInsnID")
1753 << MatchTable::IntValue(RecycleInsnID)
1754 << MatchTable::Comment("Opcode")
1755 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1756 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001757
1758 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001759 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001760 auto Namespace = Def->getValue("Namespace")
1761 ? Def->getValueAsString("Namespace")
1762 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001763 Table << MatchTable::Opcode("GIR_AddImplicitDef")
1764 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1765 << MatchTable::NamedValue(Namespace, Def->getName())
1766 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001767 }
1768 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001769 auto Namespace = Use->getValue("Namespace")
1770 ? Use->getValueAsString("Namespace")
1771 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001772 Table << MatchTable::Opcode("GIR_AddImplicitUse")
1773 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1774 << MatchTable::NamedValue(Namespace, Use->getName())
1775 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001776 }
1777 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001778 return;
1779 }
1780
1781 // TODO: Simple permutation looks like it could be almost as common as
1782 // mutation due to commutative operations.
1783
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001784 Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
1785 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
1786 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1787 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001788 for (const auto &Renderer : OperandRenderers)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001789 Renderer->emitRenderOpcodes(Table, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001790
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001791 if (I->mayLoad || I->mayStore) {
1792 Table << MatchTable::Opcode("GIR_MergeMemOperands")
1793 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1794 << MatchTable::Comment("MergeInsnID's");
1795 // Emit the ID's for all the instructions that are matched by this rule.
1796 // TODO: Limit this to matched instructions that mayLoad/mayStore or have
1797 // some other means of having a memoperand. Also limit this to
1798 // emitted instructions that expect to have a memoperand too. For
1799 // example, (G_SEXT (G_LOAD x)) that results in separate load and
1800 // sign-extend instructions shouldn't put the memoperand on the
1801 // sign-extend since it has no effect there.
1802 std::vector<unsigned> MergeInsnIDs;
1803 for (const auto &IDMatcherPair : Rule.defined_insn_vars())
1804 MergeInsnIDs.push_back(IDMatcherPair.second);
1805 std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end());
1806 for (const auto &MergeInsnID : MergeInsnIDs)
1807 Table << MatchTable::IntValue(MergeInsnID);
Daniel Sanders05540042017-08-08 10:44:31 +00001808 Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
1809 << MatchTable::LineBreak;
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001810 }
1811
1812 Table << MatchTable::Opcode("GIR_EraseFromParent")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001813 << MatchTable::Comment("InsnID")
1814 << MatchTable::IntValue(RecycleInsnID) << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001815 }
1816};
1817
1818/// Generates code to constrain the operands of an output instruction to the
1819/// register classes specified by the definition of that instruction.
1820class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001821 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001822
1823public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001824 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001825
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001826 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1827 unsigned RecycleInsnID) const override {
1828 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
1829 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1830 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001831 }
1832};
1833
1834/// Generates code to constrain the specified operand of an output instruction
1835/// to the specified register class.
1836class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001837 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001838 unsigned OpIdx;
1839 const CodeGenRegisterClass &RC;
1840
1841public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001842 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001843 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001844 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001845
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001846 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1847 unsigned RecycleInsnID) const override {
1848 Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
1849 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1850 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1851 << MatchTable::Comment("RC " + RC.getName())
1852 << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001853 }
1854};
1855
Daniel Sanders05540042017-08-08 10:44:31 +00001856InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001857 Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001858 return *Matchers.back();
1859}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001860
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001861void RuleMatcher::addRequiredFeature(Record *Feature) {
1862 RequiredFeatures.push_back(Feature);
1863}
1864
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001865const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
1866 return RequiredFeatures;
1867}
1868
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001869template <class Kind, class... Args>
1870Kind &RuleMatcher::addAction(Args &&... args) {
1871 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1872 return *static_cast<Kind *>(Actions.back().get());
1873}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001874
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001875unsigned
1876RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
1877 unsigned NewInsnVarID = NextInsnVarID++;
1878 InsnVariableIDs[&Matcher] = NewInsnVarID;
1879 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001880}
1881
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001882unsigned RuleMatcher::defineInsnVar(MatchTable &Table,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001883 const InstructionMatcher &Matcher,
1884 unsigned InsnID, unsigned OpIdx) {
1885 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001886 Table << MatchTable::Opcode("GIM_RecordInsn")
1887 << MatchTable::Comment("DefineMI") << MatchTable::IntValue(NewInsnVarID)
1888 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1889 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
1890 << MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
1891 << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001892 return NewInsnVarID;
1893}
1894
1895unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
1896 const auto &I = InsnVariableIDs.find(&InsnMatcher);
1897 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001898 return I->second;
1899 llvm_unreachable("Matched Insn was not captured in a local variable");
1900}
1901
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001902void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
1903 if (DefinedOperands.find(SymbolicName) == DefinedOperands.end()) {
1904 DefinedOperands[SymbolicName] = &OM;
1905 return;
1906 }
1907
1908 // If the operand is already defined, then we must ensure both references in
1909 // the matcher have the exact same node.
1910 OM.addPredicate<SameOperandMatcher>(OM.getSymbolicName());
1911}
1912
Daniel Sanders05540042017-08-08 10:44:31 +00001913const InstructionMatcher &
1914RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
1915 for (const auto &I : InsnVariableIDs)
1916 if (I.first->getSymbolicName() == SymbolicName)
1917 return *I.first;
1918 llvm_unreachable(
1919 ("Failed to lookup instruction " + SymbolicName).str().c_str());
1920}
1921
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001922const OperandMatcher &
1923RuleMatcher::getOperandMatcher(StringRef Name) const {
1924 const auto &I = DefinedOperands.find(Name);
1925
1926 if (I == DefinedOperands.end())
1927 PrintFatalError(SrcLoc, "Operand " + Name + " was not declared in matcher");
1928
1929 return *I->second;
1930}
1931
Daniel Sanders9d662d22017-07-06 10:06:12 +00001932/// Emit MatchTable opcodes to check the shape of the match and capture
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001933/// instructions into local variables.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001934void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001935 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001936 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001937 Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001938}
1939
Daniel Sanders8e82af22017-07-27 11:03:45 +00001940void RuleMatcher::emit(MatchTable &Table) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001941 if (Matchers.empty())
1942 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001943
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001944 // The representation supports rules that require multiple roots such as:
1945 // %ptr(p0) = ...
1946 // %elt0(s32) = G_LOAD %ptr
1947 // %1(p0) = G_ADD %ptr, 4
1948 // %elt1(s32) = G_LOAD p0 %1
1949 // which could be usefully folded into:
1950 // %ptr(p0) = ...
1951 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
1952 // on some targets but we don't need to make use of that yet.
1953 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001954
Daniel Sanders8e82af22017-07-27 11:03:45 +00001955 unsigned LabelID = Table.allocateLabelID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001956 Table << MatchTable::Opcode("GIM_Try", +1)
Daniel Sanders8e82af22017-07-27 11:03:45 +00001957 << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(LabelID)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001958 << MatchTable::LineBreak;
1959
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001960 if (!RequiredFeatures.empty()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001961 Table << MatchTable::Opcode("GIM_CheckFeatures")
1962 << MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
1963 << MatchTable::LineBreak;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001964 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001965
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001966 emitCaptureOpcodes(Table);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001967
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001968 Matchers.front()->emitPredicateOpcodes(Table, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001969 getInsnVarID(*Matchers.front()));
1970
Daniel Sandersbee57392017-04-04 13:25:23 +00001971 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001972 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00001973 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001974 SmallVector<unsigned, 2> InsnIDs;
1975 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001976 // Skip the root node since it isn't moving anywhere. Everything else is
1977 // sinking to meet it.
1978 if (Pair.first == Matchers.front().get())
1979 continue;
1980
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001981 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00001982 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001983 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00001984
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001985 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001986 // Reject the difficult cases until we have a more accurate check.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001987 Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
1988 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1989 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00001990
1991 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
1992 // account for unsafe cases.
1993 //
1994 // Example:
1995 // MI1--> %0 = ...
1996 // %1 = ... %0
1997 // MI0--> %2 = ... %0
1998 // It's not safe to erase MI1. We currently handle this by not
1999 // erasing %0 (even when it's dead).
2000 //
2001 // Example:
2002 // MI1--> %0 = load volatile @a
2003 // %1 = load volatile @a
2004 // MI0--> %2 = ... %0
2005 // It's not safe to sink %0's def past %1. We currently handle
2006 // this by rejecting all loads.
2007 //
2008 // Example:
2009 // MI1--> %0 = load @a
2010 // %1 = store @a
2011 // MI0--> %2 = ... %0
2012 // It's not safe to sink %0's def past %1. We currently handle
2013 // this by rejecting all loads.
2014 //
2015 // Example:
2016 // G_CONDBR %cond, @BB1
2017 // BB0:
2018 // MI1--> %0 = load @a
2019 // G_BR @BB1
2020 // BB1:
2021 // MI0--> %2 = ... %0
2022 // It's not always safe to sink %0 across control flow. In this
2023 // case it may introduce a memory fault. We currentl handle this
2024 // by rejecting all loads.
2025 }
2026 }
2027
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002028 for (const auto &MA : Actions)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002029 MA->emitActionOpcodes(Table, *this, 0);
2030 Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
Daniel Sanders8e82af22017-07-27 11:03:45 +00002031 << MatchTable::Label(LabelID);
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002032}
Daniel Sanders43c882c2017-02-01 10:53:10 +00002033
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002034bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
2035 // Rules involving more match roots have higher priority.
2036 if (Matchers.size() > B.Matchers.size())
2037 return true;
2038 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00002039 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002040
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002041 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
2042 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
2043 return true;
2044 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
2045 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002046 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002047
2048 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00002049}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002050
Daniel Sanders2deea182017-04-22 15:11:04 +00002051unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002052 return std::accumulate(
2053 Matchers.begin(), Matchers.end(), 0,
2054 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00002055 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002056 });
2057}
2058
Daniel Sanders05540042017-08-08 10:44:31 +00002059bool OperandPredicateMatcher::isHigherPriorityThan(
2060 const OperandPredicateMatcher &B) const {
2061 // Generally speaking, an instruction is more important than an Int or a
2062 // LiteralInt because it can cover more nodes but theres an exception to
2063 // this. G_CONSTANT's are less important than either of those two because they
2064 // are more permissive.
Daniel Sandersedd07842017-08-17 09:26:14 +00002065
2066 const InstructionOperandMatcher *AOM =
2067 dyn_cast<InstructionOperandMatcher>(this);
2068 const InstructionOperandMatcher *BOM =
2069 dyn_cast<InstructionOperandMatcher>(&B);
2070 bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
2071 bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
2072
2073 if (AOM && BOM) {
2074 // The relative priorities between a G_CONSTANT and any other instruction
2075 // don't actually matter but this code is needed to ensure a strict weak
2076 // ordering. This is particularly important on Windows where the rules will
2077 // be incorrectly sorted without it.
2078 if (AIsConstantInsn != BIsConstantInsn)
2079 return AIsConstantInsn < BIsConstantInsn;
2080 return false;
Daniel Sanders05540042017-08-08 10:44:31 +00002081 }
Daniel Sandersedd07842017-08-17 09:26:14 +00002082
2083 if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
2084 return false;
2085 if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
2086 return true;
Daniel Sanders05540042017-08-08 10:44:31 +00002087
2088 return Kind < B.Kind;
Daniel Sanders75b84fc2017-08-08 13:21:26 +00002089}
Daniel Sanders05540042017-08-08 10:44:31 +00002090
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002091void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
2092 RuleMatcher &Rule,
2093 unsigned InsnVarID,
2094 unsigned OpIdx) const {
2095 const OperandMatcher &OtherOM = Rule.getOperandMatcher(TiedTo);
2096 unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
2097
2098 Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
2099 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
2100 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2101 << MatchTable::Comment("OtherMI")
2102 << MatchTable::IntValue(OtherInsnVarID)
2103 << MatchTable::Comment("OtherOpIdx")
2104 << MatchTable::IntValue(OtherOM.getOperandIndex())
2105 << MatchTable::LineBreak;
2106}
2107
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002108//===- GlobalISelEmitter class --------------------------------------------===//
2109
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002110class GlobalISelEmitter {
2111public:
2112 explicit GlobalISelEmitter(RecordKeeper &RK);
2113 void run(raw_ostream &OS);
2114
2115private:
2116 const RecordKeeper &RK;
2117 const CodeGenDAGPatterns CGP;
2118 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002119 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002120
Daniel Sanders39690bd2017-10-15 02:41:12 +00002121 /// Keep track of the equivalence between SDNodes and Instruction by mapping
2122 /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
2123 /// check for attributes on the relation such as CheckMMOIsNonAtomic.
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002124 /// This is defined using 'GINodeEquiv' in the target description.
Daniel Sanders39690bd2017-10-15 02:41:12 +00002125 DenseMap<Record *, Record *> NodeEquivs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002126
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002127 /// Keep track of the equivalence between ComplexPattern's and
2128 /// GIComplexOperandMatcher. Map entries are specified by subclassing
2129 /// GIComplexPatternEquiv.
2130 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
2131
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002132 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002133 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002134
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002135 void gatherNodeEquivs();
Daniel Sanders39690bd2017-10-15 02:41:12 +00002136 Record *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002137
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002138 Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002139 Expected<InstructionMatcher &> createAndImportSelDAGMatcher(
2140 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2141 const TreePatternNode *Src, unsigned &TempOpIdx) const;
2142 Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
2143 unsigned &TempOpIdx) const;
2144 Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002145 const TreePatternNode *SrcChild,
2146 bool OperandIsAPointer, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00002147 unsigned &TempOpIdx) const;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002148 Expected<BuildMIAction &>
2149 createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst,
2150 const InstructionMatcher &InsnMatcher);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002151 Error importExplicitUseRenderer(RuleMatcher &Rule,
2152 BuildMIAction &DstMIBuilder,
Daniel Sandersc270c502017-03-30 09:36:33 +00002153 TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002154 const InstructionMatcher &InsnMatcher) const;
Diana Picus382602f2017-05-17 08:57:28 +00002155 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
2156 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00002157 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002158 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
2159 const std::vector<Record *> &ImplicitDefs) const;
2160
Daniel Sanders11300ce2017-10-13 21:28:03 +00002161 void emitImmPredicates(raw_ostream &OS, StringRef TypeIdentifier,
2162 StringRef Type,
Daniel Sanders649c5852017-10-13 20:42:18 +00002163 std::function<bool(const Record *R)> Filter);
2164
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002165 /// Analyze pattern \p P, returning a matcher for it if possible.
2166 /// Otherwise, return an Error explaining why we don't support it.
2167 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002168
2169 void declareSubtargetFeature(Record *Predicate);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002170};
2171
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002172void GlobalISelEmitter::gatherNodeEquivs() {
2173 assert(NodeEquivs.empty());
2174 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
Daniel Sanders39690bd2017-10-15 02:41:12 +00002175 NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002176
2177 assert(ComplexPatternEquivs.empty());
2178 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
2179 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
2180 if (!SelDAGEquiv)
2181 continue;
2182 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
2183 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002184}
2185
Daniel Sanders39690bd2017-10-15 02:41:12 +00002186Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002187 return NodeEquivs.lookup(N);
2188}
2189
2190GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002191 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()),
2192 CGRegs(RK, Target.getHwModes()) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002193
2194//===- Emitter ------------------------------------------------------------===//
2195
Daniel Sandersc270c502017-03-30 09:36:33 +00002196Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002197GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002198 ArrayRef<Predicate> Predicates) {
2199 for (const Predicate &P : Predicates) {
2200 if (!P.Def)
2201 continue;
2202 declareSubtargetFeature(P.Def);
2203 M.addRequiredFeature(P.Def);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002204 }
2205
Daniel Sandersc270c502017-03-30 09:36:33 +00002206 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002207}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002208
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002209Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
2210 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2211 const TreePatternNode *Src, unsigned &TempOpIdx) const {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002212 Record *SrcGIEquivOrNull = nullptr;
Daniel Sanders85ffd362017-07-06 08:12:20 +00002213 const CodeGenInstruction *SrcGIOrNull = nullptr;
2214
Daniel Sandersffc7d582017-03-29 15:37:18 +00002215 // Start with the defined operands (i.e., the results of the root operator).
2216 if (Src->getExtTypes().size() > 1)
2217 return failedImport("Src pattern has multiple results");
2218
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002219 if (Src->isLeaf()) {
2220 Init *SrcInit = Src->getLeafValue();
Daniel Sanders3334cc02017-05-23 20:02:48 +00002221 if (isa<IntInit>(SrcInit)) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002222 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
2223 &Target.getInstruction(RK.getDef("G_CONSTANT")));
2224 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002225 return failedImport(
2226 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002227 } else {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002228 SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
2229 if (!SrcGIEquivOrNull)
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002230 return failedImport("Pattern operator lacks an equivalent Instruction" +
2231 explainOperator(Src->getOperator()));
Daniel Sanders39690bd2017-10-15 02:41:12 +00002232 SrcGIOrNull = &Target.getInstruction(SrcGIEquivOrNull->getValueAsDef("I"));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002233
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002234 // The operators look good: match the opcode
Daniel Sanders39690bd2017-10-15 02:41:12 +00002235 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002236 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002237
2238 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002239 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002240 // Results don't have a name unless they are the root node. The caller will
2241 // set the name if appropriate.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002242 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002243 if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
2244 return failedImport(toString(std::move(Error)) +
2245 " for result of Src pattern operator");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002246 }
2247
Daniel Sanders2c269f62017-08-24 09:11:20 +00002248 for (const auto &Predicate : Src->getPredicateFns()) {
2249 if (Predicate.isAlwaysTrue())
2250 continue;
2251
2252 if (Predicate.isImmediatePattern()) {
2253 InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
2254 continue;
2255 }
2256
Daniel Sandersa71f4542017-10-16 00:56:30 +00002257 // No check required. A G_LOAD is an unindexed load.
2258 if (Predicate.isLoad() && Predicate.isUnindexed())
2259 continue;
2260
2261 // No check required. G_LOAD by itself is a non-extending load.
2262 if (Predicate.isNonExtLoad())
2263 continue;
2264
2265 if (Predicate.isLoad() && Predicate.getMemoryVT() != nullptr) {
2266 Optional<LLTCodeGen> MemTyOrNone =
2267 MVTToLLT(getValueType(Predicate.getMemoryVT()));
2268
2269 if (!MemTyOrNone)
2270 return failedImport("MemVT could not be converted to LLT");
2271
2272 InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue());
2273 continue;
2274 }
2275
Daniel Sanders2c269f62017-08-24 09:11:20 +00002276 return failedImport("Src pattern child has predicate (" +
2277 explainPredicates(Src) + ")");
2278 }
Daniel Sanders39690bd2017-10-15 02:41:12 +00002279 if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
2280 InsnMatcher.addPredicate<NonAtomicMMOPredicateMatcher>();
Daniel Sanders2c269f62017-08-24 09:11:20 +00002281
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002282 if (Src->isLeaf()) {
2283 Init *SrcInit = Src->getLeafValue();
2284 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002285 OperandMatcher &OM =
2286 InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002287 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
2288 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002289 return failedImport(
2290 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002291 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002292 assert(SrcGIOrNull &&
2293 "Expected to have already found an equivalent Instruction");
Daniel Sanders11300ce2017-10-13 21:28:03 +00002294 if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
2295 SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
2296 // imm/fpimm still have operands but we don't need to do anything with it
Daniel Sanders05540042017-08-08 10:44:31 +00002297 // here since we don't support ImmLeaf predicates yet. However, we still
2298 // need to note the hidden operand to get GIM_CheckNumOperands correct.
2299 InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2300 return InsnMatcher;
2301 }
2302
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002303 // Match the used operands (i.e. the children of the operator).
2304 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002305 TreePatternNode *SrcChild = Src->getChild(i);
2306
Daniel Sandersa71f4542017-10-16 00:56:30 +00002307 // SelectionDAG allows pointers to be represented with iN since it doesn't
2308 // distinguish between pointers and integers but they are different types in GlobalISel.
2309 // Coerce integers to pointers to address space 0 if the context indicates a pointer.
2310 // TODO: Find a better way to do this, SDTCisPtrTy?
2311 bool OperandIsAPointer =
2312 SrcGIOrNull->TheDef->getName() == "G_LOAD" && i == 0;
2313
Daniel Sanders28887fe2017-09-19 12:56:36 +00002314 // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
2315 // following the defs is an intrinsic ID.
2316 if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
2317 SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
2318 i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002319 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002320 OperandMatcher &OM =
2321 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002322 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00002323 continue;
2324 }
2325
2326 return failedImport("Expected IntInit containing instrinsic ID)");
2327 }
2328
Daniel Sandersa71f4542017-10-16 00:56:30 +00002329 if (auto Error =
2330 importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
2331 OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002332 return std::move(Error);
2333 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002334 }
2335
2336 return InsnMatcher;
2337}
2338
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002339Error GlobalISelEmitter::importComplexPatternOperandMatcher(
2340 OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
2341 const auto &ComplexPattern = ComplexPatternEquivs.find(R);
2342 if (ComplexPattern == ComplexPatternEquivs.end())
2343 return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
2344 ") not mapped to GlobalISel");
2345
2346 OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
2347 TempOpIdx++;
2348 return Error::success();
2349}
2350
2351Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
2352 InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002353 const TreePatternNode *SrcChild,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002354 bool OperandIsAPointer,
Daniel Sandersc270c502017-03-30 09:36:33 +00002355 unsigned OpIdx,
2356 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002357 OperandMatcher &OM =
2358 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002359 if (OM.isSameAsAnotherOperand())
2360 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002361
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002362 ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002363 if (ChildTypes.size() != 1)
2364 return failedImport("Src pattern child has multiple results");
2365
2366 // Check MBB's before the type check since they are not a known type.
2367 if (!SrcChild->isLeaf()) {
2368 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
2369 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
2370 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
2371 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00002372 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002373 }
2374 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002375 }
2376
Daniel Sandersa71f4542017-10-16 00:56:30 +00002377 if (auto Error =
2378 OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
2379 return failedImport(toString(std::move(Error)) + " for Src operand (" +
2380 to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002381
Daniel Sandersbee57392017-04-04 13:25:23 +00002382 // Check for nested instructions.
2383 if (!SrcChild->isLeaf()) {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002384 if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
2385 // When a ComplexPattern is used as an operator, it should do the same
2386 // thing as when used as a leaf. However, the children of the operator
2387 // name the sub-operands that make up the complex operand and we must
2388 // prepare to reference them in the renderer too.
2389 unsigned RendererID = TempOpIdx;
2390 if (auto Error = importComplexPatternOperandMatcher(
2391 OM, SrcChild->getOperator(), TempOpIdx))
2392 return Error;
2393
2394 for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
2395 auto *SubOperand = SrcChild->getChild(i);
2396 if (!SubOperand->getName().empty())
2397 Rule.defineComplexSubOperand(SubOperand->getName(),
2398 SrcChild->getOperator(), RendererID, i);
2399 }
2400
2401 return Error::success();
2402 }
2403
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002404 auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
2405 InsnMatcher.getRuleMatcher(), SrcChild->getName());
2406 if (!MaybeInsnOperand.hasValue()) {
2407 // This isn't strictly true. If the user were to provide exactly the same
2408 // matchers as the original operand then we could allow it. However, it's
2409 // simpler to not permit the redundant specification.
2410 return failedImport("Nested instruction cannot be the same as another operand");
2411 }
2412
Daniel Sandersbee57392017-04-04 13:25:23 +00002413 // Map the node to a gMIR instruction.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002414 InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
Daniel Sanders57938df2017-07-11 10:40:18 +00002415 auto InsnMatcherOrError = createAndImportSelDAGMatcher(
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002416 Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00002417 if (auto Error = InsnMatcherOrError.takeError())
2418 return Error;
2419
2420 return Error::success();
2421 }
2422
Daniel Sandersffc7d582017-03-29 15:37:18 +00002423 // Check for constant immediates.
2424 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002425 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00002426 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002427 }
2428
2429 // Check for def's like register classes or ComplexPattern's.
2430 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
2431 auto *ChildRec = ChildDefInit->getDef();
2432
2433 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002434 if (ChildRec->isSubClassOf("RegisterClass") ||
2435 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002436 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002437 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00002438 return Error::success();
2439 }
2440
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002441 // Check for ValueType.
2442 if (ChildRec->isSubClassOf("ValueType")) {
2443 // We already added a type check as standard practice so this doesn't need
2444 // to do anything.
2445 return Error::success();
2446 }
2447
Daniel Sandersffc7d582017-03-29 15:37:18 +00002448 // Check for ComplexPattern's.
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002449 if (ChildRec->isSubClassOf("ComplexPattern"))
2450 return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002451
Daniel Sandersd0656a32017-04-13 09:45:37 +00002452 if (ChildRec->isSubClassOf("ImmLeaf")) {
2453 return failedImport(
2454 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
2455 }
2456
Daniel Sandersffc7d582017-03-29 15:37:18 +00002457 return failedImport(
2458 "Src pattern child def is an unsupported tablegen class");
2459 }
2460
2461 return failedImport("Src pattern child is an unsupported kind");
2462}
2463
Daniel Sandersc270c502017-03-30 09:36:33 +00002464Error GlobalISelEmitter::importExplicitUseRenderer(
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002465 RuleMatcher &Rule, BuildMIAction &DstMIBuilder, TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002466 const InstructionMatcher &InsnMatcher) const {
Daniel Sanders2c269f62017-08-24 09:11:20 +00002467 if (DstChild->getTransformFn() != nullptr) {
2468 return failedImport("Dst pattern child has transform fn " +
2469 DstChild->getTransformFn()->getName());
2470 }
2471
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002472 const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
2473 if (SubOperand.hasValue()) {
2474 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
2475 0, *std::get<0>(*SubOperand), DstChild->getName(),
2476 std::get<1>(*SubOperand), std::get<2>(*SubOperand));
2477 return Error::success();
2478 }
2479
Daniel Sandersffc7d582017-03-29 15:37:18 +00002480 if (!DstChild->isLeaf()) {
Daniel Sanders05540042017-08-08 10:44:31 +00002481 // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
2482 // inline, but in MI it's just another operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002483 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
2484 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
2485 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002486 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
Daniel Sandersffc7d582017-03-29 15:37:18 +00002487 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00002488 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002489 }
2490 }
Daniel Sanders05540042017-08-08 10:44:31 +00002491
2492 // Similarly, imm is an operator in TreePatternNode's view but must be
2493 // rendered as operands.
2494 // FIXME: The target should be able to choose sign-extended when appropriate
2495 // (e.g. on Mips).
2496 if (DstChild->getOperator()->getName() == "imm") {
2497 DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(0,
2498 DstChild->getName());
2499 return Error::success();
Daniel Sanders11300ce2017-10-13 21:28:03 +00002500 } else if (DstChild->getOperator()->getName() == "fpimm") {
2501 DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
2502 0, DstChild->getName());
2503 return Error::success();
Daniel Sanders05540042017-08-08 10:44:31 +00002504 }
2505
Daniel Sanders2c269f62017-08-24 09:11:20 +00002506 return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002507 }
2508
2509 // Otherwise, we're looking for a bog-standard RegisterClass operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002510 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
2511 auto *ChildRec = ChildDefInit->getDef();
2512
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002513 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002514 if (ChildTypes.size() != 1)
2515 return failedImport("Dst pattern child has multiple results");
2516
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002517 Optional<LLTCodeGen> OpTyOrNone = None;
2518 if (ChildTypes.front().isMachineValueType())
2519 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002520 if (!OpTyOrNone)
2521 return failedImport("Dst operand has an unsupported type");
2522
2523 if (ChildRec->isSubClassOf("Register")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002524 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, ChildRec);
Daniel Sandersc270c502017-03-30 09:36:33 +00002525 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002526 }
2527
Daniel Sanders658541f2017-04-22 15:53:21 +00002528 if (ChildRec->isSubClassOf("RegisterClass") ||
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002529 ChildRec->isSubClassOf("RegisterOperand") ||
2530 ChildRec->isSubClassOf("ValueType")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002531 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
2532 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00002533 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002534 }
2535
2536 if (ChildRec->isSubClassOf("ComplexPattern")) {
2537 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
2538 if (ComplexPattern == ComplexPatternEquivs.end())
2539 return failedImport(
2540 "SelectionDAG ComplexPattern not mapped to GlobalISel");
2541
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002542 const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002543 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002544 0, *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00002545 OM.getAllocatedTemporariesBaseID());
Daniel Sandersc270c502017-03-30 09:36:33 +00002546 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002547 }
2548
Daniel Sandersd0656a32017-04-13 09:45:37 +00002549 if (ChildRec->isSubClassOf("SDNodeXForm"))
2550 return failedImport("Dst pattern child def is an unsupported tablegen "
2551 "class (SDNodeXForm)");
2552
Daniel Sandersffc7d582017-03-29 15:37:18 +00002553 return failedImport(
2554 "Dst pattern child def is an unsupported tablegen class");
2555 }
2556
2557 return failedImport("Dst pattern child is an unsupported kind");
2558}
2559
Daniel Sandersc270c502017-03-30 09:36:33 +00002560Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersffc7d582017-03-29 15:37:18 +00002561 RuleMatcher &M, const TreePatternNode *Dst,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002562 const InstructionMatcher &InsnMatcher) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002563 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00002564 if (!DstOp->isSubClassOf("Instruction")) {
2565 if (DstOp->isSubClassOf("ValueType"))
2566 return failedImport(
2567 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002568 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00002569 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002570 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002571
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002572 unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs;
2573 unsigned ExpectedDstINumUses = Dst->getNumChildren();
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002574 bool IsExtractSubReg = false;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002575
2576 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002577 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002578 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") {
2579 DstI = &Target.getInstruction(RK.getDef("COPY"));
2580 DstINumUses--; // Ignore the class constraint.
2581 ExpectedDstINumUses--;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002582 } else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") {
2583 DstI = &Target.getInstruction(RK.getDef("COPY"));
2584 IsExtractSubReg = true;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002585 }
2586
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002587 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002588
2589 // Render the explicit defs.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002590 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
2591 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002592 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002593 }
2594
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002595 // EXTRACT_SUBREG needs to use a subregister COPY.
2596 if (IsExtractSubReg) {
2597 if (!Dst->getChild(0)->isLeaf())
2598 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2599
Daniel Sanders32291982017-06-28 13:50:04 +00002600 if (DefInit *SubRegInit =
2601 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002602 CodeGenRegisterClass *RC = CGRegs.getRegClass(
2603 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));
2604 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
2605
2606 const auto &SrcRCDstRCPair =
2607 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2608 if (SrcRCDstRCPair.hasValue()) {
2609 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
2610 if (SrcRCDstRCPair->first != RC)
2611 return failedImport("EXTRACT_SUBREG requires an additional COPY");
2612 }
2613
2614 DstMIBuilder.addRenderer<CopySubRegRenderer>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002615 0, InsnMatcher, Dst->getChild(0)->getName(), SubIdx);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002616 return DstMIBuilder;
2617 }
2618
2619 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
2620 }
2621
Daniel Sandersffc7d582017-03-29 15:37:18 +00002622 // Render the explicit uses.
Daniel Sanders0ed28822017-04-12 08:23:08 +00002623 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00002624 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002625 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002626 const CGIOperandList::OperandInfo &DstIOperand =
2627 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00002628
Diana Picus382602f2017-05-17 08:57:28 +00002629 // If the operand has default values, introduce them now.
2630 // FIXME: Until we have a decent test case that dictates we should do
2631 // otherwise, we're going to assume that operands with default values cannot
2632 // be specified in the patterns. Therefore, adding them will not cause us to
2633 // end up with too many rendered operands.
2634 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00002635 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00002636 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
2637 return std::move(Error);
2638 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002639 continue;
2640 }
2641
2642 if (auto Error = importExplicitUseRenderer(
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002643 M, DstMIBuilder, Dst->getChild(Child), InsnMatcher))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002644 return std::move(Error);
Daniel Sanders0ed28822017-04-12 08:23:08 +00002645 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002646 }
2647
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002648 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00002649 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00002650 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002651 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00002652 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00002653 " default ones");
2654
Daniel Sandersffc7d582017-03-29 15:37:18 +00002655 return DstMIBuilder;
2656}
2657
Diana Picus382602f2017-05-17 08:57:28 +00002658Error GlobalISelEmitter::importDefaultOperandRenderers(
2659 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00002660 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00002661 // Look through ValueType operators.
2662 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
2663 if (const DefInit *DefaultDagOperator =
2664 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
2665 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
2666 DefaultOp = DefaultDagOp->getArg(0);
2667 }
2668 }
2669
2670 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002671 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00002672 continue;
2673 }
2674
2675 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002676 DstMIBuilder.addRenderer<ImmRenderer>(0, DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00002677 continue;
2678 }
2679
2680 return failedImport("Could not add default op");
2681 }
2682
2683 return Error::success();
2684}
2685
Daniel Sandersc270c502017-03-30 09:36:33 +00002686Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00002687 BuildMIAction &DstMIBuilder,
2688 const std::vector<Record *> &ImplicitDefs) const {
2689 if (!ImplicitDefs.empty())
2690 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00002691 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002692}
2693
2694Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002695 // Keep track of the matchers and actions to emit.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002696 RuleMatcher M(P.getSrcRecord()->getLoc());
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00002697 M.addAction<DebugCommentAction>(P);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002698
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002699 if (auto Error = importRulePredicates(M, P.getPredicates()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002700 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002701
2702 // Next, analyze the pattern operators.
2703 TreePatternNode *Src = P.getSrcPattern();
2704 TreePatternNode *Dst = P.getDstPattern();
2705
2706 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00002707 if (auto Err = isTrivialOperatorNode(Dst))
2708 return failedImport("Dst pattern root isn't a trivial operator (" +
2709 toString(std::move(Err)) + ")");
2710 if (auto Err = isTrivialOperatorNode(Src))
2711 return failedImport("Src pattern root isn't a trivial operator (" +
2712 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002713
Daniel Sandersedd07842017-08-17 09:26:14 +00002714 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
2715 unsigned TempOpIdx = 0;
2716 auto InsnMatcherOrError =
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002717 createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
Daniel Sandersedd07842017-08-17 09:26:14 +00002718 if (auto Error = InsnMatcherOrError.takeError())
2719 return std::move(Error);
2720 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
2721
2722 if (Dst->isLeaf()) {
2723 Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
2724
2725 const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
2726 if (RCDef) {
2727 // We need to replace the def and all its uses with the specified
2728 // operand. However, we must also insert COPY's wherever needed.
2729 // For now, emit a copy and let the register allocator clean up.
2730 auto &DstI = Target.getInstruction(RK.getDef("COPY"));
2731 const auto &DstIOperand = DstI.Operands[0];
2732
2733 OperandMatcher &OM0 = InsnMatcher.getOperand(0);
2734 OM0.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002735 M.defineOperand(OM0.getSymbolicName(), OM0);
Daniel Sandersedd07842017-08-17 09:26:14 +00002736 OM0.addPredicate<RegisterBankOperandMatcher>(RC);
2737
2738 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI, InsnMatcher);
2739 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name);
2740 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, Dst->getName());
2741 M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
2742
2743 // We're done with this pattern! It's eligible for GISel emission; return
2744 // it.
2745 ++NumPatternImported;
2746 return std::move(M);
2747 }
2748
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002749 return failedImport("Dst pattern root isn't a known leaf");
Daniel Sandersedd07842017-08-17 09:26:14 +00002750 }
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002751
Daniel Sandersbee57392017-04-04 13:25:23 +00002752 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002753 Record *DstOp = Dst->getOperator();
2754 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002755 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002756
2757 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002758 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00002759 return failedImport("Src pattern results and dst MI defs are different (" +
2760 to_string(Src->getExtTypes().size()) + " def(s) vs " +
2761 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002762
Daniel Sandersffc7d582017-03-29 15:37:18 +00002763 // The root of the match also has constraints on the register bank so that it
2764 // matches the result instruction.
2765 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002766 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
2767 (void)VTy;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002768
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002769 const auto &DstIOperand = DstI.Operands[OpIdx];
2770 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002771 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
2772 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
2773
2774 if (DstIOpRec == nullptr)
2775 return failedImport(
2776 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002777 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
2778 if (!Dst->getChild(0)->isLeaf())
2779 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
2780
Daniel Sanders32291982017-06-28 13:50:04 +00002781 // We can assume that a subregister is in the same bank as it's super
2782 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002783 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
2784
2785 if (DstIOpRec == nullptr)
2786 return failedImport(
2787 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002788 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00002789 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002790 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00002791 return failedImport("Dst MI def isn't a register class" +
2792 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002793
Daniel Sandersffc7d582017-03-29 15:37:18 +00002794 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
2795 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002796 M.defineOperand(OM.getSymbolicName(), OM);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002797 OM.addPredicate<RegisterBankOperandMatcher>(
2798 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002799 ++OpIdx;
2800 }
2801
Daniel Sandersc270c502017-03-30 09:36:33 +00002802 auto DstMIBuilderOrError =
2803 createAndImportInstructionRenderer(M, Dst, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002804 if (auto Error = DstMIBuilderOrError.takeError())
2805 return std::move(Error);
2806 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002807
Daniel Sandersffc7d582017-03-29 15:37:18 +00002808 // Render the implicit defs.
2809 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00002810 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002811 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002812
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002813 // Constrain the registers to classes. This is normally derived from the
2814 // emitted instruction but a few instructions require special handling.
2815 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
2816 // COPY_TO_REGCLASS does not provide operand constraints itself but the
2817 // result is constrained to the class given by the second child.
2818 Record *DstIOpRec =
2819 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
2820
2821 if (DstIOpRec == nullptr)
2822 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
2823
2824 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002825 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002826
2827 // We're done with this pattern! It's eligible for GISel emission; return
2828 // it.
2829 ++NumPatternImported;
2830 return std::move(M);
2831 }
2832
2833 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
2834 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
2835 // instructions, the result register class is controlled by the
2836 // subregisters of the operand. As a result, we must constrain the result
2837 // class rather than check that it's already the right one.
2838 if (!Dst->getChild(0)->isLeaf())
2839 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2840
Daniel Sanders320390b2017-06-28 15:16:03 +00002841 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
2842 if (!SubRegInit)
2843 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002844
Daniel Sanders320390b2017-06-28 15:16:03 +00002845 // Constrain the result to the same register bank as the operand.
2846 Record *DstIOpRec =
2847 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002848
Daniel Sanders320390b2017-06-28 15:16:03 +00002849 if (DstIOpRec == nullptr)
2850 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002851
Daniel Sanders320390b2017-06-28 15:16:03 +00002852 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002853 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002854
Daniel Sanders320390b2017-06-28 15:16:03 +00002855 // It would be nice to leave this constraint implicit but we're required
2856 // to pick a register class so constrain the result to a register class
2857 // that can hold the correct MVT.
2858 //
2859 // FIXME: This may introduce an extra copy if the chosen class doesn't
2860 // actually contain the subregisters.
2861 assert(Src->getExtTypes().size() == 1 &&
2862 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002863
Daniel Sanders320390b2017-06-28 15:16:03 +00002864 const auto &SrcRCDstRCPair =
2865 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2866 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002867 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
2868 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
2869
2870 // We're done with this pattern! It's eligible for GISel emission; return
2871 // it.
2872 ++NumPatternImported;
2873 return std::move(M);
2874 }
2875
2876 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002877
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002878 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002879 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002880 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002881}
2882
Daniel Sanders649c5852017-10-13 20:42:18 +00002883// Emit imm predicate table and an enum to reference them with.
2884// The 'Predicate_' part of the name is redundant but eliminating it is more
2885// trouble than it's worth.
2886void GlobalISelEmitter::emitImmPredicates(
Daniel Sanders11300ce2017-10-13 21:28:03 +00002887 raw_ostream &OS, StringRef TypeIdentifier, StringRef Type,
2888 std::function<bool(const Record *R)> Filter) {
Daniel Sanders649c5852017-10-13 20:42:18 +00002889 std::vector<const Record *> MatchedRecords;
2890 const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
2891 std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
2892 [&](Record *Record) {
2893 return !Record->getValueAsString("ImmediateCode").empty() &&
2894 Filter(Record);
2895 });
2896
Daniel Sanders11300ce2017-10-13 21:28:03 +00002897 if (!MatchedRecords.empty()) {
2898 OS << "// PatFrag predicates.\n"
2899 << "enum {\n";
Daniel Sanders2fed4ff2017-10-13 21:51:20 +00002900 std::string EnumeratorSeparator =
Daniel Sanders11300ce2017-10-13 21:28:03 +00002901 (" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str();
2902 for (const auto *Record : MatchedRecords) {
2903 OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName()
2904 << EnumeratorSeparator;
2905 EnumeratorSeparator = ",\n";
2906 }
2907 OS << "};\n";
Daniel Sanders649c5852017-10-13 20:42:18 +00002908 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00002909
Daniel Sanders649c5852017-10-13 20:42:18 +00002910 for (const auto *Record : MatchedRecords)
Daniel Sanders11300ce2017-10-13 21:28:03 +00002911 OS << "static bool Predicate_" << Record->getName() << "(" << Type
2912 << " Imm) {" << Record->getValueAsString("ImmediateCode") << "}\n";
2913
2914 OS << "static InstructionSelector::" << TypeIdentifier
2915 << "ImmediatePredicateFn " << TypeIdentifier << "ImmPredicateFns[] = {\n"
Daniel Sanders649c5852017-10-13 20:42:18 +00002916 << " nullptr,\n";
2917 for (const auto *Record : MatchedRecords)
2918 OS << " Predicate_" << Record->getName() << ",\n";
2919 OS << "};\n";
2920}
2921
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002922void GlobalISelEmitter::run(raw_ostream &OS) {
2923 // Track the GINodeEquiv definitions.
2924 gatherNodeEquivs();
2925
2926 emitSourceFileHeader(("Global Instruction Selector for the " +
2927 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002928 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002929 // Look through the SelectionDAG patterns we found, possibly emitting some.
2930 for (const PatternToMatch &Pat : CGP.ptms()) {
2931 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002932 auto MatcherOrErr = runOnPattern(Pat);
2933
2934 // The pattern analysis can fail, indicating an unsupported pattern.
2935 // Report that if we've been asked to do so.
2936 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002937 if (WarnOnSkippedPatterns) {
2938 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002939 "Skipped pattern: " + toString(std::move(Err)));
2940 } else {
2941 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002942 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002943 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002944 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002945 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002946
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002947 Rules.push_back(std::move(MatcherOrErr.get()));
2948 }
2949
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00002950 std::stable_sort(Rules.begin(), Rules.end(),
2951 [&](const RuleMatcher &A, const RuleMatcher &B) {
2952 if (A.isHigherPriorityThan(B)) {
2953 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
2954 "and less important at "
2955 "the same time");
2956 return true;
2957 }
2958 return false;
2959 });
Daniel Sanders759ff412017-02-24 13:58:11 +00002960
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002961 std::vector<Record *> ComplexPredicates =
2962 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
2963 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
2964 [](const Record *A, const Record *B) {
2965 if (A->getName() < B->getName())
2966 return true;
2967 return false;
2968 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002969 unsigned MaxTemporaries = 0;
2970 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00002971 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002972
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002973 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
2974 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
2975 << ";\n"
2976 << "using PredicateBitset = "
2977 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
2978 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
2979
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002980 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
2981 << " mutable MatcherState State;\n"
2982 << " typedef "
2983 "ComplexRendererFn("
2984 << Target.getName()
2985 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00002986 << " const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002987 "MatcherInfo;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00002988 << " static " << Target.getName()
2989 << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002990 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002991
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002992 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
2993 << ", State(" << MaxTemporaries << "),\n"
Daniel Sanders11300ce2017-10-13 21:28:03 +00002994 << "MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, "
Daniel Sandersea8711b2017-10-16 03:36:29 +00002995 "APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002996 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002997
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002998 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
2999 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
3000 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003001
3002 // Separate subtarget features by how often they must be recomputed.
3003 SubtargetFeatureInfoMap ModuleFeatures;
3004 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3005 std::inserter(ModuleFeatures, ModuleFeatures.end()),
3006 [](const SubtargetFeatureInfoMap::value_type &X) {
3007 return !X.second.mustRecomputePerFunction();
3008 });
3009 SubtargetFeatureInfoMap FunctionFeatures;
3010 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3011 std::inserter(FunctionFeatures, FunctionFeatures.end()),
3012 [](const SubtargetFeatureInfoMap::value_type &X) {
3013 return X.second.mustRecomputePerFunction();
3014 });
3015
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003016 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003017 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
3018 ModuleFeatures, OS);
3019 SubtargetFeatureInfo::emitComputeAvailableFeatures(
3020 Target.getName(), "InstructionSelector",
3021 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
3022 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003023
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003024 // Emit a table containing the LLT objects needed by the matcher and an enum
3025 // for the matcher to reference them with.
Daniel Sanders032e7f22017-08-17 13:18:35 +00003026 std::vector<LLTCodeGen> TypeObjects;
3027 for (const auto &Ty : LLTOperandMatcher::KnownTypes)
3028 TypeObjects.push_back(Ty);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003029 std::sort(TypeObjects.begin(), TypeObjects.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003030 OS << "// LLT Objects.\n"
3031 << "enum {\n";
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003032 for (const auto &TypeObject : TypeObjects) {
3033 OS << " ";
3034 TypeObject.emitCxxEnumValue(OS);
3035 OS << ",\n";
3036 }
3037 OS << "};\n"
3038 << "const static LLT TypeObjects[] = {\n";
3039 for (const auto &TypeObject : TypeObjects) {
3040 OS << " ";
3041 TypeObject.emitCxxConstructorCall(OS);
3042 OS << ",\n";
3043 }
3044 OS << "};\n\n";
3045
3046 // Emit a table containing the PredicateBitsets objects needed by the matcher
3047 // and an enum for the matcher to reference them with.
3048 std::vector<std::vector<Record *>> FeatureBitsets;
3049 for (auto &Rule : Rules)
3050 FeatureBitsets.push_back(Rule.getRequiredFeatures());
3051 std::sort(
3052 FeatureBitsets.begin(), FeatureBitsets.end(),
3053 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
3054 if (A.size() < B.size())
3055 return true;
3056 if (A.size() > B.size())
3057 return false;
3058 for (const auto &Pair : zip(A, B)) {
3059 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
3060 return true;
3061 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
3062 return false;
3063 }
3064 return false;
3065 });
3066 FeatureBitsets.erase(
3067 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
3068 FeatureBitsets.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003069 OS << "// Feature bitsets.\n"
3070 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003071 << " GIFBS_Invalid,\n";
3072 for (const auto &FeatureBitset : FeatureBitsets) {
3073 if (FeatureBitset.empty())
3074 continue;
3075 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
3076 }
3077 OS << "};\n"
3078 << "const static PredicateBitset FeatureBitsets[] {\n"
3079 << " {}, // GIFBS_Invalid\n";
3080 for (const auto &FeatureBitset : FeatureBitsets) {
3081 if (FeatureBitset.empty())
3082 continue;
3083 OS << " {";
3084 for (const auto &Feature : FeatureBitset) {
3085 const auto &I = SubtargetFeatures.find(Feature);
3086 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
3087 OS << I->second.getEnumBitName() << ", ";
3088 }
3089 OS << "},\n";
3090 }
3091 OS << "};\n\n";
3092
3093 // Emit complex predicate table and an enum to reference them with.
Daniel Sanders49980702017-08-23 10:09:25 +00003094 OS << "// ComplexPattern predicates.\n"
3095 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003096 << " GICP_Invalid,\n";
3097 for (const auto &Record : ComplexPredicates)
3098 OS << " GICP_" << Record->getName() << ",\n";
3099 OS << "};\n"
3100 << "// See constructor for table contents\n\n";
3101
Daniel Sanders11300ce2017-10-13 21:28:03 +00003102 emitImmPredicates(OS, "I64", "int64_t", [](const Record *R) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003103 bool Unset;
3104 return !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
3105 !R->getValueAsBit("IsAPInt");
3106 });
Daniel Sanders11300ce2017-10-13 21:28:03 +00003107 emitImmPredicates(OS, "APFloat", "const APFloat &", [](const Record *R) {
3108 bool Unset;
3109 return R->getValueAsBitOrUnset("IsAPFloat", Unset);
3110 });
3111 emitImmPredicates(OS, "APInt", "const APInt &", [](const Record *R) {
3112 return R->getValueAsBit("IsAPInt");
3113 });
Daniel Sandersea8711b2017-10-16 03:36:29 +00003114 OS << "\n";
3115
3116 OS << Target.getName() << "InstructionSelector::ComplexMatcherMemFn\n"
3117 << Target.getName() << "InstructionSelector::ComplexPredicateFns[] = {\n"
3118 << " nullptr, // GICP_Invalid\n";
3119 for (const auto &Record : ComplexPredicates)
3120 OS << " &" << Target.getName()
3121 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
3122 << ", // " << Record->getName() << "\n";
3123 OS << "};\n\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00003124
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003125 OS << "bool " << Target.getName()
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003126 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
3127 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003128 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00003129 << " // FIXME: This should be computed on a per-function basis rather "
3130 "than per-insn.\n"
3131 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
3132 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00003133 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
3134 << " NewMIVector OutMIs;\n"
3135 << " State.MIs.clear();\n"
3136 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003137
Daniel Sanders8e82af22017-07-27 11:03:45 +00003138 MatchTable Table(0);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00003139 for (auto &Rule : Rules) {
Daniel Sanders8e82af22017-07-27 11:03:45 +00003140 Rule.emit(Table);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003141 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003142 }
Daniel Sanders8e82af22017-07-27 11:03:45 +00003143 Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
3144 Table.emitDeclaration(OS);
3145 OS << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, ";
3146 Table.emitUse(OS);
3147 OS << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n"
3148 << " return true;\n"
3149 << " }\n\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003150
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003151 OS << " return false;\n"
3152 << "}\n"
3153 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003154
3155 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
3156 << "PredicateBitset AvailableModuleFeatures;\n"
3157 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
3158 << "PredicateBitset getAvailableFeatures() const {\n"
3159 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
3160 << "}\n"
3161 << "PredicateBitset\n"
3162 << "computeAvailableModuleFeatures(const " << Target.getName()
3163 << "Subtarget *Subtarget) const;\n"
3164 << "PredicateBitset\n"
3165 << "computeAvailableFunctionFeatures(const " << Target.getName()
3166 << "Subtarget *Subtarget,\n"
3167 << " const MachineFunction *MF) const;\n"
3168 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
3169
3170 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
3171 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
3172 << "AvailableFunctionFeatures()\n"
3173 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003174}
3175
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003176void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
3177 if (SubtargetFeatures.count(Predicate) == 0)
3178 SubtargetFeatures.emplace(
3179 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
3180}
3181
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003182} // end anonymous namespace
3183
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003184//===----------------------------------------------------------------------===//
3185
3186namespace llvm {
3187void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
3188 GlobalISelEmitter(RK).run(OS);
3189}
3190} // End llvm namespace