blob: f82b2fd3e9bb8b109aebe41c594048eabf77e5ce [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 Sandersd0656a32017-04-13 09:45:37 +0000233 }
234 return Explanation;
235}
236
Daniel Sandersd0656a32017-04-13 09:45:37 +0000237std::string explainOperator(Record *Operator) {
238 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000239 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000240
241 if (Operator->isSubClassOf("Intrinsic"))
242 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
243
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000244 if (Operator->isSubClassOf("ComplexPattern"))
245 return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
246 ")")
247 .str();
248
249 return (" (Operator " + Operator->getName() + " not understood)").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000250}
251
252/// Helper function to let the emitter report skip reason error messages.
253static Error failedImport(const Twine &Reason) {
254 return make_error<StringError>(Reason, inconvertibleErrorCode());
255}
256
257static Error isTrivialOperatorNode(const TreePatternNode *N) {
258 std::string Explanation = "";
259 std::string Separator = "";
Daniel Sanders2c269f62017-08-24 09:11:20 +0000260
261 bool HasUnsupportedPredicate = false;
262 for (const auto &Predicate : N->getPredicateFns()) {
263 if (Predicate.isAlwaysTrue())
264 continue;
265
266 if (Predicate.isImmediatePattern())
267 continue;
268
Daniel Sandersa71f4542017-10-16 00:56:30 +0000269 if (Predicate.isNonExtLoad())
270 continue;
Daniel Sandersd66e0902017-10-23 18:19:24 +0000271
Daniel Sanders76664652017-11-28 22:07:05 +0000272 if (Predicate.isNonTruncStore())
Daniel Sandersd66e0902017-10-23 18:19:24 +0000273 continue;
274
Daniel Sanders76664652017-11-28 22:07:05 +0000275 if (Predicate.isLoad() || Predicate.isStore()) {
276 if (Predicate.isUnindexed())
277 continue;
278 }
279
280 if (Predicate.isAtomic() && Predicate.getMemoryVT())
281 continue;
282
283 if (Predicate.isAtomic() &&
284 (Predicate.isAtomicOrderingMonotonic() ||
285 Predicate.isAtomicOrderingAcquire() ||
286 Predicate.isAtomicOrderingRelease() ||
287 Predicate.isAtomicOrderingAcquireRelease() ||
288 Predicate.isAtomicOrderingSequentiallyConsistent()))
Daniel Sandersd66e0902017-10-23 18:19:24 +0000289 continue;
290
Daniel Sanders2c269f62017-08-24 09:11:20 +0000291 HasUnsupportedPredicate = true;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000292 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
293 Separator = ", ";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000294 Explanation += (Separator + "first-failing:" +
295 Predicate.getOrigPatFragRecord()->getRecord()->getName())
296 .str();
Daniel Sanders2c269f62017-08-24 09:11:20 +0000297 break;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000298 }
299
300 if (N->getTransformFn()) {
301 Explanation += Separator + "Has a transform function";
302 Separator = ", ";
303 }
304
Daniel Sanders2c269f62017-08-24 09:11:20 +0000305 if (!HasUnsupportedPredicate && !N->getTransformFn())
Daniel Sandersd0656a32017-04-13 09:45:37 +0000306 return Error::success();
307
308 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000309}
310
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000311static Record *getInitValueAsRegClass(Init *V) {
312 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
313 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
314 return VDefInit->getDef()->getValueAsDef("RegClass");
315 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
316 return VDefInit->getDef();
317 }
318 return nullptr;
319}
320
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000321std::string
322getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
323 std::string Name = "GIFBS";
324 for (const auto &Feature : FeatureBitset)
325 Name += ("_" + Feature->getName()).str();
326 return Name;
327}
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000328
329//===- MatchTable Helpers -------------------------------------------------===//
330
331class MatchTable;
332
333/// A record to be stored in a MatchTable.
334///
335/// This class represents any and all output that may be required to emit the
336/// MatchTable. Instances are most often configured to represent an opcode or
337/// value that will be emitted to the table with some formatting but it can also
338/// represent commas, comments, and other formatting instructions.
339struct MatchTableRecord {
340 enum RecordFlagsBits {
341 MTRF_None = 0x0,
342 /// Causes EmitStr to be formatted as comment when emitted.
343 MTRF_Comment = 0x1,
344 /// Causes the record value to be followed by a comma when emitted.
345 MTRF_CommaFollows = 0x2,
346 /// Causes the record value to be followed by a line break when emitted.
347 MTRF_LineBreakFollows = 0x4,
348 /// Indicates that the record defines a label and causes an additional
349 /// comment to be emitted containing the index of the label.
350 MTRF_Label = 0x8,
351 /// Causes the record to be emitted as the index of the label specified by
352 /// LabelID along with a comment indicating where that label is.
353 MTRF_JumpTarget = 0x10,
354 /// Causes the formatter to add a level of indentation before emitting the
355 /// record.
356 MTRF_Indent = 0x20,
357 /// Causes the formatter to remove a level of indentation after emitting the
358 /// record.
359 MTRF_Outdent = 0x40,
360 };
361
362 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
363 /// reference or define.
364 unsigned LabelID;
365 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
366 /// value, a label name.
367 std::string EmitStr;
368
369private:
370 /// The number of MatchTable elements described by this record. Comments are 0
371 /// while values are typically 1. Values >1 may occur when we need to emit
372 /// values that exceed the size of a MatchTable element.
373 unsigned NumElements;
374
375public:
376 /// A bitfield of RecordFlagsBits flags.
377 unsigned Flags;
378
379 MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
380 unsigned NumElements, unsigned Flags)
381 : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
382 EmitStr(EmitStr), NumElements(NumElements), Flags(Flags) {
383 assert((!LabelID_.hasValue() || LabelID != ~0u) &&
384 "This value is reserved for non-labels");
385 }
386
387 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
388 const MatchTable &Table) const;
389 unsigned size() const { return NumElements; }
390};
391
392/// Holds the contents of a generated MatchTable to enable formatting and the
393/// necessary index tracking needed to support GIM_Try.
394class MatchTable {
395 /// An unique identifier for the table. The generated table will be named
396 /// MatchTable${ID}.
397 unsigned ID;
398 /// The records that make up the table. Also includes comments describing the
399 /// values being emitted and line breaks to format it.
400 std::vector<MatchTableRecord> Contents;
401 /// The currently defined labels.
402 DenseMap<unsigned, unsigned> LabelMap;
403 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
404 unsigned CurrentSize;
405
Daniel Sanders8e82af22017-07-27 11:03:45 +0000406 /// A unique identifier for a MatchTable label.
407 static unsigned CurrentLabelID;
408
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000409public:
410 static MatchTableRecord LineBreak;
411 static MatchTableRecord Comment(StringRef Comment) {
412 return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
413 }
414 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
415 unsigned ExtraFlags = 0;
416 if (IndentAdjust > 0)
417 ExtraFlags |= MatchTableRecord::MTRF_Indent;
418 if (IndentAdjust < 0)
419 ExtraFlags |= MatchTableRecord::MTRF_Outdent;
420
421 return MatchTableRecord(None, Opcode, 1,
422 MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
423 }
424 static MatchTableRecord NamedValue(StringRef NamedValue) {
425 return MatchTableRecord(None, NamedValue, 1,
426 MatchTableRecord::MTRF_CommaFollows);
427 }
428 static MatchTableRecord NamedValue(StringRef Namespace,
429 StringRef NamedValue) {
430 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
431 MatchTableRecord::MTRF_CommaFollows);
432 }
433 static MatchTableRecord IntValue(int64_t IntValue) {
434 return MatchTableRecord(None, llvm::to_string(IntValue), 1,
435 MatchTableRecord::MTRF_CommaFollows);
436 }
437 static MatchTableRecord Label(unsigned LabelID) {
438 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
439 MatchTableRecord::MTRF_Label |
440 MatchTableRecord::MTRF_Comment |
441 MatchTableRecord::MTRF_LineBreakFollows);
442 }
443 static MatchTableRecord JumpTarget(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000444 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000445 MatchTableRecord::MTRF_JumpTarget |
446 MatchTableRecord::MTRF_Comment |
447 MatchTableRecord::MTRF_CommaFollows);
448 }
449
450 MatchTable(unsigned ID) : ID(ID), CurrentSize(0) {}
451
452 void push_back(const MatchTableRecord &Value) {
453 if (Value.Flags & MatchTableRecord::MTRF_Label)
454 defineLabel(Value.LabelID);
455 Contents.push_back(Value);
456 CurrentSize += Value.size();
457 }
458
Daniel Sanders8e82af22017-07-27 11:03:45 +0000459 unsigned allocateLabelID() const { return CurrentLabelID++; }
460
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000461 void defineLabel(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000462 LabelMap.insert(std::make_pair(LabelID, CurrentSize));
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000463 }
464
465 unsigned getLabelIndex(unsigned LabelID) const {
466 const auto I = LabelMap.find(LabelID);
467 assert(I != LabelMap.end() && "Use of undeclared label");
468 return I->second;
469 }
470
Daniel Sanders8e82af22017-07-27 11:03:45 +0000471 void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
472
473 void emitDeclaration(raw_ostream &OS) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000474 unsigned Indentation = 4;
Daniel Sanderscbbbfe42017-07-27 12:47:31 +0000475 OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000476 LineBreak.emit(OS, true, *this);
477 OS << std::string(Indentation, ' ');
478
479 for (auto I = Contents.begin(), E = Contents.end(); I != E;
480 ++I) {
481 bool LineBreakIsNext = false;
482 const auto &NextI = std::next(I);
483
484 if (NextI != E) {
485 if (NextI->EmitStr == "" &&
486 NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
487 LineBreakIsNext = true;
488 }
489
490 if (I->Flags & MatchTableRecord::MTRF_Indent)
491 Indentation += 2;
492
493 I->emit(OS, LineBreakIsNext, *this);
494 if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
495 OS << std::string(Indentation, ' ');
496
497 if (I->Flags & MatchTableRecord::MTRF_Outdent)
498 Indentation -= 2;
499 }
500 OS << "};\n";
501 }
502};
503
Daniel Sanders8e82af22017-07-27 11:03:45 +0000504unsigned MatchTable::CurrentLabelID = 0;
505
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000506MatchTableRecord MatchTable::LineBreak = {
507 None, "" /* Emit String */, 0 /* Elements */,
508 MatchTableRecord::MTRF_LineBreakFollows};
509
510void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
511 const MatchTable &Table) const {
512 bool UseLineComment =
513 LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
514 if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
515 UseLineComment = false;
516
517 if (Flags & MTRF_Comment)
518 OS << (UseLineComment ? "// " : "/*");
519
520 OS << EmitStr;
521 if (Flags & MTRF_Label)
522 OS << ": @" << Table.getLabelIndex(LabelID);
523
524 if (Flags & MTRF_Comment && !UseLineComment)
525 OS << "*/";
526
527 if (Flags & MTRF_JumpTarget) {
528 if (Flags & MTRF_Comment)
529 OS << " ";
530 OS << Table.getLabelIndex(LabelID);
531 }
532
533 if (Flags & MTRF_CommaFollows) {
534 OS << ",";
535 if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
536 OS << " ";
537 }
538
539 if (Flags & MTRF_LineBreakFollows)
540 OS << "\n";
541}
542
543MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
544 Table.push_back(Value);
545 return Table;
546}
547
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000548//===- Matchers -----------------------------------------------------------===//
549
Daniel Sandersbee57392017-04-04 13:25:23 +0000550class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000551class MatchAction;
552
553/// Generates code to check that a match rule matches.
554class RuleMatcher {
Daniel Sanders7438b262017-10-31 23:03:18 +0000555public:
556 using ActionVec = std::vector<std::unique_ptr<MatchAction>>;
557 using action_iterator = ActionVec::iterator;
558
559protected:
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000560 /// A list of matchers that all need to succeed for the current rule to match.
561 /// FIXME: This currently supports a single match position but could be
562 /// extended to support multiple positions to support div/rem fusion or
563 /// load-multiple instructions.
564 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
565
566 /// A list of actions that need to be taken when all predicates in this rule
567 /// have succeeded.
Daniel Sanders7438b262017-10-31 23:03:18 +0000568 ActionVec Actions;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000569
Daniel Sandersa7b75262017-10-31 18:50:24 +0000570 using DefinedInsnVariablesMap =
571 std::map<const InstructionMatcher *, unsigned>;
572
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000573 /// A map of instruction matchers to the local variables created by
Daniel Sanders9d662d22017-07-06 10:06:12 +0000574 /// emitCaptureOpcodes().
Daniel Sanders078572b2017-08-02 11:03:36 +0000575 DefinedInsnVariablesMap InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000576
Daniel Sandersa7b75262017-10-31 18:50:24 +0000577 using MutatableInsnSet = SmallPtrSet<const InstructionMatcher *, 4>;
578
579 // The set of instruction matchers that have not yet been claimed for mutation
580 // by a BuildMI.
581 MutatableInsnSet MutatableInsns;
582
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000583 /// A map of named operands defined by the matchers that may be referenced by
584 /// the renderers.
585 StringMap<OperandMatcher *> DefinedOperands;
586
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000587 /// ID for the next instruction variable defined with defineInsnVar()
588 unsigned NextInsnVarID;
589
Daniel Sanders198447a2017-11-01 00:29:47 +0000590 /// ID for the next output instruction allocated with allocateOutputInsnID()
591 unsigned NextOutputInsnID;
592
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000593 /// ID for the next temporary register ID allocated with allocateTempRegID()
594 unsigned NextTempRegID;
595
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000596 std::vector<Record *> RequiredFeatures;
597
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000598 ArrayRef<SMLoc> SrcLoc;
599
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000600 typedef std::tuple<Record *, unsigned, unsigned>
601 DefinedComplexPatternSubOperand;
602 typedef StringMap<DefinedComplexPatternSubOperand>
603 DefinedComplexPatternSubOperandMap;
604 /// A map of Symbolic Names to ComplexPattern sub-operands.
605 DefinedComplexPatternSubOperandMap ComplexSubOperands;
606
Daniel Sandersf76f3152017-11-16 00:46:35 +0000607 uint64_t RuleID;
608 static uint64_t NextRuleID;
609
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000610public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000611 RuleMatcher(ArrayRef<SMLoc> SrcLoc)
Daniel Sandersa7b75262017-10-31 18:50:24 +0000612 : Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(),
Daniel Sanders198447a2017-11-01 00:29:47 +0000613 DefinedOperands(), NextInsnVarID(0), NextOutputInsnID(0),
Daniel Sandersf76f3152017-11-16 00:46:35 +0000614 NextTempRegID(0), SrcLoc(SrcLoc), ComplexSubOperands(),
615 RuleID(NextRuleID++) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000616 RuleMatcher(RuleMatcher &&Other) = default;
617 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000618
Daniel Sandersf76f3152017-11-16 00:46:35 +0000619 uint64_t getRuleID() const { return RuleID; }
620
Daniel Sanders05540042017-08-08 10:44:31 +0000621 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000622 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000623 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000624
625 template <class Kind, class... Args> Kind &addAction(Args &&... args);
Daniel Sanders7438b262017-10-31 23:03:18 +0000626 template <class Kind, class... Args>
627 action_iterator insertAction(action_iterator InsertPt, Args &&... args);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000628
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000629 /// Define an instruction without emitting any code to do so.
630 /// This is used for the root of the match.
631 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
632 /// Define an instruction and emit corresponding state-machine opcodes.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000633 unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000634 unsigned InsnVarID, unsigned OpIdx);
635 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sanders078572b2017-08-02 11:03:36 +0000636 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
637 return InsnVariableIDs.begin();
638 }
639 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
640 return InsnVariableIDs.end();
641 }
642 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
643 defined_insn_vars() const {
644 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
645 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000646
Daniel Sandersa7b75262017-10-31 18:50:24 +0000647 MutatableInsnSet::const_iterator mutatable_insns_begin() const {
648 return MutatableInsns.begin();
649 }
650 MutatableInsnSet::const_iterator mutatable_insns_end() const {
651 return MutatableInsns.end();
652 }
653 iterator_range<typename MutatableInsnSet::const_iterator>
654 mutatable_insns() const {
655 return make_range(mutatable_insns_begin(), mutatable_insns_end());
656 }
657 void reserveInsnMatcherForMutation(const InstructionMatcher *InsnMatcher) {
658 bool R = MutatableInsns.erase(InsnMatcher);
659 assert(R && "Reserving a mutatable insn that isn't available");
660 (void)R;
661 }
662
Daniel Sanders7438b262017-10-31 23:03:18 +0000663 action_iterator actions_begin() { return Actions.begin(); }
664 action_iterator actions_end() { return Actions.end(); }
665 iterator_range<action_iterator> actions() {
666 return make_range(actions_begin(), actions_end());
667 }
668
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000669 void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
670
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000671 void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
672 unsigned RendererID, unsigned SubOperandID) {
673 assert(ComplexSubOperands.count(SymbolicName) == 0 && "Already defined");
674 ComplexSubOperands[SymbolicName] =
675 std::make_tuple(ComplexPattern, RendererID, SubOperandID);
676 }
677 Optional<DefinedComplexPatternSubOperand>
678 getComplexSubOperand(StringRef SymbolicName) const {
679 const auto &I = ComplexSubOperands.find(SymbolicName);
680 if (I == ComplexSubOperands.end())
681 return None;
682 return I->second;
683 }
684
Daniel Sanders05540042017-08-08 10:44:31 +0000685 const InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000686 const OperandMatcher &getOperandMatcher(StringRef Name) const;
Daniel Sanders05540042017-08-08 10:44:31 +0000687
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000688 void emitCaptureOpcodes(MatchTable &Table);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000689
Daniel Sanders8e82af22017-07-27 11:03:45 +0000690 void emit(MatchTable &Table);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000691
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000692 /// Compare the priority of this object and B.
693 ///
694 /// Returns true if this object is more important than B.
695 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000696
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000697 /// Report the maximum number of temporary operands needed by the rule
698 /// matcher.
699 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000700
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000701 // FIXME: Remove this as soon as possible
702 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sanders198447a2017-11-01 00:29:47 +0000703
704 unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000705 unsigned allocateTempRegID() { return NextTempRegID++; }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000706};
707
Daniel Sandersf76f3152017-11-16 00:46:35 +0000708uint64_t RuleMatcher::NextRuleID = 0;
709
Daniel Sanders7438b262017-10-31 23:03:18 +0000710using action_iterator = RuleMatcher::action_iterator;
711
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000712template <class PredicateTy> class PredicateListMatcher {
713private:
714 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
715 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000716
Daniel Sanders2c269f62017-08-24 09:11:20 +0000717 /// Template instantiations should specialize this to return a string to use
718 /// for the comment emitted when there are no predicates.
719 std::string getNoPredicateComment() const;
720
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000721public:
722 /// Construct a new operand predicate and add it to the matcher.
723 template <class Kind, class... Args>
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000724 Optional<Kind *> addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000725 Predicates.emplace_back(
726 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000727 return static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000728 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000729
Daniel Sanders32291982017-06-28 13:50:04 +0000730 typename PredicateVec::const_iterator predicates_begin() const {
731 return Predicates.begin();
732 }
733 typename PredicateVec::const_iterator predicates_end() const {
734 return Predicates.end();
735 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000736 iterator_range<typename PredicateVec::const_iterator> predicates() const {
737 return make_range(predicates_begin(), predicates_end());
738 }
Daniel Sanders32291982017-06-28 13:50:04 +0000739 typename PredicateVec::size_type predicates_size() const {
740 return Predicates.size();
741 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000742
Daniel Sanders9d662d22017-07-06 10:06:12 +0000743 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000744 template <class... Args>
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000745 void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000746 if (Predicates.empty()) {
Daniel Sanders2c269f62017-08-24 09:11:20 +0000747 Table << MatchTable::Comment(getNoPredicateComment())
748 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000749 return;
750 }
751
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000752 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000753 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000754 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000755};
756
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000757/// Generates code to check a predicate of an operand.
758///
759/// Typical predicates include:
760/// * Operand is a particular register.
761/// * Operand is assigned a particular register bank.
762/// * Operand is an MBB.
763class OperandPredicateMatcher {
764public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000765 /// This enum is used for RTTI and also defines the priority that is given to
766 /// the predicate when generating the matcher code. Kinds with higher priority
767 /// must be tested first.
768 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000769 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
770 /// but OPM_Int must have priority over OPM_RegBank since constant integers
771 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000772 enum PredicateKind {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000773 OPM_SameOperand,
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000774 OPM_ComplexPattern,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000775 OPM_IntrinsicID,
Daniel Sanders05540042017-08-08 10:44:31 +0000776 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000777 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000778 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000779 OPM_LLT,
Daniel Sandersa71f4542017-10-16 00:56:30 +0000780 OPM_PointerToAny,
Daniel Sanders759ff412017-02-24 13:58:11 +0000781 OPM_RegBank,
782 OPM_MBB,
783 };
784
785protected:
786 PredicateKind Kind;
787
788public:
789 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000790 virtual ~OperandPredicateMatcher() {}
791
Daniel Sanders759ff412017-02-24 13:58:11 +0000792 PredicateKind getKind() const { return Kind; }
793
Daniel Sanders9d662d22017-07-06 10:06:12 +0000794 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sandersbee57392017-04-04 13:25:23 +0000795 ///
Daniel Sanders9d662d22017-07-06 10:06:12 +0000796 /// Only InstructionOperandMatcher needs to do anything for this method the
797 /// rest just walk the tree.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000798 virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +0000799 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000800
Daniel Sanders9d662d22017-07-06 10:06:12 +0000801 /// Emit MatchTable opcodes that check the predicate for the given operand.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000802 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000803 unsigned InsnVarID,
804 unsigned OpIdx) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000805
806 /// Compare the priority of this object and B.
807 ///
808 /// Returns true if this object is more important than B.
Daniel Sanders05540042017-08-08 10:44:31 +0000809 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000810
811 /// Report the maximum number of temporary operands needed by the predicate
812 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000813 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000814};
815
Daniel Sanders2c269f62017-08-24 09:11:20 +0000816template <>
817std::string
818PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
819 return "No operand predicates";
820}
821
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000822/// Generates code to check that a register operand is defined by the same exact
823/// one as another.
824class SameOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000825 std::string MatchingName;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000826
827public:
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000828 SameOperandMatcher(StringRef MatchingName)
829 : OperandPredicateMatcher(OPM_SameOperand), MatchingName(MatchingName) {}
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000830
831 static bool classof(const OperandPredicateMatcher *P) {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000832 return P->getKind() == OPM_SameOperand;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000833 }
834
835 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
836 unsigned InsnVarID, unsigned OpIdx) const override;
837};
838
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000839/// Generates code to check that an operand is a particular LLT.
840class LLTOperandMatcher : public OperandPredicateMatcher {
841protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000842 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000843
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000844public:
Daniel Sanders032e7f22017-08-17 13:18:35 +0000845 static std::set<LLTCodeGen> KnownTypes;
846
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000847 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders032e7f22017-08-17 13:18:35 +0000848 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {
849 KnownTypes.insert(Ty);
850 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000851
852 static bool classof(const OperandPredicateMatcher *P) {
853 return P->getKind() == OPM_LLT;
854 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000855
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000856 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000857 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000858 Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
859 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
860 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
861 << MatchTable::NamedValue(Ty.getCxxEnumValue())
862 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000863 }
864};
865
Daniel Sanders032e7f22017-08-17 13:18:35 +0000866std::set<LLTCodeGen> LLTOperandMatcher::KnownTypes;
867
Daniel Sandersa71f4542017-10-16 00:56:30 +0000868/// Generates code to check that an operand is a pointer to any address space.
869///
870/// In SelectionDAG, the types did not describe pointers or address spaces. As a
871/// result, iN is used to describe a pointer of N bits to any address space and
872/// PatFrag predicates are typically used to constrain the address space. There's
873/// no reliable means to derive the missing type information from the pattern so
874/// imported rules must test the components of a pointer separately.
875///
Daniel Sandersea8711b2017-10-16 03:36:29 +0000876/// If SizeInBits is zero, then the pointer size will be obtained from the
877/// subtarget.
Daniel Sandersa71f4542017-10-16 00:56:30 +0000878class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
879protected:
880 unsigned SizeInBits;
881
882public:
883 PointerToAnyOperandMatcher(unsigned SizeInBits)
884 : OperandPredicateMatcher(OPM_PointerToAny), SizeInBits(SizeInBits) {}
885
886 static bool classof(const OperandPredicateMatcher *P) {
887 return P->getKind() == OPM_PointerToAny;
888 }
889
890 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
891 unsigned InsnVarID, unsigned OpIdx) const override {
892 Table << MatchTable::Opcode("GIM_CheckPointerToAny") << MatchTable::Comment("MI")
893 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
894 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("SizeInBits")
895 << MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
896 }
897};
898
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000899/// Generates code to check that an operand is a particular target constant.
900class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
901protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000902 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000903 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000904
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000905 unsigned getAllocatedTemporariesBaseID() const;
906
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000907public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000908 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
909 const Record &TheDef)
910 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
911 TheDef(TheDef) {}
912
913 static bool classof(const OperandPredicateMatcher *P) {
914 return P->getKind() == OPM_ComplexPattern;
915 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000916
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000917 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000918 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000919 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000920 Table << MatchTable::Opcode("GIM_CheckComplexPattern")
921 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
922 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
923 << MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
924 << MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
925 << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000926 }
927
Daniel Sanders2deea182017-04-22 15:11:04 +0000928 unsigned countRendererFns() const override {
929 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000930 }
931};
932
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000933/// Generates code to check that an operand is in a particular register bank.
934class RegisterBankOperandMatcher : public OperandPredicateMatcher {
935protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000936 const CodeGenRegisterClass &RC;
937
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000938public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000939 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
940 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
941
942 static bool classof(const OperandPredicateMatcher *P) {
943 return P->getKind() == OPM_RegBank;
944 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000945
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000946 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000947 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000948 Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
949 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
950 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
951 << MatchTable::Comment("RC")
952 << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
953 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000954 }
955};
956
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000957/// Generates code to check that an operand is a basic block.
958class MBBOperandMatcher : public OperandPredicateMatcher {
959public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000960 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
961
962 static bool classof(const OperandPredicateMatcher *P) {
963 return P->getKind() == OPM_MBB;
964 }
965
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000966 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000967 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000968 Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
969 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
970 << MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000971 }
972};
973
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000974/// Generates code to check that an operand is a G_CONSTANT with a particular
975/// int.
976class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000977protected:
978 int64_t Value;
979
980public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000981 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000982 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
983
984 static bool classof(const OperandPredicateMatcher *P) {
985 return P->getKind() == OPM_Int;
986 }
987
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000988 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000989 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000990 Table << MatchTable::Opcode("GIM_CheckConstantInt")
991 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
992 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
993 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000994 }
995};
996
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000997/// Generates code to check that an operand is a raw int (where MO.isImm() or
998/// MO.isCImm() is true).
999class LiteralIntOperandMatcher : public OperandPredicateMatcher {
1000protected:
1001 int64_t Value;
1002
1003public:
1004 LiteralIntOperandMatcher(int64_t Value)
1005 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
1006
1007 static bool classof(const OperandPredicateMatcher *P) {
1008 return P->getKind() == OPM_LiteralInt;
1009 }
1010
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001011 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001012 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001013 Table << MatchTable::Opcode("GIM_CheckLiteralInt")
1014 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1015 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1016 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001017 }
1018};
1019
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001020/// Generates code to check that an operand is an intrinsic ID.
1021class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
1022protected:
1023 const CodeGenIntrinsic *II;
1024
1025public:
1026 IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
1027 : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
1028
1029 static bool classof(const OperandPredicateMatcher *P) {
1030 return P->getKind() == OPM_IntrinsicID;
1031 }
1032
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001033 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001034 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001035 Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
1036 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1037 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1038 << MatchTable::NamedValue("Intrinsic::" + II->EnumName)
1039 << MatchTable::LineBreak;
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001040 }
1041};
1042
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001043/// Generates code to check that a set of predicates match for a particular
1044/// operand.
1045class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
1046protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001047 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001048 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001049 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001050
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001051 /// The index of the first temporary variable allocated to this operand. The
1052 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +00001053 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001054 unsigned AllocatedTemporariesBaseID;
1055
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001056public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001057 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001058 const std::string &SymbolicName,
1059 unsigned AllocatedTemporariesBaseID)
1060 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
1061 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001062
1063 bool hasSymbolicName() const { return !SymbolicName.empty(); }
1064 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001065 void setSymbolicName(StringRef Name) {
1066 assert(SymbolicName.empty() && "Operand already has a symbolic name");
1067 SymbolicName = Name;
1068 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001069 unsigned getOperandIndex() const { return OpIdx; }
1070
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001071 std::string getOperandExpr(unsigned InsnVarID) const {
1072 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
1073 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +00001074 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001075
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001076 InstructionMatcher &getInstructionMatcher() const { return Insn; }
1077
Daniel Sandersa71f4542017-10-16 00:56:30 +00001078 Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001079 bool OperandIsAPointer);
Daniel Sandersa71f4542017-10-16 00:56:30 +00001080
Daniel Sanders9d662d22017-07-06 10:06:12 +00001081 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001082 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001083 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +00001084 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001085 Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00001086 }
1087
Daniel Sanders9d662d22017-07-06 10:06:12 +00001088 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001089 /// InsnVarID matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001090 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001091 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001092 std::string Comment;
1093 raw_string_ostream CommentOS(Comment);
1094 CommentOS << "MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001095 if (SymbolicName.empty())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001096 CommentOS << "Operand " << OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001097 else
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001098 CommentOS << SymbolicName;
1099 Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
1100
1101 emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001102 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001103
1104 /// Compare the priority of this object and B.
1105 ///
1106 /// Returns true if this object is more important than B.
1107 bool isHigherPriorityThan(const OperandMatcher &B) const {
1108 // Operand matchers involving more predicates have higher priority.
1109 if (predicates_size() > B.predicates_size())
1110 return true;
1111 if (predicates_size() < B.predicates_size())
1112 return false;
1113
1114 // This assumes that predicates are added in a consistent order.
1115 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1116 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1117 return true;
1118 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1119 return false;
1120 }
1121
1122 return false;
1123 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001124
1125 /// Report the maximum number of temporary operands needed by the operand
1126 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001127 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001128 return std::accumulate(
1129 predicates().begin(), predicates().end(), 0,
1130 [](unsigned A,
1131 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001132 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001133 });
1134 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001135
1136 unsigned getAllocatedTemporariesBaseID() const {
1137 return AllocatedTemporariesBaseID;
1138 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001139
1140 bool isSameAsAnotherOperand() const {
1141 for (const auto &Predicate : predicates())
1142 if (isa<SameOperandMatcher>(Predicate))
1143 return true;
1144 return false;
1145 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001146};
1147
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001148// Specialize OperandMatcher::addPredicate() to refrain from adding redundant
1149// predicates.
1150template <>
1151template <class Kind, class... Args>
1152Optional<Kind *>
1153PredicateListMatcher<OperandPredicateMatcher>::addPredicate(Args &&... args) {
1154 if (static_cast<OperandMatcher *>(this)->isSameAsAnotherOperand())
1155 return None;
1156 Predicates.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1157 return static_cast<Kind *>(Predicates.back().get());
1158}
1159
1160Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
1161 bool OperandIsAPointer) {
1162 if (!VTy.isMachineValueType())
1163 return failedImport("unsupported typeset");
1164
1165 if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
1166 addPredicate<PointerToAnyOperandMatcher>(0);
1167 return Error::success();
1168 }
1169
1170 auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
1171 if (!OpTyOrNone)
1172 return failedImport("unsupported type");
1173
1174 if (OperandIsAPointer)
1175 addPredicate<PointerToAnyOperandMatcher>(OpTyOrNone->get().getSizeInBits());
1176 else
1177 addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1178 return Error::success();
1179}
1180
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001181unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
1182 return Operand.getAllocatedTemporariesBaseID();
1183}
1184
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001185/// Generates code to check a predicate on an instruction.
1186///
1187/// Typical predicates include:
1188/// * The opcode of the instruction is a particular value.
1189/// * The nsw/nuw flag is/isn't set.
1190class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +00001191protected:
1192 /// This enum is used for RTTI and also defines the priority that is given to
1193 /// the predicate when generating the matcher code. Kinds with higher priority
1194 /// must be tested first.
1195 enum PredicateKind {
1196 IPM_Opcode,
Daniel Sanders2c269f62017-08-24 09:11:20 +00001197 IPM_ImmPredicate,
Daniel Sanders76664652017-11-28 22:07:05 +00001198 IPM_AtomicOrderingMMO,
Daniel Sanders759ff412017-02-24 13:58:11 +00001199 };
1200
1201 PredicateKind Kind;
1202
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001203public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001204 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001205 virtual ~InstructionPredicateMatcher() {}
1206
Daniel Sanders759ff412017-02-24 13:58:11 +00001207 PredicateKind getKind() const { return Kind; }
1208
Daniel Sanders9d662d22017-07-06 10:06:12 +00001209 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001210 /// InsnVarID matches the predicate.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001211 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001212 unsigned InsnVarID) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +00001213
1214 /// Compare the priority of this object and B.
1215 ///
1216 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001217 virtual bool
1218 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +00001219 return Kind < B.Kind;
1220 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001221
1222 /// Report the maximum number of temporary operands needed by the predicate
1223 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001224 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001225};
1226
Daniel Sanders2c269f62017-08-24 09:11:20 +00001227template <>
1228std::string
1229PredicateListMatcher<InstructionPredicateMatcher>::getNoPredicateComment() const {
1230 return "No instruction predicates";
1231}
1232
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001233/// Generates code to check the opcode of an instruction.
1234class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1235protected:
1236 const CodeGenInstruction *I;
1237
1238public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001239 InstructionOpcodeMatcher(const CodeGenInstruction *I)
1240 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001241
Daniel Sanders759ff412017-02-24 13:58:11 +00001242 static bool classof(const InstructionPredicateMatcher *P) {
1243 return P->getKind() == IPM_Opcode;
1244 }
1245
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001246 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001247 unsigned InsnVarID) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001248 Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
1249 << MatchTable::IntValue(InsnVarID)
1250 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1251 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001252 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001253
1254 /// Compare the priority of this object and B.
1255 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001256 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001257 bool
1258 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +00001259 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
1260 return true;
1261 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
1262 return false;
1263
1264 // Prioritize opcodes for cosmetic reasons in the generated source. Although
1265 // this is cosmetic at the moment, we may want to drive a similar ordering
1266 // using instruction frequency information to improve compile time.
1267 if (const InstructionOpcodeMatcher *BO =
1268 dyn_cast<InstructionOpcodeMatcher>(&B))
1269 return I->TheDef->getName() < BO->I->TheDef->getName();
1270
1271 return false;
1272 };
Daniel Sanders05540042017-08-08 10:44:31 +00001273
1274 bool isConstantInstruction() const {
1275 return I->TheDef->getName() == "G_CONSTANT";
1276 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001277};
1278
Daniel Sanders2c269f62017-08-24 09:11:20 +00001279/// Generates code to check that this instruction is a constant whose value
1280/// meets an immediate predicate.
1281///
1282/// Immediates are slightly odd since they are typically used like an operand
1283/// but are represented as an operator internally. We typically write simm8:$src
1284/// in a tablegen pattern, but this is just syntactic sugar for
1285/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1286/// that will be matched and the predicate (which is attached to the imm
1287/// operator) that will be tested. In SelectionDAG this describes a
1288/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
1289///
1290/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1291/// this representation, the immediate could be tested with an
1292/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1293/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1294/// there are two implementation issues with producing that matcher
1295/// configuration from the SelectionDAG pattern:
1296/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1297/// were we to sink the immediate predicate to the operand we would have to
1298/// have two partial implementations of PatFrag support, one for immediates
1299/// and one for non-immediates.
1300/// * At the point we handle the predicate, the OperandMatcher hasn't been
1301/// created yet. If we were to sink the predicate to the OperandMatcher we
1302/// would also have to complicate (or duplicate) the code that descends and
1303/// creates matchers for the subtree.
1304/// Overall, it's simpler to handle it in the place it was found.
1305class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1306protected:
1307 TreePredicateFn Predicate;
1308
1309public:
1310 InstructionImmPredicateMatcher(const TreePredicateFn &Predicate)
1311 : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {}
1312
1313 static bool classof(const InstructionPredicateMatcher *P) {
1314 return P->getKind() == IPM_ImmPredicate;
1315 }
1316
1317 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1318 unsigned InsnVarID) const override {
Daniel Sanders11300ce2017-10-13 21:28:03 +00001319 Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001320 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1321 << MatchTable::Comment("Predicate")
Daniel Sanders11300ce2017-10-13 21:28:03 +00001322 << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001323 << MatchTable::LineBreak;
1324 }
1325};
1326
Daniel Sanders76664652017-11-28 22:07:05 +00001327/// Generates code to check that a memory instruction has a atomic ordering
1328/// MachineMemoryOperand.
1329class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
1330 StringRef Order;
1331
Daniel Sanders39690bd2017-10-15 02:41:12 +00001332public:
Daniel Sanders76664652017-11-28 22:07:05 +00001333 AtomicOrderingMMOPredicateMatcher(StringRef Order)
1334 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order) {}
Daniel Sanders39690bd2017-10-15 02:41:12 +00001335
1336 static bool classof(const InstructionPredicateMatcher *P) {
Daniel Sanders76664652017-11-28 22:07:05 +00001337 return P->getKind() == IPM_AtomicOrderingMMO;
Daniel Sanders39690bd2017-10-15 02:41:12 +00001338 }
1339
1340 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1341 unsigned InsnVarID) const override {
Daniel Sanders76664652017-11-28 22:07:05 +00001342 Table << MatchTable::Opcode("GIM_CheckAtomicOrdering")
Daniel Sanders39690bd2017-10-15 02:41:12 +00001343 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
Daniel Sanders76664652017-11-28 22:07:05 +00001344 << MatchTable::Comment("Order")
1345 << MatchTable::NamedValue(("(int64_t)AtomicOrdering::" + Order).str())
Daniel Sanders39690bd2017-10-15 02:41:12 +00001346 << MatchTable::LineBreak;
1347 }
1348};
1349
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001350/// Generates code to check that a set of predicates and operands match for a
1351/// particular instruction.
1352///
1353/// Typical predicates include:
1354/// * Has a specific opcode.
1355/// * Has an nsw/nuw flag or doesn't.
1356class InstructionMatcher
1357 : public PredicateListMatcher<InstructionPredicateMatcher> {
1358protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001359 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001360
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001361 RuleMatcher &Rule;
1362
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001363 /// The operands to match. All rendered operands must be present even if the
1364 /// condition is always true.
1365 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001366
Daniel Sanders05540042017-08-08 10:44:31 +00001367 std::string SymbolicName;
1368
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001369public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001370 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
1371 : Rule(Rule), SymbolicName(SymbolicName) {}
1372
1373 RuleMatcher &getRuleMatcher() const { return Rule; }
Daniel Sanders05540042017-08-08 10:44:31 +00001374
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001375 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001376 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1377 unsigned AllocatedTemporariesBaseID) {
1378 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
1379 AllocatedTemporariesBaseID));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001380 if (!SymbolicName.empty())
1381 Rule.defineOperand(SymbolicName, *Operands.back());
1382
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001383 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001384 }
1385
Daniel Sandersffc7d582017-03-29 15:37:18 +00001386 OperandMatcher &getOperand(unsigned OpIdx) {
1387 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001388 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
1389 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001390 });
1391 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001392 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001393 llvm_unreachable("Failed to lookup operand");
1394 }
1395
Daniel Sanders05540042017-08-08 10:44:31 +00001396 StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001397 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +00001398 OperandVec::iterator operands_begin() { return Operands.begin(); }
1399 OperandVec::iterator operands_end() { return Operands.end(); }
1400 iterator_range<OperandVec::iterator> operands() {
1401 return make_range(operands_begin(), operands_end());
1402 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001403 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1404 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001405 iterator_range<OperandVec::const_iterator> operands() const {
1406 return make_range(operands_begin(), operands_end());
1407 }
1408
Daniel Sanders9d662d22017-07-06 10:06:12 +00001409 /// Emit MatchTable opcodes to check the shape of the match and capture
1410 /// instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001411 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001412 unsigned InsnID) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001413 Table << MatchTable::Opcode("GIM_CheckNumOperands")
1414 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1415 << MatchTable::Comment("Expected")
1416 << MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001417 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001418 Operand->emitCaptureOpcodes(Table, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001419 }
1420
Daniel Sanders9d662d22017-07-06 10:06:12 +00001421 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001422 /// InsnVarName matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001423 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001424 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001425 emitPredicateListOpcodes(Table, Rule, InsnVarID);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001426 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001427 Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001428 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001429
1430 /// Compare the priority of this object and B.
1431 ///
1432 /// Returns true if this object is more important than B.
1433 bool isHigherPriorityThan(const InstructionMatcher &B) const {
1434 // Instruction matchers involving more operands have higher priority.
1435 if (Operands.size() > B.Operands.size())
1436 return true;
1437 if (Operands.size() < B.Operands.size())
1438 return false;
1439
1440 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1441 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1442 return true;
1443 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1444 return false;
1445 }
1446
1447 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001448 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001449 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001450 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001451 return false;
1452 }
1453
1454 return false;
1455 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001456
1457 /// Report the maximum number of temporary operands needed by the instruction
1458 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001459 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001460 return std::accumulate(predicates().begin(), predicates().end(), 0,
1461 [](unsigned A,
1462 const std::unique_ptr<InstructionPredicateMatcher>
1463 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001464 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001465 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001466 std::accumulate(
1467 Operands.begin(), Operands.end(), 0,
1468 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001469 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001470 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001471 }
Daniel Sanders05540042017-08-08 10:44:31 +00001472
1473 bool isConstantInstruction() const {
1474 for (const auto &P : predicates())
1475 if (const InstructionOpcodeMatcher *Opcode =
1476 dyn_cast<InstructionOpcodeMatcher>(P.get()))
1477 return Opcode->isConstantInstruction();
1478 return false;
1479 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001480};
1481
Daniel Sandersbee57392017-04-04 13:25:23 +00001482/// Generates code to check that the operand is a register defined by an
1483/// instruction that matches the given instruction matcher.
1484///
1485/// For example, the pattern:
1486/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1487/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1488/// the:
1489/// (G_ADD $src1, $src2)
1490/// subpattern.
1491class InstructionOperandMatcher : public OperandPredicateMatcher {
1492protected:
1493 std::unique_ptr<InstructionMatcher> InsnMatcher;
1494
1495public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001496 InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName)
Daniel Sandersbee57392017-04-04 13:25:23 +00001497 : OperandPredicateMatcher(OPM_Instruction),
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001498 InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {}
Daniel Sandersbee57392017-04-04 13:25:23 +00001499
1500 static bool classof(const OperandPredicateMatcher *P) {
1501 return P->getKind() == OPM_Instruction;
1502 }
1503
1504 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1505
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001506 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001507 unsigned InsnID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001508 unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
1509 InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001510 }
1511
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001512 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001513 unsigned InsnVarID_,
1514 unsigned OpIdx_) const override {
1515 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001516 InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001517 }
1518};
1519
Daniel Sanders43c882c2017-02-01 10:53:10 +00001520//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001521class OperandRenderer {
1522public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001523 enum RendererKind {
1524 OR_Copy,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001525 OR_CopyOrAddZeroReg,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001526 OR_CopySubReg,
Daniel Sanders05540042017-08-08 10:44:31 +00001527 OR_CopyConstantAsImm,
Daniel Sanders11300ce2017-10-13 21:28:03 +00001528 OR_CopyFConstantAsFPImm,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001529 OR_Imm,
1530 OR_Register,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001531 OR_TempRegister,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001532 OR_ComplexPattern
1533 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001534
1535protected:
1536 RendererKind Kind;
1537
1538public:
1539 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1540 virtual ~OperandRenderer() {}
1541
1542 RendererKind getKind() const { return Kind; }
1543
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001544 virtual void emitRenderOpcodes(MatchTable &Table,
1545 RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001546};
1547
1548/// A CopyRenderer emits code to copy a single operand from an existing
1549/// instruction to the one being built.
1550class CopyRenderer : public OperandRenderer {
1551protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001552 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001553 /// The name of the operand.
1554 const StringRef SymbolicName;
1555
1556public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001557 CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
1558 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
Daniel Sanders05540042017-08-08 10:44:31 +00001559 SymbolicName(SymbolicName) {
1560 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1561 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001562
1563 static bool classof(const OperandRenderer *R) {
1564 return R->getKind() == OR_Copy;
1565 }
1566
1567 const StringRef getSymbolicName() const { return SymbolicName; }
1568
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001569 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001570 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001571 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001572 Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
1573 << MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
1574 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1575 << MatchTable::IntValue(Operand.getOperandIndex())
1576 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001577 }
1578};
1579
Daniel Sandersd66e0902017-10-23 18:19:24 +00001580/// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1581/// existing instruction to the one being built. If the operand turns out to be
1582/// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1583class CopyOrAddZeroRegRenderer : public OperandRenderer {
1584protected:
1585 unsigned NewInsnID;
1586 /// The name of the operand.
1587 const StringRef SymbolicName;
1588 const Record *ZeroRegisterDef;
1589
1590public:
1591 CopyOrAddZeroRegRenderer(unsigned NewInsnID,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001592 StringRef SymbolicName, Record *ZeroRegisterDef)
1593 : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
1594 SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
1595 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1596 }
1597
1598 static bool classof(const OperandRenderer *R) {
1599 return R->getKind() == OR_CopyOrAddZeroReg;
1600 }
1601
1602 const StringRef getSymbolicName() const { return SymbolicName; }
1603
1604 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1605 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
1606 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
1607 Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg")
1608 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1609 << MatchTable::Comment("OldInsnID")
1610 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1611 << MatchTable::IntValue(Operand.getOperandIndex())
1612 << MatchTable::NamedValue(
1613 (ZeroRegisterDef->getValue("Namespace")
1614 ? ZeroRegisterDef->getValueAsString("Namespace")
1615 : ""),
1616 ZeroRegisterDef->getName())
1617 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1618 }
1619};
1620
Daniel Sanders05540042017-08-08 10:44:31 +00001621/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1622/// an extended immediate operand.
1623class CopyConstantAsImmRenderer : public OperandRenderer {
1624protected:
1625 unsigned NewInsnID;
1626 /// The name of the operand.
1627 const std::string SymbolicName;
1628 bool Signed;
1629
1630public:
1631 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1632 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
1633 SymbolicName(SymbolicName), Signed(true) {}
1634
1635 static bool classof(const OperandRenderer *R) {
1636 return R->getKind() == OR_CopyConstantAsImm;
1637 }
1638
1639 const StringRef getSymbolicName() const { return SymbolicName; }
1640
1641 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1642 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1643 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1644 Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
1645 : "GIR_CopyConstantAsUImm")
1646 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1647 << MatchTable::Comment("OldInsnID")
1648 << MatchTable::IntValue(OldInsnVarID)
1649 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1650 }
1651};
1652
Daniel Sanders11300ce2017-10-13 21:28:03 +00001653/// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1654/// instruction to an extended immediate operand.
1655class CopyFConstantAsFPImmRenderer : public OperandRenderer {
1656protected:
1657 unsigned NewInsnID;
1658 /// The name of the operand.
1659 const std::string SymbolicName;
1660
1661public:
1662 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1663 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
1664 SymbolicName(SymbolicName) {}
1665
1666 static bool classof(const OperandRenderer *R) {
1667 return R->getKind() == OR_CopyFConstantAsFPImm;
1668 }
1669
1670 const StringRef getSymbolicName() const { return SymbolicName; }
1671
1672 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1673 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1674 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1675 Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
1676 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1677 << MatchTable::Comment("OldInsnID")
1678 << MatchTable::IntValue(OldInsnVarID)
1679 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1680 }
1681};
1682
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001683/// A CopySubRegRenderer emits code to copy a single register operand from an
1684/// existing instruction to the one being built and indicate that only a
1685/// subregister should be copied.
1686class CopySubRegRenderer : public OperandRenderer {
1687protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001688 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001689 /// The name of the operand.
1690 const StringRef SymbolicName;
1691 /// The subregister to extract.
1692 const CodeGenSubRegIndex *SubReg;
1693
1694public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001695 CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
1696 const CodeGenSubRegIndex *SubReg)
1697 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001698 SymbolicName(SymbolicName), SubReg(SubReg) {}
1699
1700 static bool classof(const OperandRenderer *R) {
1701 return R->getKind() == OR_CopySubReg;
1702 }
1703
1704 const StringRef getSymbolicName() const { return SymbolicName; }
1705
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001706 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001707 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001708 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001709 Table << MatchTable::Opcode("GIR_CopySubReg")
1710 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1711 << MatchTable::Comment("OldInsnID")
1712 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1713 << MatchTable::IntValue(Operand.getOperandIndex())
1714 << MatchTable::Comment("SubRegIdx")
1715 << MatchTable::IntValue(SubReg->EnumValue)
1716 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001717 }
1718};
1719
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001720/// Adds a specific physical register to the instruction being built.
1721/// This is typically useful for WZR/XZR on AArch64.
1722class AddRegisterRenderer : public OperandRenderer {
1723protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001724 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001725 const Record *RegisterDef;
1726
1727public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001728 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
1729 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
1730 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001731
1732 static bool classof(const OperandRenderer *R) {
1733 return R->getKind() == OR_Register;
1734 }
1735
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001736 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1737 Table << MatchTable::Opcode("GIR_AddRegister")
1738 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1739 << MatchTable::NamedValue(
1740 (RegisterDef->getValue("Namespace")
1741 ? RegisterDef->getValueAsString("Namespace")
1742 : ""),
1743 RegisterDef->getName())
1744 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001745 }
1746};
1747
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001748/// Adds a specific temporary virtual register to the instruction being built.
1749/// This is used to chain instructions together when emitting multiple
1750/// instructions.
1751class TempRegRenderer : public OperandRenderer {
1752protected:
1753 unsigned InsnID;
1754 unsigned TempRegID;
1755 bool IsDef;
1756
1757public:
1758 TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false)
1759 : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
1760 IsDef(IsDef) {}
1761
1762 static bool classof(const OperandRenderer *R) {
1763 return R->getKind() == OR_TempRegister;
1764 }
1765
1766 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1767 Table << MatchTable::Opcode("GIR_AddTempRegister")
1768 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1769 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
1770 << MatchTable::Comment("TempRegFlags");
1771 if (IsDef)
1772 Table << MatchTable::NamedValue("RegState::Define");
1773 else
1774 Table << MatchTable::IntValue(0);
1775 Table << MatchTable::LineBreak;
1776 }
1777};
1778
Daniel Sanders0ed28822017-04-12 08:23:08 +00001779/// Adds a specific immediate to the instruction being built.
1780class ImmRenderer : public OperandRenderer {
1781protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001782 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001783 int64_t Imm;
1784
1785public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001786 ImmRenderer(unsigned InsnID, int64_t Imm)
1787 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001788
1789 static bool classof(const OperandRenderer *R) {
1790 return R->getKind() == OR_Imm;
1791 }
1792
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001793 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1794 Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
1795 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
1796 << MatchTable::IntValue(Imm) << MatchTable::LineBreak;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001797 }
1798};
1799
Daniel Sanders2deea182017-04-22 15:11:04 +00001800/// Adds operands by calling a renderer function supplied by the ComplexPattern
1801/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001802class RenderComplexPatternOperand : public OperandRenderer {
1803private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001804 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001805 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001806 /// The name of the operand.
1807 const StringRef SymbolicName;
1808 /// The renderer number. This must be unique within a rule since it's used to
1809 /// identify a temporary variable to hold the renderer function.
1810 unsigned RendererID;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001811 /// When provided, this is the suboperand of the ComplexPattern operand to
1812 /// render. Otherwise all the suboperands will be rendered.
1813 Optional<unsigned> SubOperand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001814
1815 unsigned getNumOperands() const {
1816 return TheDef.getValueAsDag("Operands")->getNumArgs();
1817 }
1818
1819public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001820 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001821 StringRef SymbolicName, unsigned RendererID,
1822 Optional<unsigned> SubOperand = None)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001823 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001824 SymbolicName(SymbolicName), RendererID(RendererID),
1825 SubOperand(SubOperand) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001826
1827 static bool classof(const OperandRenderer *R) {
1828 return R->getKind() == OR_ComplexPattern;
1829 }
1830
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001831 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001832 Table << MatchTable::Opcode(SubOperand.hasValue() ? "GIR_ComplexSubOperandRenderer"
1833 : "GIR_ComplexRenderer")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001834 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1835 << MatchTable::Comment("RendererID")
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001836 << MatchTable::IntValue(RendererID);
1837 if (SubOperand.hasValue())
1838 Table << MatchTable::Comment("SubOperand")
1839 << MatchTable::IntValue(SubOperand.getValue());
1840 Table << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001841 }
1842};
1843
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001844/// An action taken when all Matcher predicates succeeded for a parent rule.
1845///
1846/// Typical actions include:
1847/// * Changing the opcode of an instruction.
1848/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001849class MatchAction {
1850public:
1851 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001852
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001853 /// Emit the MatchTable opcodes to implement the action.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001854 virtual void emitActionOpcodes(MatchTable &Table,
1855 RuleMatcher &Rule) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001856};
1857
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001858/// Generates a comment describing the matched rule being acted upon.
1859class DebugCommentAction : public MatchAction {
1860private:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001861 std::string S;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001862
1863public:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001864 DebugCommentAction(StringRef S) : S(S) {}
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001865
Daniel Sandersa7b75262017-10-31 18:50:24 +00001866 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001867 Table << MatchTable::Comment(S) << MatchTable::LineBreak;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001868 }
1869};
1870
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001871/// Generates code to build an instruction or mutate an existing instruction
1872/// into the desired instruction when this is possible.
1873class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001874private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001875 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001876 const CodeGenInstruction *I;
Daniel Sanders64f745c2017-10-24 17:08:43 +00001877 const InstructionMatcher *Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001878 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1879
1880 /// True if the instruction can be built solely by mutating the opcode.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001881 bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const {
1882 if (!Insn)
Daniel Sandersab1d1192017-10-24 18:11:54 +00001883 return false;
1884
Daniel Sandersa7b75262017-10-31 18:50:24 +00001885 if (OperandRenderers.size() != Insn->getNumOperands())
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001886 return false;
1887
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001888 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001889 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001890 const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
Daniel Sandersa7b75262017-10-31 18:50:24 +00001891 if (Insn != &OM.getInstructionMatcher() ||
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001892 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001893 return false;
1894 } else
1895 return false;
1896 }
1897
1898 return true;
1899 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001900
Daniel Sanders43c882c2017-02-01 10:53:10 +00001901public:
Daniel Sandersa7b75262017-10-31 18:50:24 +00001902 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
1903 : InsnID(InsnID), I(I), Matched(nullptr) {}
1904
Daniel Sandersdf258e32017-10-31 19:09:29 +00001905 const CodeGenInstruction *getCGI() const { return I; }
1906
Daniel Sandersa7b75262017-10-31 18:50:24 +00001907 void chooseInsnToMutate(RuleMatcher &Rule) {
1908 for (const auto *MutateCandidate : Rule.mutatable_insns()) {
1909 if (canMutate(Rule, MutateCandidate)) {
1910 // Take the first one we're offered that we're able to mutate.
1911 Rule.reserveInsnMatcherForMutation(MutateCandidate);
1912 Matched = MutateCandidate;
1913 return;
1914 }
1915 }
1916 }
Daniel Sanders43c882c2017-02-01 10:53:10 +00001917
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001918 template <class Kind, class... Args>
1919 Kind &addRenderer(Args&&... args) {
1920 OperandRenderers.emplace_back(
Daniel Sanders198447a2017-11-01 00:29:47 +00001921 llvm::make_unique<Kind>(InsnID, std::forward<Args>(args)...));
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001922 return *static_cast<Kind *>(OperandRenderers.back().get());
1923 }
1924
Daniel Sandersa7b75262017-10-31 18:50:24 +00001925 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1926 if (Matched) {
1927 assert(canMutate(Rule, Matched) &&
1928 "Arranged to mutate an insn that isn't mutatable");
1929
1930 unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001931 Table << MatchTable::Opcode("GIR_MutateOpcode")
1932 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1933 << MatchTable::Comment("RecycleInsnID")
1934 << MatchTable::IntValue(RecycleInsnID)
1935 << MatchTable::Comment("Opcode")
1936 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1937 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001938
1939 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001940 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001941 auto Namespace = Def->getValue("Namespace")
1942 ? Def->getValueAsString("Namespace")
1943 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001944 Table << MatchTable::Opcode("GIR_AddImplicitDef")
1945 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1946 << MatchTable::NamedValue(Namespace, Def->getName())
1947 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001948 }
1949 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001950 auto Namespace = Use->getValue("Namespace")
1951 ? Use->getValueAsString("Namespace")
1952 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001953 Table << MatchTable::Opcode("GIR_AddImplicitUse")
1954 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1955 << MatchTable::NamedValue(Namespace, Use->getName())
1956 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001957 }
1958 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001959 return;
1960 }
1961
1962 // TODO: Simple permutation looks like it could be almost as common as
1963 // mutation due to commutative operations.
1964
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001965 Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
1966 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
1967 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1968 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001969 for (const auto &Renderer : OperandRenderers)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001970 Renderer->emitRenderOpcodes(Table, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001971
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001972 if (I->mayLoad || I->mayStore) {
1973 Table << MatchTable::Opcode("GIR_MergeMemOperands")
1974 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1975 << MatchTable::Comment("MergeInsnID's");
1976 // Emit the ID's for all the instructions that are matched by this rule.
1977 // TODO: Limit this to matched instructions that mayLoad/mayStore or have
1978 // some other means of having a memoperand. Also limit this to
1979 // emitted instructions that expect to have a memoperand too. For
1980 // example, (G_SEXT (G_LOAD x)) that results in separate load and
1981 // sign-extend instructions shouldn't put the memoperand on the
1982 // sign-extend since it has no effect there.
1983 std::vector<unsigned> MergeInsnIDs;
1984 for (const auto &IDMatcherPair : Rule.defined_insn_vars())
1985 MergeInsnIDs.push_back(IDMatcherPair.second);
1986 std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end());
1987 for (const auto &MergeInsnID : MergeInsnIDs)
1988 Table << MatchTable::IntValue(MergeInsnID);
Daniel Sanders05540042017-08-08 10:44:31 +00001989 Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
1990 << MatchTable::LineBreak;
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001991 }
1992
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001993 // FIXME: This is a hack but it's sufficient for ISel. We'll need to do
1994 // better for combines. Particularly when there are multiple match
1995 // roots.
1996 if (InsnID == 0)
1997 Table << MatchTable::Opcode("GIR_EraseFromParent")
1998 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1999 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002000 }
2001};
2002
2003/// Generates code to constrain the operands of an output instruction to the
2004/// register classes specified by the definition of that instruction.
2005class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002006 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002007
2008public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002009 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002010
Daniel Sandersa7b75262017-10-31 18:50:24 +00002011 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002012 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2013 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2014 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002015 }
2016};
2017
2018/// Generates code to constrain the specified operand of an output instruction
2019/// to the specified register class.
2020class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002021 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002022 unsigned OpIdx;
2023 const CodeGenRegisterClass &RC;
2024
2025public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002026 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002027 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002028 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002029
Daniel Sandersa7b75262017-10-31 18:50:24 +00002030 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002031 Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
2032 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2033 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
2034 << MatchTable::Comment("RC " + RC.getName())
2035 << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002036 }
2037};
2038
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002039/// Generates code to create a temporary register which can be used to chain
2040/// instructions together.
2041class MakeTempRegisterAction : public MatchAction {
2042private:
2043 LLTCodeGen Ty;
2044 unsigned TempRegID;
2045
2046public:
2047 MakeTempRegisterAction(const LLTCodeGen &Ty, unsigned TempRegID)
2048 : Ty(Ty), TempRegID(TempRegID) {}
2049
2050 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2051 Table << MatchTable::Opcode("GIR_MakeTempReg")
2052 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
2053 << MatchTable::Comment("TypeID")
2054 << MatchTable::NamedValue(Ty.getCxxEnumValue())
2055 << MatchTable::LineBreak;
2056 }
2057};
2058
Daniel Sanders05540042017-08-08 10:44:31 +00002059InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002060 Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
Daniel Sandersa7b75262017-10-31 18:50:24 +00002061 MutatableInsns.insert(Matchers.back().get());
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002062 return *Matchers.back();
2063}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00002064
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002065void RuleMatcher::addRequiredFeature(Record *Feature) {
2066 RequiredFeatures.push_back(Feature);
2067}
2068
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002069const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
2070 return RequiredFeatures;
2071}
2072
Daniel Sanders7438b262017-10-31 23:03:18 +00002073// Emplaces an action of the specified Kind at the end of the action list.
2074//
2075// Returns a reference to the newly created action.
2076//
2077// Like std::vector::emplace_back(), may invalidate all iterators if the new
2078// size exceeds the capacity. Otherwise, only invalidates the past-the-end
2079// iterator.
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002080template <class Kind, class... Args>
2081Kind &RuleMatcher::addAction(Args &&... args) {
2082 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
2083 return *static_cast<Kind *>(Actions.back().get());
2084}
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002085
Daniel Sanders7438b262017-10-31 23:03:18 +00002086// Emplaces an action of the specified Kind before the given insertion point.
2087//
2088// Returns an iterator pointing at the newly created instruction.
2089//
2090// Like std::vector::insert(), may invalidate all iterators if the new size
2091// exceeds the capacity. Otherwise, only invalidates the iterators from the
2092// insertion point onwards.
2093template <class Kind, class... Args>
2094action_iterator RuleMatcher::insertAction(action_iterator InsertPt,
2095 Args &&... args) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002096 return Actions.emplace(InsertPt,
2097 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sanders7438b262017-10-31 23:03:18 +00002098}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002099
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002100unsigned
2101RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
2102 unsigned NewInsnVarID = NextInsnVarID++;
2103 InsnVariableIDs[&Matcher] = NewInsnVarID;
2104 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002105}
2106
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002107unsigned RuleMatcher::defineInsnVar(MatchTable &Table,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002108 const InstructionMatcher &Matcher,
2109 unsigned InsnID, unsigned OpIdx) {
2110 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002111 Table << MatchTable::Opcode("GIM_RecordInsn")
2112 << MatchTable::Comment("DefineMI") << MatchTable::IntValue(NewInsnVarID)
2113 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
2114 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2115 << MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
2116 << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002117 return NewInsnVarID;
2118}
2119
2120unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
2121 const auto &I = InsnVariableIDs.find(&InsnMatcher);
2122 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002123 return I->second;
2124 llvm_unreachable("Matched Insn was not captured in a local variable");
2125}
2126
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002127void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
2128 if (DefinedOperands.find(SymbolicName) == DefinedOperands.end()) {
2129 DefinedOperands[SymbolicName] = &OM;
2130 return;
2131 }
2132
2133 // If the operand is already defined, then we must ensure both references in
2134 // the matcher have the exact same node.
2135 OM.addPredicate<SameOperandMatcher>(OM.getSymbolicName());
2136}
2137
Daniel Sanders05540042017-08-08 10:44:31 +00002138const InstructionMatcher &
2139RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
2140 for (const auto &I : InsnVariableIDs)
2141 if (I.first->getSymbolicName() == SymbolicName)
2142 return *I.first;
2143 llvm_unreachable(
2144 ("Failed to lookup instruction " + SymbolicName).str().c_str());
2145}
2146
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002147const OperandMatcher &
2148RuleMatcher::getOperandMatcher(StringRef Name) const {
2149 const auto &I = DefinedOperands.find(Name);
2150
2151 if (I == DefinedOperands.end())
2152 PrintFatalError(SrcLoc, "Operand " + Name + " was not declared in matcher");
2153
2154 return *I->second;
2155}
2156
Daniel Sanders9d662d22017-07-06 10:06:12 +00002157/// Emit MatchTable opcodes to check the shape of the match and capture
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002158/// instructions into local variables.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002159void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002160 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002161 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002162 Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002163}
2164
Daniel Sanders8e82af22017-07-27 11:03:45 +00002165void RuleMatcher::emit(MatchTable &Table) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002166 if (Matchers.empty())
2167 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002168
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002169 // The representation supports rules that require multiple roots such as:
2170 // %ptr(p0) = ...
2171 // %elt0(s32) = G_LOAD %ptr
2172 // %1(p0) = G_ADD %ptr, 4
2173 // %elt1(s32) = G_LOAD p0 %1
2174 // which could be usefully folded into:
2175 // %ptr(p0) = ...
2176 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
2177 // on some targets but we don't need to make use of that yet.
2178 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002179
Daniel Sanders8e82af22017-07-27 11:03:45 +00002180 unsigned LabelID = Table.allocateLabelID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002181 Table << MatchTable::Opcode("GIM_Try", +1)
Daniel Sanders8e82af22017-07-27 11:03:45 +00002182 << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(LabelID)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002183 << MatchTable::LineBreak;
2184
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002185 if (!RequiredFeatures.empty()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002186 Table << MatchTable::Opcode("GIM_CheckFeatures")
2187 << MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
2188 << MatchTable::LineBreak;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002189 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002190
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002191 emitCaptureOpcodes(Table);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002192
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002193 Matchers.front()->emitPredicateOpcodes(Table, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002194 getInsnVarID(*Matchers.front()));
2195
Daniel Sandersbee57392017-04-04 13:25:23 +00002196 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002197 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00002198 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002199 SmallVector<unsigned, 2> InsnIDs;
2200 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002201 // Skip the root node since it isn't moving anywhere. Everything else is
2202 // sinking to meet it.
2203 if (Pair.first == Matchers.front().get())
2204 continue;
2205
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002206 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00002207 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002208 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00002209
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002210 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002211 // Reject the difficult cases until we have a more accurate check.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002212 Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
2213 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2214 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00002215
2216 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
2217 // account for unsafe cases.
2218 //
2219 // Example:
2220 // MI1--> %0 = ...
2221 // %1 = ... %0
2222 // MI0--> %2 = ... %0
2223 // It's not safe to erase MI1. We currently handle this by not
2224 // erasing %0 (even when it's dead).
2225 //
2226 // Example:
2227 // MI1--> %0 = load volatile @a
2228 // %1 = load volatile @a
2229 // MI0--> %2 = ... %0
2230 // It's not safe to sink %0's def past %1. We currently handle
2231 // this by rejecting all loads.
2232 //
2233 // Example:
2234 // MI1--> %0 = load @a
2235 // %1 = store @a
2236 // MI0--> %2 = ... %0
2237 // It's not safe to sink %0's def past %1. We currently handle
2238 // this by rejecting all loads.
2239 //
2240 // Example:
2241 // G_CONDBR %cond, @BB1
2242 // BB0:
2243 // MI1--> %0 = load @a
2244 // G_BR @BB1
2245 // BB1:
2246 // MI0--> %2 = ... %0
2247 // It's not always safe to sink %0 across control flow. In this
2248 // case it may introduce a memory fault. We currentl handle this
2249 // by rejecting all loads.
2250 }
2251 }
2252
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002253 for (const auto &MA : Actions)
Daniel Sandersa7b75262017-10-31 18:50:24 +00002254 MA->emitActionOpcodes(Table, *this);
Daniel Sandersf76f3152017-11-16 00:46:35 +00002255
2256 if (GenerateCoverage)
2257 Table << MatchTable::Opcode("GIR_Coverage") << MatchTable::IntValue(RuleID)
2258 << MatchTable::LineBreak;
2259
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002260 Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
Daniel Sanders8e82af22017-07-27 11:03:45 +00002261 << MatchTable::Label(LabelID);
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002262}
Daniel Sanders43c882c2017-02-01 10:53:10 +00002263
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002264bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
2265 // Rules involving more match roots have higher priority.
2266 if (Matchers.size() > B.Matchers.size())
2267 return true;
2268 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00002269 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002270
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002271 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
2272 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
2273 return true;
2274 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
2275 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002276 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002277
2278 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00002279}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002280
Daniel Sanders2deea182017-04-22 15:11:04 +00002281unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002282 return std::accumulate(
2283 Matchers.begin(), Matchers.end(), 0,
2284 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00002285 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002286 });
2287}
2288
Daniel Sanders05540042017-08-08 10:44:31 +00002289bool OperandPredicateMatcher::isHigherPriorityThan(
2290 const OperandPredicateMatcher &B) const {
2291 // Generally speaking, an instruction is more important than an Int or a
2292 // LiteralInt because it can cover more nodes but theres an exception to
2293 // this. G_CONSTANT's are less important than either of those two because they
2294 // are more permissive.
Daniel Sandersedd07842017-08-17 09:26:14 +00002295
2296 const InstructionOperandMatcher *AOM =
2297 dyn_cast<InstructionOperandMatcher>(this);
2298 const InstructionOperandMatcher *BOM =
2299 dyn_cast<InstructionOperandMatcher>(&B);
2300 bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
2301 bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
2302
2303 if (AOM && BOM) {
2304 // The relative priorities between a G_CONSTANT and any other instruction
2305 // don't actually matter but this code is needed to ensure a strict weak
2306 // ordering. This is particularly important on Windows where the rules will
2307 // be incorrectly sorted without it.
2308 if (AIsConstantInsn != BIsConstantInsn)
2309 return AIsConstantInsn < BIsConstantInsn;
2310 return false;
Daniel Sanders05540042017-08-08 10:44:31 +00002311 }
Daniel Sandersedd07842017-08-17 09:26:14 +00002312
2313 if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
2314 return false;
2315 if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
2316 return true;
Daniel Sanders05540042017-08-08 10:44:31 +00002317
2318 return Kind < B.Kind;
Daniel Sanders75b84fc2017-08-08 13:21:26 +00002319}
Daniel Sanders05540042017-08-08 10:44:31 +00002320
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002321void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
2322 RuleMatcher &Rule,
2323 unsigned InsnVarID,
2324 unsigned OpIdx) const {
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002325 const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002326 unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
2327
2328 Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
2329 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
2330 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2331 << MatchTable::Comment("OtherMI")
2332 << MatchTable::IntValue(OtherInsnVarID)
2333 << MatchTable::Comment("OtherOpIdx")
2334 << MatchTable::IntValue(OtherOM.getOperandIndex())
2335 << MatchTable::LineBreak;
2336}
2337
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002338//===- GlobalISelEmitter class --------------------------------------------===//
2339
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002340class GlobalISelEmitter {
2341public:
2342 explicit GlobalISelEmitter(RecordKeeper &RK);
2343 void run(raw_ostream &OS);
2344
2345private:
2346 const RecordKeeper &RK;
2347 const CodeGenDAGPatterns CGP;
2348 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002349 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002350
Daniel Sanders39690bd2017-10-15 02:41:12 +00002351 /// Keep track of the equivalence between SDNodes and Instruction by mapping
2352 /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
2353 /// check for attributes on the relation such as CheckMMOIsNonAtomic.
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002354 /// This is defined using 'GINodeEquiv' in the target description.
Daniel Sanders39690bd2017-10-15 02:41:12 +00002355 DenseMap<Record *, Record *> NodeEquivs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002356
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002357 /// Keep track of the equivalence between ComplexPattern's and
2358 /// GIComplexOperandMatcher. Map entries are specified by subclassing
2359 /// GIComplexPatternEquiv.
2360 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
2361
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002362 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002363 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002364
Daniel Sandersf76f3152017-11-16 00:46:35 +00002365 // Rule coverage information.
2366 Optional<CodeGenCoverage> RuleCoverage;
2367
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002368 void gatherNodeEquivs();
Daniel Sanders39690bd2017-10-15 02:41:12 +00002369 Record *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002370
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002371 Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002372 Expected<InstructionMatcher &> createAndImportSelDAGMatcher(
2373 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2374 const TreePatternNode *Src, unsigned &TempOpIdx) const;
2375 Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
2376 unsigned &TempOpIdx) const;
2377 Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002378 const TreePatternNode *SrcChild,
2379 bool OperandIsAPointer, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00002380 unsigned &TempOpIdx) const;
Daniel Sandersdf258e32017-10-31 19:09:29 +00002381
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002382 Expected<BuildMIAction &>
Daniel Sandersa7b75262017-10-31 18:50:24 +00002383 createAndImportInstructionRenderer(RuleMatcher &M,
2384 const TreePatternNode *Dst);
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002385 Expected<action_iterator> createAndImportSubInstructionRenderer(
2386 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
2387 unsigned TempReg);
Daniel Sanders7438b262017-10-31 23:03:18 +00002388 Expected<action_iterator>
2389 createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
2390 const TreePatternNode *Dst);
Daniel Sandersdf258e32017-10-31 19:09:29 +00002391 void importExplicitDefRenderers(BuildMIAction &DstMIBuilder);
Daniel Sanders7438b262017-10-31 23:03:18 +00002392 Expected<action_iterator>
2393 importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M,
2394 BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00002395 const llvm::TreePatternNode *Dst);
Daniel Sanders7438b262017-10-31 23:03:18 +00002396 Expected<action_iterator>
2397 importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
2398 BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002399 TreePatternNode *DstChild);
Diana Picus382602f2017-05-17 08:57:28 +00002400 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
2401 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00002402 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002403 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
2404 const std::vector<Record *> &ImplicitDefs) const;
2405
Daniel Sanders11300ce2017-10-13 21:28:03 +00002406 void emitImmPredicates(raw_ostream &OS, StringRef TypeIdentifier,
2407 StringRef Type,
Daniel Sanders649c5852017-10-13 20:42:18 +00002408 std::function<bool(const Record *R)> Filter);
2409
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002410 /// Analyze pattern \p P, returning a matcher for it if possible.
2411 /// Otherwise, return an Error explaining why we don't support it.
2412 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002413
2414 void declareSubtargetFeature(Record *Predicate);
Daniel Sanders7e523672017-11-11 03:23:44 +00002415
2416 TreePatternNode *fixupPatternNode(TreePatternNode *N);
2417 void fixupPatternTrees(TreePattern *P);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002418};
2419
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002420void GlobalISelEmitter::gatherNodeEquivs() {
2421 assert(NodeEquivs.empty());
2422 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
Daniel Sanders39690bd2017-10-15 02:41:12 +00002423 NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002424
2425 assert(ComplexPatternEquivs.empty());
2426 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
2427 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
2428 if (!SelDAGEquiv)
2429 continue;
2430 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
2431 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002432}
2433
Daniel Sanders39690bd2017-10-15 02:41:12 +00002434Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002435 return NodeEquivs.lookup(N);
2436}
2437
2438GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Daniel Sanders7e523672017-11-11 03:23:44 +00002439 : RK(RK), CGP(RK, [&](TreePattern *P) { fixupPatternTrees(P); }),
2440 Target(CGP.getTargetInfo()), CGRegs(RK, Target.getHwModes()) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002441
2442//===- Emitter ------------------------------------------------------------===//
2443
Daniel Sandersc270c502017-03-30 09:36:33 +00002444Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002445GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002446 ArrayRef<Predicate> Predicates) {
2447 for (const Predicate &P : Predicates) {
2448 if (!P.Def)
2449 continue;
2450 declareSubtargetFeature(P.Def);
2451 M.addRequiredFeature(P.Def);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002452 }
2453
Daniel Sandersc270c502017-03-30 09:36:33 +00002454 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002455}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002456
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002457Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
2458 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2459 const TreePatternNode *Src, unsigned &TempOpIdx) const {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002460 Record *SrcGIEquivOrNull = nullptr;
Daniel Sanders85ffd362017-07-06 08:12:20 +00002461 const CodeGenInstruction *SrcGIOrNull = nullptr;
2462
Daniel Sandersffc7d582017-03-29 15:37:18 +00002463 // Start with the defined operands (i.e., the results of the root operator).
2464 if (Src->getExtTypes().size() > 1)
2465 return failedImport("Src pattern has multiple results");
2466
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002467 if (Src->isLeaf()) {
2468 Init *SrcInit = Src->getLeafValue();
Daniel Sanders3334cc02017-05-23 20:02:48 +00002469 if (isa<IntInit>(SrcInit)) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002470 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
2471 &Target.getInstruction(RK.getDef("G_CONSTANT")));
2472 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002473 return failedImport(
2474 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002475 } else {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002476 SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
2477 if (!SrcGIEquivOrNull)
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002478 return failedImport("Pattern operator lacks an equivalent Instruction" +
2479 explainOperator(Src->getOperator()));
Daniel Sanders39690bd2017-10-15 02:41:12 +00002480 SrcGIOrNull = &Target.getInstruction(SrcGIEquivOrNull->getValueAsDef("I"));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002481
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002482 // The operators look good: match the opcode
Daniel Sanders39690bd2017-10-15 02:41:12 +00002483 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002484 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002485
2486 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002487 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002488 // Results don't have a name unless they are the root node. The caller will
2489 // set the name if appropriate.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002490 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002491 if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
2492 return failedImport(toString(std::move(Error)) +
2493 " for result of Src pattern operator");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002494 }
2495
Daniel Sanders2c269f62017-08-24 09:11:20 +00002496 for (const auto &Predicate : Src->getPredicateFns()) {
2497 if (Predicate.isAlwaysTrue())
2498 continue;
2499
2500 if (Predicate.isImmediatePattern()) {
2501 InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
2502 continue;
2503 }
2504
Daniel Sandersa71f4542017-10-16 00:56:30 +00002505 // No check required. G_LOAD by itself is a non-extending load.
2506 if (Predicate.isNonExtLoad())
2507 continue;
2508
Daniel Sandersd66e0902017-10-23 18:19:24 +00002509 // No check required. G_STORE by itself is a non-extending store.
2510 if (Predicate.isNonTruncStore())
2511 continue;
2512
Daniel Sanders76664652017-11-28 22:07:05 +00002513 if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
2514 if (Predicate.getMemoryVT() != nullptr) {
2515 Optional<LLTCodeGen> MemTyOrNone =
2516 MVTToLLT(getValueType(Predicate.getMemoryVT()));
Daniel Sandersd66e0902017-10-23 18:19:24 +00002517
Daniel Sanders76664652017-11-28 22:07:05 +00002518 if (!MemTyOrNone)
2519 return failedImport("MemVT could not be converted to LLT");
Daniel Sandersd66e0902017-10-23 18:19:24 +00002520
Daniel Sanders76664652017-11-28 22:07:05 +00002521 InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(
2522 MemTyOrNone.getValue());
2523 continue;
2524 }
2525 }
2526
2527 if (Predicate.isLoad() || Predicate.isStore()) {
2528 // No check required. A G_LOAD/G_STORE is an unindexed load.
2529 if (Predicate.isUnindexed())
2530 continue;
2531 }
2532
2533 if (Predicate.isAtomic()) {
2534 if (Predicate.isAtomicOrderingMonotonic()) {
2535 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2536 "Monotonic");
2537 continue;
2538 }
2539 if (Predicate.isAtomicOrderingAcquire()) {
2540 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
2541 continue;
2542 }
2543 if (Predicate.isAtomicOrderingRelease()) {
2544 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
2545 continue;
2546 }
2547 if (Predicate.isAtomicOrderingAcquireRelease()) {
2548 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2549 "AcquireRelease");
2550 continue;
2551 }
2552 if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
2553 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
2554 "SequentiallyConsistent");
2555 continue;
2556 }
Daniel Sandersd66e0902017-10-23 18:19:24 +00002557 }
2558
Daniel Sanders2c269f62017-08-24 09:11:20 +00002559 return failedImport("Src pattern child has predicate (" +
2560 explainPredicates(Src) + ")");
2561 }
Daniel Sanders39690bd2017-10-15 02:41:12 +00002562 if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
Daniel Sanders76664652017-11-28 22:07:05 +00002563 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
Daniel Sanders2c269f62017-08-24 09:11:20 +00002564
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002565 if (Src->isLeaf()) {
2566 Init *SrcInit = Src->getLeafValue();
2567 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002568 OperandMatcher &OM =
2569 InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002570 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
2571 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002572 return failedImport(
2573 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002574 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002575 assert(SrcGIOrNull &&
2576 "Expected to have already found an equivalent Instruction");
Daniel Sanders11300ce2017-10-13 21:28:03 +00002577 if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
2578 SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
2579 // imm/fpimm still have operands but we don't need to do anything with it
Daniel Sanders05540042017-08-08 10:44:31 +00002580 // here since we don't support ImmLeaf predicates yet. However, we still
2581 // need to note the hidden operand to get GIM_CheckNumOperands correct.
2582 InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2583 return InsnMatcher;
2584 }
2585
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002586 // Match the used operands (i.e. the children of the operator).
2587 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002588 TreePatternNode *SrcChild = Src->getChild(i);
2589
Daniel Sandersa71f4542017-10-16 00:56:30 +00002590 // SelectionDAG allows pointers to be represented with iN since it doesn't
2591 // distinguish between pointers and integers but they are different types in GlobalISel.
2592 // Coerce integers to pointers to address space 0 if the context indicates a pointer.
Daniel Sandersc54aa9c2017-11-18 00:16:44 +00002593 bool OperandIsAPointer = SrcGIOrNull->isOperandAPointer(i);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002594
Daniel Sanders28887fe2017-09-19 12:56:36 +00002595 // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
2596 // following the defs is an intrinsic ID.
2597 if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
2598 SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
2599 i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002600 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002601 OperandMatcher &OM =
2602 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002603 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00002604 continue;
2605 }
2606
2607 return failedImport("Expected IntInit containing instrinsic ID)");
2608 }
2609
Daniel Sandersa71f4542017-10-16 00:56:30 +00002610 if (auto Error =
2611 importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
2612 OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002613 return std::move(Error);
2614 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002615 }
2616
2617 return InsnMatcher;
2618}
2619
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002620Error GlobalISelEmitter::importComplexPatternOperandMatcher(
2621 OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
2622 const auto &ComplexPattern = ComplexPatternEquivs.find(R);
2623 if (ComplexPattern == ComplexPatternEquivs.end())
2624 return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
2625 ") not mapped to GlobalISel");
2626
2627 OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
2628 TempOpIdx++;
2629 return Error::success();
2630}
2631
2632Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
2633 InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002634 const TreePatternNode *SrcChild,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002635 bool OperandIsAPointer,
Daniel Sandersc270c502017-03-30 09:36:33 +00002636 unsigned OpIdx,
2637 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002638 OperandMatcher &OM =
2639 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002640 if (OM.isSameAsAnotherOperand())
2641 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002642
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002643 ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002644 if (ChildTypes.size() != 1)
2645 return failedImport("Src pattern child has multiple results");
2646
2647 // Check MBB's before the type check since they are not a known type.
2648 if (!SrcChild->isLeaf()) {
2649 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
2650 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
2651 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
2652 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00002653 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002654 }
2655 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002656 }
2657
Daniel Sandersa71f4542017-10-16 00:56:30 +00002658 if (auto Error =
2659 OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
2660 return failedImport(toString(std::move(Error)) + " for Src operand (" +
2661 to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002662
Daniel Sandersbee57392017-04-04 13:25:23 +00002663 // Check for nested instructions.
2664 if (!SrcChild->isLeaf()) {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002665 if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
2666 // When a ComplexPattern is used as an operator, it should do the same
2667 // thing as when used as a leaf. However, the children of the operator
2668 // name the sub-operands that make up the complex operand and we must
2669 // prepare to reference them in the renderer too.
2670 unsigned RendererID = TempOpIdx;
2671 if (auto Error = importComplexPatternOperandMatcher(
2672 OM, SrcChild->getOperator(), TempOpIdx))
2673 return Error;
2674
2675 for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
2676 auto *SubOperand = SrcChild->getChild(i);
2677 if (!SubOperand->getName().empty())
2678 Rule.defineComplexSubOperand(SubOperand->getName(),
2679 SrcChild->getOperator(), RendererID, i);
2680 }
2681
2682 return Error::success();
2683 }
2684
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002685 auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
2686 InsnMatcher.getRuleMatcher(), SrcChild->getName());
2687 if (!MaybeInsnOperand.hasValue()) {
2688 // This isn't strictly true. If the user were to provide exactly the same
2689 // matchers as the original operand then we could allow it. However, it's
2690 // simpler to not permit the redundant specification.
2691 return failedImport("Nested instruction cannot be the same as another operand");
2692 }
2693
Daniel Sandersbee57392017-04-04 13:25:23 +00002694 // Map the node to a gMIR instruction.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002695 InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
Daniel Sanders57938df2017-07-11 10:40:18 +00002696 auto InsnMatcherOrError = createAndImportSelDAGMatcher(
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002697 Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00002698 if (auto Error = InsnMatcherOrError.takeError())
2699 return Error;
2700
2701 return Error::success();
2702 }
2703
Diana Picusd1b61812017-11-03 10:30:19 +00002704 if (SrcChild->hasAnyPredicate())
2705 return failedImport("Src pattern child has unsupported predicate");
2706
Daniel Sandersffc7d582017-03-29 15:37:18 +00002707 // Check for constant immediates.
2708 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002709 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00002710 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002711 }
2712
2713 // Check for def's like register classes or ComplexPattern's.
2714 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
2715 auto *ChildRec = ChildDefInit->getDef();
2716
2717 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002718 if (ChildRec->isSubClassOf("RegisterClass") ||
2719 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002720 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002721 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00002722 return Error::success();
2723 }
2724
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002725 // Check for ValueType.
2726 if (ChildRec->isSubClassOf("ValueType")) {
2727 // We already added a type check as standard practice so this doesn't need
2728 // to do anything.
2729 return Error::success();
2730 }
2731
Daniel Sandersffc7d582017-03-29 15:37:18 +00002732 // Check for ComplexPattern's.
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002733 if (ChildRec->isSubClassOf("ComplexPattern"))
2734 return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002735
Daniel Sandersd0656a32017-04-13 09:45:37 +00002736 if (ChildRec->isSubClassOf("ImmLeaf")) {
2737 return failedImport(
2738 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
2739 }
2740
Daniel Sandersffc7d582017-03-29 15:37:18 +00002741 return failedImport(
2742 "Src pattern child def is an unsupported tablegen class");
2743 }
2744
2745 return failedImport("Src pattern child is an unsupported kind");
2746}
2747
Daniel Sanders7438b262017-10-31 23:03:18 +00002748Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
2749 action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002750 TreePatternNode *DstChild) {
Daniel Sanders2c269f62017-08-24 09:11:20 +00002751 if (DstChild->getTransformFn() != nullptr) {
2752 return failedImport("Dst pattern child has transform fn " +
2753 DstChild->getTransformFn()->getName());
2754 }
2755
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002756 const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
2757 if (SubOperand.hasValue()) {
2758 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002759 *std::get<0>(*SubOperand), DstChild->getName(),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002760 std::get<1>(*SubOperand), std::get<2>(*SubOperand));
Daniel Sanders7438b262017-10-31 23:03:18 +00002761 return InsertPt;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002762 }
2763
Daniel Sandersffc7d582017-03-29 15:37:18 +00002764 if (!DstChild->isLeaf()) {
Daniel Sanders05540042017-08-08 10:44:31 +00002765 // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
2766 // inline, but in MI it's just another operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002767 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
2768 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
2769 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sanders198447a2017-11-01 00:29:47 +00002770 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002771 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002772 }
2773 }
Daniel Sanders05540042017-08-08 10:44:31 +00002774
2775 // Similarly, imm is an operator in TreePatternNode's view but must be
2776 // rendered as operands.
2777 // FIXME: The target should be able to choose sign-extended when appropriate
2778 // (e.g. on Mips).
2779 if (DstChild->getOperator()->getName() == "imm") {
Daniel Sanders198447a2017-11-01 00:29:47 +00002780 DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002781 return InsertPt;
Daniel Sanders11300ce2017-10-13 21:28:03 +00002782 } else if (DstChild->getOperator()->getName() == "fpimm") {
2783 DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002784 DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002785 return InsertPt;
Daniel Sanders05540042017-08-08 10:44:31 +00002786 }
2787
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002788 if (DstChild->getOperator()->isSubClassOf("Instruction")) {
2789 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
2790 if (ChildTypes.size() != 1)
2791 return failedImport("Dst pattern child has multiple results");
2792
2793 Optional<LLTCodeGen> OpTyOrNone = None;
2794 if (ChildTypes.front().isMachineValueType())
2795 OpTyOrNone =
2796 MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
2797 if (!OpTyOrNone)
2798 return failedImport("Dst operand has an unsupported type");
2799
2800 unsigned TempRegID = Rule.allocateTempRegID();
2801 InsertPt = Rule.insertAction<MakeTempRegisterAction>(
2802 InsertPt, OpTyOrNone.getValue(), TempRegID);
2803 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
2804
2805 auto InsertPtOrError = createAndImportSubInstructionRenderer(
2806 ++InsertPt, Rule, DstChild, TempRegID);
2807 if (auto Error = InsertPtOrError.takeError())
2808 return std::move(Error);
2809 return InsertPtOrError.get();
2810 }
2811
Daniel Sanders2c269f62017-08-24 09:11:20 +00002812 return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002813 }
2814
2815 // Otherwise, we're looking for a bog-standard RegisterClass operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002816 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
2817 auto *ChildRec = ChildDefInit->getDef();
2818
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002819 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002820 if (ChildTypes.size() != 1)
2821 return failedImport("Dst pattern child has multiple results");
2822
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002823 Optional<LLTCodeGen> OpTyOrNone = None;
2824 if (ChildTypes.front().isMachineValueType())
2825 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002826 if (!OpTyOrNone)
2827 return failedImport("Dst operand has an unsupported type");
2828
2829 if (ChildRec->isSubClassOf("Register")) {
Daniel Sanders198447a2017-11-01 00:29:47 +00002830 DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
Daniel Sanders7438b262017-10-31 23:03:18 +00002831 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002832 }
2833
Daniel Sanders658541f2017-04-22 15:53:21 +00002834 if (ChildRec->isSubClassOf("RegisterClass") ||
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002835 ChildRec->isSubClassOf("RegisterOperand") ||
2836 ChildRec->isSubClassOf("ValueType")) {
Daniel Sandersd66e0902017-10-23 18:19:24 +00002837 if (ChildRec->isSubClassOf("RegisterOperand") &&
2838 !ChildRec->isValueUnset("GIZeroRegister")) {
2839 DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002840 DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
Daniel Sanders7438b262017-10-31 23:03:18 +00002841 return InsertPt;
Daniel Sandersd66e0902017-10-23 18:19:24 +00002842 }
2843
Daniel Sanders198447a2017-11-01 00:29:47 +00002844 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002845 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002846 }
2847
2848 if (ChildRec->isSubClassOf("ComplexPattern")) {
2849 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
2850 if (ComplexPattern == ComplexPatternEquivs.end())
2851 return failedImport(
2852 "SelectionDAG ComplexPattern not mapped to GlobalISel");
2853
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002854 const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002855 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002856 *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00002857 OM.getAllocatedTemporariesBaseID());
Daniel Sanders7438b262017-10-31 23:03:18 +00002858 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002859 }
2860
Daniel Sandersd0656a32017-04-13 09:45:37 +00002861 if (ChildRec->isSubClassOf("SDNodeXForm"))
2862 return failedImport("Dst pattern child def is an unsupported tablegen "
2863 "class (SDNodeXForm)");
2864
Daniel Sandersffc7d582017-03-29 15:37:18 +00002865 return failedImport(
2866 "Dst pattern child def is an unsupported tablegen class");
2867 }
2868
2869 return failedImport("Dst pattern child is an unsupported kind");
2870}
2871
Daniel Sandersc270c502017-03-30 09:36:33 +00002872Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersa7b75262017-10-31 18:50:24 +00002873 RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sanders7438b262017-10-31 23:03:18 +00002874 auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
2875 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00002876 return std::move(Error);
2877
Daniel Sanders7438b262017-10-31 23:03:18 +00002878 action_iterator InsertPt = InsertPtOrError.get();
2879 BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
Daniel Sandersdf258e32017-10-31 19:09:29 +00002880
2881 importExplicitDefRenderers(DstMIBuilder);
2882
Daniel Sanders7438b262017-10-31 23:03:18 +00002883 if (auto Error = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst)
2884 .takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00002885 return std::move(Error);
2886
2887 return DstMIBuilder;
2888}
2889
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002890Expected<action_iterator>
2891GlobalISelEmitter::createAndImportSubInstructionRenderer(
2892 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
2893 unsigned TempRegID) {
2894 auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
2895
2896 // TODO: Assert there's exactly one result.
2897
2898 if (auto Error = InsertPtOrError.takeError())
2899 return std::move(Error);
2900 InsertPt = InsertPtOrError.get();
2901
2902 BuildMIAction &DstMIBuilder =
2903 *static_cast<BuildMIAction *>(InsertPtOrError.get()->get());
2904
2905 // Assign the result to TempReg.
2906 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);
2907
2908 InsertPtOrError = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst);
2909 if (auto Error = InsertPtOrError.takeError())
2910 return std::move(Error);
2911
2912 return InsertPtOrError.get();
2913}
2914
Daniel Sanders7438b262017-10-31 23:03:18 +00002915Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
2916 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002917 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00002918 if (!DstOp->isSubClassOf("Instruction")) {
2919 if (DstOp->isSubClassOf("ValueType"))
2920 return failedImport(
2921 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002922 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00002923 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002924 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002925
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002926 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002927 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersdf258e32017-10-31 19:09:29 +00002928 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS")
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002929 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sandersdf258e32017-10-31 19:09:29 +00002930 else if (DstI->TheDef->getName() == "EXTRACT_SUBREG")
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002931 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002932 else if (DstI->TheDef->getName() == "REG_SEQUENCE")
2933 return failedImport("Unable to emit REG_SEQUENCE");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002934
Daniel Sanders198447a2017-11-01 00:29:47 +00002935 return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),
2936 DstI);
Daniel Sandersdf258e32017-10-31 19:09:29 +00002937}
2938
2939void GlobalISelEmitter::importExplicitDefRenderers(
2940 BuildMIAction &DstMIBuilder) {
2941 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002942 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
2943 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sanders198447a2017-11-01 00:29:47 +00002944 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002945 }
Daniel Sandersdf258e32017-10-31 19:09:29 +00002946}
2947
Daniel Sanders7438b262017-10-31 23:03:18 +00002948Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
2949 action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00002950 const llvm::TreePatternNode *Dst) {
2951 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
2952 CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002953
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002954 // EXTRACT_SUBREG needs to use a subregister COPY.
Daniel Sandersdf258e32017-10-31 19:09:29 +00002955 if (OrigDstI->TheDef->getName() == "EXTRACT_SUBREG") {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002956 if (!Dst->getChild(0)->isLeaf())
2957 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2958
Daniel Sanders32291982017-06-28 13:50:04 +00002959 if (DefInit *SubRegInit =
2960 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002961 Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
2962 if (!RCDef)
2963 return failedImport("EXTRACT_SUBREG child #0 could not "
2964 "be coerced to a register class");
2965
2966 CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002967 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
2968
2969 const auto &SrcRCDstRCPair =
2970 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2971 if (SrcRCDstRCPair.hasValue()) {
2972 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
2973 if (SrcRCDstRCPair->first != RC)
2974 return failedImport("EXTRACT_SUBREG requires an additional COPY");
2975 }
2976
Daniel Sanders198447a2017-11-01 00:29:47 +00002977 DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
2978 SubIdx);
Daniel Sanders7438b262017-10-31 23:03:18 +00002979 return InsertPt;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002980 }
2981
2982 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
2983 }
2984
Daniel Sandersffc7d582017-03-29 15:37:18 +00002985 // Render the explicit uses.
Daniel Sandersdf258e32017-10-31 19:09:29 +00002986 unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
2987 unsigned ExpectedDstINumUses = Dst->getNumChildren();
2988 if (OrigDstI->TheDef->getName() == "COPY_TO_REGCLASS") {
2989 DstINumUses--; // Ignore the class constraint.
2990 ExpectedDstINumUses--;
2991 }
2992
Daniel Sanders0ed28822017-04-12 08:23:08 +00002993 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00002994 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002995 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002996 const CGIOperandList::OperandInfo &DstIOperand =
2997 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00002998
Diana Picus382602f2017-05-17 08:57:28 +00002999 // If the operand has default values, introduce them now.
3000 // FIXME: Until we have a decent test case that dictates we should do
3001 // otherwise, we're going to assume that operands with default values cannot
3002 // be specified in the patterns. Therefore, adding them will not cause us to
3003 // end up with too many rendered operands.
3004 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00003005 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00003006 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
3007 return std::move(Error);
3008 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00003009 continue;
3010 }
3011
Daniel Sanders7438b262017-10-31 23:03:18 +00003012 auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
3013 Dst->getChild(Child));
3014 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersffc7d582017-03-29 15:37:18 +00003015 return std::move(Error);
Daniel Sanders7438b262017-10-31 23:03:18 +00003016 InsertPt = InsertPtOrError.get();
Daniel Sanders0ed28822017-04-12 08:23:08 +00003017 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003018 }
3019
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003020 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00003021 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00003022 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003023 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00003024 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00003025 " default ones");
3026
Daniel Sanders7438b262017-10-31 23:03:18 +00003027 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003028}
3029
Diana Picus382602f2017-05-17 08:57:28 +00003030Error GlobalISelEmitter::importDefaultOperandRenderers(
3031 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00003032 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00003033 // Look through ValueType operators.
3034 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
3035 if (const DefInit *DefaultDagOperator =
3036 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
3037 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
3038 DefaultOp = DefaultDagOp->getArg(0);
3039 }
3040 }
3041
3042 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003043 DstMIBuilder.addRenderer<AddRegisterRenderer>(DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00003044 continue;
3045 }
3046
3047 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003048 DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00003049 continue;
3050 }
3051
3052 return failedImport("Could not add default op");
3053 }
3054
3055 return Error::success();
3056}
3057
Daniel Sandersc270c502017-03-30 09:36:33 +00003058Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00003059 BuildMIAction &DstMIBuilder,
3060 const std::vector<Record *> &ImplicitDefs) const {
3061 if (!ImplicitDefs.empty())
3062 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00003063 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003064}
3065
3066Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003067 // Keep track of the matchers and actions to emit.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003068 RuleMatcher M(P.getSrcRecord()->getLoc());
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00003069 M.addAction<DebugCommentAction>(llvm::to_string(*P.getSrcPattern()) +
3070 " => " +
3071 llvm::to_string(*P.getDstPattern()));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003072
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003073 if (auto Error = importRulePredicates(M, P.getPredicates()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003074 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003075
3076 // Next, analyze the pattern operators.
3077 TreePatternNode *Src = P.getSrcPattern();
3078 TreePatternNode *Dst = P.getDstPattern();
3079
3080 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00003081 if (auto Err = isTrivialOperatorNode(Dst))
3082 return failedImport("Dst pattern root isn't a trivial operator (" +
3083 toString(std::move(Err)) + ")");
3084 if (auto Err = isTrivialOperatorNode(Src))
3085 return failedImport("Src pattern root isn't a trivial operator (" +
3086 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003087
Daniel Sandersedd07842017-08-17 09:26:14 +00003088 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
3089 unsigned TempOpIdx = 0;
3090 auto InsnMatcherOrError =
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003091 createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
Daniel Sandersedd07842017-08-17 09:26:14 +00003092 if (auto Error = InsnMatcherOrError.takeError())
3093 return std::move(Error);
3094 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
3095
3096 if (Dst->isLeaf()) {
3097 Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
3098
3099 const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
3100 if (RCDef) {
3101 // We need to replace the def and all its uses with the specified
3102 // operand. However, we must also insert COPY's wherever needed.
3103 // For now, emit a copy and let the register allocator clean up.
3104 auto &DstI = Target.getInstruction(RK.getDef("COPY"));
3105 const auto &DstIOperand = DstI.Operands[0];
3106
3107 OperandMatcher &OM0 = InsnMatcher.getOperand(0);
3108 OM0.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003109 M.defineOperand(OM0.getSymbolicName(), OM0);
Daniel Sandersedd07842017-08-17 09:26:14 +00003110 OM0.addPredicate<RegisterBankOperandMatcher>(RC);
3111
Daniel Sanders198447a2017-11-01 00:29:47 +00003112 auto &DstMIBuilder =
3113 M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
3114 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
3115 DstMIBuilder.addRenderer<CopyRenderer>(Dst->getName());
Daniel Sandersedd07842017-08-17 09:26:14 +00003116 M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
3117
3118 // We're done with this pattern! It's eligible for GISel emission; return
3119 // it.
3120 ++NumPatternImported;
3121 return std::move(M);
3122 }
3123
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003124 return failedImport("Dst pattern root isn't a known leaf");
Daniel Sandersedd07842017-08-17 09:26:14 +00003125 }
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003126
Daniel Sandersbee57392017-04-04 13:25:23 +00003127 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003128 Record *DstOp = Dst->getOperator();
3129 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003130 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003131
3132 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003133 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00003134 return failedImport("Src pattern results and dst MI defs are different (" +
3135 to_string(Src->getExtTypes().size()) + " def(s) vs " +
3136 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003137
Daniel Sandersffc7d582017-03-29 15:37:18 +00003138 // The root of the match also has constraints on the register bank so that it
3139 // matches the result instruction.
3140 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003141 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
3142 (void)VTy;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003143
Daniel Sanders066ebbf2017-02-24 15:43:30 +00003144 const auto &DstIOperand = DstI.Operands[OpIdx];
3145 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003146 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3147 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3148
3149 if (DstIOpRec == nullptr)
3150 return failedImport(
3151 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003152 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3153 if (!Dst->getChild(0)->isLeaf())
3154 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
3155
Daniel Sanders32291982017-06-28 13:50:04 +00003156 // We can assume that a subregister is in the same bank as it's super
3157 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003158 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
3159
3160 if (DstIOpRec == nullptr)
3161 return failedImport(
3162 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003163 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00003164 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003165 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00003166 return failedImport("Dst MI def isn't a register class" +
3167 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003168
Daniel Sandersffc7d582017-03-29 15:37:18 +00003169 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
3170 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003171 M.defineOperand(OM.getSymbolicName(), OM);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00003172 OM.addPredicate<RegisterBankOperandMatcher>(
3173 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003174 ++OpIdx;
3175 }
3176
Daniel Sandersa7b75262017-10-31 18:50:24 +00003177 auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003178 if (auto Error = DstMIBuilderOrError.takeError())
3179 return std::move(Error);
3180 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003181
Daniel Sandersffc7d582017-03-29 15:37:18 +00003182 // Render the implicit defs.
3183 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00003184 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003185 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003186
Daniel Sandersa7b75262017-10-31 18:50:24 +00003187 DstMIBuilder.chooseInsnToMutate(M);
3188
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003189 // Constrain the registers to classes. This is normally derived from the
3190 // emitted instruction but a few instructions require special handling.
3191 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3192 // COPY_TO_REGCLASS does not provide operand constraints itself but the
3193 // result is constrained to the class given by the second child.
3194 Record *DstIOpRec =
3195 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3196
3197 if (DstIOpRec == nullptr)
3198 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
3199
3200 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003201 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003202
3203 // We're done with this pattern! It's eligible for GISel emission; return
3204 // it.
3205 ++NumPatternImported;
3206 return std::move(M);
3207 }
3208
3209 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3210 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
3211 // instructions, the result register class is controlled by the
3212 // subregisters of the operand. As a result, we must constrain the result
3213 // class rather than check that it's already the right one.
3214 if (!Dst->getChild(0)->isLeaf())
3215 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
3216
Daniel Sanders320390b2017-06-28 15:16:03 +00003217 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
3218 if (!SubRegInit)
3219 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003220
Daniel Sanders320390b2017-06-28 15:16:03 +00003221 // Constrain the result to the same register bank as the operand.
3222 Record *DstIOpRec =
3223 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003224
Daniel Sanders320390b2017-06-28 15:16:03 +00003225 if (DstIOpRec == nullptr)
3226 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003227
Daniel Sanders320390b2017-06-28 15:16:03 +00003228 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003229 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003230
Daniel Sanders320390b2017-06-28 15:16:03 +00003231 // It would be nice to leave this constraint implicit but we're required
3232 // to pick a register class so constrain the result to a register class
3233 // that can hold the correct MVT.
3234 //
3235 // FIXME: This may introduce an extra copy if the chosen class doesn't
3236 // actually contain the subregisters.
3237 assert(Src->getExtTypes().size() == 1 &&
3238 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003239
Daniel Sanders320390b2017-06-28 15:16:03 +00003240 const auto &SrcRCDstRCPair =
3241 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
3242 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003243 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
3244 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
3245
3246 // We're done with this pattern! It's eligible for GISel emission; return
3247 // it.
3248 ++NumPatternImported;
3249 return std::move(M);
3250 }
3251
3252 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003253
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003254 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003255 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003256 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003257}
3258
Daniel Sanders649c5852017-10-13 20:42:18 +00003259// Emit imm predicate table and an enum to reference them with.
3260// The 'Predicate_' part of the name is redundant but eliminating it is more
3261// trouble than it's worth.
3262void GlobalISelEmitter::emitImmPredicates(
Daniel Sanders11300ce2017-10-13 21:28:03 +00003263 raw_ostream &OS, StringRef TypeIdentifier, StringRef Type,
3264 std::function<bool(const Record *R)> Filter) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003265 std::vector<const Record *> MatchedRecords;
3266 const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
3267 std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
3268 [&](Record *Record) {
3269 return !Record->getValueAsString("ImmediateCode").empty() &&
3270 Filter(Record);
3271 });
3272
Daniel Sanders11300ce2017-10-13 21:28:03 +00003273 if (!MatchedRecords.empty()) {
3274 OS << "// PatFrag predicates.\n"
3275 << "enum {\n";
Daniel Sanders2fed4ff2017-10-13 21:51:20 +00003276 std::string EnumeratorSeparator =
Daniel Sanders11300ce2017-10-13 21:28:03 +00003277 (" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str();
3278 for (const auto *Record : MatchedRecords) {
3279 OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName()
3280 << EnumeratorSeparator;
3281 EnumeratorSeparator = ",\n";
3282 }
3283 OS << "};\n";
Daniel Sanders649c5852017-10-13 20:42:18 +00003284 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00003285
Daniel Sanders649c5852017-10-13 20:42:18 +00003286 for (const auto *Record : MatchedRecords)
Daniel Sanders11300ce2017-10-13 21:28:03 +00003287 OS << "static bool Predicate_" << Record->getName() << "(" << Type
3288 << " Imm) {" << Record->getValueAsString("ImmediateCode") << "}\n";
3289
3290 OS << "static InstructionSelector::" << TypeIdentifier
3291 << "ImmediatePredicateFn " << TypeIdentifier << "ImmPredicateFns[] = {\n"
Daniel Sanders649c5852017-10-13 20:42:18 +00003292 << " nullptr,\n";
3293 for (const auto *Record : MatchedRecords)
3294 OS << " Predicate_" << Record->getName() << ",\n";
3295 OS << "};\n";
3296}
3297
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003298void GlobalISelEmitter::run(raw_ostream &OS) {
Daniel Sandersf76f3152017-11-16 00:46:35 +00003299 if (!UseCoverageFile.empty()) {
3300 RuleCoverage = CodeGenCoverage();
3301 auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);
3302 if (!RuleCoverageBufOrErr) {
3303 PrintWarning(SMLoc(), "Missing rule coverage data");
3304 RuleCoverage = None;
3305 } else {
3306 if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {
3307 PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");
3308 RuleCoverage = None;
3309 }
3310 }
3311 }
3312
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003313 // Track the GINodeEquiv definitions.
3314 gatherNodeEquivs();
3315
3316 emitSourceFileHeader(("Global Instruction Selector for the " +
3317 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003318 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003319 // Look through the SelectionDAG patterns we found, possibly emitting some.
3320 for (const PatternToMatch &Pat : CGP.ptms()) {
3321 ++NumPatternTotal;
Daniel Sanders7e523672017-11-11 03:23:44 +00003322
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003323 auto MatcherOrErr = runOnPattern(Pat);
3324
3325 // The pattern analysis can fail, indicating an unsupported pattern.
3326 // Report that if we've been asked to do so.
3327 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003328 if (WarnOnSkippedPatterns) {
3329 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003330 "Skipped pattern: " + toString(std::move(Err)));
3331 } else {
3332 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003333 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003334 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003335 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003336 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003337
Daniel Sandersf76f3152017-11-16 00:46:35 +00003338 if (RuleCoverage) {
3339 if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))
3340 ++NumPatternsTested;
3341 else
3342 PrintWarning(Pat.getSrcRecord()->getLoc(),
3343 "Pattern is not covered by a test");
3344 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003345 Rules.push_back(std::move(MatcherOrErr.get()));
3346 }
3347
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00003348 std::stable_sort(Rules.begin(), Rules.end(),
3349 [&](const RuleMatcher &A, const RuleMatcher &B) {
3350 if (A.isHigherPriorityThan(B)) {
3351 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
3352 "and less important at "
3353 "the same time");
3354 return true;
3355 }
3356 return false;
3357 });
Daniel Sanders759ff412017-02-24 13:58:11 +00003358
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003359 std::vector<Record *> ComplexPredicates =
3360 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
3361 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
3362 [](const Record *A, const Record *B) {
3363 if (A->getName() < B->getName())
3364 return true;
3365 return false;
3366 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003367 unsigned MaxTemporaries = 0;
3368 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00003369 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003370
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003371 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
3372 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
3373 << ";\n"
3374 << "using PredicateBitset = "
3375 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
3376 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
3377
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003378 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
3379 << " mutable MatcherState State;\n"
3380 << " typedef "
Daniel Sanders1e4569f2017-10-20 20:55:29 +00003381 "ComplexRendererFns("
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003382 << Target.getName()
3383 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003384 << " const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003385 "MatcherInfo;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003386 << " static " << Target.getName()
3387 << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003388 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003389
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003390 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
3391 << ", State(" << MaxTemporaries << "),\n"
Daniel Sanders11300ce2017-10-13 21:28:03 +00003392 << "MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, "
Daniel Sandersea8711b2017-10-16 03:36:29 +00003393 "APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003394 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003395
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003396 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
3397 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
3398 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003399
3400 // Separate subtarget features by how often they must be recomputed.
3401 SubtargetFeatureInfoMap ModuleFeatures;
3402 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3403 std::inserter(ModuleFeatures, ModuleFeatures.end()),
3404 [](const SubtargetFeatureInfoMap::value_type &X) {
3405 return !X.second.mustRecomputePerFunction();
3406 });
3407 SubtargetFeatureInfoMap FunctionFeatures;
3408 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3409 std::inserter(FunctionFeatures, FunctionFeatures.end()),
3410 [](const SubtargetFeatureInfoMap::value_type &X) {
3411 return X.second.mustRecomputePerFunction();
3412 });
3413
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003414 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003415 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
3416 ModuleFeatures, OS);
3417 SubtargetFeatureInfo::emitComputeAvailableFeatures(
3418 Target.getName(), "InstructionSelector",
3419 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
3420 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003421
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003422 // Emit a table containing the LLT objects needed by the matcher and an enum
3423 // for the matcher to reference them with.
Daniel Sanders032e7f22017-08-17 13:18:35 +00003424 std::vector<LLTCodeGen> TypeObjects;
3425 for (const auto &Ty : LLTOperandMatcher::KnownTypes)
3426 TypeObjects.push_back(Ty);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003427 std::sort(TypeObjects.begin(), TypeObjects.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003428 OS << "// LLT Objects.\n"
3429 << "enum {\n";
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003430 for (const auto &TypeObject : TypeObjects) {
3431 OS << " ";
3432 TypeObject.emitCxxEnumValue(OS);
3433 OS << ",\n";
3434 }
3435 OS << "};\n"
3436 << "const static LLT TypeObjects[] = {\n";
3437 for (const auto &TypeObject : TypeObjects) {
3438 OS << " ";
3439 TypeObject.emitCxxConstructorCall(OS);
3440 OS << ",\n";
3441 }
3442 OS << "};\n\n";
3443
3444 // Emit a table containing the PredicateBitsets objects needed by the matcher
3445 // and an enum for the matcher to reference them with.
3446 std::vector<std::vector<Record *>> FeatureBitsets;
3447 for (auto &Rule : Rules)
3448 FeatureBitsets.push_back(Rule.getRequiredFeatures());
3449 std::sort(
3450 FeatureBitsets.begin(), FeatureBitsets.end(),
3451 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
3452 if (A.size() < B.size())
3453 return true;
3454 if (A.size() > B.size())
3455 return false;
3456 for (const auto &Pair : zip(A, B)) {
3457 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
3458 return true;
3459 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
3460 return false;
3461 }
3462 return false;
3463 });
3464 FeatureBitsets.erase(
3465 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
3466 FeatureBitsets.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003467 OS << "// Feature bitsets.\n"
3468 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003469 << " GIFBS_Invalid,\n";
3470 for (const auto &FeatureBitset : FeatureBitsets) {
3471 if (FeatureBitset.empty())
3472 continue;
3473 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
3474 }
3475 OS << "};\n"
3476 << "const static PredicateBitset FeatureBitsets[] {\n"
3477 << " {}, // GIFBS_Invalid\n";
3478 for (const auto &FeatureBitset : FeatureBitsets) {
3479 if (FeatureBitset.empty())
3480 continue;
3481 OS << " {";
3482 for (const auto &Feature : FeatureBitset) {
3483 const auto &I = SubtargetFeatures.find(Feature);
3484 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
3485 OS << I->second.getEnumBitName() << ", ";
3486 }
3487 OS << "},\n";
3488 }
3489 OS << "};\n\n";
3490
3491 // Emit complex predicate table and an enum to reference them with.
Daniel Sanders49980702017-08-23 10:09:25 +00003492 OS << "// ComplexPattern predicates.\n"
3493 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003494 << " GICP_Invalid,\n";
3495 for (const auto &Record : ComplexPredicates)
3496 OS << " GICP_" << Record->getName() << ",\n";
3497 OS << "};\n"
3498 << "// See constructor for table contents\n\n";
3499
Daniel Sanders11300ce2017-10-13 21:28:03 +00003500 emitImmPredicates(OS, "I64", "int64_t", [](const Record *R) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003501 bool Unset;
3502 return !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
3503 !R->getValueAsBit("IsAPInt");
3504 });
Daniel Sanders11300ce2017-10-13 21:28:03 +00003505 emitImmPredicates(OS, "APFloat", "const APFloat &", [](const Record *R) {
3506 bool Unset;
3507 return R->getValueAsBitOrUnset("IsAPFloat", Unset);
3508 });
3509 emitImmPredicates(OS, "APInt", "const APInt &", [](const Record *R) {
3510 return R->getValueAsBit("IsAPInt");
3511 });
Daniel Sandersea8711b2017-10-16 03:36:29 +00003512 OS << "\n";
3513
3514 OS << Target.getName() << "InstructionSelector::ComplexMatcherMemFn\n"
3515 << Target.getName() << "InstructionSelector::ComplexPredicateFns[] = {\n"
3516 << " nullptr, // GICP_Invalid\n";
3517 for (const auto &Record : ComplexPredicates)
3518 OS << " &" << Target.getName()
3519 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
3520 << ", // " << Record->getName() << "\n";
3521 OS << "};\n\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00003522
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003523 OS << "bool " << Target.getName()
Daniel Sandersf76f3152017-11-16 00:46:35 +00003524 << "InstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage "
3525 "&CoverageInfo) const {\n"
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003526 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003527 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00003528 << " // FIXME: This should be computed on a per-function basis rather "
3529 "than per-insn.\n"
3530 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
3531 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00003532 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
3533 << " NewMIVector OutMIs;\n"
3534 << " State.MIs.clear();\n"
3535 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003536
Daniel Sanders8e82af22017-07-27 11:03:45 +00003537 MatchTable Table(0);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00003538 for (auto &Rule : Rules) {
Daniel Sanders8e82af22017-07-27 11:03:45 +00003539 Rule.emit(Table);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003540 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003541 }
Daniel Sanders8e82af22017-07-27 11:03:45 +00003542 Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
3543 Table.emitDeclaration(OS);
3544 OS << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, ";
3545 Table.emitUse(OS);
Daniel Sandersf76f3152017-11-16 00:46:35 +00003546 OS << ", TII, MRI, TRI, RBI, AvailableFeatures, CoverageInfo)) {\n"
Daniel Sanders8e82af22017-07-27 11:03:45 +00003547 << " return true;\n"
3548 << " }\n\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003549
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003550 OS << " return false;\n"
3551 << "}\n"
3552 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003553
3554 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
3555 << "PredicateBitset AvailableModuleFeatures;\n"
3556 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
3557 << "PredicateBitset getAvailableFeatures() const {\n"
3558 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
3559 << "}\n"
3560 << "PredicateBitset\n"
3561 << "computeAvailableModuleFeatures(const " << Target.getName()
3562 << "Subtarget *Subtarget) const;\n"
3563 << "PredicateBitset\n"
3564 << "computeAvailableFunctionFeatures(const " << Target.getName()
3565 << "Subtarget *Subtarget,\n"
3566 << " const MachineFunction *MF) const;\n"
3567 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
3568
3569 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
3570 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
3571 << "AvailableFunctionFeatures()\n"
3572 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003573}
3574
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003575void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
3576 if (SubtargetFeatures.count(Predicate) == 0)
3577 SubtargetFeatures.emplace(
3578 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
3579}
3580
Daniel Sanders7e523672017-11-11 03:23:44 +00003581TreePatternNode *GlobalISelEmitter::fixupPatternNode(TreePatternNode *N) {
3582 if (!N->isLeaf()) {
3583 for (unsigned I = 0, E = N->getNumChildren(); I < E; ++I) {
3584 TreePatternNode *OrigChild = N->getChild(I);
3585 TreePatternNode *NewChild = fixupPatternNode(OrigChild);
3586 if (OrigChild != NewChild)
3587 N->setChild(I, NewChild);
3588 }
3589
3590 if (N->getOperator()->getName() == "ld") {
3591 // If it's a signext-load we need to adapt the pattern slightly. We need
3592 // to split the node into (sext (ld ...)), remove the <<signext>> predicate,
3593 // and then apply the <<signextTY>> predicate by updating the result type
3594 // of the load.
3595 //
3596 // For example:
3597 // (ld:[i32] [iPTR])<<unindexed>><<signext>><<signexti16>>
3598 // must be transformed into:
3599 // (sext:[i32] (ld:[i16] [iPTR])<<unindexed>>)
3600 //
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003601 // Likewise for zeroext-load and anyext-load.
Daniel Sanders7e523672017-11-11 03:23:44 +00003602
3603 std::vector<TreePredicateFn> Predicates;
3604 bool IsSignExtLoad = false;
3605 bool IsZeroExtLoad = false;
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003606 bool IsAnyExtLoad = false;
Daniel Sanders7e523672017-11-11 03:23:44 +00003607 Record *MemVT = nullptr;
3608 for (const auto &P : N->getPredicateFns()) {
3609 if (P.isLoad() && P.isSignExtLoad()) {
3610 IsSignExtLoad = true;
3611 continue;
3612 }
3613 if (P.isLoad() && P.isZeroExtLoad()) {
3614 IsZeroExtLoad = true;
3615 continue;
3616 }
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003617 if (P.isLoad() && P.isAnyExtLoad()) {
3618 IsAnyExtLoad = true;
3619 continue;
3620 }
Daniel Sanders7e523672017-11-11 03:23:44 +00003621 if (P.isLoad() && P.getMemoryVT()) {
3622 MemVT = P.getMemoryVT();
3623 continue;
3624 }
3625 Predicates.push_back(P);
3626 }
3627
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003628 if ((IsSignExtLoad || IsZeroExtLoad || IsAnyExtLoad) && MemVT) {
3629 assert((IsSignExtLoad + IsZeroExtLoad + IsAnyExtLoad) == 1 &&
3630 "IsSignExtLoad, IsZeroExtLoad, IsAnyExtLoad are mutually exclusive");
Daniel Sanders7e523672017-11-11 03:23:44 +00003631 TreePatternNode *Ext = new TreePatternNode(
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003632 RK.getDef(IsSignExtLoad ? "sext"
3633 : IsZeroExtLoad ? "zext" : "anyext"),
3634 {N}, 1);
Daniel Sanders7e523672017-11-11 03:23:44 +00003635 Ext->setType(0, N->getType(0));
3636 N->clearPredicateFns();
3637 N->setPredicateFns(Predicates);
3638 N->setType(0, getValueType(MemVT));
3639 return Ext;
3640 }
3641 }
3642 }
3643
3644 return N;
3645}
3646
3647void GlobalISelEmitter::fixupPatternTrees(TreePattern *P) {
3648 for (unsigned I = 0, E = P->getNumTrees(); I < E; ++I) {
3649 TreePatternNode *OrigTree = P->getTree(I);
3650 TreePatternNode *NewTree = fixupPatternNode(OrigTree);
3651 if (OrigTree != NewTree)
3652 P->setTree(I, NewTree);
3653 }
3654}
3655
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003656} // end anonymous namespace
3657
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003658//===----------------------------------------------------------------------===//
3659
3660namespace llvm {
3661void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
3662 GlobalISelEmitter(RK).run(OS);
3663}
3664} // End llvm namespace