blob: 56a638483c01861a96f1dc3c598d66775cb0e4ea [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();
194 if (P.isAlwaysTrue())
195 Explanation += " always-true";
196 if (P.isImmediatePattern())
197 Explanation += " immediate";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000198
199 if (P.isUnindexed())
200 Explanation += " unindexed";
201
202 if (P.isNonExtLoad())
203 Explanation += " non-extload";
204 if (P.isAnyExtLoad())
205 Explanation += " extload";
206 if (P.isSignExtLoad())
207 Explanation += " sextload";
208 if (P.isZeroExtLoad())
209 Explanation += " zextload";
210
211 if (P.isNonTruncStore())
212 Explanation += " non-truncstore";
213 if (P.isTruncStore())
214 Explanation += " truncstore";
215
216 if (Record *VT = P.getMemoryVT())
217 Explanation += (" MemVT=" + VT->getName()).str();
218 if (Record *VT = P.getScalarMemoryVT())
219 Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000220 }
221 return Explanation;
222}
223
Daniel Sandersd0656a32017-04-13 09:45:37 +0000224std::string explainOperator(Record *Operator) {
225 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000226 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000227
228 if (Operator->isSubClassOf("Intrinsic"))
229 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
230
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000231 if (Operator->isSubClassOf("ComplexPattern"))
232 return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
233 ")")
234 .str();
235
236 return (" (Operator " + Operator->getName() + " not understood)").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000237}
238
239/// Helper function to let the emitter report skip reason error messages.
240static Error failedImport(const Twine &Reason) {
241 return make_error<StringError>(Reason, inconvertibleErrorCode());
242}
243
244static Error isTrivialOperatorNode(const TreePatternNode *N) {
245 std::string Explanation = "";
246 std::string Separator = "";
Daniel Sanders2c269f62017-08-24 09:11:20 +0000247
248 bool HasUnsupportedPredicate = false;
249 for (const auto &Predicate : N->getPredicateFns()) {
250 if (Predicate.isAlwaysTrue())
251 continue;
252
253 if (Predicate.isImmediatePattern())
254 continue;
255
Daniel Sandersa71f4542017-10-16 00:56:30 +0000256 if (Predicate.isLoad() && Predicate.isUnindexed())
257 continue;
258
259 if (Predicate.isNonExtLoad())
260 continue;
Daniel Sandersd66e0902017-10-23 18:19:24 +0000261
262 if (Predicate.isStore() && Predicate.isUnindexed())
263 continue;
264
265 if (Predicate.isNonTruncStore())
266 continue;
267
Daniel Sanders2c269f62017-08-24 09:11:20 +0000268 HasUnsupportedPredicate = true;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000269 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
270 Separator = ", ";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000271 Explanation += (Separator + "first-failing:" +
272 Predicate.getOrigPatFragRecord()->getRecord()->getName())
273 .str();
Daniel Sanders2c269f62017-08-24 09:11:20 +0000274 break;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000275 }
276
277 if (N->getTransformFn()) {
278 Explanation += Separator + "Has a transform function";
279 Separator = ", ";
280 }
281
Daniel Sanders2c269f62017-08-24 09:11:20 +0000282 if (!HasUnsupportedPredicate && !N->getTransformFn())
Daniel Sandersd0656a32017-04-13 09:45:37 +0000283 return Error::success();
284
285 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000286}
287
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000288static Record *getInitValueAsRegClass(Init *V) {
289 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
290 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
291 return VDefInit->getDef()->getValueAsDef("RegClass");
292 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
293 return VDefInit->getDef();
294 }
295 return nullptr;
296}
297
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000298std::string
299getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
300 std::string Name = "GIFBS";
301 for (const auto &Feature : FeatureBitset)
302 Name += ("_" + Feature->getName()).str();
303 return Name;
304}
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000305
306//===- MatchTable Helpers -------------------------------------------------===//
307
308class MatchTable;
309
310/// A record to be stored in a MatchTable.
311///
312/// This class represents any and all output that may be required to emit the
313/// MatchTable. Instances are most often configured to represent an opcode or
314/// value that will be emitted to the table with some formatting but it can also
315/// represent commas, comments, and other formatting instructions.
316struct MatchTableRecord {
317 enum RecordFlagsBits {
318 MTRF_None = 0x0,
319 /// Causes EmitStr to be formatted as comment when emitted.
320 MTRF_Comment = 0x1,
321 /// Causes the record value to be followed by a comma when emitted.
322 MTRF_CommaFollows = 0x2,
323 /// Causes the record value to be followed by a line break when emitted.
324 MTRF_LineBreakFollows = 0x4,
325 /// Indicates that the record defines a label and causes an additional
326 /// comment to be emitted containing the index of the label.
327 MTRF_Label = 0x8,
328 /// Causes the record to be emitted as the index of the label specified by
329 /// LabelID along with a comment indicating where that label is.
330 MTRF_JumpTarget = 0x10,
331 /// Causes the formatter to add a level of indentation before emitting the
332 /// record.
333 MTRF_Indent = 0x20,
334 /// Causes the formatter to remove a level of indentation after emitting the
335 /// record.
336 MTRF_Outdent = 0x40,
337 };
338
339 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
340 /// reference or define.
341 unsigned LabelID;
342 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
343 /// value, a label name.
344 std::string EmitStr;
345
346private:
347 /// The number of MatchTable elements described by this record. Comments are 0
348 /// while values are typically 1. Values >1 may occur when we need to emit
349 /// values that exceed the size of a MatchTable element.
350 unsigned NumElements;
351
352public:
353 /// A bitfield of RecordFlagsBits flags.
354 unsigned Flags;
355
356 MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
357 unsigned NumElements, unsigned Flags)
358 : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
359 EmitStr(EmitStr), NumElements(NumElements), Flags(Flags) {
360 assert((!LabelID_.hasValue() || LabelID != ~0u) &&
361 "This value is reserved for non-labels");
362 }
363
364 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
365 const MatchTable &Table) const;
366 unsigned size() const { return NumElements; }
367};
368
369/// Holds the contents of a generated MatchTable to enable formatting and the
370/// necessary index tracking needed to support GIM_Try.
371class MatchTable {
372 /// An unique identifier for the table. The generated table will be named
373 /// MatchTable${ID}.
374 unsigned ID;
375 /// The records that make up the table. Also includes comments describing the
376 /// values being emitted and line breaks to format it.
377 std::vector<MatchTableRecord> Contents;
378 /// The currently defined labels.
379 DenseMap<unsigned, unsigned> LabelMap;
380 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
381 unsigned CurrentSize;
382
Daniel Sanders8e82af22017-07-27 11:03:45 +0000383 /// A unique identifier for a MatchTable label.
384 static unsigned CurrentLabelID;
385
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000386public:
387 static MatchTableRecord LineBreak;
388 static MatchTableRecord Comment(StringRef Comment) {
389 return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
390 }
391 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
392 unsigned ExtraFlags = 0;
393 if (IndentAdjust > 0)
394 ExtraFlags |= MatchTableRecord::MTRF_Indent;
395 if (IndentAdjust < 0)
396 ExtraFlags |= MatchTableRecord::MTRF_Outdent;
397
398 return MatchTableRecord(None, Opcode, 1,
399 MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
400 }
401 static MatchTableRecord NamedValue(StringRef NamedValue) {
402 return MatchTableRecord(None, NamedValue, 1,
403 MatchTableRecord::MTRF_CommaFollows);
404 }
405 static MatchTableRecord NamedValue(StringRef Namespace,
406 StringRef NamedValue) {
407 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
408 MatchTableRecord::MTRF_CommaFollows);
409 }
410 static MatchTableRecord IntValue(int64_t IntValue) {
411 return MatchTableRecord(None, llvm::to_string(IntValue), 1,
412 MatchTableRecord::MTRF_CommaFollows);
413 }
414 static MatchTableRecord Label(unsigned LabelID) {
415 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
416 MatchTableRecord::MTRF_Label |
417 MatchTableRecord::MTRF_Comment |
418 MatchTableRecord::MTRF_LineBreakFollows);
419 }
420 static MatchTableRecord JumpTarget(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000421 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000422 MatchTableRecord::MTRF_JumpTarget |
423 MatchTableRecord::MTRF_Comment |
424 MatchTableRecord::MTRF_CommaFollows);
425 }
426
427 MatchTable(unsigned ID) : ID(ID), CurrentSize(0) {}
428
429 void push_back(const MatchTableRecord &Value) {
430 if (Value.Flags & MatchTableRecord::MTRF_Label)
431 defineLabel(Value.LabelID);
432 Contents.push_back(Value);
433 CurrentSize += Value.size();
434 }
435
Daniel Sanders8e82af22017-07-27 11:03:45 +0000436 unsigned allocateLabelID() const { return CurrentLabelID++; }
437
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000438 void defineLabel(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000439 LabelMap.insert(std::make_pair(LabelID, CurrentSize));
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000440 }
441
442 unsigned getLabelIndex(unsigned LabelID) const {
443 const auto I = LabelMap.find(LabelID);
444 assert(I != LabelMap.end() && "Use of undeclared label");
445 return I->second;
446 }
447
Daniel Sanders8e82af22017-07-27 11:03:45 +0000448 void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
449
450 void emitDeclaration(raw_ostream &OS) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000451 unsigned Indentation = 4;
Daniel Sanderscbbbfe42017-07-27 12:47:31 +0000452 OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000453 LineBreak.emit(OS, true, *this);
454 OS << std::string(Indentation, ' ');
455
456 for (auto I = Contents.begin(), E = Contents.end(); I != E;
457 ++I) {
458 bool LineBreakIsNext = false;
459 const auto &NextI = std::next(I);
460
461 if (NextI != E) {
462 if (NextI->EmitStr == "" &&
463 NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
464 LineBreakIsNext = true;
465 }
466
467 if (I->Flags & MatchTableRecord::MTRF_Indent)
468 Indentation += 2;
469
470 I->emit(OS, LineBreakIsNext, *this);
471 if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
472 OS << std::string(Indentation, ' ');
473
474 if (I->Flags & MatchTableRecord::MTRF_Outdent)
475 Indentation -= 2;
476 }
477 OS << "};\n";
478 }
479};
480
Daniel Sanders8e82af22017-07-27 11:03:45 +0000481unsigned MatchTable::CurrentLabelID = 0;
482
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000483MatchTableRecord MatchTable::LineBreak = {
484 None, "" /* Emit String */, 0 /* Elements */,
485 MatchTableRecord::MTRF_LineBreakFollows};
486
487void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
488 const MatchTable &Table) const {
489 bool UseLineComment =
490 LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
491 if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
492 UseLineComment = false;
493
494 if (Flags & MTRF_Comment)
495 OS << (UseLineComment ? "// " : "/*");
496
497 OS << EmitStr;
498 if (Flags & MTRF_Label)
499 OS << ": @" << Table.getLabelIndex(LabelID);
500
501 if (Flags & MTRF_Comment && !UseLineComment)
502 OS << "*/";
503
504 if (Flags & MTRF_JumpTarget) {
505 if (Flags & MTRF_Comment)
506 OS << " ";
507 OS << Table.getLabelIndex(LabelID);
508 }
509
510 if (Flags & MTRF_CommaFollows) {
511 OS << ",";
512 if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
513 OS << " ";
514 }
515
516 if (Flags & MTRF_LineBreakFollows)
517 OS << "\n";
518}
519
520MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
521 Table.push_back(Value);
522 return Table;
523}
524
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000525//===- Matchers -----------------------------------------------------------===//
526
Daniel Sandersbee57392017-04-04 13:25:23 +0000527class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000528class MatchAction;
529
530/// Generates code to check that a match rule matches.
531class RuleMatcher {
Daniel Sanders7438b262017-10-31 23:03:18 +0000532public:
533 using ActionVec = std::vector<std::unique_ptr<MatchAction>>;
534 using action_iterator = ActionVec::iterator;
535
536protected:
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000537 /// A list of matchers that all need to succeed for the current rule to match.
538 /// FIXME: This currently supports a single match position but could be
539 /// extended to support multiple positions to support div/rem fusion or
540 /// load-multiple instructions.
541 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
542
543 /// A list of actions that need to be taken when all predicates in this rule
544 /// have succeeded.
Daniel Sanders7438b262017-10-31 23:03:18 +0000545 ActionVec Actions;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000546
Daniel Sandersa7b75262017-10-31 18:50:24 +0000547 using DefinedInsnVariablesMap =
548 std::map<const InstructionMatcher *, unsigned>;
549
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000550 /// A map of instruction matchers to the local variables created by
Daniel Sanders9d662d22017-07-06 10:06:12 +0000551 /// emitCaptureOpcodes().
Daniel Sanders078572b2017-08-02 11:03:36 +0000552 DefinedInsnVariablesMap InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000553
Daniel Sandersa7b75262017-10-31 18:50:24 +0000554 using MutatableInsnSet = SmallPtrSet<const InstructionMatcher *, 4>;
555
556 // The set of instruction matchers that have not yet been claimed for mutation
557 // by a BuildMI.
558 MutatableInsnSet MutatableInsns;
559
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000560 /// A map of named operands defined by the matchers that may be referenced by
561 /// the renderers.
562 StringMap<OperandMatcher *> DefinedOperands;
563
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000564 /// ID for the next instruction variable defined with defineInsnVar()
565 unsigned NextInsnVarID;
566
Daniel Sanders198447a2017-11-01 00:29:47 +0000567 /// ID for the next output instruction allocated with allocateOutputInsnID()
568 unsigned NextOutputInsnID;
569
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000570 /// ID for the next temporary register ID allocated with allocateTempRegID()
571 unsigned NextTempRegID;
572
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000573 std::vector<Record *> RequiredFeatures;
574
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000575 ArrayRef<SMLoc> SrcLoc;
576
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000577 typedef std::tuple<Record *, unsigned, unsigned>
578 DefinedComplexPatternSubOperand;
579 typedef StringMap<DefinedComplexPatternSubOperand>
580 DefinedComplexPatternSubOperandMap;
581 /// A map of Symbolic Names to ComplexPattern sub-operands.
582 DefinedComplexPatternSubOperandMap ComplexSubOperands;
583
Daniel Sandersf76f3152017-11-16 00:46:35 +0000584 uint64_t RuleID;
585 static uint64_t NextRuleID;
586
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000587public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000588 RuleMatcher(ArrayRef<SMLoc> SrcLoc)
Daniel Sandersa7b75262017-10-31 18:50:24 +0000589 : Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(),
Daniel Sanders198447a2017-11-01 00:29:47 +0000590 DefinedOperands(), NextInsnVarID(0), NextOutputInsnID(0),
Daniel Sandersf76f3152017-11-16 00:46:35 +0000591 NextTempRegID(0), SrcLoc(SrcLoc), ComplexSubOperands(),
592 RuleID(NextRuleID++) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000593 RuleMatcher(RuleMatcher &&Other) = default;
594 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000595
Daniel Sandersf76f3152017-11-16 00:46:35 +0000596 uint64_t getRuleID() const { return RuleID; }
597
Daniel Sanders05540042017-08-08 10:44:31 +0000598 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000599 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000600 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000601
602 template <class Kind, class... Args> Kind &addAction(Args &&... args);
Daniel Sanders7438b262017-10-31 23:03:18 +0000603 template <class Kind, class... Args>
604 action_iterator insertAction(action_iterator InsertPt, Args &&... args);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000605
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000606 /// Define an instruction without emitting any code to do so.
607 /// This is used for the root of the match.
608 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
609 /// Define an instruction and emit corresponding state-machine opcodes.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000610 unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000611 unsigned InsnVarID, unsigned OpIdx);
612 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sanders078572b2017-08-02 11:03:36 +0000613 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
614 return InsnVariableIDs.begin();
615 }
616 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
617 return InsnVariableIDs.end();
618 }
619 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
620 defined_insn_vars() const {
621 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
622 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000623
Daniel Sandersa7b75262017-10-31 18:50:24 +0000624 MutatableInsnSet::const_iterator mutatable_insns_begin() const {
625 return MutatableInsns.begin();
626 }
627 MutatableInsnSet::const_iterator mutatable_insns_end() const {
628 return MutatableInsns.end();
629 }
630 iterator_range<typename MutatableInsnSet::const_iterator>
631 mutatable_insns() const {
632 return make_range(mutatable_insns_begin(), mutatable_insns_end());
633 }
634 void reserveInsnMatcherForMutation(const InstructionMatcher *InsnMatcher) {
635 bool R = MutatableInsns.erase(InsnMatcher);
636 assert(R && "Reserving a mutatable insn that isn't available");
637 (void)R;
638 }
639
Daniel Sanders7438b262017-10-31 23:03:18 +0000640 action_iterator actions_begin() { return Actions.begin(); }
641 action_iterator actions_end() { return Actions.end(); }
642 iterator_range<action_iterator> actions() {
643 return make_range(actions_begin(), actions_end());
644 }
645
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000646 void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
647
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000648 void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
649 unsigned RendererID, unsigned SubOperandID) {
650 assert(ComplexSubOperands.count(SymbolicName) == 0 && "Already defined");
651 ComplexSubOperands[SymbolicName] =
652 std::make_tuple(ComplexPattern, RendererID, SubOperandID);
653 }
654 Optional<DefinedComplexPatternSubOperand>
655 getComplexSubOperand(StringRef SymbolicName) const {
656 const auto &I = ComplexSubOperands.find(SymbolicName);
657 if (I == ComplexSubOperands.end())
658 return None;
659 return I->second;
660 }
661
Daniel Sanders05540042017-08-08 10:44:31 +0000662 const InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000663 const OperandMatcher &getOperandMatcher(StringRef Name) const;
Daniel Sanders05540042017-08-08 10:44:31 +0000664
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000665 void emitCaptureOpcodes(MatchTable &Table);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000666
Daniel Sanders8e82af22017-07-27 11:03:45 +0000667 void emit(MatchTable &Table);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000668
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000669 /// Compare the priority of this object and B.
670 ///
671 /// Returns true if this object is more important than B.
672 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000673
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000674 /// Report the maximum number of temporary operands needed by the rule
675 /// matcher.
676 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000677
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000678 // FIXME: Remove this as soon as possible
679 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sanders198447a2017-11-01 00:29:47 +0000680
681 unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000682 unsigned allocateTempRegID() { return NextTempRegID++; }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000683};
684
Daniel Sandersf76f3152017-11-16 00:46:35 +0000685uint64_t RuleMatcher::NextRuleID = 0;
686
Daniel Sanders7438b262017-10-31 23:03:18 +0000687using action_iterator = RuleMatcher::action_iterator;
688
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000689template <class PredicateTy> class PredicateListMatcher {
690private:
691 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
692 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000693
Daniel Sanders2c269f62017-08-24 09:11:20 +0000694 /// Template instantiations should specialize this to return a string to use
695 /// for the comment emitted when there are no predicates.
696 std::string getNoPredicateComment() const;
697
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000698public:
699 /// Construct a new operand predicate and add it to the matcher.
700 template <class Kind, class... Args>
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000701 Optional<Kind *> addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000702 Predicates.emplace_back(
703 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000704 return static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000705 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000706
Daniel Sanders32291982017-06-28 13:50:04 +0000707 typename PredicateVec::const_iterator predicates_begin() const {
708 return Predicates.begin();
709 }
710 typename PredicateVec::const_iterator predicates_end() const {
711 return Predicates.end();
712 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000713 iterator_range<typename PredicateVec::const_iterator> predicates() const {
714 return make_range(predicates_begin(), predicates_end());
715 }
Daniel Sanders32291982017-06-28 13:50:04 +0000716 typename PredicateVec::size_type predicates_size() const {
717 return Predicates.size();
718 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000719
Daniel Sanders9d662d22017-07-06 10:06:12 +0000720 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000721 template <class... Args>
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000722 void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000723 if (Predicates.empty()) {
Daniel Sanders2c269f62017-08-24 09:11:20 +0000724 Table << MatchTable::Comment(getNoPredicateComment())
725 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000726 return;
727 }
728
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000729 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000730 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000731 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000732};
733
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000734/// Generates code to check a predicate of an operand.
735///
736/// Typical predicates include:
737/// * Operand is a particular register.
738/// * Operand is assigned a particular register bank.
739/// * Operand is an MBB.
740class OperandPredicateMatcher {
741public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000742 /// This enum is used for RTTI and also defines the priority that is given to
743 /// the predicate when generating the matcher code. Kinds with higher priority
744 /// must be tested first.
745 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000746 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
747 /// but OPM_Int must have priority over OPM_RegBank since constant integers
748 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000749 enum PredicateKind {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000750 OPM_SameOperand,
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000751 OPM_ComplexPattern,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000752 OPM_IntrinsicID,
Daniel Sanders05540042017-08-08 10:44:31 +0000753 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000754 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000755 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000756 OPM_LLT,
Daniel Sandersa71f4542017-10-16 00:56:30 +0000757 OPM_PointerToAny,
Daniel Sanders759ff412017-02-24 13:58:11 +0000758 OPM_RegBank,
759 OPM_MBB,
760 };
761
762protected:
763 PredicateKind Kind;
764
765public:
766 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000767 virtual ~OperandPredicateMatcher() {}
768
Daniel Sanders759ff412017-02-24 13:58:11 +0000769 PredicateKind getKind() const { return Kind; }
770
Daniel Sanders9d662d22017-07-06 10:06:12 +0000771 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sandersbee57392017-04-04 13:25:23 +0000772 ///
Daniel Sanders9d662d22017-07-06 10:06:12 +0000773 /// Only InstructionOperandMatcher needs to do anything for this method the
774 /// rest just walk the tree.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000775 virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +0000776 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000777
Daniel Sanders9d662d22017-07-06 10:06:12 +0000778 /// Emit MatchTable opcodes that check the predicate for the given operand.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000779 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000780 unsigned InsnVarID,
781 unsigned OpIdx) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000782
783 /// Compare the priority of this object and B.
784 ///
785 /// Returns true if this object is more important than B.
Daniel Sanders05540042017-08-08 10:44:31 +0000786 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000787
788 /// Report the maximum number of temporary operands needed by the predicate
789 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000790 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000791};
792
Daniel Sanders2c269f62017-08-24 09:11:20 +0000793template <>
794std::string
795PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
796 return "No operand predicates";
797}
798
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000799/// Generates code to check that a register operand is defined by the same exact
800/// one as another.
801class SameOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000802 std::string MatchingName;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000803
804public:
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000805 SameOperandMatcher(StringRef MatchingName)
806 : OperandPredicateMatcher(OPM_SameOperand), MatchingName(MatchingName) {}
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000807
808 static bool classof(const OperandPredicateMatcher *P) {
Daniel Sanders1e4569f2017-10-20 20:55:29 +0000809 return P->getKind() == OPM_SameOperand;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000810 }
811
812 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
813 unsigned InsnVarID, unsigned OpIdx) const override;
814};
815
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000816/// Generates code to check that an operand is a particular LLT.
817class LLTOperandMatcher : public OperandPredicateMatcher {
818protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000819 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000820
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000821public:
Daniel Sanders032e7f22017-08-17 13:18:35 +0000822 static std::set<LLTCodeGen> KnownTypes;
823
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000824 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders032e7f22017-08-17 13:18:35 +0000825 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {
826 KnownTypes.insert(Ty);
827 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000828
829 static bool classof(const OperandPredicateMatcher *P) {
830 return P->getKind() == OPM_LLT;
831 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000832
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000833 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000834 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000835 Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
836 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
837 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
838 << MatchTable::NamedValue(Ty.getCxxEnumValue())
839 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000840 }
841};
842
Daniel Sanders032e7f22017-08-17 13:18:35 +0000843std::set<LLTCodeGen> LLTOperandMatcher::KnownTypes;
844
Daniel Sandersa71f4542017-10-16 00:56:30 +0000845/// Generates code to check that an operand is a pointer to any address space.
846///
847/// In SelectionDAG, the types did not describe pointers or address spaces. As a
848/// result, iN is used to describe a pointer of N bits to any address space and
849/// PatFrag predicates are typically used to constrain the address space. There's
850/// no reliable means to derive the missing type information from the pattern so
851/// imported rules must test the components of a pointer separately.
852///
Daniel Sandersea8711b2017-10-16 03:36:29 +0000853/// If SizeInBits is zero, then the pointer size will be obtained from the
854/// subtarget.
Daniel Sandersa71f4542017-10-16 00:56:30 +0000855class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
856protected:
857 unsigned SizeInBits;
858
859public:
860 PointerToAnyOperandMatcher(unsigned SizeInBits)
861 : OperandPredicateMatcher(OPM_PointerToAny), SizeInBits(SizeInBits) {}
862
863 static bool classof(const OperandPredicateMatcher *P) {
864 return P->getKind() == OPM_PointerToAny;
865 }
866
867 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
868 unsigned InsnVarID, unsigned OpIdx) const override {
869 Table << MatchTable::Opcode("GIM_CheckPointerToAny") << MatchTable::Comment("MI")
870 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
871 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("SizeInBits")
872 << MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
873 }
874};
875
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000876/// Generates code to check that an operand is a particular target constant.
877class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
878protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000879 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000880 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000881
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000882 unsigned getAllocatedTemporariesBaseID() const;
883
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000884public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000885 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
886 const Record &TheDef)
887 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
888 TheDef(TheDef) {}
889
890 static bool classof(const OperandPredicateMatcher *P) {
891 return P->getKind() == OPM_ComplexPattern;
892 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000893
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000894 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000895 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000896 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000897 Table << MatchTable::Opcode("GIM_CheckComplexPattern")
898 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
899 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
900 << MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
901 << MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
902 << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000903 }
904
Daniel Sanders2deea182017-04-22 15:11:04 +0000905 unsigned countRendererFns() const override {
906 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000907 }
908};
909
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000910/// Generates code to check that an operand is in a particular register bank.
911class RegisterBankOperandMatcher : public OperandPredicateMatcher {
912protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000913 const CodeGenRegisterClass &RC;
914
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000915public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000916 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
917 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
918
919 static bool classof(const OperandPredicateMatcher *P) {
920 return P->getKind() == OPM_RegBank;
921 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000922
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000923 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000924 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000925 Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
926 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
927 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
928 << MatchTable::Comment("RC")
929 << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
930 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000931 }
932};
933
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000934/// Generates code to check that an operand is a basic block.
935class MBBOperandMatcher : public OperandPredicateMatcher {
936public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000937 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
938
939 static bool classof(const OperandPredicateMatcher *P) {
940 return P->getKind() == OPM_MBB;
941 }
942
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000943 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000944 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000945 Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
946 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
947 << MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000948 }
949};
950
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000951/// Generates code to check that an operand is a G_CONSTANT with a particular
952/// int.
953class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000954protected:
955 int64_t Value;
956
957public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000958 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000959 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
960
961 static bool classof(const OperandPredicateMatcher *P) {
962 return P->getKind() == OPM_Int;
963 }
964
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000965 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000966 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000967 Table << MatchTable::Opcode("GIM_CheckConstantInt")
968 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
969 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
970 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000971 }
972};
973
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000974/// Generates code to check that an operand is a raw int (where MO.isImm() or
975/// MO.isCImm() is true).
976class LiteralIntOperandMatcher : public OperandPredicateMatcher {
977protected:
978 int64_t Value;
979
980public:
981 LiteralIntOperandMatcher(int64_t Value)
982 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
983
984 static bool classof(const OperandPredicateMatcher *P) {
985 return P->getKind() == OPM_LiteralInt;
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_CheckLiteralInt")
991 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
992 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
993 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000994 }
995};
996
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000997/// Generates code to check that an operand is an intrinsic ID.
998class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
999protected:
1000 const CodeGenIntrinsic *II;
1001
1002public:
1003 IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
1004 : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
1005
1006 static bool classof(const OperandPredicateMatcher *P) {
1007 return P->getKind() == OPM_IntrinsicID;
1008 }
1009
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001010 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001011 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001012 Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
1013 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1014 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1015 << MatchTable::NamedValue("Intrinsic::" + II->EnumName)
1016 << MatchTable::LineBreak;
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001017 }
1018};
1019
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001020/// Generates code to check that a set of predicates match for a particular
1021/// operand.
1022class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
1023protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001024 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001025 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001026 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001027
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001028 /// The index of the first temporary variable allocated to this operand. The
1029 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +00001030 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001031 unsigned AllocatedTemporariesBaseID;
1032
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001033public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001034 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001035 const std::string &SymbolicName,
1036 unsigned AllocatedTemporariesBaseID)
1037 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
1038 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001039
1040 bool hasSymbolicName() const { return !SymbolicName.empty(); }
1041 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001042 void setSymbolicName(StringRef Name) {
1043 assert(SymbolicName.empty() && "Operand already has a symbolic name");
1044 SymbolicName = Name;
1045 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001046 unsigned getOperandIndex() const { return OpIdx; }
1047
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001048 std::string getOperandExpr(unsigned InsnVarID) const {
1049 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
1050 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +00001051 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001052
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001053 InstructionMatcher &getInstructionMatcher() const { return Insn; }
1054
Daniel Sandersa71f4542017-10-16 00:56:30 +00001055 Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001056 bool OperandIsAPointer);
Daniel Sandersa71f4542017-10-16 00:56:30 +00001057
Daniel Sanders9d662d22017-07-06 10:06:12 +00001058 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001059 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001060 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +00001061 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001062 Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00001063 }
1064
Daniel Sanders9d662d22017-07-06 10:06:12 +00001065 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001066 /// InsnVarID matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001067 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001068 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001069 std::string Comment;
1070 raw_string_ostream CommentOS(Comment);
1071 CommentOS << "MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001072 if (SymbolicName.empty())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001073 CommentOS << "Operand " << OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001074 else
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001075 CommentOS << SymbolicName;
1076 Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
1077
1078 emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001079 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001080
1081 /// Compare the priority of this object and B.
1082 ///
1083 /// Returns true if this object is more important than B.
1084 bool isHigherPriorityThan(const OperandMatcher &B) const {
1085 // Operand matchers involving more predicates have higher priority.
1086 if (predicates_size() > B.predicates_size())
1087 return true;
1088 if (predicates_size() < B.predicates_size())
1089 return false;
1090
1091 // This assumes that predicates are added in a consistent order.
1092 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1093 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1094 return true;
1095 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1096 return false;
1097 }
1098
1099 return false;
1100 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001101
1102 /// Report the maximum number of temporary operands needed by the operand
1103 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001104 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001105 return std::accumulate(
1106 predicates().begin(), predicates().end(), 0,
1107 [](unsigned A,
1108 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001109 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001110 });
1111 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001112
1113 unsigned getAllocatedTemporariesBaseID() const {
1114 return AllocatedTemporariesBaseID;
1115 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001116
1117 bool isSameAsAnotherOperand() const {
1118 for (const auto &Predicate : predicates())
1119 if (isa<SameOperandMatcher>(Predicate))
1120 return true;
1121 return false;
1122 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001123};
1124
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001125// Specialize OperandMatcher::addPredicate() to refrain from adding redundant
1126// predicates.
1127template <>
1128template <class Kind, class... Args>
1129Optional<Kind *>
1130PredicateListMatcher<OperandPredicateMatcher>::addPredicate(Args &&... args) {
1131 if (static_cast<OperandMatcher *>(this)->isSameAsAnotherOperand())
1132 return None;
1133 Predicates.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1134 return static_cast<Kind *>(Predicates.back().get());
1135}
1136
1137Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
1138 bool OperandIsAPointer) {
1139 if (!VTy.isMachineValueType())
1140 return failedImport("unsupported typeset");
1141
1142 if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
1143 addPredicate<PointerToAnyOperandMatcher>(0);
1144 return Error::success();
1145 }
1146
1147 auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
1148 if (!OpTyOrNone)
1149 return failedImport("unsupported type");
1150
1151 if (OperandIsAPointer)
1152 addPredicate<PointerToAnyOperandMatcher>(OpTyOrNone->get().getSizeInBits());
1153 else
1154 addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1155 return Error::success();
1156}
1157
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001158unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
1159 return Operand.getAllocatedTemporariesBaseID();
1160}
1161
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001162/// Generates code to check a predicate on an instruction.
1163///
1164/// Typical predicates include:
1165/// * The opcode of the instruction is a particular value.
1166/// * The nsw/nuw flag is/isn't set.
1167class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +00001168protected:
1169 /// This enum is used for RTTI and also defines the priority that is given to
1170 /// the predicate when generating the matcher code. Kinds with higher priority
1171 /// must be tested first.
1172 enum PredicateKind {
1173 IPM_Opcode,
Daniel Sanders2c269f62017-08-24 09:11:20 +00001174 IPM_ImmPredicate,
Daniel Sanders39690bd2017-10-15 02:41:12 +00001175 IPM_NonAtomicMMO,
Daniel Sanders759ff412017-02-24 13:58:11 +00001176 };
1177
1178 PredicateKind Kind;
1179
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001180public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001181 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001182 virtual ~InstructionPredicateMatcher() {}
1183
Daniel Sanders759ff412017-02-24 13:58:11 +00001184 PredicateKind getKind() const { return Kind; }
1185
Daniel Sanders9d662d22017-07-06 10:06:12 +00001186 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001187 /// InsnVarID matches the predicate.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001188 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001189 unsigned InsnVarID) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +00001190
1191 /// Compare the priority of this object and B.
1192 ///
1193 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001194 virtual bool
1195 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +00001196 return Kind < B.Kind;
1197 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001198
1199 /// Report the maximum number of temporary operands needed by the predicate
1200 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001201 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001202};
1203
Daniel Sanders2c269f62017-08-24 09:11:20 +00001204template <>
1205std::string
1206PredicateListMatcher<InstructionPredicateMatcher>::getNoPredicateComment() const {
1207 return "No instruction predicates";
1208}
1209
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001210/// Generates code to check the opcode of an instruction.
1211class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1212protected:
1213 const CodeGenInstruction *I;
1214
1215public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +00001216 InstructionOpcodeMatcher(const CodeGenInstruction *I)
1217 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001218
Daniel Sanders759ff412017-02-24 13:58:11 +00001219 static bool classof(const InstructionPredicateMatcher *P) {
1220 return P->getKind() == IPM_Opcode;
1221 }
1222
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001223 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001224 unsigned InsnVarID) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001225 Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
1226 << MatchTable::IntValue(InsnVarID)
1227 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1228 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001229 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001230
1231 /// Compare the priority of this object and B.
1232 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001233 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001234 bool
1235 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +00001236 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
1237 return true;
1238 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
1239 return false;
1240
1241 // Prioritize opcodes for cosmetic reasons in the generated source. Although
1242 // this is cosmetic at the moment, we may want to drive a similar ordering
1243 // using instruction frequency information to improve compile time.
1244 if (const InstructionOpcodeMatcher *BO =
1245 dyn_cast<InstructionOpcodeMatcher>(&B))
1246 return I->TheDef->getName() < BO->I->TheDef->getName();
1247
1248 return false;
1249 };
Daniel Sanders05540042017-08-08 10:44:31 +00001250
1251 bool isConstantInstruction() const {
1252 return I->TheDef->getName() == "G_CONSTANT";
1253 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001254};
1255
Daniel Sanders2c269f62017-08-24 09:11:20 +00001256/// Generates code to check that this instruction is a constant whose value
1257/// meets an immediate predicate.
1258///
1259/// Immediates are slightly odd since they are typically used like an operand
1260/// but are represented as an operator internally. We typically write simm8:$src
1261/// in a tablegen pattern, but this is just syntactic sugar for
1262/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1263/// that will be matched and the predicate (which is attached to the imm
1264/// operator) that will be tested. In SelectionDAG this describes a
1265/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
1266///
1267/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1268/// this representation, the immediate could be tested with an
1269/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1270/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1271/// there are two implementation issues with producing that matcher
1272/// configuration from the SelectionDAG pattern:
1273/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1274/// were we to sink the immediate predicate to the operand we would have to
1275/// have two partial implementations of PatFrag support, one for immediates
1276/// and one for non-immediates.
1277/// * At the point we handle the predicate, the OperandMatcher hasn't been
1278/// created yet. If we were to sink the predicate to the OperandMatcher we
1279/// would also have to complicate (or duplicate) the code that descends and
1280/// creates matchers for the subtree.
1281/// Overall, it's simpler to handle it in the place it was found.
1282class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1283protected:
1284 TreePredicateFn Predicate;
1285
1286public:
1287 InstructionImmPredicateMatcher(const TreePredicateFn &Predicate)
1288 : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {}
1289
1290 static bool classof(const InstructionPredicateMatcher *P) {
1291 return P->getKind() == IPM_ImmPredicate;
1292 }
1293
1294 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1295 unsigned InsnVarID) const override {
Daniel Sanders11300ce2017-10-13 21:28:03 +00001296 Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001297 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1298 << MatchTable::Comment("Predicate")
Daniel Sanders11300ce2017-10-13 21:28:03 +00001299 << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001300 << MatchTable::LineBreak;
1301 }
1302};
1303
Daniel Sanders39690bd2017-10-15 02:41:12 +00001304/// Generates code to check that a memory instruction has a non-atomic MachineMemoryOperand.
1305class NonAtomicMMOPredicateMatcher : public InstructionPredicateMatcher {
1306public:
1307 NonAtomicMMOPredicateMatcher()
1308 : InstructionPredicateMatcher(IPM_NonAtomicMMO) {}
1309
1310 static bool classof(const InstructionPredicateMatcher *P) {
1311 return P->getKind() == IPM_NonAtomicMMO;
1312 }
1313
1314 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1315 unsigned InsnVarID) const override {
1316 Table << MatchTable::Opcode("GIM_CheckNonAtomic")
1317 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1318 << MatchTable::LineBreak;
1319 }
1320};
1321
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001322/// Generates code to check that a set of predicates and operands match for a
1323/// particular instruction.
1324///
1325/// Typical predicates include:
1326/// * Has a specific opcode.
1327/// * Has an nsw/nuw flag or doesn't.
1328class InstructionMatcher
1329 : public PredicateListMatcher<InstructionPredicateMatcher> {
1330protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001331 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001332
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001333 RuleMatcher &Rule;
1334
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001335 /// The operands to match. All rendered operands must be present even if the
1336 /// condition is always true.
1337 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001338
Daniel Sanders05540042017-08-08 10:44:31 +00001339 std::string SymbolicName;
1340
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001341public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001342 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
1343 : Rule(Rule), SymbolicName(SymbolicName) {}
1344
1345 RuleMatcher &getRuleMatcher() const { return Rule; }
Daniel Sanders05540042017-08-08 10:44:31 +00001346
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001347 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001348 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1349 unsigned AllocatedTemporariesBaseID) {
1350 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
1351 AllocatedTemporariesBaseID));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001352 if (!SymbolicName.empty())
1353 Rule.defineOperand(SymbolicName, *Operands.back());
1354
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001355 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001356 }
1357
Daniel Sandersffc7d582017-03-29 15:37:18 +00001358 OperandMatcher &getOperand(unsigned OpIdx) {
1359 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001360 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
1361 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001362 });
1363 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001364 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001365 llvm_unreachable("Failed to lookup operand");
1366 }
1367
Daniel Sanders05540042017-08-08 10:44:31 +00001368 StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001369 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +00001370 OperandVec::iterator operands_begin() { return Operands.begin(); }
1371 OperandVec::iterator operands_end() { return Operands.end(); }
1372 iterator_range<OperandVec::iterator> operands() {
1373 return make_range(operands_begin(), operands_end());
1374 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001375 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1376 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001377 iterator_range<OperandVec::const_iterator> operands() const {
1378 return make_range(operands_begin(), operands_end());
1379 }
1380
Daniel Sanders9d662d22017-07-06 10:06:12 +00001381 /// Emit MatchTable opcodes to check the shape of the match and capture
1382 /// instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001383 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001384 unsigned InsnID) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001385 Table << MatchTable::Opcode("GIM_CheckNumOperands")
1386 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1387 << MatchTable::Comment("Expected")
1388 << MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001389 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001390 Operand->emitCaptureOpcodes(Table, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001391 }
1392
Daniel Sanders9d662d22017-07-06 10:06:12 +00001393 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001394 /// InsnVarName matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001395 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001396 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001397 emitPredicateListOpcodes(Table, Rule, InsnVarID);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001398 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001399 Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001400 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001401
1402 /// Compare the priority of this object and B.
1403 ///
1404 /// Returns true if this object is more important than B.
1405 bool isHigherPriorityThan(const InstructionMatcher &B) const {
1406 // Instruction matchers involving more operands have higher priority.
1407 if (Operands.size() > B.Operands.size())
1408 return true;
1409 if (Operands.size() < B.Operands.size())
1410 return false;
1411
1412 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1413 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1414 return true;
1415 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1416 return false;
1417 }
1418
1419 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001420 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001421 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001422 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001423 return false;
1424 }
1425
1426 return false;
1427 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001428
1429 /// Report the maximum number of temporary operands needed by the instruction
1430 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001431 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001432 return std::accumulate(predicates().begin(), predicates().end(), 0,
1433 [](unsigned A,
1434 const std::unique_ptr<InstructionPredicateMatcher>
1435 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001436 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001437 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001438 std::accumulate(
1439 Operands.begin(), Operands.end(), 0,
1440 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001441 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001442 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001443 }
Daniel Sanders05540042017-08-08 10:44:31 +00001444
1445 bool isConstantInstruction() const {
1446 for (const auto &P : predicates())
1447 if (const InstructionOpcodeMatcher *Opcode =
1448 dyn_cast<InstructionOpcodeMatcher>(P.get()))
1449 return Opcode->isConstantInstruction();
1450 return false;
1451 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001452};
1453
Daniel Sandersbee57392017-04-04 13:25:23 +00001454/// Generates code to check that the operand is a register defined by an
1455/// instruction that matches the given instruction matcher.
1456///
1457/// For example, the pattern:
1458/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1459/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1460/// the:
1461/// (G_ADD $src1, $src2)
1462/// subpattern.
1463class InstructionOperandMatcher : public OperandPredicateMatcher {
1464protected:
1465 std::unique_ptr<InstructionMatcher> InsnMatcher;
1466
1467public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001468 InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName)
Daniel Sandersbee57392017-04-04 13:25:23 +00001469 : OperandPredicateMatcher(OPM_Instruction),
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001470 InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {}
Daniel Sandersbee57392017-04-04 13:25:23 +00001471
1472 static bool classof(const OperandPredicateMatcher *P) {
1473 return P->getKind() == OPM_Instruction;
1474 }
1475
1476 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1477
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001478 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001479 unsigned InsnID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001480 unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
1481 InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001482 }
1483
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001484 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001485 unsigned InsnVarID_,
1486 unsigned OpIdx_) const override {
1487 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001488 InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001489 }
1490};
1491
Daniel Sanders43c882c2017-02-01 10:53:10 +00001492//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001493class OperandRenderer {
1494public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001495 enum RendererKind {
1496 OR_Copy,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001497 OR_CopyOrAddZeroReg,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001498 OR_CopySubReg,
Daniel Sanders05540042017-08-08 10:44:31 +00001499 OR_CopyConstantAsImm,
Daniel Sanders11300ce2017-10-13 21:28:03 +00001500 OR_CopyFConstantAsFPImm,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001501 OR_Imm,
1502 OR_Register,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001503 OR_TempRegister,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001504 OR_ComplexPattern
1505 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001506
1507protected:
1508 RendererKind Kind;
1509
1510public:
1511 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1512 virtual ~OperandRenderer() {}
1513
1514 RendererKind getKind() const { return Kind; }
1515
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001516 virtual void emitRenderOpcodes(MatchTable &Table,
1517 RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001518};
1519
1520/// A CopyRenderer emits code to copy a single operand from an existing
1521/// instruction to the one being built.
1522class CopyRenderer : public OperandRenderer {
1523protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001524 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001525 /// The name of the operand.
1526 const StringRef SymbolicName;
1527
1528public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001529 CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
1530 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
Daniel Sanders05540042017-08-08 10:44:31 +00001531 SymbolicName(SymbolicName) {
1532 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1533 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001534
1535 static bool classof(const OperandRenderer *R) {
1536 return R->getKind() == OR_Copy;
1537 }
1538
1539 const StringRef getSymbolicName() const { return SymbolicName; }
1540
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001541 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001542 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001543 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001544 Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
1545 << MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
1546 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1547 << MatchTable::IntValue(Operand.getOperandIndex())
1548 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001549 }
1550};
1551
Daniel Sandersd66e0902017-10-23 18:19:24 +00001552/// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
1553/// existing instruction to the one being built. If the operand turns out to be
1554/// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
1555class CopyOrAddZeroRegRenderer : public OperandRenderer {
1556protected:
1557 unsigned NewInsnID;
1558 /// The name of the operand.
1559 const StringRef SymbolicName;
1560 const Record *ZeroRegisterDef;
1561
1562public:
1563 CopyOrAddZeroRegRenderer(unsigned NewInsnID,
Daniel Sandersd66e0902017-10-23 18:19:24 +00001564 StringRef SymbolicName, Record *ZeroRegisterDef)
1565 : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
1566 SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
1567 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1568 }
1569
1570 static bool classof(const OperandRenderer *R) {
1571 return R->getKind() == OR_CopyOrAddZeroReg;
1572 }
1573
1574 const StringRef getSymbolicName() const { return SymbolicName; }
1575
1576 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1577 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
1578 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
1579 Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg")
1580 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1581 << MatchTable::Comment("OldInsnID")
1582 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1583 << MatchTable::IntValue(Operand.getOperandIndex())
1584 << MatchTable::NamedValue(
1585 (ZeroRegisterDef->getValue("Namespace")
1586 ? ZeroRegisterDef->getValueAsString("Namespace")
1587 : ""),
1588 ZeroRegisterDef->getName())
1589 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1590 }
1591};
1592
Daniel Sanders05540042017-08-08 10:44:31 +00001593/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1594/// an extended immediate operand.
1595class CopyConstantAsImmRenderer : public OperandRenderer {
1596protected:
1597 unsigned NewInsnID;
1598 /// The name of the operand.
1599 const std::string SymbolicName;
1600 bool Signed;
1601
1602public:
1603 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1604 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
1605 SymbolicName(SymbolicName), Signed(true) {}
1606
1607 static bool classof(const OperandRenderer *R) {
1608 return R->getKind() == OR_CopyConstantAsImm;
1609 }
1610
1611 const StringRef getSymbolicName() const { return SymbolicName; }
1612
1613 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1614 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1615 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1616 Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
1617 : "GIR_CopyConstantAsUImm")
1618 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1619 << MatchTable::Comment("OldInsnID")
1620 << MatchTable::IntValue(OldInsnVarID)
1621 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1622 }
1623};
1624
Daniel Sanders11300ce2017-10-13 21:28:03 +00001625/// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
1626/// instruction to an extended immediate operand.
1627class CopyFConstantAsFPImmRenderer : public OperandRenderer {
1628protected:
1629 unsigned NewInsnID;
1630 /// The name of the operand.
1631 const std::string SymbolicName;
1632
1633public:
1634 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1635 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
1636 SymbolicName(SymbolicName) {}
1637
1638 static bool classof(const OperandRenderer *R) {
1639 return R->getKind() == OR_CopyFConstantAsFPImm;
1640 }
1641
1642 const StringRef getSymbolicName() const { return SymbolicName; }
1643
1644 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1645 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1646 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1647 Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
1648 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1649 << MatchTable::Comment("OldInsnID")
1650 << MatchTable::IntValue(OldInsnVarID)
1651 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1652 }
1653};
1654
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001655/// A CopySubRegRenderer emits code to copy a single register operand from an
1656/// existing instruction to the one being built and indicate that only a
1657/// subregister should be copied.
1658class CopySubRegRenderer : public OperandRenderer {
1659protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001660 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001661 /// The name of the operand.
1662 const StringRef SymbolicName;
1663 /// The subregister to extract.
1664 const CodeGenSubRegIndex *SubReg;
1665
1666public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00001667 CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
1668 const CodeGenSubRegIndex *SubReg)
1669 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001670 SymbolicName(SymbolicName), SubReg(SubReg) {}
1671
1672 static bool classof(const OperandRenderer *R) {
1673 return R->getKind() == OR_CopySubReg;
1674 }
1675
1676 const StringRef getSymbolicName() const { return SymbolicName; }
1677
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001678 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001679 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001680 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001681 Table << MatchTable::Opcode("GIR_CopySubReg")
1682 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1683 << MatchTable::Comment("OldInsnID")
1684 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1685 << MatchTable::IntValue(Operand.getOperandIndex())
1686 << MatchTable::Comment("SubRegIdx")
1687 << MatchTable::IntValue(SubReg->EnumValue)
1688 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001689 }
1690};
1691
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001692/// Adds a specific physical register to the instruction being built.
1693/// This is typically useful for WZR/XZR on AArch64.
1694class AddRegisterRenderer : public OperandRenderer {
1695protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001696 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001697 const Record *RegisterDef;
1698
1699public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001700 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
1701 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
1702 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001703
1704 static bool classof(const OperandRenderer *R) {
1705 return R->getKind() == OR_Register;
1706 }
1707
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001708 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1709 Table << MatchTable::Opcode("GIR_AddRegister")
1710 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1711 << MatchTable::NamedValue(
1712 (RegisterDef->getValue("Namespace")
1713 ? RegisterDef->getValueAsString("Namespace")
1714 : ""),
1715 RegisterDef->getName())
1716 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001717 }
1718};
1719
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001720/// Adds a specific temporary virtual register to the instruction being built.
1721/// This is used to chain instructions together when emitting multiple
1722/// instructions.
1723class TempRegRenderer : public OperandRenderer {
1724protected:
1725 unsigned InsnID;
1726 unsigned TempRegID;
1727 bool IsDef;
1728
1729public:
1730 TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false)
1731 : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
1732 IsDef(IsDef) {}
1733
1734 static bool classof(const OperandRenderer *R) {
1735 return R->getKind() == OR_TempRegister;
1736 }
1737
1738 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1739 Table << MatchTable::Opcode("GIR_AddTempRegister")
1740 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1741 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
1742 << MatchTable::Comment("TempRegFlags");
1743 if (IsDef)
1744 Table << MatchTable::NamedValue("RegState::Define");
1745 else
1746 Table << MatchTable::IntValue(0);
1747 Table << MatchTable::LineBreak;
1748 }
1749};
1750
Daniel Sanders0ed28822017-04-12 08:23:08 +00001751/// Adds a specific immediate to the instruction being built.
1752class ImmRenderer : public OperandRenderer {
1753protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001754 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001755 int64_t Imm;
1756
1757public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001758 ImmRenderer(unsigned InsnID, int64_t Imm)
1759 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001760
1761 static bool classof(const OperandRenderer *R) {
1762 return R->getKind() == OR_Imm;
1763 }
1764
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001765 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1766 Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
1767 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
1768 << MatchTable::IntValue(Imm) << MatchTable::LineBreak;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001769 }
1770};
1771
Daniel Sanders2deea182017-04-22 15:11:04 +00001772/// Adds operands by calling a renderer function supplied by the ComplexPattern
1773/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001774class RenderComplexPatternOperand : public OperandRenderer {
1775private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001776 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001777 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001778 /// The name of the operand.
1779 const StringRef SymbolicName;
1780 /// The renderer number. This must be unique within a rule since it's used to
1781 /// identify a temporary variable to hold the renderer function.
1782 unsigned RendererID;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001783 /// When provided, this is the suboperand of the ComplexPattern operand to
1784 /// render. Otherwise all the suboperands will be rendered.
1785 Optional<unsigned> SubOperand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001786
1787 unsigned getNumOperands() const {
1788 return TheDef.getValueAsDag("Operands")->getNumArgs();
1789 }
1790
1791public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001792 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001793 StringRef SymbolicName, unsigned RendererID,
1794 Optional<unsigned> SubOperand = None)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001795 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001796 SymbolicName(SymbolicName), RendererID(RendererID),
1797 SubOperand(SubOperand) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001798
1799 static bool classof(const OperandRenderer *R) {
1800 return R->getKind() == OR_ComplexPattern;
1801 }
1802
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001803 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001804 Table << MatchTable::Opcode(SubOperand.hasValue() ? "GIR_ComplexSubOperandRenderer"
1805 : "GIR_ComplexRenderer")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001806 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1807 << MatchTable::Comment("RendererID")
Daniel Sandersdf39cba2017-10-15 18:22:54 +00001808 << MatchTable::IntValue(RendererID);
1809 if (SubOperand.hasValue())
1810 Table << MatchTable::Comment("SubOperand")
1811 << MatchTable::IntValue(SubOperand.getValue());
1812 Table << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001813 }
1814};
1815
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001816/// An action taken when all Matcher predicates succeeded for a parent rule.
1817///
1818/// Typical actions include:
1819/// * Changing the opcode of an instruction.
1820/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001821class MatchAction {
1822public:
1823 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001824
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001825 /// Emit the MatchTable opcodes to implement the action.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001826 virtual void emitActionOpcodes(MatchTable &Table,
1827 RuleMatcher &Rule) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001828};
1829
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001830/// Generates a comment describing the matched rule being acted upon.
1831class DebugCommentAction : public MatchAction {
1832private:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001833 std::string S;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001834
1835public:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001836 DebugCommentAction(StringRef S) : S(S) {}
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001837
Daniel Sandersa7b75262017-10-31 18:50:24 +00001838 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00001839 Table << MatchTable::Comment(S) << MatchTable::LineBreak;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001840 }
1841};
1842
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001843/// Generates code to build an instruction or mutate an existing instruction
1844/// into the desired instruction when this is possible.
1845class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001846private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001847 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001848 const CodeGenInstruction *I;
Daniel Sanders64f745c2017-10-24 17:08:43 +00001849 const InstructionMatcher *Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001850 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1851
1852 /// True if the instruction can be built solely by mutating the opcode.
Daniel Sandersa7b75262017-10-31 18:50:24 +00001853 bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const {
1854 if (!Insn)
Daniel Sandersab1d1192017-10-24 18:11:54 +00001855 return false;
1856
Daniel Sandersa7b75262017-10-31 18:50:24 +00001857 if (OperandRenderers.size() != Insn->getNumOperands())
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001858 return false;
1859
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001860 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001861 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001862 const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
Daniel Sandersa7b75262017-10-31 18:50:24 +00001863 if (Insn != &OM.getInstructionMatcher() ||
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001864 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001865 return false;
1866 } else
1867 return false;
1868 }
1869
1870 return true;
1871 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001872
Daniel Sanders43c882c2017-02-01 10:53:10 +00001873public:
Daniel Sandersa7b75262017-10-31 18:50:24 +00001874 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
1875 : InsnID(InsnID), I(I), Matched(nullptr) {}
1876
Daniel Sandersdf258e32017-10-31 19:09:29 +00001877 const CodeGenInstruction *getCGI() const { return I; }
1878
Daniel Sandersa7b75262017-10-31 18:50:24 +00001879 void chooseInsnToMutate(RuleMatcher &Rule) {
1880 for (const auto *MutateCandidate : Rule.mutatable_insns()) {
1881 if (canMutate(Rule, MutateCandidate)) {
1882 // Take the first one we're offered that we're able to mutate.
1883 Rule.reserveInsnMatcherForMutation(MutateCandidate);
1884 Matched = MutateCandidate;
1885 return;
1886 }
1887 }
1888 }
Daniel Sanders43c882c2017-02-01 10:53:10 +00001889
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001890 template <class Kind, class... Args>
1891 Kind &addRenderer(Args&&... args) {
1892 OperandRenderers.emplace_back(
Daniel Sanders198447a2017-11-01 00:29:47 +00001893 llvm::make_unique<Kind>(InsnID, std::forward<Args>(args)...));
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001894 return *static_cast<Kind *>(OperandRenderers.back().get());
1895 }
1896
Daniel Sandersa7b75262017-10-31 18:50:24 +00001897 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1898 if (Matched) {
1899 assert(canMutate(Rule, Matched) &&
1900 "Arranged to mutate an insn that isn't mutatable");
1901
1902 unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001903 Table << MatchTable::Opcode("GIR_MutateOpcode")
1904 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1905 << MatchTable::Comment("RecycleInsnID")
1906 << MatchTable::IntValue(RecycleInsnID)
1907 << MatchTable::Comment("Opcode")
1908 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1909 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001910
1911 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001912 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001913 auto Namespace = Def->getValue("Namespace")
1914 ? Def->getValueAsString("Namespace")
1915 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001916 Table << MatchTable::Opcode("GIR_AddImplicitDef")
1917 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1918 << MatchTable::NamedValue(Namespace, Def->getName())
1919 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001920 }
1921 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001922 auto Namespace = Use->getValue("Namespace")
1923 ? Use->getValueAsString("Namespace")
1924 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001925 Table << MatchTable::Opcode("GIR_AddImplicitUse")
1926 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1927 << MatchTable::NamedValue(Namespace, Use->getName())
1928 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001929 }
1930 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001931 return;
1932 }
1933
1934 // TODO: Simple permutation looks like it could be almost as common as
1935 // mutation due to commutative operations.
1936
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001937 Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
1938 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
1939 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1940 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001941 for (const auto &Renderer : OperandRenderers)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001942 Renderer->emitRenderOpcodes(Table, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001943
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001944 if (I->mayLoad || I->mayStore) {
1945 Table << MatchTable::Opcode("GIR_MergeMemOperands")
1946 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1947 << MatchTable::Comment("MergeInsnID's");
1948 // Emit the ID's for all the instructions that are matched by this rule.
1949 // TODO: Limit this to matched instructions that mayLoad/mayStore or have
1950 // some other means of having a memoperand. Also limit this to
1951 // emitted instructions that expect to have a memoperand too. For
1952 // example, (G_SEXT (G_LOAD x)) that results in separate load and
1953 // sign-extend instructions shouldn't put the memoperand on the
1954 // sign-extend since it has no effect there.
1955 std::vector<unsigned> MergeInsnIDs;
1956 for (const auto &IDMatcherPair : Rule.defined_insn_vars())
1957 MergeInsnIDs.push_back(IDMatcherPair.second);
1958 std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end());
1959 for (const auto &MergeInsnID : MergeInsnIDs)
1960 Table << MatchTable::IntValue(MergeInsnID);
Daniel Sanders05540042017-08-08 10:44:31 +00001961 Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
1962 << MatchTable::LineBreak;
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001963 }
1964
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00001965 // FIXME: This is a hack but it's sufficient for ISel. We'll need to do
1966 // better for combines. Particularly when there are multiple match
1967 // roots.
1968 if (InsnID == 0)
1969 Table << MatchTable::Opcode("GIR_EraseFromParent")
1970 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1971 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001972 }
1973};
1974
1975/// Generates code to constrain the operands of an output instruction to the
1976/// register classes specified by the definition of that instruction.
1977class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001978 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001979
1980public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001981 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001982
Daniel Sandersa7b75262017-10-31 18:50:24 +00001983 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001984 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
1985 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1986 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001987 }
1988};
1989
1990/// Generates code to constrain the specified operand of an output instruction
1991/// to the specified register class.
1992class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001993 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001994 unsigned OpIdx;
1995 const CodeGenRegisterClass &RC;
1996
1997public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001998 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001999 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002000 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002001
Daniel Sandersa7b75262017-10-31 18:50:24 +00002002 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002003 Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
2004 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2005 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
2006 << MatchTable::Comment("RC " + RC.getName())
2007 << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002008 }
2009};
2010
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002011/// Generates code to create a temporary register which can be used to chain
2012/// instructions together.
2013class MakeTempRegisterAction : public MatchAction {
2014private:
2015 LLTCodeGen Ty;
2016 unsigned TempRegID;
2017
2018public:
2019 MakeTempRegisterAction(const LLTCodeGen &Ty, unsigned TempRegID)
2020 : Ty(Ty), TempRegID(TempRegID) {}
2021
2022 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2023 Table << MatchTable::Opcode("GIR_MakeTempReg")
2024 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
2025 << MatchTable::Comment("TypeID")
2026 << MatchTable::NamedValue(Ty.getCxxEnumValue())
2027 << MatchTable::LineBreak;
2028 }
2029};
2030
Daniel Sanders05540042017-08-08 10:44:31 +00002031InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002032 Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
Daniel Sandersa7b75262017-10-31 18:50:24 +00002033 MutatableInsns.insert(Matchers.back().get());
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002034 return *Matchers.back();
2035}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00002036
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002037void RuleMatcher::addRequiredFeature(Record *Feature) {
2038 RequiredFeatures.push_back(Feature);
2039}
2040
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002041const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
2042 return RequiredFeatures;
2043}
2044
Daniel Sanders7438b262017-10-31 23:03:18 +00002045// Emplaces an action of the specified Kind at the end of the action list.
2046//
2047// Returns a reference to the newly created action.
2048//
2049// Like std::vector::emplace_back(), may invalidate all iterators if the new
2050// size exceeds the capacity. Otherwise, only invalidates the past-the-end
2051// iterator.
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002052template <class Kind, class... Args>
2053Kind &RuleMatcher::addAction(Args &&... args) {
2054 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
2055 return *static_cast<Kind *>(Actions.back().get());
2056}
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002057
Daniel Sanders7438b262017-10-31 23:03:18 +00002058// Emplaces an action of the specified Kind before the given insertion point.
2059//
2060// Returns an iterator pointing at the newly created instruction.
2061//
2062// Like std::vector::insert(), may invalidate all iterators if the new size
2063// exceeds the capacity. Otherwise, only invalidates the iterators from the
2064// insertion point onwards.
2065template <class Kind, class... Args>
2066action_iterator RuleMatcher::insertAction(action_iterator InsertPt,
2067 Args &&... args) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002068 return Actions.emplace(InsertPt,
2069 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sanders7438b262017-10-31 23:03:18 +00002070}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002071
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002072unsigned
2073RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
2074 unsigned NewInsnVarID = NextInsnVarID++;
2075 InsnVariableIDs[&Matcher] = NewInsnVarID;
2076 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002077}
2078
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002079unsigned RuleMatcher::defineInsnVar(MatchTable &Table,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002080 const InstructionMatcher &Matcher,
2081 unsigned InsnID, unsigned OpIdx) {
2082 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002083 Table << MatchTable::Opcode("GIM_RecordInsn")
2084 << MatchTable::Comment("DefineMI") << MatchTable::IntValue(NewInsnVarID)
2085 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
2086 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2087 << MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
2088 << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002089 return NewInsnVarID;
2090}
2091
2092unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
2093 const auto &I = InsnVariableIDs.find(&InsnMatcher);
2094 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002095 return I->second;
2096 llvm_unreachable("Matched Insn was not captured in a local variable");
2097}
2098
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002099void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
2100 if (DefinedOperands.find(SymbolicName) == DefinedOperands.end()) {
2101 DefinedOperands[SymbolicName] = &OM;
2102 return;
2103 }
2104
2105 // If the operand is already defined, then we must ensure both references in
2106 // the matcher have the exact same node.
2107 OM.addPredicate<SameOperandMatcher>(OM.getSymbolicName());
2108}
2109
Daniel Sanders05540042017-08-08 10:44:31 +00002110const InstructionMatcher &
2111RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
2112 for (const auto &I : InsnVariableIDs)
2113 if (I.first->getSymbolicName() == SymbolicName)
2114 return *I.first;
2115 llvm_unreachable(
2116 ("Failed to lookup instruction " + SymbolicName).str().c_str());
2117}
2118
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002119const OperandMatcher &
2120RuleMatcher::getOperandMatcher(StringRef Name) const {
2121 const auto &I = DefinedOperands.find(Name);
2122
2123 if (I == DefinedOperands.end())
2124 PrintFatalError(SrcLoc, "Operand " + Name + " was not declared in matcher");
2125
2126 return *I->second;
2127}
2128
Daniel Sanders9d662d22017-07-06 10:06:12 +00002129/// Emit MatchTable opcodes to check the shape of the match and capture
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002130/// instructions into local variables.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002131void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002132 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002133 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002134 Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002135}
2136
Daniel Sanders8e82af22017-07-27 11:03:45 +00002137void RuleMatcher::emit(MatchTable &Table) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002138 if (Matchers.empty())
2139 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002140
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002141 // The representation supports rules that require multiple roots such as:
2142 // %ptr(p0) = ...
2143 // %elt0(s32) = G_LOAD %ptr
2144 // %1(p0) = G_ADD %ptr, 4
2145 // %elt1(s32) = G_LOAD p0 %1
2146 // which could be usefully folded into:
2147 // %ptr(p0) = ...
2148 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
2149 // on some targets but we don't need to make use of that yet.
2150 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002151
Daniel Sanders8e82af22017-07-27 11:03:45 +00002152 unsigned LabelID = Table.allocateLabelID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002153 Table << MatchTable::Opcode("GIM_Try", +1)
Daniel Sanders8e82af22017-07-27 11:03:45 +00002154 << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(LabelID)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002155 << MatchTable::LineBreak;
2156
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002157 if (!RequiredFeatures.empty()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002158 Table << MatchTable::Opcode("GIM_CheckFeatures")
2159 << MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
2160 << MatchTable::LineBreak;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002161 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002162
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002163 emitCaptureOpcodes(Table);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002164
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002165 Matchers.front()->emitPredicateOpcodes(Table, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002166 getInsnVarID(*Matchers.front()));
2167
Daniel Sandersbee57392017-04-04 13:25:23 +00002168 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002169 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00002170 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002171 SmallVector<unsigned, 2> InsnIDs;
2172 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002173 // Skip the root node since it isn't moving anywhere. Everything else is
2174 // sinking to meet it.
2175 if (Pair.first == Matchers.front().get())
2176 continue;
2177
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002178 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00002179 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002180 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00002181
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002182 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002183 // Reject the difficult cases until we have a more accurate check.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002184 Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
2185 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2186 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00002187
2188 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
2189 // account for unsafe cases.
2190 //
2191 // Example:
2192 // MI1--> %0 = ...
2193 // %1 = ... %0
2194 // MI0--> %2 = ... %0
2195 // It's not safe to erase MI1. We currently handle this by not
2196 // erasing %0 (even when it's dead).
2197 //
2198 // Example:
2199 // MI1--> %0 = load volatile @a
2200 // %1 = load volatile @a
2201 // MI0--> %2 = ... %0
2202 // It's not safe to sink %0's def past %1. We currently handle
2203 // this by rejecting all loads.
2204 //
2205 // Example:
2206 // MI1--> %0 = load @a
2207 // %1 = store @a
2208 // MI0--> %2 = ... %0
2209 // It's not safe to sink %0's def past %1. We currently handle
2210 // this by rejecting all loads.
2211 //
2212 // Example:
2213 // G_CONDBR %cond, @BB1
2214 // BB0:
2215 // MI1--> %0 = load @a
2216 // G_BR @BB1
2217 // BB1:
2218 // MI0--> %2 = ... %0
2219 // It's not always safe to sink %0 across control flow. In this
2220 // case it may introduce a memory fault. We currentl handle this
2221 // by rejecting all loads.
2222 }
2223 }
2224
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002225 for (const auto &MA : Actions)
Daniel Sandersa7b75262017-10-31 18:50:24 +00002226 MA->emitActionOpcodes(Table, *this);
Daniel Sandersf76f3152017-11-16 00:46:35 +00002227
2228 if (GenerateCoverage)
2229 Table << MatchTable::Opcode("GIR_Coverage") << MatchTable::IntValue(RuleID)
2230 << MatchTable::LineBreak;
2231
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002232 Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
Daniel Sanders8e82af22017-07-27 11:03:45 +00002233 << MatchTable::Label(LabelID);
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002234}
Daniel Sanders43c882c2017-02-01 10:53:10 +00002235
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002236bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
2237 // Rules involving more match roots have higher priority.
2238 if (Matchers.size() > B.Matchers.size())
2239 return true;
2240 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00002241 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002242
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002243 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
2244 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
2245 return true;
2246 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
2247 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002248 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002249
2250 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00002251}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002252
Daniel Sanders2deea182017-04-22 15:11:04 +00002253unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002254 return std::accumulate(
2255 Matchers.begin(), Matchers.end(), 0,
2256 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00002257 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002258 });
2259}
2260
Daniel Sanders05540042017-08-08 10:44:31 +00002261bool OperandPredicateMatcher::isHigherPriorityThan(
2262 const OperandPredicateMatcher &B) const {
2263 // Generally speaking, an instruction is more important than an Int or a
2264 // LiteralInt because it can cover more nodes but theres an exception to
2265 // this. G_CONSTANT's are less important than either of those two because they
2266 // are more permissive.
Daniel Sandersedd07842017-08-17 09:26:14 +00002267
2268 const InstructionOperandMatcher *AOM =
2269 dyn_cast<InstructionOperandMatcher>(this);
2270 const InstructionOperandMatcher *BOM =
2271 dyn_cast<InstructionOperandMatcher>(&B);
2272 bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
2273 bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
2274
2275 if (AOM && BOM) {
2276 // The relative priorities between a G_CONSTANT and any other instruction
2277 // don't actually matter but this code is needed to ensure a strict weak
2278 // ordering. This is particularly important on Windows where the rules will
2279 // be incorrectly sorted without it.
2280 if (AIsConstantInsn != BIsConstantInsn)
2281 return AIsConstantInsn < BIsConstantInsn;
2282 return false;
Daniel Sanders05540042017-08-08 10:44:31 +00002283 }
Daniel Sandersedd07842017-08-17 09:26:14 +00002284
2285 if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
2286 return false;
2287 if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
2288 return true;
Daniel Sanders05540042017-08-08 10:44:31 +00002289
2290 return Kind < B.Kind;
Daniel Sanders75b84fc2017-08-08 13:21:26 +00002291}
Daniel Sanders05540042017-08-08 10:44:31 +00002292
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002293void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
2294 RuleMatcher &Rule,
2295 unsigned InsnVarID,
2296 unsigned OpIdx) const {
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002297 const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002298 unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
2299
2300 Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
2301 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
2302 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2303 << MatchTable::Comment("OtherMI")
2304 << MatchTable::IntValue(OtherInsnVarID)
2305 << MatchTable::Comment("OtherOpIdx")
2306 << MatchTable::IntValue(OtherOM.getOperandIndex())
2307 << MatchTable::LineBreak;
2308}
2309
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002310//===- GlobalISelEmitter class --------------------------------------------===//
2311
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002312class GlobalISelEmitter {
2313public:
2314 explicit GlobalISelEmitter(RecordKeeper &RK);
2315 void run(raw_ostream &OS);
2316
2317private:
2318 const RecordKeeper &RK;
2319 const CodeGenDAGPatterns CGP;
2320 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002321 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002322
Daniel Sanders39690bd2017-10-15 02:41:12 +00002323 /// Keep track of the equivalence between SDNodes and Instruction by mapping
2324 /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
2325 /// check for attributes on the relation such as CheckMMOIsNonAtomic.
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002326 /// This is defined using 'GINodeEquiv' in the target description.
Daniel Sanders39690bd2017-10-15 02:41:12 +00002327 DenseMap<Record *, Record *> NodeEquivs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002328
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002329 /// Keep track of the equivalence between ComplexPattern's and
2330 /// GIComplexOperandMatcher. Map entries are specified by subclassing
2331 /// GIComplexPatternEquiv.
2332 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
2333
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002334 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002335 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002336
Daniel Sandersf76f3152017-11-16 00:46:35 +00002337 // Rule coverage information.
2338 Optional<CodeGenCoverage> RuleCoverage;
2339
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002340 void gatherNodeEquivs();
Daniel Sanders39690bd2017-10-15 02:41:12 +00002341 Record *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002342
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002343 Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002344 Expected<InstructionMatcher &> createAndImportSelDAGMatcher(
2345 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2346 const TreePatternNode *Src, unsigned &TempOpIdx) const;
2347 Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
2348 unsigned &TempOpIdx) const;
2349 Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002350 const TreePatternNode *SrcChild,
2351 bool OperandIsAPointer, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00002352 unsigned &TempOpIdx) const;
Daniel Sandersdf258e32017-10-31 19:09:29 +00002353
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002354 Expected<BuildMIAction &>
Daniel Sandersa7b75262017-10-31 18:50:24 +00002355 createAndImportInstructionRenderer(RuleMatcher &M,
2356 const TreePatternNode *Dst);
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002357 Expected<action_iterator> createAndImportSubInstructionRenderer(
2358 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
2359 unsigned TempReg);
Daniel Sanders7438b262017-10-31 23:03:18 +00002360 Expected<action_iterator>
2361 createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
2362 const TreePatternNode *Dst);
Daniel Sandersdf258e32017-10-31 19:09:29 +00002363 void importExplicitDefRenderers(BuildMIAction &DstMIBuilder);
Daniel Sanders7438b262017-10-31 23:03:18 +00002364 Expected<action_iterator>
2365 importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M,
2366 BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00002367 const llvm::TreePatternNode *Dst);
Daniel Sanders7438b262017-10-31 23:03:18 +00002368 Expected<action_iterator>
2369 importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
2370 BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002371 TreePatternNode *DstChild);
Diana Picus382602f2017-05-17 08:57:28 +00002372 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
2373 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00002374 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002375 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
2376 const std::vector<Record *> &ImplicitDefs) const;
2377
Daniel Sanders11300ce2017-10-13 21:28:03 +00002378 void emitImmPredicates(raw_ostream &OS, StringRef TypeIdentifier,
2379 StringRef Type,
Daniel Sanders649c5852017-10-13 20:42:18 +00002380 std::function<bool(const Record *R)> Filter);
2381
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002382 /// Analyze pattern \p P, returning a matcher for it if possible.
2383 /// Otherwise, return an Error explaining why we don't support it.
2384 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002385
2386 void declareSubtargetFeature(Record *Predicate);
Daniel Sanders7e523672017-11-11 03:23:44 +00002387
2388 TreePatternNode *fixupPatternNode(TreePatternNode *N);
2389 void fixupPatternTrees(TreePattern *P);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002390};
2391
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002392void GlobalISelEmitter::gatherNodeEquivs() {
2393 assert(NodeEquivs.empty());
2394 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
Daniel Sanders39690bd2017-10-15 02:41:12 +00002395 NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002396
2397 assert(ComplexPatternEquivs.empty());
2398 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
2399 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
2400 if (!SelDAGEquiv)
2401 continue;
2402 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
2403 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002404}
2405
Daniel Sanders39690bd2017-10-15 02:41:12 +00002406Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002407 return NodeEquivs.lookup(N);
2408}
2409
2410GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Daniel Sanders7e523672017-11-11 03:23:44 +00002411 : RK(RK), CGP(RK, [&](TreePattern *P) { fixupPatternTrees(P); }),
2412 Target(CGP.getTargetInfo()), CGRegs(RK, Target.getHwModes()) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002413
2414//===- Emitter ------------------------------------------------------------===//
2415
Daniel Sandersc270c502017-03-30 09:36:33 +00002416Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002417GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002418 ArrayRef<Predicate> Predicates) {
2419 for (const Predicate &P : Predicates) {
2420 if (!P.Def)
2421 continue;
2422 declareSubtargetFeature(P.Def);
2423 M.addRequiredFeature(P.Def);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002424 }
2425
Daniel Sandersc270c502017-03-30 09:36:33 +00002426 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002427}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002428
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002429Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
2430 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2431 const TreePatternNode *Src, unsigned &TempOpIdx) const {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002432 Record *SrcGIEquivOrNull = nullptr;
Daniel Sanders85ffd362017-07-06 08:12:20 +00002433 const CodeGenInstruction *SrcGIOrNull = nullptr;
2434
Daniel Sandersffc7d582017-03-29 15:37:18 +00002435 // Start with the defined operands (i.e., the results of the root operator).
2436 if (Src->getExtTypes().size() > 1)
2437 return failedImport("Src pattern has multiple results");
2438
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002439 if (Src->isLeaf()) {
2440 Init *SrcInit = Src->getLeafValue();
Daniel Sanders3334cc02017-05-23 20:02:48 +00002441 if (isa<IntInit>(SrcInit)) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002442 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
2443 &Target.getInstruction(RK.getDef("G_CONSTANT")));
2444 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002445 return failedImport(
2446 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002447 } else {
Daniel Sanders39690bd2017-10-15 02:41:12 +00002448 SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
2449 if (!SrcGIEquivOrNull)
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002450 return failedImport("Pattern operator lacks an equivalent Instruction" +
2451 explainOperator(Src->getOperator()));
Daniel Sanders39690bd2017-10-15 02:41:12 +00002452 SrcGIOrNull = &Target.getInstruction(SrcGIEquivOrNull->getValueAsDef("I"));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002453
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002454 // The operators look good: match the opcode
Daniel Sanders39690bd2017-10-15 02:41:12 +00002455 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002456 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002457
2458 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002459 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002460 // Results don't have a name unless they are the root node. The caller will
2461 // set the name if appropriate.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002462 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002463 if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
2464 return failedImport(toString(std::move(Error)) +
2465 " for result of Src pattern operator");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002466 }
2467
Daniel Sanders2c269f62017-08-24 09:11:20 +00002468 for (const auto &Predicate : Src->getPredicateFns()) {
2469 if (Predicate.isAlwaysTrue())
2470 continue;
2471
2472 if (Predicate.isImmediatePattern()) {
2473 InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
2474 continue;
2475 }
2476
Daniel Sandersa71f4542017-10-16 00:56:30 +00002477 // No check required. A G_LOAD is an unindexed load.
2478 if (Predicate.isLoad() && Predicate.isUnindexed())
2479 continue;
2480
2481 // No check required. G_LOAD by itself is a non-extending load.
2482 if (Predicate.isNonExtLoad())
2483 continue;
2484
2485 if (Predicate.isLoad() && Predicate.getMemoryVT() != nullptr) {
2486 Optional<LLTCodeGen> MemTyOrNone =
2487 MVTToLLT(getValueType(Predicate.getMemoryVT()));
2488
2489 if (!MemTyOrNone)
2490 return failedImport("MemVT could not be converted to LLT");
2491
2492 InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue());
2493 continue;
2494 }
2495
Daniel Sandersd66e0902017-10-23 18:19:24 +00002496 // No check required. A G_STORE is an unindexed store.
2497 if (Predicate.isStore() && Predicate.isUnindexed())
2498 continue;
2499
2500 // No check required. G_STORE by itself is a non-extending store.
2501 if (Predicate.isNonTruncStore())
2502 continue;
2503
2504 if (Predicate.isStore() && Predicate.getMemoryVT() != nullptr) {
2505 Optional<LLTCodeGen> MemTyOrNone =
2506 MVTToLLT(getValueType(Predicate.getMemoryVT()));
2507
2508 if (!MemTyOrNone)
2509 return failedImport("MemVT could not be converted to LLT");
2510
2511 InsnMatcher.getOperand(0).addPredicate<LLTOperandMatcher>(MemTyOrNone.getValue());
2512 continue;
2513 }
2514
Daniel Sanders2c269f62017-08-24 09:11:20 +00002515 return failedImport("Src pattern child has predicate (" +
2516 explainPredicates(Src) + ")");
2517 }
Daniel Sanders39690bd2017-10-15 02:41:12 +00002518 if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
2519 InsnMatcher.addPredicate<NonAtomicMMOPredicateMatcher>();
Daniel Sanders2c269f62017-08-24 09:11:20 +00002520
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002521 if (Src->isLeaf()) {
2522 Init *SrcInit = Src->getLeafValue();
2523 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002524 OperandMatcher &OM =
2525 InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002526 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
2527 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002528 return failedImport(
2529 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002530 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002531 assert(SrcGIOrNull &&
2532 "Expected to have already found an equivalent Instruction");
Daniel Sanders11300ce2017-10-13 21:28:03 +00002533 if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
2534 SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
2535 // imm/fpimm still have operands but we don't need to do anything with it
Daniel Sanders05540042017-08-08 10:44:31 +00002536 // here since we don't support ImmLeaf predicates yet. However, we still
2537 // need to note the hidden operand to get GIM_CheckNumOperands correct.
2538 InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2539 return InsnMatcher;
2540 }
2541
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002542 // Match the used operands (i.e. the children of the operator).
2543 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002544 TreePatternNode *SrcChild = Src->getChild(i);
2545
Daniel Sandersa71f4542017-10-16 00:56:30 +00002546 // SelectionDAG allows pointers to be represented with iN since it doesn't
2547 // distinguish between pointers and integers but they are different types in GlobalISel.
2548 // Coerce integers to pointers to address space 0 if the context indicates a pointer.
2549 // TODO: Find a better way to do this, SDTCisPtrTy?
2550 bool OperandIsAPointer =
Daniel Sandersd66e0902017-10-23 18:19:24 +00002551 (SrcGIOrNull->TheDef->getName() == "G_LOAD" && i == 0) ||
2552 (SrcGIOrNull->TheDef->getName() == "G_STORE" && i == 1);
Daniel Sandersa71f4542017-10-16 00:56:30 +00002553
Daniel Sanders28887fe2017-09-19 12:56:36 +00002554 // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
2555 // following the defs is an intrinsic ID.
2556 if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
2557 SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
2558 i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002559 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002560 OperandMatcher &OM =
2561 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002562 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00002563 continue;
2564 }
2565
2566 return failedImport("Expected IntInit containing instrinsic ID)");
2567 }
2568
Daniel Sandersa71f4542017-10-16 00:56:30 +00002569 if (auto Error =
2570 importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
2571 OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002572 return std::move(Error);
2573 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002574 }
2575
2576 return InsnMatcher;
2577}
2578
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002579Error GlobalISelEmitter::importComplexPatternOperandMatcher(
2580 OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
2581 const auto &ComplexPattern = ComplexPatternEquivs.find(R);
2582 if (ComplexPattern == ComplexPatternEquivs.end())
2583 return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
2584 ") not mapped to GlobalISel");
2585
2586 OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
2587 TempOpIdx++;
2588 return Error::success();
2589}
2590
2591Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
2592 InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002593 const TreePatternNode *SrcChild,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002594 bool OperandIsAPointer,
Daniel Sandersc270c502017-03-30 09:36:33 +00002595 unsigned OpIdx,
2596 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002597 OperandMatcher &OM =
2598 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002599 if (OM.isSameAsAnotherOperand())
2600 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002601
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002602 ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002603 if (ChildTypes.size() != 1)
2604 return failedImport("Src pattern child has multiple results");
2605
2606 // Check MBB's before the type check since they are not a known type.
2607 if (!SrcChild->isLeaf()) {
2608 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
2609 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
2610 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
2611 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00002612 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002613 }
2614 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002615 }
2616
Daniel Sandersa71f4542017-10-16 00:56:30 +00002617 if (auto Error =
2618 OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
2619 return failedImport(toString(std::move(Error)) + " for Src operand (" +
2620 to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002621
Daniel Sandersbee57392017-04-04 13:25:23 +00002622 // Check for nested instructions.
2623 if (!SrcChild->isLeaf()) {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002624 if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
2625 // When a ComplexPattern is used as an operator, it should do the same
2626 // thing as when used as a leaf. However, the children of the operator
2627 // name the sub-operands that make up the complex operand and we must
2628 // prepare to reference them in the renderer too.
2629 unsigned RendererID = TempOpIdx;
2630 if (auto Error = importComplexPatternOperandMatcher(
2631 OM, SrcChild->getOperator(), TempOpIdx))
2632 return Error;
2633
2634 for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
2635 auto *SubOperand = SrcChild->getChild(i);
2636 if (!SubOperand->getName().empty())
2637 Rule.defineComplexSubOperand(SubOperand->getName(),
2638 SrcChild->getOperator(), RendererID, i);
2639 }
2640
2641 return Error::success();
2642 }
2643
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002644 auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
2645 InsnMatcher.getRuleMatcher(), SrcChild->getName());
2646 if (!MaybeInsnOperand.hasValue()) {
2647 // This isn't strictly true. If the user were to provide exactly the same
2648 // matchers as the original operand then we could allow it. However, it's
2649 // simpler to not permit the redundant specification.
2650 return failedImport("Nested instruction cannot be the same as another operand");
2651 }
2652
Daniel Sandersbee57392017-04-04 13:25:23 +00002653 // Map the node to a gMIR instruction.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002654 InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
Daniel Sanders57938df2017-07-11 10:40:18 +00002655 auto InsnMatcherOrError = createAndImportSelDAGMatcher(
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002656 Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00002657 if (auto Error = InsnMatcherOrError.takeError())
2658 return Error;
2659
2660 return Error::success();
2661 }
2662
Diana Picusd1b61812017-11-03 10:30:19 +00002663 if (SrcChild->hasAnyPredicate())
2664 return failedImport("Src pattern child has unsupported predicate");
2665
Daniel Sandersffc7d582017-03-29 15:37:18 +00002666 // Check for constant immediates.
2667 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002668 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00002669 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002670 }
2671
2672 // Check for def's like register classes or ComplexPattern's.
2673 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
2674 auto *ChildRec = ChildDefInit->getDef();
2675
2676 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002677 if (ChildRec->isSubClassOf("RegisterClass") ||
2678 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002679 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002680 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00002681 return Error::success();
2682 }
2683
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002684 // Check for ValueType.
2685 if (ChildRec->isSubClassOf("ValueType")) {
2686 // We already added a type check as standard practice so this doesn't need
2687 // to do anything.
2688 return Error::success();
2689 }
2690
Daniel Sandersffc7d582017-03-29 15:37:18 +00002691 // Check for ComplexPattern's.
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002692 if (ChildRec->isSubClassOf("ComplexPattern"))
2693 return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002694
Daniel Sandersd0656a32017-04-13 09:45:37 +00002695 if (ChildRec->isSubClassOf("ImmLeaf")) {
2696 return failedImport(
2697 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
2698 }
2699
Daniel Sandersffc7d582017-03-29 15:37:18 +00002700 return failedImport(
2701 "Src pattern child def is an unsupported tablegen class");
2702 }
2703
2704 return failedImport("Src pattern child is an unsupported kind");
2705}
2706
Daniel Sanders7438b262017-10-31 23:03:18 +00002707Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
2708 action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002709 TreePatternNode *DstChild) {
Daniel Sanders2c269f62017-08-24 09:11:20 +00002710 if (DstChild->getTransformFn() != nullptr) {
2711 return failedImport("Dst pattern child has transform fn " +
2712 DstChild->getTransformFn()->getName());
2713 }
2714
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002715 const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
2716 if (SubOperand.hasValue()) {
2717 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002718 *std::get<0>(*SubOperand), DstChild->getName(),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002719 std::get<1>(*SubOperand), std::get<2>(*SubOperand));
Daniel Sanders7438b262017-10-31 23:03:18 +00002720 return InsertPt;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002721 }
2722
Daniel Sandersffc7d582017-03-29 15:37:18 +00002723 if (!DstChild->isLeaf()) {
Daniel Sanders05540042017-08-08 10:44:31 +00002724 // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
2725 // inline, but in MI it's just another operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002726 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
2727 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
2728 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sanders198447a2017-11-01 00:29:47 +00002729 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002730 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002731 }
2732 }
Daniel Sanders05540042017-08-08 10:44:31 +00002733
2734 // Similarly, imm is an operator in TreePatternNode's view but must be
2735 // rendered as operands.
2736 // FIXME: The target should be able to choose sign-extended when appropriate
2737 // (e.g. on Mips).
2738 if (DstChild->getOperator()->getName() == "imm") {
Daniel Sanders198447a2017-11-01 00:29:47 +00002739 DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002740 return InsertPt;
Daniel Sanders11300ce2017-10-13 21:28:03 +00002741 } else if (DstChild->getOperator()->getName() == "fpimm") {
2742 DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002743 DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002744 return InsertPt;
Daniel Sanders05540042017-08-08 10:44:31 +00002745 }
2746
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002747 if (DstChild->getOperator()->isSubClassOf("Instruction")) {
2748 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
2749 if (ChildTypes.size() != 1)
2750 return failedImport("Dst pattern child has multiple results");
2751
2752 Optional<LLTCodeGen> OpTyOrNone = None;
2753 if (ChildTypes.front().isMachineValueType())
2754 OpTyOrNone =
2755 MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
2756 if (!OpTyOrNone)
2757 return failedImport("Dst operand has an unsupported type");
2758
2759 unsigned TempRegID = Rule.allocateTempRegID();
2760 InsertPt = Rule.insertAction<MakeTempRegisterAction>(
2761 InsertPt, OpTyOrNone.getValue(), TempRegID);
2762 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
2763
2764 auto InsertPtOrError = createAndImportSubInstructionRenderer(
2765 ++InsertPt, Rule, DstChild, TempRegID);
2766 if (auto Error = InsertPtOrError.takeError())
2767 return std::move(Error);
2768 return InsertPtOrError.get();
2769 }
2770
Daniel Sanders2c269f62017-08-24 09:11:20 +00002771 return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002772 }
2773
2774 // Otherwise, we're looking for a bog-standard RegisterClass operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002775 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
2776 auto *ChildRec = ChildDefInit->getDef();
2777
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002778 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002779 if (ChildTypes.size() != 1)
2780 return failedImport("Dst pattern child has multiple results");
2781
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002782 Optional<LLTCodeGen> OpTyOrNone = None;
2783 if (ChildTypes.front().isMachineValueType())
2784 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002785 if (!OpTyOrNone)
2786 return failedImport("Dst operand has an unsupported type");
2787
2788 if (ChildRec->isSubClassOf("Register")) {
Daniel Sanders198447a2017-11-01 00:29:47 +00002789 DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
Daniel Sanders7438b262017-10-31 23:03:18 +00002790 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002791 }
2792
Daniel Sanders658541f2017-04-22 15:53:21 +00002793 if (ChildRec->isSubClassOf("RegisterClass") ||
Daniel Sanders4d4e7652017-10-09 18:14:53 +00002794 ChildRec->isSubClassOf("RegisterOperand") ||
2795 ChildRec->isSubClassOf("ValueType")) {
Daniel Sandersd66e0902017-10-23 18:19:24 +00002796 if (ChildRec->isSubClassOf("RegisterOperand") &&
2797 !ChildRec->isValueUnset("GIZeroRegister")) {
2798 DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002799 DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
Daniel Sanders7438b262017-10-31 23:03:18 +00002800 return InsertPt;
Daniel Sandersd66e0902017-10-23 18:19:24 +00002801 }
2802
Daniel Sanders198447a2017-11-01 00:29:47 +00002803 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00002804 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002805 }
2806
2807 if (ChildRec->isSubClassOf("ComplexPattern")) {
2808 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
2809 if (ComplexPattern == ComplexPatternEquivs.end())
2810 return failedImport(
2811 "SelectionDAG ComplexPattern not mapped to GlobalISel");
2812
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002813 const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002814 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00002815 *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00002816 OM.getAllocatedTemporariesBaseID());
Daniel Sanders7438b262017-10-31 23:03:18 +00002817 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002818 }
2819
Daniel Sandersd0656a32017-04-13 09:45:37 +00002820 if (ChildRec->isSubClassOf("SDNodeXForm"))
2821 return failedImport("Dst pattern child def is an unsupported tablegen "
2822 "class (SDNodeXForm)");
2823
Daniel Sandersffc7d582017-03-29 15:37:18 +00002824 return failedImport(
2825 "Dst pattern child def is an unsupported tablegen class");
2826 }
2827
2828 return failedImport("Dst pattern child is an unsupported kind");
2829}
2830
Daniel Sandersc270c502017-03-30 09:36:33 +00002831Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersa7b75262017-10-31 18:50:24 +00002832 RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sanders7438b262017-10-31 23:03:18 +00002833 auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
2834 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00002835 return std::move(Error);
2836
Daniel Sanders7438b262017-10-31 23:03:18 +00002837 action_iterator InsertPt = InsertPtOrError.get();
2838 BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
Daniel Sandersdf258e32017-10-31 19:09:29 +00002839
2840 importExplicitDefRenderers(DstMIBuilder);
2841
Daniel Sanders7438b262017-10-31 23:03:18 +00002842 if (auto Error = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst)
2843 .takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00002844 return std::move(Error);
2845
2846 return DstMIBuilder;
2847}
2848
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002849Expected<action_iterator>
2850GlobalISelEmitter::createAndImportSubInstructionRenderer(
2851 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
2852 unsigned TempRegID) {
2853 auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
2854
2855 // TODO: Assert there's exactly one result.
2856
2857 if (auto Error = InsertPtOrError.takeError())
2858 return std::move(Error);
2859 InsertPt = InsertPtOrError.get();
2860
2861 BuildMIAction &DstMIBuilder =
2862 *static_cast<BuildMIAction *>(InsertPtOrError.get()->get());
2863
2864 // Assign the result to TempReg.
2865 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);
2866
2867 InsertPtOrError = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst);
2868 if (auto Error = InsertPtOrError.takeError())
2869 return std::move(Error);
2870
2871 return InsertPtOrError.get();
2872}
2873
Daniel Sanders7438b262017-10-31 23:03:18 +00002874Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
2875 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002876 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00002877 if (!DstOp->isSubClassOf("Instruction")) {
2878 if (DstOp->isSubClassOf("ValueType"))
2879 return failedImport(
2880 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002881 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00002882 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002883 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002884
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002885 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002886 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersdf258e32017-10-31 19:09:29 +00002887 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS")
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002888 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sandersdf258e32017-10-31 19:09:29 +00002889 else if (DstI->TheDef->getName() == "EXTRACT_SUBREG")
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002890 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002891 else if (DstI->TheDef->getName() == "REG_SEQUENCE")
2892 return failedImport("Unable to emit REG_SEQUENCE");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002893
Daniel Sanders198447a2017-11-01 00:29:47 +00002894 return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),
2895 DstI);
Daniel Sandersdf258e32017-10-31 19:09:29 +00002896}
2897
2898void GlobalISelEmitter::importExplicitDefRenderers(
2899 BuildMIAction &DstMIBuilder) {
2900 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002901 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
2902 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sanders198447a2017-11-01 00:29:47 +00002903 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002904 }
Daniel Sandersdf258e32017-10-31 19:09:29 +00002905}
2906
Daniel Sanders7438b262017-10-31 23:03:18 +00002907Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
2908 action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00002909 const llvm::TreePatternNode *Dst) {
2910 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
2911 CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002912
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002913 // EXTRACT_SUBREG needs to use a subregister COPY.
Daniel Sandersdf258e32017-10-31 19:09:29 +00002914 if (OrigDstI->TheDef->getName() == "EXTRACT_SUBREG") {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002915 if (!Dst->getChild(0)->isLeaf())
2916 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2917
Daniel Sanders32291982017-06-28 13:50:04 +00002918 if (DefInit *SubRegInit =
2919 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002920 Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
2921 if (!RCDef)
2922 return failedImport("EXTRACT_SUBREG child #0 could not "
2923 "be coerced to a register class");
2924
2925 CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002926 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
2927
2928 const auto &SrcRCDstRCPair =
2929 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2930 if (SrcRCDstRCPair.hasValue()) {
2931 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
2932 if (SrcRCDstRCPair->first != RC)
2933 return failedImport("EXTRACT_SUBREG requires an additional COPY");
2934 }
2935
Daniel Sanders198447a2017-11-01 00:29:47 +00002936 DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
2937 SubIdx);
Daniel Sanders7438b262017-10-31 23:03:18 +00002938 return InsertPt;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002939 }
2940
2941 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
2942 }
2943
Daniel Sandersffc7d582017-03-29 15:37:18 +00002944 // Render the explicit uses.
Daniel Sandersdf258e32017-10-31 19:09:29 +00002945 unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
2946 unsigned ExpectedDstINumUses = Dst->getNumChildren();
2947 if (OrigDstI->TheDef->getName() == "COPY_TO_REGCLASS") {
2948 DstINumUses--; // Ignore the class constraint.
2949 ExpectedDstINumUses--;
2950 }
2951
Daniel Sanders0ed28822017-04-12 08:23:08 +00002952 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00002953 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002954 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002955 const CGIOperandList::OperandInfo &DstIOperand =
2956 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00002957
Diana Picus382602f2017-05-17 08:57:28 +00002958 // If the operand has default values, introduce them now.
2959 // FIXME: Until we have a decent test case that dictates we should do
2960 // otherwise, we're going to assume that operands with default values cannot
2961 // be specified in the patterns. Therefore, adding them will not cause us to
2962 // end up with too many rendered operands.
2963 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00002964 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00002965 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
2966 return std::move(Error);
2967 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002968 continue;
2969 }
2970
Daniel Sanders7438b262017-10-31 23:03:18 +00002971 auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
2972 Dst->getChild(Child));
2973 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersffc7d582017-03-29 15:37:18 +00002974 return std::move(Error);
Daniel Sanders7438b262017-10-31 23:03:18 +00002975 InsertPt = InsertPtOrError.get();
Daniel Sanders0ed28822017-04-12 08:23:08 +00002976 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002977 }
2978
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002979 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00002980 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00002981 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002982 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00002983 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00002984 " default ones");
2985
Daniel Sanders7438b262017-10-31 23:03:18 +00002986 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002987}
2988
Diana Picus382602f2017-05-17 08:57:28 +00002989Error GlobalISelEmitter::importDefaultOperandRenderers(
2990 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00002991 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00002992 // Look through ValueType operators.
2993 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
2994 if (const DefInit *DefaultDagOperator =
2995 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
2996 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
2997 DefaultOp = DefaultDagOp->getArg(0);
2998 }
2999 }
3000
3001 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003002 DstMIBuilder.addRenderer<AddRegisterRenderer>(DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00003003 continue;
3004 }
3005
3006 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003007 DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00003008 continue;
3009 }
3010
3011 return failedImport("Could not add default op");
3012 }
3013
3014 return Error::success();
3015}
3016
Daniel Sandersc270c502017-03-30 09:36:33 +00003017Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00003018 BuildMIAction &DstMIBuilder,
3019 const std::vector<Record *> &ImplicitDefs) const {
3020 if (!ImplicitDefs.empty())
3021 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00003022 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003023}
3024
3025Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003026 // Keep track of the matchers and actions to emit.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003027 RuleMatcher M(P.getSrcRecord()->getLoc());
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00003028 M.addAction<DebugCommentAction>(llvm::to_string(*P.getSrcPattern()) +
3029 " => " +
3030 llvm::to_string(*P.getDstPattern()));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003031
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003032 if (auto Error = importRulePredicates(M, P.getPredicates()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003033 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003034
3035 // Next, analyze the pattern operators.
3036 TreePatternNode *Src = P.getSrcPattern();
3037 TreePatternNode *Dst = P.getDstPattern();
3038
3039 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00003040 if (auto Err = isTrivialOperatorNode(Dst))
3041 return failedImport("Dst pattern root isn't a trivial operator (" +
3042 toString(std::move(Err)) + ")");
3043 if (auto Err = isTrivialOperatorNode(Src))
3044 return failedImport("Src pattern root isn't a trivial operator (" +
3045 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003046
Daniel Sandersedd07842017-08-17 09:26:14 +00003047 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
3048 unsigned TempOpIdx = 0;
3049 auto InsnMatcherOrError =
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003050 createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
Daniel Sandersedd07842017-08-17 09:26:14 +00003051 if (auto Error = InsnMatcherOrError.takeError())
3052 return std::move(Error);
3053 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
3054
3055 if (Dst->isLeaf()) {
3056 Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
3057
3058 const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
3059 if (RCDef) {
3060 // We need to replace the def and all its uses with the specified
3061 // operand. However, we must also insert COPY's wherever needed.
3062 // For now, emit a copy and let the register allocator clean up.
3063 auto &DstI = Target.getInstruction(RK.getDef("COPY"));
3064 const auto &DstIOperand = DstI.Operands[0];
3065
3066 OperandMatcher &OM0 = InsnMatcher.getOperand(0);
3067 OM0.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003068 M.defineOperand(OM0.getSymbolicName(), OM0);
Daniel Sandersedd07842017-08-17 09:26:14 +00003069 OM0.addPredicate<RegisterBankOperandMatcher>(RC);
3070
Daniel Sanders198447a2017-11-01 00:29:47 +00003071 auto &DstMIBuilder =
3072 M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
3073 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
3074 DstMIBuilder.addRenderer<CopyRenderer>(Dst->getName());
Daniel Sandersedd07842017-08-17 09:26:14 +00003075 M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
3076
3077 // We're done with this pattern! It's eligible for GISel emission; return
3078 // it.
3079 ++NumPatternImported;
3080 return std::move(M);
3081 }
3082
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003083 return failedImport("Dst pattern root isn't a known leaf");
Daniel Sandersedd07842017-08-17 09:26:14 +00003084 }
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003085
Daniel Sandersbee57392017-04-04 13:25:23 +00003086 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003087 Record *DstOp = Dst->getOperator();
3088 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003089 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003090
3091 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003092 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00003093 return failedImport("Src pattern results and dst MI defs are different (" +
3094 to_string(Src->getExtTypes().size()) + " def(s) vs " +
3095 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003096
Daniel Sandersffc7d582017-03-29 15:37:18 +00003097 // The root of the match also has constraints on the register bank so that it
3098 // matches the result instruction.
3099 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003100 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
3101 (void)VTy;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003102
Daniel Sanders066ebbf2017-02-24 15:43:30 +00003103 const auto &DstIOperand = DstI.Operands[OpIdx];
3104 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003105 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3106 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3107
3108 if (DstIOpRec == nullptr)
3109 return failedImport(
3110 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003111 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3112 if (!Dst->getChild(0)->isLeaf())
3113 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
3114
Daniel Sanders32291982017-06-28 13:50:04 +00003115 // We can assume that a subregister is in the same bank as it's super
3116 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003117 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
3118
3119 if (DstIOpRec == nullptr)
3120 return failedImport(
3121 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003122 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00003123 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003124 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00003125 return failedImport("Dst MI def isn't a register class" +
3126 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003127
Daniel Sandersffc7d582017-03-29 15:37:18 +00003128 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
3129 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003130 M.defineOperand(OM.getSymbolicName(), OM);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00003131 OM.addPredicate<RegisterBankOperandMatcher>(
3132 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003133 ++OpIdx;
3134 }
3135
Daniel Sandersa7b75262017-10-31 18:50:24 +00003136 auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003137 if (auto Error = DstMIBuilderOrError.takeError())
3138 return std::move(Error);
3139 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003140
Daniel Sandersffc7d582017-03-29 15:37:18 +00003141 // Render the implicit defs.
3142 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00003143 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003144 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003145
Daniel Sandersa7b75262017-10-31 18:50:24 +00003146 DstMIBuilder.chooseInsnToMutate(M);
3147
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003148 // Constrain the registers to classes. This is normally derived from the
3149 // emitted instruction but a few instructions require special handling.
3150 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3151 // COPY_TO_REGCLASS does not provide operand constraints itself but the
3152 // result is constrained to the class given by the second child.
3153 Record *DstIOpRec =
3154 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3155
3156 if (DstIOpRec == nullptr)
3157 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
3158
3159 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003160 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003161
3162 // We're done with this pattern! It's eligible for GISel emission; return
3163 // it.
3164 ++NumPatternImported;
3165 return std::move(M);
3166 }
3167
3168 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3169 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
3170 // instructions, the result register class is controlled by the
3171 // subregisters of the operand. As a result, we must constrain the result
3172 // class rather than check that it's already the right one.
3173 if (!Dst->getChild(0)->isLeaf())
3174 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
3175
Daniel Sanders320390b2017-06-28 15:16:03 +00003176 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
3177 if (!SubRegInit)
3178 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003179
Daniel Sanders320390b2017-06-28 15:16:03 +00003180 // Constrain the result to the same register bank as the operand.
3181 Record *DstIOpRec =
3182 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003183
Daniel Sanders320390b2017-06-28 15:16:03 +00003184 if (DstIOpRec == nullptr)
3185 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003186
Daniel Sanders320390b2017-06-28 15:16:03 +00003187 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003188 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003189
Daniel Sanders320390b2017-06-28 15:16:03 +00003190 // It would be nice to leave this constraint implicit but we're required
3191 // to pick a register class so constrain the result to a register class
3192 // that can hold the correct MVT.
3193 //
3194 // FIXME: This may introduce an extra copy if the chosen class doesn't
3195 // actually contain the subregisters.
3196 assert(Src->getExtTypes().size() == 1 &&
3197 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003198
Daniel Sanders320390b2017-06-28 15:16:03 +00003199 const auto &SrcRCDstRCPair =
3200 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
3201 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003202 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
3203 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
3204
3205 // We're done with this pattern! It's eligible for GISel emission; return
3206 // it.
3207 ++NumPatternImported;
3208 return std::move(M);
3209 }
3210
3211 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003212
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003213 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003214 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003215 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003216}
3217
Daniel Sanders649c5852017-10-13 20:42:18 +00003218// Emit imm predicate table and an enum to reference them with.
3219// The 'Predicate_' part of the name is redundant but eliminating it is more
3220// trouble than it's worth.
3221void GlobalISelEmitter::emitImmPredicates(
Daniel Sanders11300ce2017-10-13 21:28:03 +00003222 raw_ostream &OS, StringRef TypeIdentifier, StringRef Type,
3223 std::function<bool(const Record *R)> Filter) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003224 std::vector<const Record *> MatchedRecords;
3225 const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
3226 std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
3227 [&](Record *Record) {
3228 return !Record->getValueAsString("ImmediateCode").empty() &&
3229 Filter(Record);
3230 });
3231
Daniel Sanders11300ce2017-10-13 21:28:03 +00003232 if (!MatchedRecords.empty()) {
3233 OS << "// PatFrag predicates.\n"
3234 << "enum {\n";
Daniel Sanders2fed4ff2017-10-13 21:51:20 +00003235 std::string EnumeratorSeparator =
Daniel Sanders11300ce2017-10-13 21:28:03 +00003236 (" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str();
3237 for (const auto *Record : MatchedRecords) {
3238 OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName()
3239 << EnumeratorSeparator;
3240 EnumeratorSeparator = ",\n";
3241 }
3242 OS << "};\n";
Daniel Sanders649c5852017-10-13 20:42:18 +00003243 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00003244
Daniel Sanders649c5852017-10-13 20:42:18 +00003245 for (const auto *Record : MatchedRecords)
Daniel Sanders11300ce2017-10-13 21:28:03 +00003246 OS << "static bool Predicate_" << Record->getName() << "(" << Type
3247 << " Imm) {" << Record->getValueAsString("ImmediateCode") << "}\n";
3248
3249 OS << "static InstructionSelector::" << TypeIdentifier
3250 << "ImmediatePredicateFn " << TypeIdentifier << "ImmPredicateFns[] = {\n"
Daniel Sanders649c5852017-10-13 20:42:18 +00003251 << " nullptr,\n";
3252 for (const auto *Record : MatchedRecords)
3253 OS << " Predicate_" << Record->getName() << ",\n";
3254 OS << "};\n";
3255}
3256
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003257void GlobalISelEmitter::run(raw_ostream &OS) {
Daniel Sandersf76f3152017-11-16 00:46:35 +00003258 if (!UseCoverageFile.empty()) {
3259 RuleCoverage = CodeGenCoverage();
3260 auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);
3261 if (!RuleCoverageBufOrErr) {
3262 PrintWarning(SMLoc(), "Missing rule coverage data");
3263 RuleCoverage = None;
3264 } else {
3265 if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {
3266 PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");
3267 RuleCoverage = None;
3268 }
3269 }
3270 }
3271
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003272 // Track the GINodeEquiv definitions.
3273 gatherNodeEquivs();
3274
3275 emitSourceFileHeader(("Global Instruction Selector for the " +
3276 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003277 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003278 // Look through the SelectionDAG patterns we found, possibly emitting some.
3279 for (const PatternToMatch &Pat : CGP.ptms()) {
3280 ++NumPatternTotal;
Daniel Sanders7e523672017-11-11 03:23:44 +00003281
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003282 auto MatcherOrErr = runOnPattern(Pat);
3283
3284 // The pattern analysis can fail, indicating an unsupported pattern.
3285 // Report that if we've been asked to do so.
3286 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003287 if (WarnOnSkippedPatterns) {
3288 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003289 "Skipped pattern: " + toString(std::move(Err)));
3290 } else {
3291 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003292 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003293 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003294 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003295 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003296
Daniel Sandersf76f3152017-11-16 00:46:35 +00003297 if (RuleCoverage) {
3298 if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))
3299 ++NumPatternsTested;
3300 else
3301 PrintWarning(Pat.getSrcRecord()->getLoc(),
3302 "Pattern is not covered by a test");
3303 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003304 Rules.push_back(std::move(MatcherOrErr.get()));
3305 }
3306
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00003307 std::stable_sort(Rules.begin(), Rules.end(),
3308 [&](const RuleMatcher &A, const RuleMatcher &B) {
3309 if (A.isHigherPriorityThan(B)) {
3310 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
3311 "and less important at "
3312 "the same time");
3313 return true;
3314 }
3315 return false;
3316 });
Daniel Sanders759ff412017-02-24 13:58:11 +00003317
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003318 std::vector<Record *> ComplexPredicates =
3319 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
3320 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
3321 [](const Record *A, const Record *B) {
3322 if (A->getName() < B->getName())
3323 return true;
3324 return false;
3325 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003326 unsigned MaxTemporaries = 0;
3327 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00003328 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003329
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003330 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
3331 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
3332 << ";\n"
3333 << "using PredicateBitset = "
3334 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
3335 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
3336
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003337 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
3338 << " mutable MatcherState State;\n"
3339 << " typedef "
Daniel Sanders1e4569f2017-10-20 20:55:29 +00003340 "ComplexRendererFns("
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003341 << Target.getName()
3342 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003343 << " const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003344 "MatcherInfo;\n"
Daniel Sandersea8711b2017-10-16 03:36:29 +00003345 << " static " << Target.getName()
3346 << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003347 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003348
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003349 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
3350 << ", State(" << MaxTemporaries << "),\n"
Daniel Sanders11300ce2017-10-13 21:28:03 +00003351 << "MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, "
Daniel Sandersea8711b2017-10-16 03:36:29 +00003352 "APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003353 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003354
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003355 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
3356 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
3357 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003358
3359 // Separate subtarget features by how often they must be recomputed.
3360 SubtargetFeatureInfoMap ModuleFeatures;
3361 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3362 std::inserter(ModuleFeatures, ModuleFeatures.end()),
3363 [](const SubtargetFeatureInfoMap::value_type &X) {
3364 return !X.second.mustRecomputePerFunction();
3365 });
3366 SubtargetFeatureInfoMap FunctionFeatures;
3367 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
3368 std::inserter(FunctionFeatures, FunctionFeatures.end()),
3369 [](const SubtargetFeatureInfoMap::value_type &X) {
3370 return X.second.mustRecomputePerFunction();
3371 });
3372
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003373 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003374 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
3375 ModuleFeatures, OS);
3376 SubtargetFeatureInfo::emitComputeAvailableFeatures(
3377 Target.getName(), "InstructionSelector",
3378 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
3379 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003380
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003381 // Emit a table containing the LLT objects needed by the matcher and an enum
3382 // for the matcher to reference them with.
Daniel Sanders032e7f22017-08-17 13:18:35 +00003383 std::vector<LLTCodeGen> TypeObjects;
3384 for (const auto &Ty : LLTOperandMatcher::KnownTypes)
3385 TypeObjects.push_back(Ty);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003386 std::sort(TypeObjects.begin(), TypeObjects.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003387 OS << "// LLT Objects.\n"
3388 << "enum {\n";
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003389 for (const auto &TypeObject : TypeObjects) {
3390 OS << " ";
3391 TypeObject.emitCxxEnumValue(OS);
3392 OS << ",\n";
3393 }
3394 OS << "};\n"
3395 << "const static LLT TypeObjects[] = {\n";
3396 for (const auto &TypeObject : TypeObjects) {
3397 OS << " ";
3398 TypeObject.emitCxxConstructorCall(OS);
3399 OS << ",\n";
3400 }
3401 OS << "};\n\n";
3402
3403 // Emit a table containing the PredicateBitsets objects needed by the matcher
3404 // and an enum for the matcher to reference them with.
3405 std::vector<std::vector<Record *>> FeatureBitsets;
3406 for (auto &Rule : Rules)
3407 FeatureBitsets.push_back(Rule.getRequiredFeatures());
3408 std::sort(
3409 FeatureBitsets.begin(), FeatureBitsets.end(),
3410 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
3411 if (A.size() < B.size())
3412 return true;
3413 if (A.size() > B.size())
3414 return false;
3415 for (const auto &Pair : zip(A, B)) {
3416 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
3417 return true;
3418 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
3419 return false;
3420 }
3421 return false;
3422 });
3423 FeatureBitsets.erase(
3424 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
3425 FeatureBitsets.end());
Daniel Sanders49980702017-08-23 10:09:25 +00003426 OS << "// Feature bitsets.\n"
3427 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003428 << " GIFBS_Invalid,\n";
3429 for (const auto &FeatureBitset : FeatureBitsets) {
3430 if (FeatureBitset.empty())
3431 continue;
3432 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
3433 }
3434 OS << "};\n"
3435 << "const static PredicateBitset FeatureBitsets[] {\n"
3436 << " {}, // GIFBS_Invalid\n";
3437 for (const auto &FeatureBitset : FeatureBitsets) {
3438 if (FeatureBitset.empty())
3439 continue;
3440 OS << " {";
3441 for (const auto &Feature : FeatureBitset) {
3442 const auto &I = SubtargetFeatures.find(Feature);
3443 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
3444 OS << I->second.getEnumBitName() << ", ";
3445 }
3446 OS << "},\n";
3447 }
3448 OS << "};\n\n";
3449
3450 // Emit complex predicate table and an enum to reference them with.
Daniel Sanders49980702017-08-23 10:09:25 +00003451 OS << "// ComplexPattern predicates.\n"
3452 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003453 << " GICP_Invalid,\n";
3454 for (const auto &Record : ComplexPredicates)
3455 OS << " GICP_" << Record->getName() << ",\n";
3456 OS << "};\n"
3457 << "// See constructor for table contents\n\n";
3458
Daniel Sanders11300ce2017-10-13 21:28:03 +00003459 emitImmPredicates(OS, "I64", "int64_t", [](const Record *R) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003460 bool Unset;
3461 return !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
3462 !R->getValueAsBit("IsAPInt");
3463 });
Daniel Sanders11300ce2017-10-13 21:28:03 +00003464 emitImmPredicates(OS, "APFloat", "const APFloat &", [](const Record *R) {
3465 bool Unset;
3466 return R->getValueAsBitOrUnset("IsAPFloat", Unset);
3467 });
3468 emitImmPredicates(OS, "APInt", "const APInt &", [](const Record *R) {
3469 return R->getValueAsBit("IsAPInt");
3470 });
Daniel Sandersea8711b2017-10-16 03:36:29 +00003471 OS << "\n";
3472
3473 OS << Target.getName() << "InstructionSelector::ComplexMatcherMemFn\n"
3474 << Target.getName() << "InstructionSelector::ComplexPredicateFns[] = {\n"
3475 << " nullptr, // GICP_Invalid\n";
3476 for (const auto &Record : ComplexPredicates)
3477 OS << " &" << Target.getName()
3478 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
3479 << ", // " << Record->getName() << "\n";
3480 OS << "};\n\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00003481
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003482 OS << "bool " << Target.getName()
Daniel Sandersf76f3152017-11-16 00:46:35 +00003483 << "InstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage "
3484 "&CoverageInfo) const {\n"
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003485 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00003486 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00003487 << " // FIXME: This should be computed on a per-function basis rather "
3488 "than per-insn.\n"
3489 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
3490 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00003491 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
3492 << " NewMIVector OutMIs;\n"
3493 << " State.MIs.clear();\n"
3494 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003495
Daniel Sanders8e82af22017-07-27 11:03:45 +00003496 MatchTable Table(0);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00003497 for (auto &Rule : Rules) {
Daniel Sanders8e82af22017-07-27 11:03:45 +00003498 Rule.emit(Table);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003499 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003500 }
Daniel Sanders8e82af22017-07-27 11:03:45 +00003501 Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
3502 Table.emitDeclaration(OS);
3503 OS << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, ";
3504 Table.emitUse(OS);
Daniel Sandersf76f3152017-11-16 00:46:35 +00003505 OS << ", TII, MRI, TRI, RBI, AvailableFeatures, CoverageInfo)) {\n"
Daniel Sanders8e82af22017-07-27 11:03:45 +00003506 << " return true;\n"
3507 << " }\n\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003508
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003509 OS << " return false;\n"
3510 << "}\n"
3511 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00003512
3513 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
3514 << "PredicateBitset AvailableModuleFeatures;\n"
3515 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
3516 << "PredicateBitset getAvailableFeatures() const {\n"
3517 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
3518 << "}\n"
3519 << "PredicateBitset\n"
3520 << "computeAvailableModuleFeatures(const " << Target.getName()
3521 << "Subtarget *Subtarget) const;\n"
3522 << "PredicateBitset\n"
3523 << "computeAvailableFunctionFeatures(const " << Target.getName()
3524 << "Subtarget *Subtarget,\n"
3525 << " const MachineFunction *MF) const;\n"
3526 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
3527
3528 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
3529 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
3530 << "AvailableFunctionFeatures()\n"
3531 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003532}
3533
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003534void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
3535 if (SubtargetFeatures.count(Predicate) == 0)
3536 SubtargetFeatures.emplace(
3537 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
3538}
3539
Daniel Sanders7e523672017-11-11 03:23:44 +00003540TreePatternNode *GlobalISelEmitter::fixupPatternNode(TreePatternNode *N) {
3541 if (!N->isLeaf()) {
3542 for (unsigned I = 0, E = N->getNumChildren(); I < E; ++I) {
3543 TreePatternNode *OrigChild = N->getChild(I);
3544 TreePatternNode *NewChild = fixupPatternNode(OrigChild);
3545 if (OrigChild != NewChild)
3546 N->setChild(I, NewChild);
3547 }
3548
3549 if (N->getOperator()->getName() == "ld") {
3550 // If it's a signext-load we need to adapt the pattern slightly. We need
3551 // to split the node into (sext (ld ...)), remove the <<signext>> predicate,
3552 // and then apply the <<signextTY>> predicate by updating the result type
3553 // of the load.
3554 //
3555 // For example:
3556 // (ld:[i32] [iPTR])<<unindexed>><<signext>><<signexti16>>
3557 // must be transformed into:
3558 // (sext:[i32] (ld:[i16] [iPTR])<<unindexed>>)
3559 //
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003560 // Likewise for zeroext-load and anyext-load.
Daniel Sanders7e523672017-11-11 03:23:44 +00003561
3562 std::vector<TreePredicateFn> Predicates;
3563 bool IsSignExtLoad = false;
3564 bool IsZeroExtLoad = false;
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003565 bool IsAnyExtLoad = false;
Daniel Sanders7e523672017-11-11 03:23:44 +00003566 Record *MemVT = nullptr;
3567 for (const auto &P : N->getPredicateFns()) {
3568 if (P.isLoad() && P.isSignExtLoad()) {
3569 IsSignExtLoad = true;
3570 continue;
3571 }
3572 if (P.isLoad() && P.isZeroExtLoad()) {
3573 IsZeroExtLoad = true;
3574 continue;
3575 }
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003576 if (P.isLoad() && P.isAnyExtLoad()) {
3577 IsAnyExtLoad = true;
3578 continue;
3579 }
Daniel Sanders7e523672017-11-11 03:23:44 +00003580 if (P.isLoad() && P.getMemoryVT()) {
3581 MemVT = P.getMemoryVT();
3582 continue;
3583 }
3584 Predicates.push_back(P);
3585 }
3586
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003587 if ((IsSignExtLoad || IsZeroExtLoad || IsAnyExtLoad) && MemVT) {
3588 assert((IsSignExtLoad + IsZeroExtLoad + IsAnyExtLoad) == 1 &&
3589 "IsSignExtLoad, IsZeroExtLoad, IsAnyExtLoad are mutually exclusive");
Daniel Sanders7e523672017-11-11 03:23:44 +00003590 TreePatternNode *Ext = new TreePatternNode(
Daniel Sandersb78ac6e2017-11-13 18:30:23 +00003591 RK.getDef(IsSignExtLoad ? "sext"
3592 : IsZeroExtLoad ? "zext" : "anyext"),
3593 {N}, 1);
Daniel Sanders7e523672017-11-11 03:23:44 +00003594 Ext->setType(0, N->getType(0));
3595 N->clearPredicateFns();
3596 N->setPredicateFns(Predicates);
3597 N->setType(0, getValueType(MemVT));
3598 return Ext;
3599 }
3600 }
3601 }
3602
3603 return N;
3604}
3605
3606void GlobalISelEmitter::fixupPatternTrees(TreePattern *P) {
3607 for (unsigned I = 0, E = P->getNumTrees(); I < E; ++I) {
3608 TreePatternNode *OrigTree = P->getTree(I);
3609 TreePatternNode *NewTree = fixupPatternNode(OrigTree);
3610 if (OrigTree != NewTree)
3611 P->setTree(I, NewTree);
3612 }
3613}
3614
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003615} // end anonymous namespace
3616
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003617//===----------------------------------------------------------------------===//
3618
3619namespace llvm {
3620void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
3621 GlobalISelEmitter(RK).run(OS);
3622}
3623} // End llvm namespace