blob: 8b5defd9d326e41d191da8c467a017e939b2e8fb [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"
Daniel Sandersf76f3152017-11-16 00:46:35 +000039#include "llvm/Support/CodeGenCoverage.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000040#include "llvm/Support/CommandLine.h"
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +000041#include "llvm/Support/Error.h"
Daniel Sanders52b4ce72017-03-07 23:20:35 +000042#include "llvm/Support/LowLevelTypeImpl.h"
Pavel Labath52a82e22017-02-21 09:19:41 +000043#include "llvm/Support/ScopedPrinter.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000044#include "llvm/TableGen/Error.h"
45#include "llvm/TableGen/Record.h"
46#include "llvm/TableGen/TableGenBackend.h"
Daniel Sanders8a4bae92017-03-14 21:32:08 +000047#include <numeric>
Daniel Sandersf76f3152017-11-16 00:46:35 +000048#include <string>
Ahmed Bougacha36f70352016-12-21 23:26:20 +000049using namespace llvm;
50
51#define DEBUG_TYPE "gisel-emitter"
52
53STATISTIC(NumPatternTotal, "Total number of patterns");
Daniel Sandersb41ce2b2017-02-20 14:31:27 +000054STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
55STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
Daniel Sandersf76f3152017-11-16 00:46:35 +000056STATISTIC(NumPatternsTested, "Number of patterns executed according to coverage information");
Ahmed Bougacha36f70352016-12-21 23:26:20 +000057STATISTIC(NumPatternEmitted, "Number of patterns emitted");
58
Daniel Sanders0848b232017-03-27 13:15:13 +000059cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
60
Ahmed Bougacha36f70352016-12-21 23:26:20 +000061static cl::opt<bool> WarnOnSkippedPatterns(
62 "warn-on-skipped-patterns",
63 cl::desc("Explain why a pattern was skipped for inclusion "
64 "in the GlobalISel selector"),
Daniel Sanders0848b232017-03-27 13:15:13 +000065 cl::init(false), cl::cat(GlobalISelEmitterCat));
Ahmed Bougacha36f70352016-12-21 23:26:20 +000066
Daniel Sandersf76f3152017-11-16 00:46:35 +000067static cl::opt<bool> GenerateCoverage(
68 "instrument-gisel-coverage",
69 cl::desc("Generate coverage instrumentation for GlobalISel"),
70 cl::init(false), cl::cat(GlobalISelEmitterCat));
71
72static cl::opt<std::string> UseCoverageFile(
73 "gisel-coverage-file", cl::init(""),
74 cl::desc("Specify file to retrieve coverage information from"),
75 cl::cat(GlobalISelEmitterCat));
76
Daniel Sandersbdfebb82017-03-15 20:18:38 +000077namespace {
Ahmed Bougacha36f70352016-12-21 23:26:20 +000078//===- Helper functions ---------------------------------------------------===//
79
Daniel Sanders11300ce2017-10-13 21:28:03 +000080
81/// Get the name of the enum value used to number the predicate function.
82std::string getEnumNameForPredicate(const TreePredicateFn &Predicate) {
Simon Pilgrim6ecae9f2017-10-14 21:27:53 +000083 return "GIPFP_" + Predicate.getImmTypeIdentifier().str() + "_" +
Daniel Sanders11300ce2017-10-13 21:28:03 +000084 Predicate.getFnName();
85}
86
87/// Get the opcode used to check this predicate.
88std::string getMatchOpcodeForPredicate(const TreePredicateFn &Predicate) {
Simon Pilgrim6ecae9f2017-10-14 21:27:53 +000089 return "GIM_Check" + Predicate.getImmTypeIdentifier().str() + "ImmPredicate";
Daniel Sanders11300ce2017-10-13 21:28:03 +000090}
91
Daniel Sanders52b4ce72017-03-07 23:20:35 +000092/// This class stands in for LLT wherever we want to tablegen-erate an
93/// equivalent at compiler run-time.
94class LLTCodeGen {
95private:
96 LLT Ty;
97
98public:
99 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
100
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000101 std::string getCxxEnumValue() const {
102 std::string Str;
103 raw_string_ostream OS(Str);
104
105 emitCxxEnumValue(OS);
106 return OS.str();
107 }
108
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000109 void emitCxxEnumValue(raw_ostream &OS) const {
110 if (Ty.isScalar()) {
111 OS << "GILLT_s" << Ty.getSizeInBits();
112 return;
113 }
114 if (Ty.isVector()) {
115 OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
116 return;
117 }
Daniel Sandersa71f4542017-10-16 00:56:30 +0000118 if (Ty.isPointer()) {
119 OS << "GILLT_p" << Ty.getAddressSpace();
120 if (Ty.getSizeInBits() > 0)
121 OS << "s" << Ty.getSizeInBits();
122 return;
123 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000124 llvm_unreachable("Unhandled LLT");
125 }
126
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000127 void emitCxxConstructorCall(raw_ostream &OS) const {
128 if (Ty.isScalar()) {
129 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
130 return;
131 }
132 if (Ty.isVector()) {
Daniel Sanders32291982017-06-28 13:50:04 +0000133 OS << "LLT::vector(" << Ty.getNumElements() << ", "
134 << Ty.getScalarSizeInBits() << ")";
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000135 return;
136 }
Daniel Sandersa71f4542017-10-16 00:56:30 +0000137 if (Ty.isPointer() && Ty.getSizeInBits() > 0) {
138 OS << "LLT::pointer(" << Ty.getAddressSpace() << ", "
139 << Ty.getSizeInBits() << ")";
140 return;
141 }
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000142 llvm_unreachable("Unhandled LLT");
143 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000144
145 const LLT &get() const { return Ty; }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000146
147 /// This ordering is used for std::unique() and std::sort(). There's no
Daniel Sanders032e7f22017-08-17 13:18:35 +0000148 /// particular logic behind the order but either A < B or B < A must be
149 /// true if A != B.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000150 bool operator<(const LLTCodeGen &Other) const {
Daniel Sanders032e7f22017-08-17 13:18:35 +0000151 if (Ty.isValid() != Other.Ty.isValid())
152 return Ty.isValid() < Other.Ty.isValid();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000153 if (!Ty.isValid())
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000154 return false;
Daniel Sanders032e7f22017-08-17 13:18:35 +0000155
156 if (Ty.isVector() != Other.Ty.isVector())
157 return Ty.isVector() < Other.Ty.isVector();
158 if (Ty.isScalar() != Other.Ty.isScalar())
159 return Ty.isScalar() < Other.Ty.isScalar();
160 if (Ty.isPointer() != Other.Ty.isPointer())
161 return Ty.isPointer() < Other.Ty.isPointer();
162
163 if (Ty.isPointer() && Ty.getAddressSpace() != Other.Ty.getAddressSpace())
164 return Ty.getAddressSpace() < Other.Ty.getAddressSpace();
165
166 if (Ty.isVector() && Ty.getNumElements() != Other.Ty.getNumElements())
167 return Ty.getNumElements() < Other.Ty.getNumElements();
168
169 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000170 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000171};
172
173class InstructionMatcher;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000174/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
175/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000176static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000177 MVT VT(SVT);
Daniel Sandersa71f4542017-10-16 00:56:30 +0000178
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000179 if (VT.isVector() && VT.getVectorNumElements() != 1)
Daniel Sanders32291982017-06-28 13:50:04 +0000180 return LLTCodeGen(
181 LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
Daniel Sandersa71f4542017-10-16 00:56:30 +0000182
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000183 if (VT.isInteger() || VT.isFloatingPoint())
184 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
185 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000186}
187
Daniel Sandersd0656a32017-04-13 09:45:37 +0000188static std::string explainPredicates(const TreePatternNode *N) {
189 std::string Explanation = "";
190 StringRef Separator = "";
191 for (const auto &P : N->getPredicateFns()) {
192 Explanation +=
193 (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
Daniel Sanders76664652017-11-28 22:07:05 +0000194 Separator = ", ";
195
Daniel Sandersd0656a32017-04-13 09:45:37 +0000196 if (P.isAlwaysTrue())
197 Explanation += " always-true";
198 if (P.isImmediatePattern())
199 Explanation += " immediate";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000200
201 if (P.isUnindexed())
202 Explanation += " unindexed";
203
204 if (P.isNonExtLoad())
205 Explanation += " non-extload";
206 if (P.isAnyExtLoad())
207 Explanation += " extload";
208 if (P.isSignExtLoad())
209 Explanation += " sextload";
210 if (P.isZeroExtLoad())
211 Explanation += " zextload";
212
213 if (P.isNonTruncStore())
214 Explanation += " non-truncstore";
215 if (P.isTruncStore())
216 Explanation += " truncstore";
217
218 if (Record *VT = P.getMemoryVT())
219 Explanation += (" MemVT=" + VT->getName()).str();
220 if (Record *VT = P.getScalarMemoryVT())
221 Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();
Daniel Sanders76664652017-11-28 22:07:05 +0000222
223 if (P.isAtomicOrderingMonotonic())
224 Explanation += " monotonic";
225 if (P.isAtomicOrderingAcquire())
226 Explanation += " acquire";
227 if (P.isAtomicOrderingRelease())
228 Explanation += " release";
229 if (P.isAtomicOrderingAcquireRelease())
230 Explanation += " acq_rel";
231 if (P.isAtomicOrderingSequentiallyConsistent())
232 Explanation += " seq_cst";
Daniel Sanders0c43b3a2017-11-30 21:05:59 +0000233 if (P.isAtomicOrderingAcquireOrStronger())
234 Explanation += " >=acquire";
235 if (P.isAtomicOrderingWeakerThanAcquire())
236 Explanation += " <acquire";
237 if (P.isAtomicOrderingReleaseOrStronger())
238 Explanation += " >=release";
239 if (P.isAtomicOrderingWeakerThanRelease())
240 Explanation += " <release";
Daniel Sandersd0656a32017-04-13 09:45:37 +0000241 }
242 return Explanation;
243}
244
Daniel Sandersd0656a32017-04-13 09:45:37 +0000245std::string explainOperator(Record *Operator) {
246 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000247 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000248
249 if (Operator->isSubClassOf("Intrinsic"))
250 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
251
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000252 if (Operator->isSubClassOf("ComplexPattern"))
253 return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
254 ")")
255 .str();
256
257 return (" (Operator " + Operator->getName() + " not understood)").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000258}
259
260/// Helper function to let the emitter report skip reason error messages.
261static Error failedImport(const Twine &Reason) {
262 return make_error<StringError>(Reason, inconvertibleErrorCode());
263}
264
265static Error isTrivialOperatorNode(const TreePatternNode *N) {
266 std::string Explanation = "";
267 std::string Separator = "";
Daniel Sanders2c269f62017-08-24 09:11:20 +0000268
269 bool HasUnsupportedPredicate = false;
270 for (const auto &Predicate : N->getPredicateFns()) {
271 if (Predicate.isAlwaysTrue())
272 continue;
273
274 if (Predicate.isImmediatePattern())
275 continue;
276
Daniel Sandersa71f4542017-10-16 00:56:30 +0000277 if (Predicate.isNonExtLoad())
278 continue;
Daniel Sandersd66e0902017-10-23 18:19:24 +0000279
Daniel Sanders76664652017-11-28 22:07:05 +0000280 if (Predicate.isNonTruncStore())
Daniel Sandersd66e0902017-10-23 18:19:24 +0000281 continue;
282
Daniel Sanders76664652017-11-28 22:07:05 +0000283 if (Predicate.isLoad() || Predicate.isStore()) {
284 if (Predicate.isUnindexed())
285 continue;
286 }
287
288 if (Predicate.isAtomic() && Predicate.getMemoryVT())
289 continue;
290
291 if (Predicate.isAtomic() &&
292 (Predicate.isAtomicOrderingMonotonic() ||
293 Predicate.isAtomicOrderingAcquire() ||
294 Predicate.isAtomicOrderingRelease() ||
295 Predicate.isAtomicOrderingAcquireRelease() ||
Daniel Sanders0c43b3a2017-11-30 21:05:59 +0000296 Predicate.isAtomicOrderingSequentiallyConsistent() ||
297 Predicate.isAtomicOrderingAcquireOrStronger() ||
298 Predicate.isAtomicOrderingWeakerThanAcquire() ||
299 Predicate.isAtomicOrderingReleaseOrStronger() ||
300 Predicate.isAtomicOrderingWeakerThanRelease()))
Daniel Sandersd66e0902017-10-23 18:19:24 +0000301 continue;
302
Daniel Sanders2c269f62017-08-24 09:11:20 +0000303 HasUnsupportedPredicate = true;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000304 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
305 Separator = ", ";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000306 Explanation += (Separator + "first-failing:" +
307 Predicate.getOrigPatFragRecord()->getRecord()->getName())
308 .str();
Daniel Sanders2c269f62017-08-24 09:11:20 +0000309 break;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000310 }
311
312 if (N->getTransformFn()) {
313 Explanation += Separator + "Has a transform function";
314 Separator = ", ";
315 }
316
Daniel Sanders2c269f62017-08-24 09:11:20 +0000317 if (!HasUnsupportedPredicate && !N->getTransformFn())
Daniel Sandersd0656a32017-04-13 09:45:37 +0000318 return Error::success();
319
320 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000321}
322
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000323static Record *getInitValueAsRegClass(Init *V) {
324 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
325 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
326 return VDefInit->getDef()->getValueAsDef("RegClass");
327 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
328 return VDefInit->getDef();
329 }
330 return nullptr;
331}
332
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000333std::string
334getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
335 std::string Name = "GIFBS";
336 for (const auto &Feature : FeatureBitset)
337 Name += ("_" + Feature->getName()).str();
338 return Name;
339}
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000340
341//===- MatchTable Helpers -------------------------------------------------===//
342
343class MatchTable;
344
345/// A record to be stored in a MatchTable.
346///
347/// This class represents any and all output that may be required to emit the
348/// MatchTable. Instances are most often configured to represent an opcode or
349/// value that will be emitted to the table with some formatting but it can also
350/// represent commas, comments, and other formatting instructions.
351struct MatchTableRecord {
352 enum RecordFlagsBits {
353 MTRF_None = 0x0,
354 /// Causes EmitStr to be formatted as comment when emitted.
355 MTRF_Comment = 0x1,
356 /// Causes the record value to be followed by a comma when emitted.
357 MTRF_CommaFollows = 0x2,
358 /// Causes the record value to be followed by a line break when emitted.
359 MTRF_LineBreakFollows = 0x4,
360 /// Indicates that the record defines a label and causes an additional
361 /// comment to be emitted containing the index of the label.
362 MTRF_Label = 0x8,
363 /// Causes the record to be emitted as the index of the label specified by
364 /// LabelID along with a comment indicating where that label is.
365 MTRF_JumpTarget = 0x10,
366 /// Causes the formatter to add a level of indentation before emitting the
367 /// record.
368 MTRF_Indent = 0x20,
369 /// Causes the formatter to remove a level of indentation after emitting the
370 /// record.
371 MTRF_Outdent = 0x40,
372 };
373
374 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
375 /// reference or define.
376 unsigned LabelID;
377 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
378 /// value, a label name.
379 std::string EmitStr;
380
381private:
382 /// The number of MatchTable elements described by this record. Comments are 0
383 /// while values are typically 1. Values >1 may occur when we need to emit
384 /// values that exceed the size of a MatchTable element.
385 unsigned NumElements;
386
387public:
388 /// A bitfield of RecordFlagsBits flags.
389 unsigned Flags;
390
391 MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
392 unsigned NumElements, unsigned Flags)
393 : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
394 EmitStr(EmitStr), NumElements(NumElements), Flags(Flags) {
395 assert((!LabelID_.hasValue() || LabelID != ~0u) &&
396 "This value is reserved for non-labels");
397 }
398
399 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
400 const MatchTable &Table) const;
401 unsigned size() const { return NumElements; }
402};
403
404/// Holds the contents of a generated MatchTable to enable formatting and the
405/// necessary index tracking needed to support GIM_Try.
406class MatchTable {
407 /// An unique identifier for the table. The generated table will be named
408 /// MatchTable${ID}.
409 unsigned ID;
410 /// The records that make up the table. Also includes comments describing the
411 /// values being emitted and line breaks to format it.
412 std::vector<MatchTableRecord> Contents;
413 /// The currently defined labels.
414 DenseMap<unsigned, unsigned> LabelMap;
415 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
416 unsigned CurrentSize;
417
Daniel Sanders8e82af22017-07-27 11:03:45 +0000418 /// A unique identifier for a MatchTable label.
419 static unsigned CurrentLabelID;
420
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000421public:
422 static MatchTableRecord LineBreak;
423 static MatchTableRecord Comment(StringRef Comment) {
424 return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
425 }
426 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
427 unsigned ExtraFlags = 0;
428 if (IndentAdjust > 0)
429 ExtraFlags |= MatchTableRecord::MTRF_Indent;
430 if (IndentAdjust < 0)
431 ExtraFlags |= MatchTableRecord::MTRF_Outdent;
432
433 return MatchTableRecord(None, Opcode, 1,
434 MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
435 }
436 static MatchTableRecord NamedValue(StringRef NamedValue) {
437 return MatchTableRecord(None, NamedValue, 1,
438 MatchTableRecord::MTRF_CommaFollows);
439 }
440 static MatchTableRecord NamedValue(StringRef Namespace,
441 StringRef NamedValue) {
442 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
443 MatchTableRecord::MTRF_CommaFollows);
444 }
445 static MatchTableRecord IntValue(int64_t IntValue) {
446 return MatchTableRecord(None, llvm::to_string(IntValue), 1,
447 MatchTableRecord::MTRF_CommaFollows);
448 }
449 static MatchTableRecord Label(unsigned LabelID) {
450 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
451 MatchTableRecord::MTRF_Label |
452 MatchTableRecord::MTRF_Comment |
453 MatchTableRecord::MTRF_LineBreakFollows);
454 }
455 static MatchTableRecord JumpTarget(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000456 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000457 MatchTableRecord::MTRF_JumpTarget |
458 MatchTableRecord::MTRF_Comment |
459 MatchTableRecord::MTRF_CommaFollows);
460 }
461
462 MatchTable(unsigned ID) : ID(ID), CurrentSize(0) {}
463
464 void push_back(const MatchTableRecord &Value) {
465 if (Value.Flags & MatchTableRecord::MTRF_Label)
466 defineLabel(Value.LabelID);
467 Contents.push_back(Value);
468 CurrentSize += Value.size();
469 }
470
Daniel Sanders8e82af22017-07-27 11:03:45 +0000471 unsigned allocateLabelID() const { return CurrentLabelID++; }
472
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000473 void defineLabel(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000474 LabelMap.insert(std::make_pair(LabelID, CurrentSize));
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000475 }
476
477 unsigned getLabelIndex(unsigned LabelID) const {
478 const auto I = LabelMap.find(LabelID);
479 assert(I != LabelMap.end() && "Use of undeclared label");
480 return I->second;
481 }
482
Daniel Sanders8e82af22017-07-27 11:03:45 +0000483 void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
484
485 void emitDeclaration(raw_ostream &OS) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000486 unsigned Indentation = 4;
Daniel Sanderscbbbfe42017-07-27 12:47:31 +0000487 OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000488 LineBreak.emit(OS, true, *this);
489 OS << std::string(Indentation, ' ');
490
491 for (auto I = Contents.begin(), E = Contents.end(); I != E;
492 ++I) {
493 bool LineBreakIsNext = false;
494 const auto &NextI = std::next(I);
495
496 if (NextI != E) {
497 if (NextI->EmitStr == "" &&
498 NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
499 LineBreakIsNext = true;
500 }
501
502 if (I->Flags & MatchTableRecord::MTRF_Indent)
503 Indentation += 2;
504
505 I->emit(OS, LineBreakIsNext, *this);
506 if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
507 OS << std::string(Indentation, ' ');
508
509 if (I->Flags & MatchTableRecord::MTRF_Outdent)
510 Indentation -= 2;
511 }
512 OS << "};\n";
513 }
514};
515
Daniel Sanders8e82af22017-07-27 11:03:45 +0000516unsigned MatchTable::CurrentLabelID = 0;
517
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000518MatchTableRecord MatchTable::LineBreak = {
519 None, "" /* Emit String */, 0 /* Elements */,
520 MatchTableRecord::MTRF_LineBreakFollows};
521
522void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
523 const MatchTable &Table) const {
524 bool UseLineComment =
525 LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
526 if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
527 UseLineComment = false;
528
529 if (Flags & MTRF_Comment)
530 OS << (UseLineComment ? "// " : "/*");
531
532 OS << EmitStr;
533 if (Flags & MTRF_Label)
534 OS << ": @" << Table.getLabelIndex(LabelID);
535
536 if (Flags & MTRF_Comment && !UseLineComment)
537 OS << "*/";
538
539 if (Flags & MTRF_JumpTarget) {
540 if (Flags & MTRF_Comment)
541 OS << " ";
542 OS << Table.getLabelIndex(LabelID);
543 }
544
545 if (Flags & MTRF_CommaFollows) {
546 OS << ",";
547 if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
548 OS << " ";
549 }
550
551 if (Flags & MTRF_LineBreakFollows)
552 OS << "\n";
553}
554
555MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
556 Table.push_back(Value);
557 return Table;
558}
559
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000560//===- Matchers -----------------------------------------------------------===//
561
Daniel Sandersbee57392017-04-04 13:25:23 +0000562class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000563class MatchAction;
564
565/// Generates code to check that a match rule matches.
566class RuleMatcher {
Daniel Sanders7438b262017-10-31 23:03:18 +0000567public:
568 using ActionVec = std::vector<std::unique_ptr<MatchAction>>;
569 using action_iterator = ActionVec::iterator;
570
571protected:
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000572 /// A list of matchers that all need to succeed for the current rule to match.
573 /// FIXME: This currently supports a single match position but could be
574 /// extended to support multiple positions to support div/rem fusion or
575 /// load-multiple instructions.
576 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
577
578 /// A list of actions that need to be taken when all predicates in this rule
579 /// have succeeded.
Daniel Sanders7438b262017-10-31 23:03:18 +0000580 ActionVec Actions;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000581
Daniel Sandersa7b75262017-10-31 18:50:24 +0000582 using DefinedInsnVariablesMap =
583 std::map<const InstructionMatcher *, unsigned>;
584
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000585 /// A map of instruction matchers to the local variables created by
Daniel Sanders9d662d22017-07-06 10:06:12 +0000586 /// emitCaptureOpcodes().
Daniel Sanders078572b2017-08-02 11:03:36 +0000587 DefinedInsnVariablesMap InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000588
Daniel Sandersa7b75262017-10-31 18:50:24 +0000589 using MutatableInsnSet = SmallPtrSet<const InstructionMatcher *, 4>;
590
591 // The set of instruction matchers that have not yet been claimed for mutation
592 // by a BuildMI.
593 MutatableInsnSet MutatableInsns;
594
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000595 /// A map of named operands defined by the matchers that may be referenced by
596 /// the renderers.
597 StringMap<OperandMatcher *> DefinedOperands;
598
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000599 /// ID for the next instruction variable defined with defineInsnVar()
600 unsigned NextInsnVarID;
601
Daniel Sanders198447a2017-11-01 00:29:47 +0000602 /// ID for the next output instruction allocated with allocateOutputInsnID()
603 unsigned NextOutputInsnID;
604
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000605 /// ID for the next temporary register ID allocated with allocateTempRegID()
606 unsigned NextTempRegID;
607
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000608 std::vector<Record *> RequiredFeatures;
609
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000610 ArrayRef<SMLoc> SrcLoc;
611
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000612 typedef std::tuple<Record *, unsigned, unsigned>
613 DefinedComplexPatternSubOperand;
614 typedef StringMap<DefinedComplexPatternSubOperand>
615 DefinedComplexPatternSubOperandMap;
616 /// A map of Symbolic Names to ComplexPattern sub-operands.
617 DefinedComplexPatternSubOperandMap ComplexSubOperands;
618
Daniel Sandersf76f3152017-11-16 00:46:35 +0000619 uint64_t RuleID;
620 static uint64_t NextRuleID;
621
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000622public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000623 RuleMatcher(ArrayRef<SMLoc> SrcLoc)
Daniel Sandersa7b75262017-10-31 18:50:24 +0000624 : Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(),
Daniel Sanders198447a2017-11-01 00:29:47 +0000625 DefinedOperands(), NextInsnVarID(0), NextOutputInsnID(0),
Daniel Sandersf76f3152017-11-16 00:46:35 +0000626 NextTempRegID(0), SrcLoc(SrcLoc), ComplexSubOperands(),
627 RuleID(NextRuleID++) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000628 RuleMatcher(RuleMatcher &&Other) = default;
629 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000630
Daniel Sandersf76f3152017-11-16 00:46:35 +0000631 uint64_t getRuleID() const { return RuleID; }
632
Daniel Sanders05540042017-08-08 10:44:31 +0000633 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000634 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000635 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000636
637 template <class Kind, class... Args> Kind &addAction(Args &&... args);
Daniel Sanders7438b262017-10-31 23:03:18 +0000638 template <class Kind, class... Args>
639 action_iterator insertAction(action_iterator InsertPt, Args &&... args);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000640
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000641 /// Define an instruction without emitting any code to do so.
642 /// This is used for the root of the match.
643 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
644 /// Define an instruction and emit corresponding state-machine opcodes.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000645 unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000646 unsigned InsnVarID, unsigned OpIdx);
647 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sanders078572b2017-08-02 11:03:36 +0000648 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
649 return InsnVariableIDs.begin();
650 }
651 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
652 return InsnVariableIDs.end();
653 }
654 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
655 defined_insn_vars() const {
656 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
657 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000658
Daniel Sandersa7b75262017-10-31 18:50:24 +0000659 MutatableInsnSet::const_iterator mutatable_insns_begin() const {
660 return MutatableInsns.begin();
661 }
662 MutatableInsnSet::const_iterator mutatable_insns_end() const {
663 return MutatableInsns.end();
664 }
665 iterator_range<typename MutatableInsnSet::const_iterator>
666 mutatable_insns() const {
667 return make_range(mutatable_insns_begin(), mutatable_insns_end());
668 }
669 void reserveInsnMatcherForMutation(const InstructionMatcher *InsnMatcher) {
670 bool R = MutatableInsns.erase(InsnMatcher);
671 assert(R && "Reserving a mutatable insn that isn't available");
672 (void)R;
673 }
674
Daniel Sanders7438b262017-10-31 23:03:18 +0000675 action_iterator actions_begin() { return Actions.begin(); }
676 action_iterator actions_end() { return Actions.end(); }
677 iterator_range<action_iterator> actions() {
678 return make_range(actions_begin(), actions_end());
679 }
680
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000681 void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
682
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000683 void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
684 unsigned RendererID, unsigned SubOperandID) {
685 assert(ComplexSubOperands.count(SymbolicName) == 0 && "Already defined");
686 ComplexSubOperands[SymbolicName] =
687 std::make_tuple(ComplexPattern, RendererID, SubOperandID);
688 }
689 Optional<DefinedComplexPatternSubOperand>
690 getComplexSubOperand(StringRef SymbolicName) const {
691 const auto &I = ComplexSubOperands.find(SymbolicName);
692 if (I == ComplexSubOperands.end())
693 return None;
694 return I->second;
695 }
696
Daniel Sanders05540042017-08-08 10:44:31 +0000697 const InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000698 const OperandMatcher &getOperandMatcher(StringRef Name) const;
Daniel Sanders05540042017-08-08 10:44:31 +0000699
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000700 void emitCaptureOpcodes(MatchTable &Table);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000701
Daniel Sanders8e82af22017-07-27 11:03:45 +0000702 void emit(MatchTable &Table);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000703
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000704 /// Compare the priority of this object and B.
705 ///
706 /// Returns true if this object is more important than B.
707 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000708
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000709 /// Report the maximum number of temporary operands needed by the rule
710 /// matcher.
711 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000712
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000713 // FIXME: Remove this as soon as possible
714 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sanders198447a2017-11-01 00:29:47 +0000715
716 unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000717 unsigned allocateTempRegID() { return NextTempRegID++; }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000718};
719
Daniel Sandersf76f3152017-11-16 00:46:35 +0000720uint64_t RuleMatcher::NextRuleID = 0;
721
Daniel Sanders7438b262017-10-31 23:03:18 +0000722using action_iterator = RuleMatcher::action_iterator;
723
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000724template <class PredicateTy> class PredicateListMatcher {
725private:
726 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
727 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000728
Daniel Sanders2c269f62017-08-24 09:11:20 +0000729 /// Template instantiations should specialize this to return a string to use
730 /// for the comment emitted when there are no predicates.
731 std::string getNoPredicateComment() const;
732
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000733public:
734 /// Construct a new operand predicate and add it to the matcher.
735 template <class Kind, class... Args>
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000736 Optional<Kind *> addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000737 Predicates.emplace_back(
738 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000739 return static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000740 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000741
Daniel Sanders32291982017-06-28 13:50:04 +0000742 typename PredicateVec::const_iterator predicates_begin() const {
743 return Predicates.begin();
744 }
745 typename PredicateVec::const_iterator predicates_end() const {
746 return Predicates.end();
747 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000748 iterator_range<typename PredicateVec::const_iterator> predicates() const {
749 return make_range(predicates_begin(), predicates_end());
750 }
Daniel Sanders32291982017-06-28 13:50:04 +0000751 typename PredicateVec::size_type predicates_size() const {
752 return Predicates.size();
753 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000754
Daniel Sanders9d662d22017-07-06 10:06:12 +0000755 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000756 template <class... Args>
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000757 void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000758 if (Predicates.empty()) {
Daniel Sanders2c269f62017-08-24 09:11:20 +0000759 Table << MatchTable::Comment(getNoPredicateComment())
760 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000761 return;
762 }
763
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000764 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000765 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000766 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000767};
768
Quentin Colombet063d7982017-12-14 23:44:07 +0000769class PredicateMatcher {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000770public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000771 /// This enum is used for RTTI and also defines the priority that is given to
772 /// the predicate when generating the matcher code. Kinds with higher priority
773 /// must be tested first.
774 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000775 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
776 /// but OPM_Int must have priority over OPM_RegBank since constant integers
777 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Quentin Colombet063d7982017-12-14 23:44:07 +0000778 ///
779 /// Note: The relative priority between IPM_ and OPM_ does not matter, they
780 /// are currently not compared between each other.
Daniel Sanders759ff412017-02-24 13:58:11 +0000781 enum PredicateKind {
Quentin Colombet063d7982017-12-14 23:44:07 +0000782 IPM_Opcode,
783 IPM_ImmPredicate,
784 IPM_AtomicOrderingMMO,
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000785 OPM_SameOperand,
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000786 OPM_ComplexPattern,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000787 OPM_IntrinsicID,
Daniel Sanders05540042017-08-08 10:44:31 +0000788 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000789 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000790 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000791 OPM_LLT,
Daniel Sandersa71f4542017-10-16 00:56:30 +0000792 OPM_PointerToAny,
Daniel Sanders759ff412017-02-24 13:58:11 +0000793 OPM_RegBank,
794 OPM_MBB,
795 };
796
797protected:
798 PredicateKind Kind;
799
800public:
Quentin Colombet063d7982017-12-14 23:44:07 +0000801 PredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
802
803 virtual ~PredicateMatcher() = default;
804 /// Emit MatchTable opcodes that check the predicate for the given operand.
805 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
806 unsigned InsnVarID,
807 unsigned OpIdx = ~0) const = 0;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000808
Daniel Sanders759ff412017-02-24 13:58:11 +0000809 PredicateKind getKind() const { return Kind; }
Quentin Colombet063d7982017-12-14 23:44:07 +0000810};
811
812/// Generates code to check a predicate of an operand.
813///
814/// Typical predicates include:
815/// * Operand is a particular register.
816/// * Operand is assigned a particular register bank.
817/// * Operand is an MBB.
818class OperandPredicateMatcher : public PredicateMatcher {
819public:
820 OperandPredicateMatcher(PredicateKind Kind) : PredicateMatcher(Kind) {}
821 virtual ~OperandPredicateMatcher() {}
Daniel Sanders759ff412017-02-24 13:58:11 +0000822
Daniel Sanders9d662d22017-07-06 10:06:12 +0000823 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sandersbee57392017-04-04 13:25:23 +0000824 ///
Daniel Sanders9d662d22017-07-06 10:06:12 +0000825 /// Only InstructionOperandMatcher needs to do anything for this method the
826 /// rest just walk the tree.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000827 virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +0000828 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000829
Daniel Sanders759ff412017-02-24 13:58:11 +0000830 /// Compare the priority of this object and B.
831 ///
832 /// Returns true if this object is more important than B.
Daniel Sanders05540042017-08-08 10:44:31 +0000833 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000834
835 /// Report the maximum number of temporary operands needed by the predicate
836 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000837 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000838};
839
Daniel Sanders2c269f62017-08-24 09:11:20 +0000840template <>
841std::string
842PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
843 return "No operand predicates";
844}
845
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000846/// Generates code to check that a register operand is defined by the same exact
847/// one as another.
848class SameOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000849 std::string MatchingName;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000850
851public:
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000852 SameOperandMatcher(StringRef MatchingName)
853 : OperandPredicateMatcher(OPM_SameOperand), MatchingName(MatchingName) {}
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000854
855 static bool classof(const OperandPredicateMatcher *P) {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000856 return P->getKind() == OPM_SameOperand;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000857 }
858
859 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
860 unsigned InsnVarID, unsigned OpIdx) const override;
861};
862
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000863/// Generates code to check that an operand is a particular LLT.
864class LLTOperandMatcher : public OperandPredicateMatcher {
865protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000866 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000867
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000868public:
Daniel Sanders032e7f22017-08-17 13:18:35 +0000869 static std::set<LLTCodeGen> KnownTypes;
870
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000871 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders032e7f22017-08-17 13:18:35 +0000872 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {
873 KnownTypes.insert(Ty);
874 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000875
Quentin Colombet063d7982017-12-14 23:44:07 +0000876 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +0000877 return P->getKind() == OPM_LLT;
878 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000879
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000880 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000881 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000882 Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
883 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
884 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
885 << MatchTable::NamedValue(Ty.getCxxEnumValue())
886 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000887 }
888};
889
Daniel Sanders032e7f22017-08-17 13:18:35 +0000890std::set<LLTCodeGen> LLTOperandMatcher::KnownTypes;
891
Daniel Sandersa71f4542017-10-16 00:56:30 +0000892/// Generates code to check that an operand is a pointer to any address space.
893///
894/// In SelectionDAG, the types did not describe pointers or address spaces. As a
895/// result, iN is used to describe a pointer of N bits to any address space and
896/// PatFrag predicates are typically used to constrain the address space. There's
897/// no reliable means to derive the missing type information from the pattern so
898/// imported rules must test the components of a pointer separately.
899///
Daniel Sandersea8711b2017-10-16 03:36:29 +0000900/// If SizeInBits is zero, then the pointer size will be obtained from the
901/// subtarget.
Daniel Sandersa71f4542017-10-16 00:56:30 +0000902class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
903protected:
904 unsigned SizeInBits;
905
906public:
907 PointerToAnyOperandMatcher(unsigned SizeInBits)
908 : OperandPredicateMatcher(OPM_PointerToAny), SizeInBits(SizeInBits) {}
909
910 static bool classof(const OperandPredicateMatcher *P) {
911 return P->getKind() == OPM_PointerToAny;
912 }
913
914 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
915 unsigned InsnVarID, unsigned OpIdx) const override {
916 Table << MatchTable::Opcode("GIM_CheckPointerToAny") << MatchTable::Comment("MI")
917 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
918 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("SizeInBits")
919 << MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
920 }
921};
922
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000923/// Generates code to check that an operand is a particular target constant.
924class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
925protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000926 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000927 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000928
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000929 unsigned getAllocatedTemporariesBaseID() const;
930
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000931public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000932 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
933 const Record &TheDef)
934 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
935 TheDef(TheDef) {}
936
Quentin Colombet063d7982017-12-14 23:44:07 +0000937 static bool classof(const PredicateMatcher *P) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000938 return P->getKind() == OPM_ComplexPattern;
939 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000940
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000941 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000942 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000943 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000944 Table << MatchTable::Opcode("GIM_CheckComplexPattern")
945 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
946 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
947 << MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
948 << MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
949 << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000950 }
951
Daniel Sanders2deea182017-04-22 15:11:04 +0000952 unsigned countRendererFns() const override {
953 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000954 }
955};
956
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000957/// Generates code to check that an operand is in a particular register bank.
958class RegisterBankOperandMatcher : public OperandPredicateMatcher {
959protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000960 const CodeGenRegisterClass &RC;
961
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000962public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000963 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
964 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
965
Quentin Colombet063d7982017-12-14 23:44:07 +0000966 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +0000967 return P->getKind() == OPM_RegBank;
968 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000969
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000970 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000971 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000972 Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
973 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
974 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
975 << MatchTable::Comment("RC")
976 << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
977 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000978 }
979};
980
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000981/// Generates code to check that an operand is a basic block.
982class MBBOperandMatcher : public OperandPredicateMatcher {
983public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000984 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
985
Quentin Colombet063d7982017-12-14 23:44:07 +0000986 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +0000987 return P->getKind() == OPM_MBB;
988 }
989
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000990 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000991 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000992 Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
993 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
994 << MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000995 }
996};
997
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000998/// Generates code to check that an operand is a G_CONSTANT with a particular
999/// int.
1000class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001001protected:
1002 int64_t Value;
1003
1004public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001005 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001006 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
1007
Quentin Colombet063d7982017-12-14 23:44:07 +00001008 static bool classof(const PredicateMatcher *P) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001009 return P->getKind() == OPM_Int;
1010 }
1011
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001012 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001013 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001014 Table << MatchTable::Opcode("GIM_CheckConstantInt")
1015 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1016 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1017 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001018 }
1019};
1020
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001021/// Generates code to check that an operand is a raw int (where MO.isImm() or
1022/// MO.isCImm() is true).
1023class LiteralIntOperandMatcher : public OperandPredicateMatcher {
1024protected:
1025 int64_t Value;
1026
1027public:
1028 LiteralIntOperandMatcher(int64_t Value)
1029 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
1030
Quentin Colombet063d7982017-12-14 23:44:07 +00001031 static bool classof(const PredicateMatcher *P) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001032 return P->getKind() == OPM_LiteralInt;
1033 }
1034
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001035 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001036 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001037 Table << MatchTable::Opcode("GIM_CheckLiteralInt")
1038 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1039 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1040 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001041 }
1042};
1043
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001044/// Generates code to check that an operand is an intrinsic ID.
1045class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
1046protected:
1047 const CodeGenIntrinsic *II;
1048
1049public:
1050 IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
1051 : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
1052
Quentin Colombet063d7982017-12-14 23:44:07 +00001053 static bool classof(const PredicateMatcher *P) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001054 return P->getKind() == OPM_IntrinsicID;
1055 }
1056
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001057 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001058 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001059 Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
1060 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1061 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1062 << MatchTable::NamedValue("Intrinsic::" + II->EnumName)
1063 << MatchTable::LineBreak;
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001064 }
1065};
1066
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001067/// Generates code to check that a set of predicates match for a particular
1068/// operand.
1069class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
1070protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001071 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001072 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001073 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001074
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001075 /// The index of the first temporary variable allocated to this operand. The
1076 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +00001077 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001078 unsigned AllocatedTemporariesBaseID;
1079
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001080public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001081 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001082 const std::string &SymbolicName,
1083 unsigned AllocatedTemporariesBaseID)
1084 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
1085 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001086
1087 bool hasSymbolicName() const { return !SymbolicName.empty(); }
1088 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001089 void setSymbolicName(StringRef Name) {
1090 assert(SymbolicName.empty() && "Operand already has a symbolic name");
1091 SymbolicName = Name;
1092 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001093 unsigned getOperandIndex() const { return OpIdx; }
1094
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001095 std::string getOperandExpr(unsigned InsnVarID) const {
1096 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
1097 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +00001098 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001099
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001100 InstructionMatcher &getInstructionMatcher() const { return Insn; }
1101
Daniel Sandersa71f4542017-10-16 00:56:30 +00001102 Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001103 bool OperandIsAPointer);
Daniel Sandersa71f4542017-10-16 00:56:30 +00001104
Daniel Sanders9d662d22017-07-06 10:06:12 +00001105 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001106 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001107 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +00001108 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001109 Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00001110 }
1111
Daniel Sanders9d662d22017-07-06 10:06:12 +00001112 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001113 /// InsnVarID matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001114 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001115 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001116 std::string Comment;
1117 raw_string_ostream CommentOS(Comment);
1118 CommentOS << "MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001119 if (SymbolicName.empty())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001120 CommentOS << "Operand " << OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001121 else
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001122 CommentOS << SymbolicName;
1123 Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
1124
1125 emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001126 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001127
1128 /// Compare the priority of this object and B.
1129 ///
1130 /// Returns true if this object is more important than B.
1131 bool isHigherPriorityThan(const OperandMatcher &B) const {
1132 // Operand matchers involving more predicates have higher priority.
1133 if (predicates_size() > B.predicates_size())
1134 return true;
1135 if (predicates_size() < B.predicates_size())
1136 return false;
1137
1138 // This assumes that predicates are added in a consistent order.
1139 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1140 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1141 return true;
1142 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1143 return false;
1144 }
1145
1146 return false;
1147 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001148
1149 /// Report the maximum number of temporary operands needed by the operand
1150 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001151 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001152 return std::accumulate(
1153 predicates().begin(), predicates().end(), 0,
1154 [](unsigned A,
1155 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001156 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001157 });
1158 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001159
1160 unsigned getAllocatedTemporariesBaseID() const {
1161 return AllocatedTemporariesBaseID;
1162 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001163
1164 bool isSameAsAnotherOperand() const {
1165 for (const auto &Predicate : predicates())
1166 if (isa<SameOperandMatcher>(Predicate))
1167 return true;
1168 return false;
1169 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001170};
1171
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001172// Specialize OperandMatcher::addPredicate() to refrain from adding redundant
1173// predicates.
1174template <>
1175template <class Kind, class... Args>
1176Optional<Kind *>
1177PredicateListMatcher<OperandPredicateMatcher>::addPredicate(Args &&... args) {
1178 if (static_cast<OperandMatcher *>(this)->isSameAsAnotherOperand())
1179 return None;
1180 Predicates.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1181 return static_cast<Kind *>(Predicates.back().get());
1182}
1183
1184Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
1185 bool OperandIsAPointer) {
1186 if (!VTy.isMachineValueType())
1187 return failedImport("unsupported typeset");
1188
1189 if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
1190 addPredicate<PointerToAnyOperandMatcher>(0);
1191 return Error::success();
1192 }
1193
1194 auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
1195 if (!OpTyOrNone)
1196 return failedImport("unsupported type");
1197
1198 if (OperandIsAPointer)
1199 addPredicate<PointerToAnyOperandMatcher>(OpTyOrNone->get().getSizeInBits());
1200 else
1201 addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1202 return Error::success();
1203}
1204
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001205unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
1206 return Operand.getAllocatedTemporariesBaseID();
1207}
1208
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001209/// Generates code to check a predicate on an instruction.
1210///
1211/// Typical predicates include:
1212/// * The opcode of the instruction is a particular value.
1213/// * The nsw/nuw flag is/isn't set.
Quentin Colombet063d7982017-12-14 23:44:07 +00001214class InstructionPredicateMatcher : public PredicateMatcher {
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001215public:
Quentin Colombet063d7982017-12-14 23:44:07 +00001216 InstructionPredicateMatcher(PredicateKind Kind) : PredicateMatcher(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001217 virtual ~InstructionPredicateMatcher() {}
1218
Daniel Sanders759ff412017-02-24 13:58:11 +00001219 /// Compare the priority of this object and B.
1220 ///
1221 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001222 virtual bool
1223 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +00001224 return Kind < B.Kind;
1225 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001226
1227 /// Report the maximum number of temporary operands needed by the predicate
1228 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001229 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001230};
1231
Daniel Sanders2c269f62017-08-24 09:11:20 +00001232template <>
1233std::string
1234PredicateListMatcher<InstructionPredicateMatcher>::getNoPredicateComment() const {
1235 return "No instruction predicates";
1236}
1237
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001238/// Generates code to check the opcode of an instruction.
1239class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1240protected:
1241 const CodeGenInstruction *I;
1242
1243public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001244 InstructionOpcodeMatcher(const CodeGenInstruction *I)
1245 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001246
Quentin Colombet063d7982017-12-14 23:44:07 +00001247 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001248 return P->getKind() == IPM_Opcode;
1249 }
1250
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001251 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Quentin Colombet063d7982017-12-14 23:44:07 +00001252 unsigned InsnVarID,
1253 unsigned OpIdx = ~0) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001254 Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
1255 << MatchTable::IntValue(InsnVarID)
1256 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1257 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001258 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001259
1260 /// Compare the priority of this object and B.
1261 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001262 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001263 bool
1264 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +00001265 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
1266 return true;
1267 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
1268 return false;
1269
1270 // Prioritize opcodes for cosmetic reasons in the generated source. Although
1271 // this is cosmetic at the moment, we may want to drive a similar ordering
1272 // using instruction frequency information to improve compile time.
1273 if (const InstructionOpcodeMatcher *BO =
1274 dyn_cast<InstructionOpcodeMatcher>(&B))
1275 return I->TheDef->getName() < BO->I->TheDef->getName();
1276
1277 return false;
1278 };
Daniel Sanders05540042017-08-08 10:44:31 +00001279
1280 bool isConstantInstruction() const {
1281 return I->TheDef->getName() == "G_CONSTANT";
1282 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001283};
1284
Daniel Sanders2c269f62017-08-24 09:11:20 +00001285/// Generates code to check that this instruction is a constant whose value
1286/// meets an immediate predicate.
1287///
1288/// Immediates are slightly odd since they are typically used like an operand
1289/// but are represented as an operator internally. We typically write simm8:$src
1290/// in a tablegen pattern, but this is just syntactic sugar for
1291/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1292/// that will be matched and the predicate (which is attached to the imm
1293/// operator) that will be tested. In SelectionDAG this describes a
1294/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
1295///
1296/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1297/// this representation, the immediate could be tested with an
1298/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1299/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1300/// there are two implementation issues with producing that matcher
1301/// configuration from the SelectionDAG pattern:
1302/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1303/// were we to sink the immediate predicate to the operand we would have to
1304/// have two partial implementations of PatFrag support, one for immediates
1305/// and one for non-immediates.
1306/// * At the point we handle the predicate, the OperandMatcher hasn't been
1307/// created yet. If we were to sink the predicate to the OperandMatcher we
1308/// would also have to complicate (or duplicate) the code that descends and
1309/// creates matchers for the subtree.
1310/// Overall, it's simpler to handle it in the place it was found.
1311class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1312protected:
1313 TreePredicateFn Predicate;
1314
1315public:
1316 InstructionImmPredicateMatcher(const TreePredicateFn &Predicate)
1317 : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {}
1318
Quentin Colombet063d7982017-12-14 23:44:07 +00001319 static bool classof(const PredicateMatcher *P) {
Daniel Sanders2c269f62017-08-24 09:11:20 +00001320 return P->getKind() == IPM_ImmPredicate;
1321 }
1322
1323 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Quentin Colombet063d7982017-12-14 23:44:07 +00001324 unsigned InsnVarID,
1325 unsigned OpIdx = ~0) const override {
Daniel Sanders11300ce2017-10-13 21:28:03 +00001326 Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001327 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1328 << MatchTable::Comment("Predicate")
Daniel Sanders11300ce2017-10-13 21:28:03 +00001329 << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001330 << MatchTable::LineBreak;
1331 }
1332};
1333
Daniel Sanders76664652017-11-28 22:07:05 +00001334/// Generates code to check that a memory instruction has a atomic ordering
1335/// MachineMemoryOperand.
1336class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001337public:
1338 enum AOComparator {
1339 AO_Exactly,
1340 AO_OrStronger,
1341 AO_WeakerThan,
1342 };
1343
1344protected:
Daniel Sanders76664652017-11-28 22:07:05 +00001345 StringRef Order;
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001346 AOComparator Comparator;
Daniel Sanders76664652017-11-28 22:07:05 +00001347
Daniel Sanders39690bd2017-10-15 02:41:12 +00001348public:
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001349 AtomicOrderingMMOPredicateMatcher(StringRef Order,
1350 AOComparator Comparator = AO_Exactly)
1351 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order),
1352 Comparator(Comparator) {}
Daniel Sanders39690bd2017-10-15 02:41:12 +00001353
1354 static bool classof(const InstructionPredicateMatcher *P) {
Daniel Sanders76664652017-11-28 22:07:05 +00001355 return P->getKind() == IPM_AtomicOrderingMMO;
Daniel Sanders39690bd2017-10-15 02:41:12 +00001356 }
1357
1358 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Quentin Colombet063d7982017-12-14 23:44:07 +00001359 unsigned InsnVarID,
1360 unsigned OpIdx = ~0) const override {
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001361 StringRef Opcode = "GIM_CheckAtomicOrdering";
1362
1363 if (Comparator == AO_OrStronger)
1364 Opcode = "GIM_CheckAtomicOrderingOrStrongerThan";
1365 if (Comparator == AO_WeakerThan)
1366 Opcode = "GIM_CheckAtomicOrderingWeakerThan";
1367
1368 Table << MatchTable::Opcode(Opcode) << MatchTable::Comment("MI")
1369 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Order")
Daniel Sanders76664652017-11-28 22:07:05 +00001370 << MatchTable::NamedValue(("(int64_t)AtomicOrdering::" + Order).str())
Daniel Sanders39690bd2017-10-15 02:41:12 +00001371 << MatchTable::LineBreak;
1372 }
1373};
1374
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001375/// Generates code to check that a set of predicates and operands match for a
1376/// particular instruction.
1377///
1378/// Typical predicates include:
1379/// * Has a specific opcode.
1380/// * Has an nsw/nuw flag or doesn't.
1381class InstructionMatcher
1382 : public PredicateListMatcher<InstructionPredicateMatcher> {
1383protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001384 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001385
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001386 RuleMatcher &Rule;
1387
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001388 /// The operands to match. All rendered operands must be present even if the
1389 /// condition is always true.
1390 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001391
Daniel Sanders05540042017-08-08 10:44:31 +00001392 std::string SymbolicName;
1393
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001394public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001395 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
1396 : Rule(Rule), SymbolicName(SymbolicName) {}
1397
1398 RuleMatcher &getRuleMatcher() const { return Rule; }
Daniel Sanders05540042017-08-08 10:44:31 +00001399
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001400 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001401 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1402 unsigned AllocatedTemporariesBaseID) {
1403 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
1404 AllocatedTemporariesBaseID));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001405 if (!SymbolicName.empty())
1406 Rule.defineOperand(SymbolicName, *Operands.back());
1407
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001408 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001409 }
1410
Daniel Sandersffc7d582017-03-29 15:37:18 +00001411 OperandMatcher &getOperand(unsigned OpIdx) {
1412 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001413 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
1414 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001415 });
1416 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001417 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001418 llvm_unreachable("Failed to lookup operand");
1419 }
1420
Daniel Sanders05540042017-08-08 10:44:31 +00001421 StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001422 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +00001423 OperandVec::iterator operands_begin() { return Operands.begin(); }
1424 OperandVec::iterator operands_end() { return Operands.end(); }
1425 iterator_range<OperandVec::iterator> operands() {
1426 return make_range(operands_begin(), operands_end());
1427 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001428 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1429 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001430 iterator_range<OperandVec::const_iterator> operands() const {
1431 return make_range(operands_begin(), operands_end());
1432 }
1433
Daniel Sanders9d662d22017-07-06 10:06:12 +00001434 /// Emit MatchTable opcodes to check the shape of the match and capture
1435 /// instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001436 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001437 unsigned InsnID) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001438 Table << MatchTable::Opcode("GIM_CheckNumOperands")
1439 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1440 << MatchTable::Comment("Expected")
1441 << MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001442 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001443 Operand->emitCaptureOpcodes(Table, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001444 }
1445
Daniel Sanders9d662d22017-07-06 10:06:12 +00001446 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001447 /// InsnVarName matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001448 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001449 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001450 emitPredicateListOpcodes(Table, Rule, InsnVarID);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001451 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001452 Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001453 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001454
1455 /// Compare the priority of this object and B.
1456 ///
1457 /// Returns true if this object is more important than B.
1458 bool isHigherPriorityThan(const InstructionMatcher &B) const {
1459 // Instruction matchers involving more operands have higher priority.
1460 if (Operands.size() > B.Operands.size())
1461 return true;
1462 if (Operands.size() < B.Operands.size())
1463 return false;
1464
1465 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1466 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1467 return true;
1468 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1469 return false;
1470 }
1471
1472 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001473 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001474 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001475 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001476 return false;
1477 }
1478
1479 return false;
1480 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001481
1482 /// Report the maximum number of temporary operands needed by the instruction
1483 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001484 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001485 return std::accumulate(predicates().begin(), predicates().end(), 0,
1486 [](unsigned A,
1487 const std::unique_ptr<InstructionPredicateMatcher>
1488 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001489 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001490 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001491 std::accumulate(
1492 Operands.begin(), Operands.end(), 0,
1493 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001494 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001495 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001496 }
Daniel Sanders05540042017-08-08 10:44:31 +00001497
1498 bool isConstantInstruction() const {
1499 for (const auto &P : predicates())
1500 if (const InstructionOpcodeMatcher *Opcode =
1501 dyn_cast<InstructionOpcodeMatcher>(P.get()))
1502 return Opcode->isConstantInstruction();
1503 return false;
1504 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001505};
1506
Daniel Sandersbee57392017-04-04 13:25:23 +00001507/// Generates code to check that the operand is a register defined by an
1508/// instruction that matches the given instruction matcher.
1509///
1510/// For example, the pattern:
1511/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1512/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1513/// the:
1514/// (G_ADD $src1, $src2)
1515/// subpattern.
1516class InstructionOperandMatcher : public OperandPredicateMatcher {
1517protected:
1518 std::unique_ptr<InstructionMatcher> InsnMatcher;
1519
1520public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001521 InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName)
Daniel Sandersbee57392017-04-04 13:25:23 +00001522 : OperandPredicateMatcher(OPM_Instruction),
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001523 InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {}
Daniel Sandersbee57392017-04-04 13:25:23 +00001524
Quentin Colombet063d7982017-12-14 23:44:07 +00001525 static bool classof(const PredicateMatcher *P) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001526 return P->getKind() == OPM_Instruction;
1527 }
1528
1529 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1530
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001531 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001532 unsigned InsnID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001533 unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
1534 InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001535 }
1536
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001537 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001538 unsigned InsnVarID_,
1539 unsigned OpIdx_) const override {
1540 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001541 InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001542 }
1543};
1544
Daniel Sanders43c882c2017-02-01 10:53:10 +00001545//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001546class OperandRenderer {
1547public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001548 enum RendererKind {
1549 OR_Copy,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001550 OR_CopyOrAddZeroReg,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001551 OR_CopySubReg,
Daniel Sanders05540042017-08-08 10:44:31 +00001552 OR_CopyConstantAsImm,
Daniel Sanders11300ce2017-10-13 21:28:03 +00001553 OR_CopyFConstantAsFPImm,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001554 OR_Imm,
1555 OR_Register,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001556 OR_TempRegister,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001557 OR_ComplexPattern
1558 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001559
1560protected:
1561 RendererKind Kind;
1562
1563public:
1564 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1565 virtual ~OperandRenderer() {}
1566
1567 RendererKind getKind() const { return Kind; }
1568
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001569 virtual void emitRenderOpcodes(MatchTable &Table,
1570 RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001571};
1572
1573/// A CopyRenderer emits code to copy a single operand from an existing
1574/// instruction to the one being built.
1575class CopyRenderer : public OperandRenderer {
1576protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001577 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001578 /// The name of the operand.
1579 const StringRef SymbolicName;
1580
1581public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001582 CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
1583 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
Daniel Sanders05540042017-08-08 10:44:31 +00001584 SymbolicName(SymbolicName) {
1585 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1586 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001587
1588 static bool classof(const OperandRenderer *R) {
1589 return R->getKind() == OR_Copy;
1590 }
1591
1592 const StringRef getSymbolicName() const { return SymbolicName; }
1593
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001594 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001595 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001596 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001597 Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
1598 << MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
1599 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1600 << MatchTable::IntValue(Operand.getOperandIndex())
1601 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001602 }
1603};
1604
Daniel Sandersd66e0902017-10-23 18:19:24 +00001605/// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1606/// existing instruction to the one being built. If the operand turns out to be
1607/// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1608class CopyOrAddZeroRegRenderer : public OperandRenderer {
1609protected:
1610 unsigned NewInsnID;
1611 /// The name of the operand.
1612 const StringRef SymbolicName;
1613 const Record *ZeroRegisterDef;
1614
1615public:
1616 CopyOrAddZeroRegRenderer(unsigned NewInsnID,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001617 StringRef SymbolicName, Record *ZeroRegisterDef)
1618 : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
1619 SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
1620 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1621 }
1622
1623 static bool classof(const OperandRenderer *R) {
1624 return R->getKind() == OR_CopyOrAddZeroReg;
1625 }
1626
1627 const StringRef getSymbolicName() const { return SymbolicName; }
1628
1629 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1630 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
1631 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
1632 Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg")
1633 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1634 << MatchTable::Comment("OldInsnID")
1635 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1636 << MatchTable::IntValue(Operand.getOperandIndex())
1637 << MatchTable::NamedValue(
1638 (ZeroRegisterDef->getValue("Namespace")
1639 ? ZeroRegisterDef->getValueAsString("Namespace")
1640 : ""),
1641 ZeroRegisterDef->getName())
1642 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1643 }
1644};
1645
Daniel Sanders05540042017-08-08 10:44:31 +00001646/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1647/// an extended immediate operand.
1648class CopyConstantAsImmRenderer : public OperandRenderer {
1649protected:
1650 unsigned NewInsnID;
1651 /// The name of the operand.
1652 const std::string SymbolicName;
1653 bool Signed;
1654
1655public:
1656 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1657 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
1658 SymbolicName(SymbolicName), Signed(true) {}
1659
1660 static bool classof(const OperandRenderer *R) {
1661 return R->getKind() == OR_CopyConstantAsImm;
1662 }
1663
1664 const StringRef getSymbolicName() const { return SymbolicName; }
1665
1666 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1667 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1668 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1669 Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
1670 : "GIR_CopyConstantAsUImm")
1671 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1672 << MatchTable::Comment("OldInsnID")
1673 << MatchTable::IntValue(OldInsnVarID)
1674 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1675 }
1676};
1677
Daniel Sanders11300ce2017-10-13 21:28:03 +00001678/// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1679/// instruction to an extended immediate operand.
1680class CopyFConstantAsFPImmRenderer : public OperandRenderer {
1681protected:
1682 unsigned NewInsnID;
1683 /// The name of the operand.
1684 const std::string SymbolicName;
1685
1686public:
1687 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1688 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
1689 SymbolicName(SymbolicName) {}
1690
1691 static bool classof(const OperandRenderer *R) {
1692 return R->getKind() == OR_CopyFConstantAsFPImm;
1693 }
1694
1695 const StringRef getSymbolicName() const { return SymbolicName; }
1696
1697 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1698 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1699 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1700 Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
1701 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1702 << MatchTable::Comment("OldInsnID")
1703 << MatchTable::IntValue(OldInsnVarID)
1704 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1705 }
1706};
1707
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001708/// A CopySubRegRenderer emits code to copy a single register operand from an
1709/// existing instruction to the one being built and indicate that only a
1710/// subregister should be copied.
1711class CopySubRegRenderer : public OperandRenderer {
1712protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001713 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001714 /// The name of the operand.
1715 const StringRef SymbolicName;
1716 /// The subregister to extract.
1717 const CodeGenSubRegIndex *SubReg;
1718
1719public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001720 CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
1721 const CodeGenSubRegIndex *SubReg)
1722 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001723 SymbolicName(SymbolicName), SubReg(SubReg) {}
1724
1725 static bool classof(const OperandRenderer *R) {
1726 return R->getKind() == OR_CopySubReg;
1727 }
1728
1729 const StringRef getSymbolicName() const { return SymbolicName; }
1730
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001731 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001732 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001733 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001734 Table << MatchTable::Opcode("GIR_CopySubReg")
1735 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1736 << MatchTable::Comment("OldInsnID")
1737 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1738 << MatchTable::IntValue(Operand.getOperandIndex())
1739 << MatchTable::Comment("SubRegIdx")
1740 << MatchTable::IntValue(SubReg->EnumValue)
1741 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001742 }
1743};
1744
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001745/// Adds a specific physical register to the instruction being built.
1746/// This is typically useful for WZR/XZR on AArch64.
1747class AddRegisterRenderer : public OperandRenderer {
1748protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001749 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001750 const Record *RegisterDef;
1751
1752public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001753 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
1754 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
1755 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001756
1757 static bool classof(const OperandRenderer *R) {
1758 return R->getKind() == OR_Register;
1759 }
1760
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001761 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1762 Table << MatchTable::Opcode("GIR_AddRegister")
1763 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1764 << MatchTable::NamedValue(
1765 (RegisterDef->getValue("Namespace")
1766 ? RegisterDef->getValueAsString("Namespace")
1767 : ""),
1768 RegisterDef->getName())
1769 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001770 }
1771};
1772
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001773/// Adds a specific temporary virtual register to the instruction being built.
1774/// This is used to chain instructions together when emitting multiple
1775/// instructions.
1776class TempRegRenderer : public OperandRenderer {
1777protected:
1778 unsigned InsnID;
1779 unsigned TempRegID;
1780 bool IsDef;
1781
1782public:
1783 TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false)
1784 : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
1785 IsDef(IsDef) {}
1786
1787 static bool classof(const OperandRenderer *R) {
1788 return R->getKind() == OR_TempRegister;
1789 }
1790
1791 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1792 Table << MatchTable::Opcode("GIR_AddTempRegister")
1793 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1794 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
1795 << MatchTable::Comment("TempRegFlags");
1796 if (IsDef)
1797 Table << MatchTable::NamedValue("RegState::Define");
1798 else
1799 Table << MatchTable::IntValue(0);
1800 Table << MatchTable::LineBreak;
1801 }
1802};
1803
Daniel Sanders0ed28822017-04-12 08:23:08 +00001804/// Adds a specific immediate to the instruction being built.
1805class ImmRenderer : public OperandRenderer {
1806protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001807 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001808 int64_t Imm;
1809
1810public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001811 ImmRenderer(unsigned InsnID, int64_t Imm)
1812 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001813
1814 static bool classof(const OperandRenderer *R) {
1815 return R->getKind() == OR_Imm;
1816 }
1817
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001818 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1819 Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
1820 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
1821 << MatchTable::IntValue(Imm) << MatchTable::LineBreak;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001822 }
1823};
1824
Daniel Sanders2deea182017-04-22 15:11:04 +00001825/// Adds operands by calling a renderer function supplied by the ComplexPattern
1826/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001827class RenderComplexPatternOperand : public OperandRenderer {
1828private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001829 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001830 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001831 /// The name of the operand.
1832 const StringRef SymbolicName;
1833 /// The renderer number. This must be unique within a rule since it's used to
1834 /// identify a temporary variable to hold the renderer function.
1835 unsigned RendererID;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001836 /// When provided, this is the suboperand of the ComplexPattern operand to
1837 /// render. Otherwise all the suboperands will be rendered.
1838 Optional<unsigned> SubOperand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001839
1840 unsigned getNumOperands() const {
1841 return TheDef.getValueAsDag("Operands")->getNumArgs();
1842 }
1843
1844public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001845 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001846 StringRef SymbolicName, unsigned RendererID,
1847 Optional<unsigned> SubOperand = None)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001848 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001849 SymbolicName(SymbolicName), RendererID(RendererID),
1850 SubOperand(SubOperand) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001851
1852 static bool classof(const OperandRenderer *R) {
1853 return R->getKind() == OR_ComplexPattern;
1854 }
1855
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001856 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001857 Table << MatchTable::Opcode(SubOperand.hasValue() ? "GIR_ComplexSubOperandRenderer"
1858 : "GIR_ComplexRenderer")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001859 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1860 << MatchTable::Comment("RendererID")
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001861 << MatchTable::IntValue(RendererID);
1862 if (SubOperand.hasValue())
1863 Table << MatchTable::Comment("SubOperand")
1864 << MatchTable::IntValue(SubOperand.getValue());
1865 Table << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001866 }
1867};
1868
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001869/// An action taken when all Matcher predicates succeeded for a parent rule.
1870///
1871/// Typical actions include:
1872/// * Changing the opcode of an instruction.
1873/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001874class MatchAction {
1875public:
1876 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001877
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001878 /// Emit the MatchTable opcodes to implement the action.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001879 virtual void emitActionOpcodes(MatchTable &Table,
1880 RuleMatcher &Rule) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001881};
1882
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001883/// Generates a comment describing the matched rule being acted upon.
1884class DebugCommentAction : public MatchAction {
1885private:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001886 std::string S;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001887
1888public:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001889 DebugCommentAction(StringRef S) : S(S) {}
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001890
Daniel Sandersa7b75262017-10-31 18:50:24 +00001891 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001892 Table << MatchTable::Comment(S) << MatchTable::LineBreak;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001893 }
1894};
1895
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001896/// Generates code to build an instruction or mutate an existing instruction
1897/// into the desired instruction when this is possible.
1898class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001899private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001900 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001901 const CodeGenInstruction *I;
Daniel Sanders64f745c2017-10-24 17:08:43 +00001902 const InstructionMatcher *Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001903 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1904
1905 /// True if the instruction can be built solely by mutating the opcode.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001906 bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const {
1907 if (!Insn)
Daniel Sandersab1d1192017-10-24 18:11:54 +00001908 return false;
1909
Daniel Sandersa7b75262017-10-31 18:50:24 +00001910 if (OperandRenderers.size() != Insn->getNumOperands())
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001911 return false;
1912
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001913 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001914 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001915 const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
Daniel Sandersa7b75262017-10-31 18:50:24 +00001916 if (Insn != &OM.getInstructionMatcher() ||
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001917 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001918 return false;
1919 } else
1920 return false;
1921 }
1922
1923 return true;
1924 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001925
Daniel Sanders43c882c2017-02-01 10:53:10 +00001926public:
Daniel Sandersa7b75262017-10-31 18:50:24 +00001927 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
1928 : InsnID(InsnID), I(I), Matched(nullptr) {}
1929
Daniel Sandersdf258e32017-10-31 19:09:29 +00001930 const CodeGenInstruction *getCGI() const { return I; }
1931
Daniel Sandersa7b75262017-10-31 18:50:24 +00001932 void chooseInsnToMutate(RuleMatcher &Rule) {
1933 for (const auto *MutateCandidate : Rule.mutatable_insns()) {
1934 if (canMutate(Rule, MutateCandidate)) {
1935 // Take the first one we're offered that we're able to mutate.
1936 Rule.reserveInsnMatcherForMutation(MutateCandidate);
1937 Matched = MutateCandidate;
1938 return;
1939 }
1940 }
1941 }
Daniel Sanders43c882c2017-02-01 10:53:10 +00001942
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001943 template <class Kind, class... Args>
1944 Kind &addRenderer(Args&&... args) {
1945 OperandRenderers.emplace_back(
Daniel Sanders198447a2017-11-01 00:29:47 +00001946 llvm::make_unique<Kind>(InsnID, std::forward<Args>(args)...));
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001947 return *static_cast<Kind *>(OperandRenderers.back().get());
1948 }
1949
Daniel Sandersa7b75262017-10-31 18:50:24 +00001950 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1951 if (Matched) {
1952 assert(canMutate(Rule, Matched) &&
1953 "Arranged to mutate an insn that isn't mutatable");
1954
1955 unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001956 Table << MatchTable::Opcode("GIR_MutateOpcode")
1957 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1958 << MatchTable::Comment("RecycleInsnID")
1959 << MatchTable::IntValue(RecycleInsnID)
1960 << MatchTable::Comment("Opcode")
1961 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1962 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001963
1964 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001965 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001966 auto Namespace = Def->getValue("Namespace")
1967 ? Def->getValueAsString("Namespace")
1968 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001969 Table << MatchTable::Opcode("GIR_AddImplicitDef")
1970 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1971 << MatchTable::NamedValue(Namespace, Def->getName())
1972 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001973 }
1974 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001975 auto Namespace = Use->getValue("Namespace")
1976 ? Use->getValueAsString("Namespace")
1977 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001978 Table << MatchTable::Opcode("GIR_AddImplicitUse")
1979 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1980 << MatchTable::NamedValue(Namespace, Use->getName())
1981 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001982 }
1983 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001984 return;
1985 }
1986
1987 // TODO: Simple permutation looks like it could be almost as common as
1988 // mutation due to commutative operations.
1989
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001990 Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
1991 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
1992 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1993 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001994 for (const auto &Renderer : OperandRenderers)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001995 Renderer->emitRenderOpcodes(Table, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001996
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001997 if (I->mayLoad || I->mayStore) {
1998 Table << MatchTable::Opcode("GIR_MergeMemOperands")
1999 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2000 << MatchTable::Comment("MergeInsnID's");
2001 // Emit the ID's for all the instructions that are matched by this rule.
2002 // TODO: Limit this to matched instructions that mayLoad/mayStore or have
2003 // some other means of having a memoperand. Also limit this to
2004 // emitted instructions that expect to have a memoperand too. For
2005 // example, (G_SEXT (G_LOAD x)) that results in separate load and
2006 // sign-extend instructions shouldn't put the memoperand on the
2007 // sign-extend since it has no effect there.
2008 std::vector<unsigned> MergeInsnIDs;
2009 for (const auto &IDMatcherPair : Rule.defined_insn_vars())
2010 MergeInsnIDs.push_back(IDMatcherPair.second);
2011 std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end());
2012 for (const auto &MergeInsnID : MergeInsnIDs)
2013 Table << MatchTable::IntValue(MergeInsnID);
Daniel Sanders05540042017-08-08 10:44:31 +00002014 Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
2015 << MatchTable::LineBreak;
Florian Hahn3bc3ec62017-08-03 14:48:22 +00002016 }
2017
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002018 // FIXME: This is a hack but it's sufficient for ISel. We'll need to do
2019 // better for combines. Particularly when there are multiple match
2020 // roots.
2021 if (InsnID == 0)
2022 Table << MatchTable::Opcode("GIR_EraseFromParent")
2023 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2024 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002025 }
2026};
2027
2028/// Generates code to constrain the operands of an output instruction to the
2029/// register classes specified by the definition of that instruction.
2030class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002031 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002032
2033public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002034 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002035
Daniel Sandersa7b75262017-10-31 18:50:24 +00002036 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002037 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2038 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2039 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002040 }
2041};
2042
2043/// Generates code to constrain the specified operand of an output instruction
2044/// to the specified register class.
2045class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002046 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002047 unsigned OpIdx;
2048 const CodeGenRegisterClass &RC;
2049
2050public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002051 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002052 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002053 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002054
Daniel Sandersa7b75262017-10-31 18:50:24 +00002055 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002056 Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
2057 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2058 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
2059 << MatchTable::Comment("RC " + RC.getName())
2060 << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002061 }
2062};
2063
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002064/// Generates code to create a temporary register which can be used to chain
2065/// instructions together.
2066class MakeTempRegisterAction : public MatchAction {
2067private:
2068 LLTCodeGen Ty;
2069 unsigned TempRegID;
2070
2071public:
2072 MakeTempRegisterAction(const LLTCodeGen &Ty, unsigned TempRegID)
2073 : Ty(Ty), TempRegID(TempRegID) {}
2074
2075 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2076 Table << MatchTable::Opcode("GIR_MakeTempReg")
2077 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
2078 << MatchTable::Comment("TypeID")
2079 << MatchTable::NamedValue(Ty.getCxxEnumValue())
2080 << MatchTable::LineBreak;
2081 }
2082};
2083
Daniel Sanders05540042017-08-08 10:44:31 +00002084InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002085 Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
Daniel Sandersa7b75262017-10-31 18:50:24 +00002086 MutatableInsns.insert(Matchers.back().get());
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002087 return *Matchers.back();
2088}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00002089
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002090void RuleMatcher::addRequiredFeature(Record *Feature) {
2091 RequiredFeatures.push_back(Feature);
2092}
2093
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002094const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
2095 return RequiredFeatures;
2096}
2097
Daniel Sanders7438b262017-10-31 23:03:18 +00002098// Emplaces an action of the specified Kind at the end of the action list.
2099//
2100// Returns a reference to the newly created action.
2101//
2102// Like std::vector::emplace_back(), may invalidate all iterators if the new
2103// size exceeds the capacity. Otherwise, only invalidates the past-the-end
2104// iterator.
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002105template <class Kind, class... Args>
2106Kind &RuleMatcher::addAction(Args &&... args) {
2107 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
2108 return *static_cast<Kind *>(Actions.back().get());
2109}
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002110
Daniel Sanders7438b262017-10-31 23:03:18 +00002111// Emplaces an action of the specified Kind before the given insertion point.
2112//
2113// Returns an iterator pointing at the newly created instruction.
2114//
2115// Like std::vector::insert(), may invalidate all iterators if the new size
2116// exceeds the capacity. Otherwise, only invalidates the iterators from the
2117// insertion point onwards.
2118template <class Kind, class... Args>
2119action_iterator RuleMatcher::insertAction(action_iterator InsertPt,
2120 Args &&... args) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002121 return Actions.emplace(InsertPt,
2122 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sanders7438b262017-10-31 23:03:18 +00002123}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002124
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002125unsigned
2126RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
2127 unsigned NewInsnVarID = NextInsnVarID++;
2128 InsnVariableIDs[&Matcher] = NewInsnVarID;
2129 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002130}
2131
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002132unsigned RuleMatcher::defineInsnVar(MatchTable &Table,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002133 const InstructionMatcher &Matcher,
2134 unsigned InsnID, unsigned OpIdx) {
2135 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002136 Table << MatchTable::Opcode("GIM_RecordInsn")
2137 << MatchTable::Comment("DefineMI") << MatchTable::IntValue(NewInsnVarID)
2138 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
2139 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2140 << MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
2141 << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002142 return NewInsnVarID;
2143}
2144
2145unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
2146 const auto &I = InsnVariableIDs.find(&InsnMatcher);
2147 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002148 return I->second;
2149 llvm_unreachable("Matched Insn was not captured in a local variable");
2150}
2151
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002152void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
2153 if (DefinedOperands.find(SymbolicName) == DefinedOperands.end()) {
2154 DefinedOperands[SymbolicName] = &OM;
2155 return;
2156 }
2157
2158 // If the operand is already defined, then we must ensure both references in
2159 // the matcher have the exact same node.
2160 OM.addPredicate<SameOperandMatcher>(OM.getSymbolicName());
2161}
2162
Daniel Sanders05540042017-08-08 10:44:31 +00002163const InstructionMatcher &
2164RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
2165 for (const auto &I : InsnVariableIDs)
2166 if (I.first->getSymbolicName() == SymbolicName)
2167 return *I.first;
2168 llvm_unreachable(
2169 ("Failed to lookup instruction " + SymbolicName).str().c_str());
2170}
2171
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002172const OperandMatcher &
2173RuleMatcher::getOperandMatcher(StringRef Name) const {
2174 const auto &I = DefinedOperands.find(Name);
2175
2176 if (I == DefinedOperands.end())
2177 PrintFatalError(SrcLoc, "Operand " + Name + " was not declared in matcher");
2178
2179 return *I->second;
2180}
2181
Daniel Sanders9d662d22017-07-06 10:06:12 +00002182/// Emit MatchTable opcodes to check the shape of the match and capture
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002183/// instructions into local variables.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002184void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002185 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002186 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002187 Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002188}
2189
Daniel Sanders8e82af22017-07-27 11:03:45 +00002190void RuleMatcher::emit(MatchTable &Table) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002191 if (Matchers.empty())
2192 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002193
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002194 // The representation supports rules that require multiple roots such as:
2195 // %ptr(p0) = ...
2196 // %elt0(s32) = G_LOAD %ptr
2197 // %1(p0) = G_ADD %ptr, 4
2198 // %elt1(s32) = G_LOAD p0 %1
2199 // which could be usefully folded into:
2200 // %ptr(p0) = ...
2201 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
2202 // on some targets but we don't need to make use of that yet.
2203 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002204
Daniel Sanders8e82af22017-07-27 11:03:45 +00002205 unsigned LabelID = Table.allocateLabelID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002206 Table << MatchTable::Opcode("GIM_Try", +1)
Daniel Sanders8e82af22017-07-27 11:03:45 +00002207 << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(LabelID)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002208 << MatchTable::LineBreak;
2209
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002210 if (!RequiredFeatures.empty()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002211 Table << MatchTable::Opcode("GIM_CheckFeatures")
2212 << MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
2213 << MatchTable::LineBreak;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002214 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002215
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002216 emitCaptureOpcodes(Table);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002217
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002218 Matchers.front()->emitPredicateOpcodes(Table, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002219 getInsnVarID(*Matchers.front()));
2220
Daniel Sandersbee57392017-04-04 13:25:23 +00002221 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002222 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00002223 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002224 SmallVector<unsigned, 2> InsnIDs;
2225 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002226 // Skip the root node since it isn't moving anywhere. Everything else is
2227 // sinking to meet it.
2228 if (Pair.first == Matchers.front().get())
2229 continue;
2230
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002231 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00002232 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002233 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00002234
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002235 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002236 // Reject the difficult cases until we have a more accurate check.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002237 Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
2238 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2239 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00002240
2241 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
2242 // account for unsafe cases.
2243 //
2244 // Example:
2245 // MI1--> %0 = ...
2246 // %1 = ... %0
2247 // MI0--> %2 = ... %0
2248 // It's not safe to erase MI1. We currently handle this by not
2249 // erasing %0 (even when it's dead).
2250 //
2251 // Example:
2252 // MI1--> %0 = load volatile @a
2253 // %1 = load volatile @a
2254 // MI0--> %2 = ... %0
2255 // It's not safe to sink %0's def past %1. We currently handle
2256 // this by rejecting all loads.
2257 //
2258 // Example:
2259 // MI1--> %0 = load @a
2260 // %1 = store @a
2261 // MI0--> %2 = ... %0
2262 // It's not safe to sink %0's def past %1. We currently handle
2263 // this by rejecting all loads.
2264 //
2265 // Example:
2266 // G_CONDBR %cond, @BB1
2267 // BB0:
2268 // MI1--> %0 = load @a
2269 // G_BR @BB1
2270 // BB1:
2271 // MI0--> %2 = ... %0
2272 // It's not always safe to sink %0 across control flow. In this
2273 // case it may introduce a memory fault. We currentl handle this
2274 // by rejecting all loads.
2275 }
2276 }
2277
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002278 for (const auto &MA : Actions)
Daniel Sandersa7b75262017-10-31 18:50:24 +00002279 MA->emitActionOpcodes(Table, *this);
Daniel Sandersf76f3152017-11-16 00:46:35 +00002280
2281 if (GenerateCoverage)
2282 Table << MatchTable::Opcode("GIR_Coverage") << MatchTable::IntValue(RuleID)
2283 << MatchTable::LineBreak;
2284
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002285 Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
Daniel Sanders8e82af22017-07-27 11:03:45 +00002286 << MatchTable::Label(LabelID);
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002287}
Daniel Sanders43c882c2017-02-01 10:53:10 +00002288
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002289bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
2290 // Rules involving more match roots have higher priority.
2291 if (Matchers.size() > B.Matchers.size())
2292 return true;
2293 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00002294 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002295
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002296 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
2297 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
2298 return true;
2299 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
2300 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002301 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002302
2303 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00002304}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002305
Daniel Sanders2deea182017-04-22 15:11:04 +00002306unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002307 return std::accumulate(
2308 Matchers.begin(), Matchers.end(), 0,
2309 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00002310 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002311 });
2312}
2313
Daniel Sanders05540042017-08-08 10:44:31 +00002314bool OperandPredicateMatcher::isHigherPriorityThan(
2315 const OperandPredicateMatcher &B) const {
2316 // Generally speaking, an instruction is more important than an Int or a
2317 // LiteralInt because it can cover more nodes but theres an exception to
2318 // this. G_CONSTANT's are less important than either of those two because they
2319 // are more permissive.
Daniel Sandersedd07842017-08-17 09:26:14 +00002320
2321 const InstructionOperandMatcher *AOM =
2322 dyn_cast<InstructionOperandMatcher>(this);
2323 const InstructionOperandMatcher *BOM =
2324 dyn_cast<InstructionOperandMatcher>(&B);
2325 bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
2326 bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
2327
2328 if (AOM && BOM) {
2329 // The relative priorities between a G_CONSTANT and any other instruction
2330 // don't actually matter but this code is needed to ensure a strict weak
2331 // ordering. This is particularly important on Windows where the rules will
2332 // be incorrectly sorted without it.
2333 if (AIsConstantInsn != BIsConstantInsn)
2334 return AIsConstantInsn < BIsConstantInsn;
2335 return false;
Daniel Sanders05540042017-08-08 10:44:31 +00002336 }
Daniel Sandersedd07842017-08-17 09:26:14 +00002337
2338 if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
2339 return false;
2340 if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
2341 return true;
Daniel Sanders05540042017-08-08 10:44:31 +00002342
2343 return Kind < B.Kind;
Daniel Sanders75b84fc2017-08-08 13:21:26 +00002344}
Daniel Sanders05540042017-08-08 10:44:31 +00002345
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002346void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
2347 RuleMatcher &Rule,
2348 unsigned InsnVarID,
2349 unsigned OpIdx) const {
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002350 const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002351 unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
2352
2353 Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
2354 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
2355 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2356 << MatchTable::Comment("OtherMI")
2357 << MatchTable::IntValue(OtherInsnVarID)
2358 << MatchTable::Comment("OtherOpIdx")
2359 << MatchTable::IntValue(OtherOM.getOperandIndex())
2360 << MatchTable::LineBreak;
2361}
2362
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002363//===- GlobalISelEmitter class --------------------------------------------===//
2364
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002365class GlobalISelEmitter {
2366public:
2367 explicit GlobalISelEmitter(RecordKeeper &RK);
2368 void run(raw_ostream &OS);
2369
2370private:
2371 const RecordKeeper &RK;
2372 const CodeGenDAGPatterns CGP;
2373 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002374 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002375
Daniel Sanders39690bd2017-10-15 02:41:12 +00002376 /// Keep track of the equivalence between SDNodes and Instruction by mapping
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00002377 /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
2378 /// check for attributes on the relation such as CheckMMOIsNonAtomic.
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002379 /// This is defined using 'GINodeEquiv' in the target description.
Daniel Sanders39690bd2017-10-15 02:41:12 +00002380 DenseMap<Record *, Record *> NodeEquivs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002381
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002382 /// Keep track of the equivalence between ComplexPattern's and
2383 /// GIComplexOperandMatcher. Map entries are specified by subclassing
2384 /// GIComplexPatternEquiv.
2385 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
2386
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002387 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002388 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002389
Daniel Sandersf76f3152017-11-16 00:46:35 +00002390 // Rule coverage information.
2391 Optional<CodeGenCoverage> RuleCoverage;
2392
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002393 void gatherNodeEquivs();
Daniel Sanders39690bd2017-10-15 02:41:12 +00002394 Record *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002395
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002396 Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002397 Expected<InstructionMatcher &> createAndImportSelDAGMatcher(
2398 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2399 const TreePatternNode *Src, unsigned &TempOpIdx) const;
2400 Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
2401 unsigned &TempOpIdx) const;
2402 Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002403 const TreePatternNode *SrcChild,
2404 bool OperandIsAPointer, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00002405 unsigned &TempOpIdx) const;
Daniel Sandersdf258e32017-10-31 19:09:29 +00002406
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002407 Expected<BuildMIAction &>
Daniel Sandersa7b75262017-10-31 18:50:24 +00002408 createAndImportInstructionRenderer(RuleMatcher &M,
2409 const TreePatternNode *Dst);
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002410 Expected<action_iterator> createAndImportSubInstructionRenderer(
2411 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
2412 unsigned TempReg);
Daniel Sanders7438b262017-10-31 23:03:18 +00002413 Expected<action_iterator>
2414 createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
2415 const TreePatternNode *Dst);
Daniel Sandersdf258e32017-10-31 19:09:29 +00002416 void importExplicitDefRenderers(BuildMIAction &DstMIBuilder);
Daniel Sanders7438b262017-10-31 23:03:18 +00002417 Expected<action_iterator>
2418 importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M,
2419 BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00002420 const llvm::TreePatternNode *Dst);
Daniel Sanders7438b262017-10-31 23:03:18 +00002421 Expected<action_iterator>
2422 importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
2423 BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002424 TreePatternNode *DstChild);
Diana Picus382602f2017-05-17 08:57:28 +00002425 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
2426 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00002427 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002428 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
2429 const std::vector<Record *> &ImplicitDefs) const;
2430
Daniel Sanders11300ce2017-10-13 21:28:03 +00002431 void emitImmPredicates(raw_ostream &OS, StringRef TypeIdentifier,
2432 StringRef Type,
Daniel Sanders649c5852017-10-13 20:42:18 +00002433 std::function<bool(const Record *R)> Filter);
2434
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002435 /// Analyze pattern \p P, returning a matcher for it if possible.
2436 /// Otherwise, return an Error explaining why we don't support it.
2437 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002438
2439 void declareSubtargetFeature(Record *Predicate);
Daniel Sanders7e523672017-11-11 03:23:44 +00002440
2441 TreePatternNode *fixupPatternNode(TreePatternNode *N);
2442 void fixupPatternTrees(TreePattern *P);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002443};
2444
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002445void GlobalISelEmitter::gatherNodeEquivs() {
2446 assert(NodeEquivs.empty());
2447 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
Daniel Sanders39690bd2017-10-15 02:41:12 +00002448 NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002449
2450 assert(ComplexPatternEquivs.empty());
2451 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
2452 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
2453 if (!SelDAGEquiv)
2454 continue;
2455 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
2456 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002457}
2458
Daniel Sanders39690bd2017-10-15 02:41:12 +00002459Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002460 return NodeEquivs.lookup(N);
2461}
2462
2463GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Daniel Sanders7e523672017-11-11 03:23:44 +00002464 : RK(RK), CGP(RK, [&](TreePattern *P) { fixupPatternTrees(P); }),
2465 Target(CGP.getTargetInfo()), CGRegs(RK, Target.getHwModes()) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002466
2467//===- Emitter ------------------------------------------------------------===//
2468
Daniel Sandersc270c502017-03-30 09:36:33 +00002469Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002470GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002471 ArrayRef<Predicate> Predicates) {
2472 for (const Predicate &P : Predicates) {
2473 if (!P.Def)
2474 continue;
2475 declareSubtargetFeature(P.Def);
2476 M.addRequiredFeature(P.Def);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002477 }
2478
Daniel Sandersc270c502017-03-30 09:36:33 +00002479 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002480}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002481
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00002482Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
2483 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2484 const TreePatternNode *Src, unsigned &TempOpIdx) const {
2485 Record *SrcGIEquivOrNull = nullptr;
2486 const CodeGenInstruction *SrcGIOrNull = nullptr;
2487
2488 // Start with the defined operands (i.e., the results of the root operator).
2489 if (Src->getExtTypes().size() > 1)
2490 return failedImport("Src pattern has multiple results");
2491
2492 if (Src->isLeaf()) {
2493 Init *SrcInit = Src->getLeafValue();
2494 if (isa<IntInit>(SrcInit)) {
2495 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
2496 &Target.getInstruction(RK.getDef("G_CONSTANT")));
2497 } else
2498 return failedImport(
2499 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
2500 } else {
2501 SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
2502 if (!SrcGIEquivOrNull)
2503 return failedImport("Pattern operator lacks an equivalent Instruction" +
2504 explainOperator(Src->getOperator()));
2505 SrcGIOrNull = &Target.getInstruction(SrcGIEquivOrNull->getValueAsDef("I"));
2506
2507 // The operators look good: match the opcode
2508 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
2509 }
2510
2511 unsigned OpIdx = 0;
2512 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
2513 // Results don't have a name unless they are the root node. The caller will
2514 // set the name if appropriate.
2515 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2516 if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
2517 return failedImport(toString(std::move(Error)) +
2518 " for result of Src pattern operator");
2519 }
2520
Daniel Sanders2c269f62017-08-24 09:11:20 +00002521 for (const auto &Predicate : Src->getPredicateFns()) {
2522 if (Predicate.isAlwaysTrue())
2523 continue;
2524
2525 if (Predicate.isImmediatePattern()) {
2526 InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
2527 continue;
2528 }
2529
Daniel Sandersa71f4542017-10-16 00:56:30 +00002530 // No check required. G_LOAD by itself is a non-extending load.
2531 if (Predicate.isNonExtLoad())
2532 continue;
2533
Daniel Sandersd66e0902017-10-23 18:19:24 +00002534 // No check required. G_STORE by itself is a non-extending store.
2535 if (Predicate.isNonTruncStore())
2536 continue;
2537
Daniel Sanders76664652017-11-28 22:07:05 +00002538 if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
2539 if (Predicate.getMemoryVT() != nullptr) {
2540 Optional<LLTCodeGen> MemTyOrNone =
2541 MVTToLLT(getValueType(Predicate.getMemoryVT()));
Daniel Sandersd66e0902017-10-23 18:19:24 +00002542
Daniel Sanders76664652017-11-28 22:07:05 +00002543 if (!MemTyOrNone)
2544 return failedImport("MemVT could not be converted to LLT");
Daniel Sandersd66e0902017-10-23 18:19:24 +00002545
Daniel Sanders76664652017-11-28 22:07:05 +00002546 InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(
2547 MemTyOrNone.getValue());
2548 continue;
2549 }
2550 }
2551
2552 if (Predicate.isLoad() || Predicate.isStore()) {
2553 // No check required. A G_LOAD/G_STORE is an unindexed load.
2554 if (Predicate.isUnindexed())
2555 continue;
2556 }
2557
2558 if (Predicate.isAtomic()) {
2559 if (Predicate.isAtomicOrderingMonotonic()) {
2560 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2561 "Monotonic");
2562 continue;
2563 }
2564 if (Predicate.isAtomicOrderingAcquire()) {
2565 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
2566 continue;
2567 }
2568 if (Predicate.isAtomicOrderingRelease()) {
2569 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
2570 continue;
2571 }
2572 if (Predicate.isAtomicOrderingAcquireRelease()) {
2573 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2574 "AcquireRelease");
2575 continue;
2576 }
2577 if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
2578 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2579 "SequentiallyConsistent");
2580 continue;
2581 }
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00002582
2583 if (Predicate.isAtomicOrderingAcquireOrStronger()) {
2584 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2585 "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
2586 continue;
2587 }
2588 if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
2589 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2590 "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
2591 continue;
2592 }
2593
2594 if (Predicate.isAtomicOrderingReleaseOrStronger()) {
2595 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2596 "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
2597 continue;
2598 }
2599 if (Predicate.isAtomicOrderingWeakerThanRelease()) {
2600 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2601 "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
2602 continue;
2603 }
Daniel Sandersd66e0902017-10-23 18:19:24 +00002604 }
2605
Daniel Sanders2c269f62017-08-24 09:11:20 +00002606 return failedImport("Src pattern child has predicate (" +
2607 explainPredicates(Src) + ")");
2608 }
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00002609 if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
2610 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
Daniel Sanders2c269f62017-08-24 09:11:20 +00002611
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002612 if (Src->isLeaf()) {
2613 Init *SrcInit = Src->getLeafValue();
2614 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002615 OperandMatcher &OM =
2616 InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002617 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
2618 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002619 return failedImport(
2620 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002621 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002622 assert(SrcGIOrNull &&
2623 "Expected to have already found an equivalent Instruction");
Daniel Sanders11300ce2017-10-13 21:28:03 +00002624 if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
2625 SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
2626 // imm/fpimm still have operands but we don't need to do anything with it
Daniel Sanders05540042017-08-08 10:44:31 +00002627 // here since we don't support ImmLeaf predicates yet. However, we still
2628 // need to note the hidden operand to get GIM_CheckNumOperands correct.
2629 InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2630 return InsnMatcher;
2631 }
2632
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002633 // Match the used operands (i.e. the children of the operator).
2634 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002635 TreePatternNode *SrcChild = Src->getChild(i);
2636
Daniel Sandersa71f4542017-10-16 00:56:30 +00002637 // SelectionDAG allows pointers to be represented with iN since it doesn't
2638 // distinguish between pointers and integers but they are different types in GlobalISel.
2639 // Coerce integers to pointers to address space 0 if the context indicates a pointer.
Daniel Sandersc54aa9c2017-11-18 00:16:44 +00002640 bool OperandIsAPointer = SrcGIOrNull->isOperandAPointer(i);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002641
Daniel Sanders28887fe2017-09-19 12:56:36 +00002642 // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
2643 // following the defs is an intrinsic ID.
2644 if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
2645 SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
2646 i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002647 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002648 OperandMatcher &OM =
2649 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002650 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00002651 continue;
2652 }
2653
2654 return failedImport("Expected IntInit containing instrinsic ID)");
2655 }
2656
Daniel Sandersa71f4542017-10-16 00:56:30 +00002657 if (auto Error =
2658 importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
2659 OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002660 return std::move(Error);
2661 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002662 }
2663
2664 return InsnMatcher;
2665}
2666
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002667Error GlobalISelEmitter::importComplexPatternOperandMatcher(
2668 OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
2669 const auto &ComplexPattern = ComplexPatternEquivs.find(R);
2670 if (ComplexPattern == ComplexPatternEquivs.end())
2671 return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
2672 ") not mapped to GlobalISel");
2673
2674 OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
2675 TempOpIdx++;
2676 return Error::success();
2677}
2678
2679Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
2680 InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002681 const TreePatternNode *SrcChild,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002682 bool OperandIsAPointer,
Daniel Sandersc270c502017-03-30 09:36:33 +00002683 unsigned OpIdx,
2684 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002685 OperandMatcher &OM =
2686 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002687 if (OM.isSameAsAnotherOperand())
2688 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002689
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002690 ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002691 if (ChildTypes.size() != 1)
2692 return failedImport("Src pattern child has multiple results");
2693
2694 // Check MBB's before the type check since they are not a known type.
2695 if (!SrcChild->isLeaf()) {
2696 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
2697 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
2698 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
2699 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00002700 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002701 }
2702 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002703 }
2704
Daniel Sandersa71f4542017-10-16 00:56:30 +00002705 if (auto Error =
2706 OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
2707 return failedImport(toString(std::move(Error)) + " for Src operand (" +
2708 to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002709
Daniel Sandersbee57392017-04-04 13:25:23 +00002710 // Check for nested instructions.
2711 if (!SrcChild->isLeaf()) {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002712 if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
2713 // When a ComplexPattern is used as an operator, it should do the same
2714 // thing as when used as a leaf. However, the children of the operator
2715 // name the sub-operands that make up the complex operand and we must
2716 // prepare to reference them in the renderer too.
2717 unsigned RendererID = TempOpIdx;
2718 if (auto Error = importComplexPatternOperandMatcher(
2719 OM, SrcChild->getOperator(), TempOpIdx))
2720 return Error;
2721
2722 for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
2723 auto *SubOperand = SrcChild->getChild(i);
2724 if (!SubOperand->getName().empty())
2725 Rule.defineComplexSubOperand(SubOperand->getName(),
2726 SrcChild->getOperator(), RendererID, i);
2727 }
2728
2729 return Error::success();
2730 }
2731
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002732 auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
2733 InsnMatcher.getRuleMatcher(), SrcChild->getName());
2734 if (!MaybeInsnOperand.hasValue()) {
2735 // This isn't strictly true. If the user were to provide exactly the same
2736 // matchers as the original operand then we could allow it. However, it's
2737 // simpler to not permit the redundant specification.
2738 return failedImport("Nested instruction cannot be the same as another operand");
2739 }
2740
Daniel Sandersbee57392017-04-04 13:25:23 +00002741 // Map the node to a gMIR instruction.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002742 InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
Daniel Sanders57938df2017-07-11 10:40:18 +00002743 auto InsnMatcherOrError = createAndImportSelDAGMatcher(
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002744 Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00002745 if (auto Error = InsnMatcherOrError.takeError())
2746 return Error;
2747
2748 return Error::success();
2749 }
2750
Diana Picusd1b61812017-11-03 10:30:19 +00002751 if (SrcChild->hasAnyPredicate())
2752 return failedImport("Src pattern child has unsupported predicate");
2753
Daniel Sandersffc7d582017-03-29 15:37:18 +00002754 // Check for constant immediates.
2755 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002756 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00002757 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002758 }
2759
2760 // Check for def's like register classes or ComplexPattern's.
2761 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
2762 auto *ChildRec = ChildDefInit->getDef();
2763
2764 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002765 if (ChildRec->isSubClassOf("RegisterClass") ||
2766 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002767 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002768 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00002769 return Error::success();
2770 }
2771
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002772 // Check for ValueType.
2773 if (ChildRec->isSubClassOf("ValueType")) {
2774 // We already added a type check as standard practice so this doesn't need
2775 // to do anything.
2776 return Error::success();
2777 }
2778
Daniel Sandersffc7d582017-03-29 15:37:18 +00002779 // Check for ComplexPattern's.
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002780 if (ChildRec->isSubClassOf("ComplexPattern"))
2781 return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002782
Daniel Sandersd0656a32017-04-13 09:45:37 +00002783 if (ChildRec->isSubClassOf("ImmLeaf")) {
2784 return failedImport(
2785 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
2786 }
2787
Daniel Sandersffc7d582017-03-29 15:37:18 +00002788 return failedImport(
2789 "Src pattern child def is an unsupported tablegen class");
2790 }
2791
2792 return failedImport("Src pattern child is an unsupported kind");
2793}
2794
Daniel Sanders7438b262017-10-31 23:03:18 +00002795Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
2796 action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002797 TreePatternNode *DstChild) {
Daniel Sanders2c269f62017-08-24 09:11:20 +00002798 if (DstChild->getTransformFn() != nullptr) {
2799 return failedImport("Dst pattern child has transform fn " +
2800 DstChild->getTransformFn()->getName());
2801 }
2802
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002803 const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
2804 if (SubOperand.hasValue()) {
2805 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002806 *std::get<0>(*SubOperand), DstChild->getName(),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002807 std::get<1>(*SubOperand), std::get<2>(*SubOperand));
Daniel Sanders7438b262017-10-31 23:03:18 +00002808 return InsertPt;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002809 }
2810
Daniel Sandersffc7d582017-03-29 15:37:18 +00002811 if (!DstChild->isLeaf()) {
Daniel Sanders05540042017-08-08 10:44:31 +00002812 // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
2813 // inline, but in MI it's just another operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002814 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
2815 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
2816 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sanders198447a2017-11-01 00:29:47 +00002817 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002818 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002819 }
2820 }
Daniel Sanders05540042017-08-08 10:44:31 +00002821
2822 // Similarly, imm is an operator in TreePatternNode's view but must be
2823 // rendered as operands.
2824 // FIXME: The target should be able to choose sign-extended when appropriate
2825 // (e.g. on Mips).
2826 if (DstChild->getOperator()->getName() == "imm") {
Daniel Sanders198447a2017-11-01 00:29:47 +00002827 DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002828 return InsertPt;
Daniel Sanders11300ce2017-10-13 21:28:03 +00002829 } else if (DstChild->getOperator()->getName() == "fpimm") {
2830 DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002831 DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002832 return InsertPt;
Daniel Sanders05540042017-08-08 10:44:31 +00002833 }
2834
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002835 if (DstChild->getOperator()->isSubClassOf("Instruction")) {
2836 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
2837 if (ChildTypes.size() != 1)
2838 return failedImport("Dst pattern child has multiple results");
2839
2840 Optional<LLTCodeGen> OpTyOrNone = None;
2841 if (ChildTypes.front().isMachineValueType())
2842 OpTyOrNone =
2843 MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
2844 if (!OpTyOrNone)
2845 return failedImport("Dst operand has an unsupported type");
2846
2847 unsigned TempRegID = Rule.allocateTempRegID();
2848 InsertPt = Rule.insertAction<MakeTempRegisterAction>(
2849 InsertPt, OpTyOrNone.getValue(), TempRegID);
2850 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
2851
2852 auto InsertPtOrError = createAndImportSubInstructionRenderer(
2853 ++InsertPt, Rule, DstChild, TempRegID);
2854 if (auto Error = InsertPtOrError.takeError())
2855 return std::move(Error);
2856 return InsertPtOrError.get();
2857 }
2858
Daniel Sanders2c269f62017-08-24 09:11:20 +00002859 return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002860 }
2861
Daniel Sandersf499b2b2017-11-30 18:48:35 +00002862 // It could be a specific immediate in which case we should just check for
2863 // that immediate.
2864 if (const IntInit *ChildIntInit =
2865 dyn_cast<IntInit>(DstChild->getLeafValue())) {
2866 DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue());
2867 return InsertPt;
2868 }
2869
Daniel Sandersffc7d582017-03-29 15:37:18 +00002870 // Otherwise, we're looking for a bog-standard RegisterClass operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002871 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
2872 auto *ChildRec = ChildDefInit->getDef();
2873
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002874 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002875 if (ChildTypes.size() != 1)
2876 return failedImport("Dst pattern child has multiple results");
2877
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002878 Optional<LLTCodeGen> OpTyOrNone = None;
2879 if (ChildTypes.front().isMachineValueType())
2880 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002881 if (!OpTyOrNone)
2882 return failedImport("Dst operand has an unsupported type");
2883
2884 if (ChildRec->isSubClassOf("Register")) {
Daniel Sanders198447a2017-11-01 00:29:47 +00002885 DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
Daniel Sanders7438b262017-10-31 23:03:18 +00002886 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002887 }
2888
Daniel Sanders658541f2017-04-22 15:53:21 +00002889 if (ChildRec->isSubClassOf("RegisterClass") ||
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002890 ChildRec->isSubClassOf("RegisterOperand") ||
2891 ChildRec->isSubClassOf("ValueType")) {
Daniel Sandersd66e0902017-10-23 18:19:24 +00002892 if (ChildRec->isSubClassOf("RegisterOperand") &&
2893 !ChildRec->isValueUnset("GIZeroRegister")) {
2894 DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002895 DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
Daniel Sanders7438b262017-10-31 23:03:18 +00002896 return InsertPt;
Daniel Sandersd66e0902017-10-23 18:19:24 +00002897 }
2898
Daniel Sanders198447a2017-11-01 00:29:47 +00002899 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002900 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002901 }
2902
2903 if (ChildRec->isSubClassOf("ComplexPattern")) {
2904 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
2905 if (ComplexPattern == ComplexPatternEquivs.end())
2906 return failedImport(
2907 "SelectionDAG ComplexPattern not mapped to GlobalISel");
2908
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002909 const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002910 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002911 *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00002912 OM.getAllocatedTemporariesBaseID());
Daniel Sanders7438b262017-10-31 23:03:18 +00002913 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002914 }
2915
Daniel Sandersd0656a32017-04-13 09:45:37 +00002916 if (ChildRec->isSubClassOf("SDNodeXForm"))
2917 return failedImport("Dst pattern child def is an unsupported tablegen "
2918 "class (SDNodeXForm)");
2919
Daniel Sandersffc7d582017-03-29 15:37:18 +00002920 return failedImport(
2921 "Dst pattern child def is an unsupported tablegen class");
2922 }
2923
2924 return failedImport("Dst pattern child is an unsupported kind");
2925}
2926
Daniel Sandersc270c502017-03-30 09:36:33 +00002927Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersa7b75262017-10-31 18:50:24 +00002928 RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sanders7438b262017-10-31 23:03:18 +00002929 auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
2930 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00002931 return std::move(Error);
2932
Daniel Sanders7438b262017-10-31 23:03:18 +00002933 action_iterator InsertPt = InsertPtOrError.get();
2934 BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
Daniel Sandersdf258e32017-10-31 19:09:29 +00002935
2936 importExplicitDefRenderers(DstMIBuilder);
2937
Daniel Sanders7438b262017-10-31 23:03:18 +00002938 if (auto Error = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst)
2939 .takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00002940 return std::move(Error);
2941
2942 return DstMIBuilder;
2943}
2944
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002945Expected<action_iterator>
2946GlobalISelEmitter::createAndImportSubInstructionRenderer(
2947 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
2948 unsigned TempRegID) {
2949 auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
2950
2951 // TODO: Assert there's exactly one result.
2952
2953 if (auto Error = InsertPtOrError.takeError())
2954 return std::move(Error);
2955 InsertPt = InsertPtOrError.get();
2956
2957 BuildMIAction &DstMIBuilder =
2958 *static_cast<BuildMIAction *>(InsertPtOrError.get()->get());
2959
2960 // Assign the result to TempReg.
2961 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);
2962
2963 InsertPtOrError = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst);
2964 if (auto Error = InsertPtOrError.takeError())
2965 return std::move(Error);
2966
2967 return InsertPtOrError.get();
2968}
2969
Daniel Sanders7438b262017-10-31 23:03:18 +00002970Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
2971 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002972 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00002973 if (!DstOp->isSubClassOf("Instruction")) {
2974 if (DstOp->isSubClassOf("ValueType"))
2975 return failedImport(
2976 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002977 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00002978 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002979 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002980
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002981 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002982 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersdf258e32017-10-31 19:09:29 +00002983 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS")
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002984 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sandersdf258e32017-10-31 19:09:29 +00002985 else if (DstI->TheDef->getName() == "EXTRACT_SUBREG")
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002986 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002987 else if (DstI->TheDef->getName() == "REG_SEQUENCE")
2988 return failedImport("Unable to emit REG_SEQUENCE");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002989
Daniel Sanders198447a2017-11-01 00:29:47 +00002990 return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),
2991 DstI);
Daniel Sandersdf258e32017-10-31 19:09:29 +00002992}
2993
2994void GlobalISelEmitter::importExplicitDefRenderers(
2995 BuildMIAction &DstMIBuilder) {
2996 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002997 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
2998 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sanders198447a2017-11-01 00:29:47 +00002999 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003000 }
Daniel Sandersdf258e32017-10-31 19:09:29 +00003001}
3002
Daniel Sanders7438b262017-10-31 23:03:18 +00003003Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
3004 action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00003005 const llvm::TreePatternNode *Dst) {
3006 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
3007 CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
Daniel Sandersffc7d582017-03-29 15:37:18 +00003008
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003009 // EXTRACT_SUBREG needs to use a subregister COPY.
Daniel Sandersdf258e32017-10-31 19:09:29 +00003010 if (OrigDstI->TheDef->getName() == "EXTRACT_SUBREG") {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003011 if (!Dst->getChild(0)->isLeaf())
3012 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
3013
Daniel Sanders32291982017-06-28 13:50:04 +00003014 if (DefInit *SubRegInit =
3015 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003016 Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
3017 if (!RCDef)
3018 return failedImport("EXTRACT_SUBREG child #0 could not "
3019 "be coerced to a register class");
3020
3021 CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003022 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
3023
3024 const auto &SrcRCDstRCPair =
3025 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
3026 if (SrcRCDstRCPair.hasValue()) {
3027 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
3028 if (SrcRCDstRCPair->first != RC)
3029 return failedImport("EXTRACT_SUBREG requires an additional COPY");
3030 }
3031
Daniel Sanders198447a2017-11-01 00:29:47 +00003032 DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
3033 SubIdx);
Daniel Sanders7438b262017-10-31 23:03:18 +00003034 return InsertPt;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003035 }
3036
3037 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
3038 }
3039
Daniel Sandersffc7d582017-03-29 15:37:18 +00003040 // Render the explicit uses.
Daniel Sandersdf258e32017-10-31 19:09:29 +00003041 unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
3042 unsigned ExpectedDstINumUses = Dst->getNumChildren();
3043 if (OrigDstI->TheDef->getName() == "COPY_TO_REGCLASS") {
3044 DstINumUses--; // Ignore the class constraint.
3045 ExpectedDstINumUses--;
3046 }
3047
Daniel Sanders0ed28822017-04-12 08:23:08 +00003048 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00003049 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00003050 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003051 const CGIOperandList::OperandInfo &DstIOperand =
3052 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00003053
Diana Picus382602f2017-05-17 08:57:28 +00003054 // If the operand has default values, introduce them now.
3055 // FIXME: Until we have a decent test case that dictates we should do
3056 // otherwise, we're going to assume that operands with default values cannot
3057 // be specified in the patterns. Therefore, adding them will not cause us to
3058 // end up with too many rendered operands.
3059 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00003060 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00003061 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
3062 return std::move(Error);
3063 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00003064 continue;
3065 }
3066
Daniel Sanders7438b262017-10-31 23:03:18 +00003067 auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
3068 Dst->getChild(Child));
3069 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersffc7d582017-03-29 15:37:18 +00003070 return std::move(Error);
Daniel Sanders7438b262017-10-31 23:03:18 +00003071 InsertPt = InsertPtOrError.get();
Daniel Sanders0ed28822017-04-12 08:23:08 +00003072 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003073 }
3074
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003075 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00003076 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00003077 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003078 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00003079 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00003080 " default ones");
3081
Daniel Sanders7438b262017-10-31 23:03:18 +00003082 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003083}
3084
Diana Picus382602f2017-05-17 08:57:28 +00003085Error GlobalISelEmitter::importDefaultOperandRenderers(
3086 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00003087 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00003088 // Look through ValueType operators.
3089 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
3090 if (const DefInit *DefaultDagOperator =
3091 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
3092 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
3093 DefaultOp = DefaultDagOp->getArg(0);
3094 }
3095 }
3096
3097 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003098 DstMIBuilder.addRenderer<AddRegisterRenderer>(DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00003099 continue;
3100 }
3101
3102 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003103 DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00003104 continue;
3105 }
3106
3107 return failedImport("Could not add default op");
3108 }
3109
3110 return Error::success();
3111}
3112
Daniel Sandersc270c502017-03-30 09:36:33 +00003113Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00003114 BuildMIAction &DstMIBuilder,
3115 const std::vector<Record *> &ImplicitDefs) const {
3116 if (!ImplicitDefs.empty())
3117 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00003118 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003119}
3120
3121Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003122 // Keep track of the matchers and actions to emit.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003123 RuleMatcher M(P.getSrcRecord()->getLoc());
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00003124 M.addAction<DebugCommentAction>(llvm::to_string(*P.getSrcPattern()) +
3125 " => " +
3126 llvm::to_string(*P.getDstPattern()));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003127
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003128 if (auto Error = importRulePredicates(M, P.getPredicates()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003129 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003130
3131 // Next, analyze the pattern operators.
3132 TreePatternNode *Src = P.getSrcPattern();
3133 TreePatternNode *Dst = P.getDstPattern();
3134
3135 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00003136 if (auto Err = isTrivialOperatorNode(Dst))
3137 return failedImport("Dst pattern root isn't a trivial operator (" +
3138 toString(std::move(Err)) + ")");
3139 if (auto Err = isTrivialOperatorNode(Src))
3140 return failedImport("Src pattern root isn't a trivial operator (" +
3141 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003142
Daniel Sandersedd07842017-08-17 09:26:14 +00003143 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
3144 unsigned TempOpIdx = 0;
3145 auto InsnMatcherOrError =
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003146 createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
Daniel Sandersedd07842017-08-17 09:26:14 +00003147 if (auto Error = InsnMatcherOrError.takeError())
3148 return std::move(Error);
3149 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
3150
3151 if (Dst->isLeaf()) {
3152 Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
3153
3154 const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
3155 if (RCDef) {
3156 // We need to replace the def and all its uses with the specified
3157 // operand. However, we must also insert COPY's wherever needed.
3158 // For now, emit a copy and let the register allocator clean up.
3159 auto &DstI = Target.getInstruction(RK.getDef("COPY"));
3160 const auto &DstIOperand = DstI.Operands[0];
3161
3162 OperandMatcher &OM0 = InsnMatcher.getOperand(0);
3163 OM0.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003164 M.defineOperand(OM0.getSymbolicName(), OM0);
Daniel Sandersedd07842017-08-17 09:26:14 +00003165 OM0.addPredicate<RegisterBankOperandMatcher>(RC);
3166
Daniel Sanders198447a2017-11-01 00:29:47 +00003167 auto &DstMIBuilder =
3168 M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
3169 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
3170 DstMIBuilder.addRenderer<CopyRenderer>(Dst->getName());
Daniel Sandersedd07842017-08-17 09:26:14 +00003171 M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
3172
3173 // We're done with this pattern! It's eligible for GISel emission; return
3174 // it.
3175 ++NumPatternImported;
3176 return std::move(M);
3177 }
3178
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003179 return failedImport("Dst pattern root isn't a known leaf");
Daniel Sandersedd07842017-08-17 09:26:14 +00003180 }
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003181
Daniel Sandersbee57392017-04-04 13:25:23 +00003182 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003183 Record *DstOp = Dst->getOperator();
3184 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003185 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003186
3187 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003188 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00003189 return failedImport("Src pattern results and dst MI defs are different (" +
3190 to_string(Src->getExtTypes().size()) + " def(s) vs " +
3191 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003192
Daniel Sandersffc7d582017-03-29 15:37:18 +00003193 // The root of the match also has constraints on the register bank so that it
3194 // matches the result instruction.
3195 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003196 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
3197 (void)VTy;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003198
Daniel Sanders066ebbf2017-02-24 15:43:30 +00003199 const auto &DstIOperand = DstI.Operands[OpIdx];
3200 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003201 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3202 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3203
3204 if (DstIOpRec == nullptr)
3205 return failedImport(
3206 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003207 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3208 if (!Dst->getChild(0)->isLeaf())
3209 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
3210
Daniel Sanders32291982017-06-28 13:50:04 +00003211 // We can assume that a subregister is in the same bank as it's super
3212 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003213 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
3214
3215 if (DstIOpRec == nullptr)
3216 return failedImport(
3217 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003218 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00003219 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003220 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00003221 return failedImport("Dst MI def isn't a register class" +
3222 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003223
Daniel Sandersffc7d582017-03-29 15:37:18 +00003224 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
3225 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003226 M.defineOperand(OM.getSymbolicName(), OM);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00003227 OM.addPredicate<RegisterBankOperandMatcher>(
3228 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003229 ++OpIdx;
3230 }
3231
Daniel Sandersa7b75262017-10-31 18:50:24 +00003232 auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003233 if (auto Error = DstMIBuilderOrError.takeError())
3234 return std::move(Error);
3235 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003236
Daniel Sandersffc7d582017-03-29 15:37:18 +00003237 // Render the implicit defs.
3238 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00003239 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003240 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003241
Daniel Sandersa7b75262017-10-31 18:50:24 +00003242 DstMIBuilder.chooseInsnToMutate(M);
3243
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003244 // Constrain the registers to classes. This is normally derived from the
3245 // emitted instruction but a few instructions require special handling.
3246 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3247 // COPY_TO_REGCLASS does not provide operand constraints itself but the
3248 // result is constrained to the class given by the second child.
3249 Record *DstIOpRec =
3250 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3251
3252 if (DstIOpRec == nullptr)
3253 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
3254
3255 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003256 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003257
3258 // We're done with this pattern! It's eligible for GISel emission; return
3259 // it.
3260 ++NumPatternImported;
3261 return std::move(M);
3262 }
3263
3264 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3265 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
3266 // instructions, the result register class is controlled by the
3267 // subregisters of the operand. As a result, we must constrain the result
3268 // class rather than check that it's already the right one.
3269 if (!Dst->getChild(0)->isLeaf())
3270 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
3271
Daniel Sanders320390b2017-06-28 15:16:03 +00003272 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
3273 if (!SubRegInit)
3274 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003275
Daniel Sanders320390b2017-06-28 15:16:03 +00003276 // Constrain the result to the same register bank as the operand.
3277 Record *DstIOpRec =
3278 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003279
Daniel Sanders320390b2017-06-28 15:16:03 +00003280 if (DstIOpRec == nullptr)
3281 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003282
Daniel Sanders320390b2017-06-28 15:16:03 +00003283 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003284 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003285
Daniel Sanders320390b2017-06-28 15:16:03 +00003286 // It would be nice to leave this constraint implicit but we're required
3287 // to pick a register class so constrain the result to a register class
3288 // that can hold the correct MVT.
3289 //
3290 // FIXME: This may introduce an extra copy if the chosen class doesn't
3291 // actually contain the subregisters.
3292 assert(Src->getExtTypes().size() == 1 &&
3293 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003294
Daniel Sanders320390b2017-06-28 15:16:03 +00003295 const auto &SrcRCDstRCPair =
3296 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
3297 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003298 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
3299 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
3300
3301 // We're done with this pattern! It's eligible for GISel emission; return
3302 // it.
3303 ++NumPatternImported;
3304 return std::move(M);
3305 }
3306
3307 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003308
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003309 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003310 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003311 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003312}
3313
Daniel Sanders649c5852017-10-13 20:42:18 +00003314// Emit imm predicate table and an enum to reference them with.
3315// The 'Predicate_' part of the name is redundant but eliminating it is more
3316// trouble than it's worth.
3317void GlobalISelEmitter::emitImmPredicates(
Daniel Sanders11300ce2017-10-13 21:28:03 +00003318 raw_ostream &OS, StringRef TypeIdentifier, StringRef Type,
3319 std::function<bool(const Record *R)> Filter) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003320 std::vector<const Record *> MatchedRecords;
3321 const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
3322 std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
3323 [&](Record *Record) {
3324 return !Record->getValueAsString("ImmediateCode").empty() &&
3325 Filter(Record);
3326 });
3327
Daniel Sanders11300ce2017-10-13 21:28:03 +00003328 if (!MatchedRecords.empty()) {
3329 OS << "// PatFrag predicates.\n"
3330 << "enum {\n";
Daniel Sanders2fed4ff2017-10-13 21:51:20 +00003331 std::string EnumeratorSeparator =
Daniel Sanders11300ce2017-10-13 21:28:03 +00003332 (" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str();
3333 for (const auto *Record : MatchedRecords) {
3334 OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName()
3335 << EnumeratorSeparator;
3336 EnumeratorSeparator = ",\n";
3337 }
3338 OS << "};\n";
Daniel Sanders649c5852017-10-13 20:42:18 +00003339 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00003340
Daniel Sanders649c5852017-10-13 20:42:18 +00003341 for (const auto *Record : MatchedRecords)
Daniel Sanders11300ce2017-10-13 21:28:03 +00003342 OS << "static bool Predicate_" << Record->getName() << "(" << Type
3343 << " Imm) {" << Record->getValueAsString("ImmediateCode") << "}\n";
3344
3345 OS << "static InstructionSelector::" << TypeIdentifier
3346 << "ImmediatePredicateFn " << TypeIdentifier << "ImmPredicateFns[] = {\n"
Daniel Sanders649c5852017-10-13 20:42:18 +00003347 << " nullptr,\n";
3348 for (const auto *Record : MatchedRecords)
3349 OS << " Predicate_" << Record->getName() << ",\n";
3350 OS << "};\n";
3351}
3352
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003353void GlobalISelEmitter::run(raw_ostream &OS) {
Daniel Sandersf76f3152017-11-16 00:46:35 +00003354 if (!UseCoverageFile.empty()) {
3355 RuleCoverage = CodeGenCoverage();
3356 auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);
3357 if (!RuleCoverageBufOrErr) {
3358 PrintWarning(SMLoc(), "Missing rule coverage data");
3359 RuleCoverage = None;
3360 } else {
3361 if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {
3362 PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");
3363 RuleCoverage = None;
3364 }
3365 }
3366 }
3367
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003368 // Track the GINodeEquiv definitions.
3369 gatherNodeEquivs();
3370
3371 emitSourceFileHeader(("Global Instruction Selector for the " +
3372 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003373 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003374 // Look through the SelectionDAG patterns we found, possibly emitting some.
3375 for (const PatternToMatch &Pat : CGP.ptms()) {
3376 ++NumPatternTotal;
Daniel Sanders7e523672017-11-11 03:23:44 +00003377
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003378 auto MatcherOrErr = runOnPattern(Pat);
3379
3380 // The pattern analysis can fail, indicating an unsupported pattern.
3381 // Report that if we've been asked to do so.
3382 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003383 if (WarnOnSkippedPatterns) {
3384 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003385 "Skipped pattern: " + toString(std::move(Err)));
3386 } else {
3387 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003388 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003389 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003390 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003391 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003392
Daniel Sandersf76f3152017-11-16 00:46:35 +00003393 if (RuleCoverage) {
3394 if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))
3395 ++NumPatternsTested;
3396 else
3397 PrintWarning(Pat.getSrcRecord()->getLoc(),
3398 "Pattern is not covered by a test");
3399 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003400 Rules.push_back(std::move(MatcherOrErr.get()));
3401 }
3402
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00003403 std::stable_sort(Rules.begin(), Rules.end(),
3404 [&](const RuleMatcher &A, const RuleMatcher &B) {
3405 if (A.isHigherPriorityThan(B)) {
3406 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
3407 "and less important at "
3408 "the same time");
3409 return true;
3410 }
3411 return false;
3412 });
Daniel Sanders759ff412017-02-24 13:58:11 +00003413
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003414 std::vector<Record *> ComplexPredicates =
3415 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
3416 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
3417 [](const Record *A, const Record *B) {
3418 if (A->getName() < B->getName())
3419 return true;
3420 return false;
3421 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003422 unsigned MaxTemporaries = 0;
3423 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00003424 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003425
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003426 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
3427 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
3428 << ";\n"
3429 << "using PredicateBitset = "
3430 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
3431 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
3432
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003433 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
3434 << " mutable MatcherState State;\n"
3435 << " typedef "
Daniel Sanders1e4569f2017-10-20 20:55:29 +00003436 "ComplexRendererFns("
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003437 << Target.getName()
3438 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003439 << " const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003440 "MatcherInfo;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003441 << " static " << Target.getName()
3442 << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003443 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003444
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003445 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
3446 << ", State(" << MaxTemporaries << "),\n"
Daniel Sanders11300ce2017-10-13 21:28:03 +00003447 << "MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, "
Daniel Sandersea8711b2017-10-16 03:36:29 +00003448 "APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003449 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003450
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003451 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
3452 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
3453 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003454
3455 // Separate subtarget features by how often they must be recomputed.
3456 SubtargetFeatureInfoMap ModuleFeatures;
3457 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3458 std::inserter(ModuleFeatures, ModuleFeatures.end()),
3459 [](const SubtargetFeatureInfoMap::value_type &X) {
3460 return !X.second.mustRecomputePerFunction();
3461 });
3462 SubtargetFeatureInfoMap FunctionFeatures;
3463 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3464 std::inserter(FunctionFeatures, FunctionFeatures.end()),
3465 [](const SubtargetFeatureInfoMap::value_type &X) {
3466 return X.second.mustRecomputePerFunction();
3467 });
3468
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003469 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003470 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
3471 ModuleFeatures, OS);
3472 SubtargetFeatureInfo::emitComputeAvailableFeatures(
3473 Target.getName(), "InstructionSelector",
3474 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
3475 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003476
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003477 // Emit a table containing the LLT objects needed by the matcher and an enum
3478 // for the matcher to reference them with.
Daniel Sanders032e7f22017-08-17 13:18:35 +00003479 std::vector<LLTCodeGen> TypeObjects;
3480 for (const auto &Ty : LLTOperandMatcher::KnownTypes)
3481 TypeObjects.push_back(Ty);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003482 std::sort(TypeObjects.begin(), TypeObjects.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003483 OS << "// LLT Objects.\n"
3484 << "enum {\n";
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003485 for (const auto &TypeObject : TypeObjects) {
3486 OS << " ";
3487 TypeObject.emitCxxEnumValue(OS);
3488 OS << ",\n";
3489 }
3490 OS << "};\n"
3491 << "const static LLT TypeObjects[] = {\n";
3492 for (const auto &TypeObject : TypeObjects) {
3493 OS << " ";
3494 TypeObject.emitCxxConstructorCall(OS);
3495 OS << ",\n";
3496 }
3497 OS << "};\n\n";
3498
3499 // Emit a table containing the PredicateBitsets objects needed by the matcher
3500 // and an enum for the matcher to reference them with.
3501 std::vector<std::vector<Record *>> FeatureBitsets;
3502 for (auto &Rule : Rules)
3503 FeatureBitsets.push_back(Rule.getRequiredFeatures());
3504 std::sort(
3505 FeatureBitsets.begin(), FeatureBitsets.end(),
3506 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
3507 if (A.size() < B.size())
3508 return true;
3509 if (A.size() > B.size())
3510 return false;
3511 for (const auto &Pair : zip(A, B)) {
3512 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
3513 return true;
3514 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
3515 return false;
3516 }
3517 return false;
3518 });
3519 FeatureBitsets.erase(
3520 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
3521 FeatureBitsets.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003522 OS << "// Feature bitsets.\n"
3523 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003524 << " GIFBS_Invalid,\n";
3525 for (const auto &FeatureBitset : FeatureBitsets) {
3526 if (FeatureBitset.empty())
3527 continue;
3528 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
3529 }
3530 OS << "};\n"
3531 << "const static PredicateBitset FeatureBitsets[] {\n"
3532 << " {}, // GIFBS_Invalid\n";
3533 for (const auto &FeatureBitset : FeatureBitsets) {
3534 if (FeatureBitset.empty())
3535 continue;
3536 OS << " {";
3537 for (const auto &Feature : FeatureBitset) {
3538 const auto &I = SubtargetFeatures.find(Feature);
3539 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
3540 OS << I->second.getEnumBitName() << ", ";
3541 }
3542 OS << "},\n";
3543 }
3544 OS << "};\n\n";
3545
3546 // Emit complex predicate table and an enum to reference them with.
Daniel Sanders49980702017-08-23 10:09:25 +00003547 OS << "// ComplexPattern predicates.\n"
3548 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003549 << " GICP_Invalid,\n";
3550 for (const auto &Record : ComplexPredicates)
3551 OS << " GICP_" << Record->getName() << ",\n";
3552 OS << "};\n"
3553 << "// See constructor for table contents\n\n";
3554
Daniel Sanders11300ce2017-10-13 21:28:03 +00003555 emitImmPredicates(OS, "I64", "int64_t", [](const Record *R) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003556 bool Unset;
3557 return !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
3558 !R->getValueAsBit("IsAPInt");
3559 });
Daniel Sanders11300ce2017-10-13 21:28:03 +00003560 emitImmPredicates(OS, "APFloat", "const APFloat &", [](const Record *R) {
3561 bool Unset;
3562 return R->getValueAsBitOrUnset("IsAPFloat", Unset);
3563 });
3564 emitImmPredicates(OS, "APInt", "const APInt &", [](const Record *R) {
3565 return R->getValueAsBit("IsAPInt");
3566 });
Daniel Sandersea8711b2017-10-16 03:36:29 +00003567 OS << "\n";
3568
3569 OS << Target.getName() << "InstructionSelector::ComplexMatcherMemFn\n"
3570 << Target.getName() << "InstructionSelector::ComplexPredicateFns[] = {\n"
3571 << " nullptr, // GICP_Invalid\n";
3572 for (const auto &Record : ComplexPredicates)
3573 OS << " &" << Target.getName()
3574 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
3575 << ", // " << Record->getName() << "\n";
3576 OS << "};\n\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00003577
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003578 OS << "bool " << Target.getName()
Daniel Sandersf76f3152017-11-16 00:46:35 +00003579 << "InstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage "
3580 "&CoverageInfo) const {\n"
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003581 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003582 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00003583 << " // FIXME: This should be computed on a per-function basis rather "
3584 "than per-insn.\n"
3585 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
3586 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00003587 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
3588 << " NewMIVector OutMIs;\n"
3589 << " State.MIs.clear();\n"
3590 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003591
Daniel Sanders8e82af22017-07-27 11:03:45 +00003592 MatchTable Table(0);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00003593 for (auto &Rule : Rules) {
Daniel Sanders8e82af22017-07-27 11:03:45 +00003594 Rule.emit(Table);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003595 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003596 }
Daniel Sanders8e82af22017-07-27 11:03:45 +00003597 Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
3598 Table.emitDeclaration(OS);
3599 OS << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, ";
3600 Table.emitUse(OS);
Daniel Sandersf76f3152017-11-16 00:46:35 +00003601 OS << ", TII, MRI, TRI, RBI, AvailableFeatures, CoverageInfo)) {\n"
Daniel Sanders8e82af22017-07-27 11:03:45 +00003602 << " return true;\n"
3603 << " }\n\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003604
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003605 OS << " return false;\n"
3606 << "}\n"
3607 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003608
3609 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
3610 << "PredicateBitset AvailableModuleFeatures;\n"
3611 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
3612 << "PredicateBitset getAvailableFeatures() const {\n"
3613 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
3614 << "}\n"
3615 << "PredicateBitset\n"
3616 << "computeAvailableModuleFeatures(const " << Target.getName()
3617 << "Subtarget *Subtarget) const;\n"
3618 << "PredicateBitset\n"
3619 << "computeAvailableFunctionFeatures(const " << Target.getName()
3620 << "Subtarget *Subtarget,\n"
3621 << " const MachineFunction *MF) const;\n"
3622 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
3623
3624 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
3625 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
3626 << "AvailableFunctionFeatures()\n"
3627 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003628}
3629
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003630void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
3631 if (SubtargetFeatures.count(Predicate) == 0)
3632 SubtargetFeatures.emplace(
3633 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
3634}
3635
Daniel Sanders7e523672017-11-11 03:23:44 +00003636TreePatternNode *GlobalISelEmitter::fixupPatternNode(TreePatternNode *N) {
3637 if (!N->isLeaf()) {
3638 for (unsigned I = 0, E = N->getNumChildren(); I < E; ++I) {
3639 TreePatternNode *OrigChild = N->getChild(I);
3640 TreePatternNode *NewChild = fixupPatternNode(OrigChild);
3641 if (OrigChild != NewChild)
3642 N->setChild(I, NewChild);
3643 }
3644
3645 if (N->getOperator()->getName() == "ld") {
3646 // If it's a signext-load we need to adapt the pattern slightly. We need
3647 // to split the node into (sext (ld ...)), remove the <<signext>> predicate,
3648 // and then apply the <<signextTY>> predicate by updating the result type
3649 // of the load.
3650 //
3651 // For example:
3652 // (ld:[i32] [iPTR])<<unindexed>><<signext>><<signexti16>>
3653 // must be transformed into:
3654 // (sext:[i32] (ld:[i16] [iPTR])<<unindexed>>)
3655 //
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003656 // Likewise for zeroext-load and anyext-load.
Daniel Sanders7e523672017-11-11 03:23:44 +00003657
3658 std::vector<TreePredicateFn> Predicates;
3659 bool IsSignExtLoad = false;
3660 bool IsZeroExtLoad = false;
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003661 bool IsAnyExtLoad = false;
Daniel Sanders7e523672017-11-11 03:23:44 +00003662 Record *MemVT = nullptr;
3663 for (const auto &P : N->getPredicateFns()) {
3664 if (P.isLoad() && P.isSignExtLoad()) {
3665 IsSignExtLoad = true;
3666 continue;
3667 }
3668 if (P.isLoad() && P.isZeroExtLoad()) {
3669 IsZeroExtLoad = true;
3670 continue;
3671 }
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003672 if (P.isLoad() && P.isAnyExtLoad()) {
3673 IsAnyExtLoad = true;
3674 continue;
3675 }
Daniel Sanders7e523672017-11-11 03:23:44 +00003676 if (P.isLoad() && P.getMemoryVT()) {
3677 MemVT = P.getMemoryVT();
3678 continue;
3679 }
3680 Predicates.push_back(P);
3681 }
3682
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003683 if ((IsSignExtLoad || IsZeroExtLoad || IsAnyExtLoad) && MemVT) {
3684 assert((IsSignExtLoad + IsZeroExtLoad + IsAnyExtLoad) == 1 &&
3685 "IsSignExtLoad, IsZeroExtLoad, IsAnyExtLoad are mutually exclusive");
Daniel Sanders7e523672017-11-11 03:23:44 +00003686 TreePatternNode *Ext = new TreePatternNode(
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003687 RK.getDef(IsSignExtLoad ? "sext"
3688 : IsZeroExtLoad ? "zext" : "anyext"),
3689 {N}, 1);
Daniel Sanders7e523672017-11-11 03:23:44 +00003690 Ext->setType(0, N->getType(0));
3691 N->clearPredicateFns();
3692 N->setPredicateFns(Predicates);
3693 N->setType(0, getValueType(MemVT));
3694 return Ext;
3695 }
3696 }
3697 }
3698
3699 return N;
3700}
3701
3702void GlobalISelEmitter::fixupPatternTrees(TreePattern *P) {
3703 for (unsigned I = 0, E = P->getNumTrees(); I < E; ++I) {
3704 TreePatternNode *OrigTree = P->getTree(I);
3705 TreePatternNode *NewTree = fixupPatternNode(OrigTree);
3706 if (OrigTree != NewTree)
3707 P->setTree(I, NewTree);
3708 }
3709}
3710
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003711} // end anonymous namespace
3712
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003713//===----------------------------------------------------------------------===//
3714
3715namespace llvm {
3716void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
3717 GlobalISelEmitter(RK).run(OS);
3718}
3719} // End llvm namespace