blob: 4e7d5dc517479be71fe8e5f599dc9fe2f888dcb6 [file] [log] [blame]
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001//===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// This tablegen backend emits code for use by the GlobalISel instruction
12/// selector. See include/llvm/CodeGen/TargetGlobalISel.td.
13///
14/// This file analyzes the patterns recognized by the SelectionDAGISel tablegen
15/// backend, filters out the ones that are unsupported, maps
16/// SelectionDAG-specific constructs to their GlobalISel counterpart
17/// (when applicable: MVT to LLT; SDNode to generic Instruction).
18///
19/// Not all patterns are supported: pass the tablegen invocation
20/// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,
21/// as well as why.
22///
23/// The generated file defines a single method:
24/// bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;
25/// intended to be used in InstructionSelector::select as the first-step
26/// selector for the patterns that don't require complex C++.
27///
28/// FIXME: We'll probably want to eventually define a base
29/// "TargetGenInstructionSelector" class.
30///
31//===----------------------------------------------------------------------===//
32
33#include "CodeGenDAGPatterns.h"
Daniel Sanderse7b0d662017-04-21 15:59:56 +000034#include "SubtargetFeatureInfo.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000035#include "llvm/ADT/Optional.h"
Daniel Sanders0ed28822017-04-12 08:23:08 +000036#include "llvm/ADT/SmallSet.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000037#include "llvm/ADT/Statistic.h"
38#include "llvm/CodeGen/MachineValueType.h"
39#include "llvm/Support/CommandLine.h"
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +000040#include "llvm/Support/Error.h"
Daniel Sanders52b4ce72017-03-07 23:20:35 +000041#include "llvm/Support/LowLevelTypeImpl.h"
Pavel Labath52a82e22017-02-21 09:19:41 +000042#include "llvm/Support/ScopedPrinter.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000043#include "llvm/TableGen/Error.h"
44#include "llvm/TableGen/Record.h"
45#include "llvm/TableGen/TableGenBackend.h"
46#include <string>
Daniel Sanders8a4bae92017-03-14 21:32:08 +000047#include <numeric>
Ahmed Bougacha36f70352016-12-21 23:26:20 +000048using namespace llvm;
49
50#define DEBUG_TYPE "gisel-emitter"
51
52STATISTIC(NumPatternTotal, "Total number of patterns");
Daniel Sandersb41ce2b2017-02-20 14:31:27 +000053STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
54STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
Ahmed Bougacha36f70352016-12-21 23:26:20 +000055STATISTIC(NumPatternEmitted, "Number of patterns emitted");
56
Daniel Sanders0848b232017-03-27 13:15:13 +000057cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
58
Ahmed Bougacha36f70352016-12-21 23:26:20 +000059static cl::opt<bool> WarnOnSkippedPatterns(
60 "warn-on-skipped-patterns",
61 cl::desc("Explain why a pattern was skipped for inclusion "
62 "in the GlobalISel selector"),
Daniel Sanders0848b232017-03-27 13:15:13 +000063 cl::init(false), cl::cat(GlobalISelEmitterCat));
Ahmed Bougacha36f70352016-12-21 23:26:20 +000064
Daniel Sandersbdfebb82017-03-15 20:18:38 +000065namespace {
Ahmed Bougacha36f70352016-12-21 23:26:20 +000066//===- Helper functions ---------------------------------------------------===//
67
Daniel Sanders52b4ce72017-03-07 23:20:35 +000068/// This class stands in for LLT wherever we want to tablegen-erate an
69/// equivalent at compiler run-time.
70class LLTCodeGen {
71private:
72 LLT Ty;
73
74public:
75 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
76
Daniel Sanders7aac7cc2017-07-20 09:25:44 +000077 std::string getCxxEnumValue() const {
78 std::string Str;
79 raw_string_ostream OS(Str);
80
81 emitCxxEnumValue(OS);
82 return OS.str();
83 }
84
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000085 void emitCxxEnumValue(raw_ostream &OS) const {
86 if (Ty.isScalar()) {
87 OS << "GILLT_s" << Ty.getSizeInBits();
88 return;
89 }
90 if (Ty.isVector()) {
91 OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
92 return;
93 }
94 llvm_unreachable("Unhandled LLT");
95 }
96
Daniel Sanders52b4ce72017-03-07 23:20:35 +000097 void emitCxxConstructorCall(raw_ostream &OS) const {
98 if (Ty.isScalar()) {
99 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
100 return;
101 }
102 if (Ty.isVector()) {
Daniel Sanders32291982017-06-28 13:50:04 +0000103 OS << "LLT::vector(" << Ty.getNumElements() << ", "
104 << Ty.getScalarSizeInBits() << ")";
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000105 return;
106 }
107 llvm_unreachable("Unhandled LLT");
108 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000109
110 const LLT &get() const { return Ty; }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000111
112 /// This ordering is used for std::unique() and std::sort(). There's no
Daniel Sanders032e7f22017-08-17 13:18:35 +0000113 /// particular logic behind the order but either A < B or B < A must be
114 /// true if A != B.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000115 bool operator<(const LLTCodeGen &Other) const {
Daniel Sanders032e7f22017-08-17 13:18:35 +0000116 if (Ty.isValid() != Other.Ty.isValid())
117 return Ty.isValid() < Other.Ty.isValid();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000118 if (!Ty.isValid())
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000119 return false;
Daniel Sanders032e7f22017-08-17 13:18:35 +0000120
121 if (Ty.isVector() != Other.Ty.isVector())
122 return Ty.isVector() < Other.Ty.isVector();
123 if (Ty.isScalar() != Other.Ty.isScalar())
124 return Ty.isScalar() < Other.Ty.isScalar();
125 if (Ty.isPointer() != Other.Ty.isPointer())
126 return Ty.isPointer() < Other.Ty.isPointer();
127
128 if (Ty.isPointer() && Ty.getAddressSpace() != Other.Ty.getAddressSpace())
129 return Ty.getAddressSpace() < Other.Ty.getAddressSpace();
130
131 if (Ty.isVector() && Ty.getNumElements() != Other.Ty.getNumElements())
132 return Ty.getNumElements() < Other.Ty.getNumElements();
133
134 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000135 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000136};
137
138class InstructionMatcher;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000139/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
140/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000141static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000142 MVT VT(SVT);
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000143 if (VT.isVector() && VT.getVectorNumElements() != 1)
Daniel Sanders32291982017-06-28 13:50:04 +0000144 return LLTCodeGen(
145 LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000146 if (VT.isInteger() || VT.isFloatingPoint())
147 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
148 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000149}
150
Daniel Sandersd0656a32017-04-13 09:45:37 +0000151static std::string explainPredicates(const TreePatternNode *N) {
152 std::string Explanation = "";
153 StringRef Separator = "";
154 for (const auto &P : N->getPredicateFns()) {
155 Explanation +=
156 (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
157 if (P.isAlwaysTrue())
158 Explanation += " always-true";
159 if (P.isImmediatePattern())
160 Explanation += " immediate";
161 }
162 return Explanation;
163}
164
Daniel Sandersd0656a32017-04-13 09:45:37 +0000165std::string explainOperator(Record *Operator) {
166 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000167 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000168
169 if (Operator->isSubClassOf("Intrinsic"))
170 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
171
172 return " (Operator not understood)";
173}
174
175/// Helper function to let the emitter report skip reason error messages.
176static Error failedImport(const Twine &Reason) {
177 return make_error<StringError>(Reason, inconvertibleErrorCode());
178}
179
180static Error isTrivialOperatorNode(const TreePatternNode *N) {
181 std::string Explanation = "";
182 std::string Separator = "";
Daniel Sanders2c269f62017-08-24 09:11:20 +0000183
184 bool HasUnsupportedPredicate = false;
185 for (const auto &Predicate : N->getPredicateFns()) {
186 if (Predicate.isAlwaysTrue())
187 continue;
188
189 if (Predicate.isImmediatePattern())
190 continue;
191
192 HasUnsupportedPredicate = true;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000193 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
194 Separator = ", ";
Daniel Sanders2c269f62017-08-24 09:11:20 +0000195 break;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000196 }
197
198 if (N->getTransformFn()) {
199 Explanation += Separator + "Has a transform function";
200 Separator = ", ";
201 }
202
Daniel Sanders2c269f62017-08-24 09:11:20 +0000203 if (!HasUnsupportedPredicate && !N->getTransformFn())
Daniel Sandersd0656a32017-04-13 09:45:37 +0000204 return Error::success();
205
206 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000207}
208
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000209static Record *getInitValueAsRegClass(Init *V) {
210 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
211 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
212 return VDefInit->getDef()->getValueAsDef("RegClass");
213 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
214 return VDefInit->getDef();
215 }
216 return nullptr;
217}
218
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000219std::string
220getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
221 std::string Name = "GIFBS";
222 for (const auto &Feature : FeatureBitset)
223 Name += ("_" + Feature->getName()).str();
224 return Name;
225}
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000226
227//===- MatchTable Helpers -------------------------------------------------===//
228
229class MatchTable;
230
231/// A record to be stored in a MatchTable.
232///
233/// This class represents any and all output that may be required to emit the
234/// MatchTable. Instances are most often configured to represent an opcode or
235/// value that will be emitted to the table with some formatting but it can also
236/// represent commas, comments, and other formatting instructions.
237struct MatchTableRecord {
238 enum RecordFlagsBits {
239 MTRF_None = 0x0,
240 /// Causes EmitStr to be formatted as comment when emitted.
241 MTRF_Comment = 0x1,
242 /// Causes the record value to be followed by a comma when emitted.
243 MTRF_CommaFollows = 0x2,
244 /// Causes the record value to be followed by a line break when emitted.
245 MTRF_LineBreakFollows = 0x4,
246 /// Indicates that the record defines a label and causes an additional
247 /// comment to be emitted containing the index of the label.
248 MTRF_Label = 0x8,
249 /// Causes the record to be emitted as the index of the label specified by
250 /// LabelID along with a comment indicating where that label is.
251 MTRF_JumpTarget = 0x10,
252 /// Causes the formatter to add a level of indentation before emitting the
253 /// record.
254 MTRF_Indent = 0x20,
255 /// Causes the formatter to remove a level of indentation after emitting the
256 /// record.
257 MTRF_Outdent = 0x40,
258 };
259
260 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
261 /// reference or define.
262 unsigned LabelID;
263 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
264 /// value, a label name.
265 std::string EmitStr;
266
267private:
268 /// The number of MatchTable elements described by this record. Comments are 0
269 /// while values are typically 1. Values >1 may occur when we need to emit
270 /// values that exceed the size of a MatchTable element.
271 unsigned NumElements;
272
273public:
274 /// A bitfield of RecordFlagsBits flags.
275 unsigned Flags;
276
277 MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
278 unsigned NumElements, unsigned Flags)
279 : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
280 EmitStr(EmitStr), NumElements(NumElements), Flags(Flags) {
281 assert((!LabelID_.hasValue() || LabelID != ~0u) &&
282 "This value is reserved for non-labels");
283 }
284
285 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
286 const MatchTable &Table) const;
287 unsigned size() const { return NumElements; }
288};
289
290/// Holds the contents of a generated MatchTable to enable formatting and the
291/// necessary index tracking needed to support GIM_Try.
292class MatchTable {
293 /// An unique identifier for the table. The generated table will be named
294 /// MatchTable${ID}.
295 unsigned ID;
296 /// The records that make up the table. Also includes comments describing the
297 /// values being emitted and line breaks to format it.
298 std::vector<MatchTableRecord> Contents;
299 /// The currently defined labels.
300 DenseMap<unsigned, unsigned> LabelMap;
301 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
302 unsigned CurrentSize;
303
Daniel Sanders8e82af22017-07-27 11:03:45 +0000304 /// A unique identifier for a MatchTable label.
305 static unsigned CurrentLabelID;
306
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000307public:
308 static MatchTableRecord LineBreak;
309 static MatchTableRecord Comment(StringRef Comment) {
310 return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
311 }
312 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
313 unsigned ExtraFlags = 0;
314 if (IndentAdjust > 0)
315 ExtraFlags |= MatchTableRecord::MTRF_Indent;
316 if (IndentAdjust < 0)
317 ExtraFlags |= MatchTableRecord::MTRF_Outdent;
318
319 return MatchTableRecord(None, Opcode, 1,
320 MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
321 }
322 static MatchTableRecord NamedValue(StringRef NamedValue) {
323 return MatchTableRecord(None, NamedValue, 1,
324 MatchTableRecord::MTRF_CommaFollows);
325 }
326 static MatchTableRecord NamedValue(StringRef Namespace,
327 StringRef NamedValue) {
328 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
329 MatchTableRecord::MTRF_CommaFollows);
330 }
331 static MatchTableRecord IntValue(int64_t IntValue) {
332 return MatchTableRecord(None, llvm::to_string(IntValue), 1,
333 MatchTableRecord::MTRF_CommaFollows);
334 }
335 static MatchTableRecord Label(unsigned LabelID) {
336 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
337 MatchTableRecord::MTRF_Label |
338 MatchTableRecord::MTRF_Comment |
339 MatchTableRecord::MTRF_LineBreakFollows);
340 }
341 static MatchTableRecord JumpTarget(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000342 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000343 MatchTableRecord::MTRF_JumpTarget |
344 MatchTableRecord::MTRF_Comment |
345 MatchTableRecord::MTRF_CommaFollows);
346 }
347
348 MatchTable(unsigned ID) : ID(ID), CurrentSize(0) {}
349
350 void push_back(const MatchTableRecord &Value) {
351 if (Value.Flags & MatchTableRecord::MTRF_Label)
352 defineLabel(Value.LabelID);
353 Contents.push_back(Value);
354 CurrentSize += Value.size();
355 }
356
Daniel Sanders8e82af22017-07-27 11:03:45 +0000357 unsigned allocateLabelID() const { return CurrentLabelID++; }
358
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000359 void defineLabel(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000360 LabelMap.insert(std::make_pair(LabelID, CurrentSize));
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000361 }
362
363 unsigned getLabelIndex(unsigned LabelID) const {
364 const auto I = LabelMap.find(LabelID);
365 assert(I != LabelMap.end() && "Use of undeclared label");
366 return I->second;
367 }
368
Daniel Sanders8e82af22017-07-27 11:03:45 +0000369 void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
370
371 void emitDeclaration(raw_ostream &OS) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000372 unsigned Indentation = 4;
Daniel Sanderscbbbfe42017-07-27 12:47:31 +0000373 OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000374 LineBreak.emit(OS, true, *this);
375 OS << std::string(Indentation, ' ');
376
377 for (auto I = Contents.begin(), E = Contents.end(); I != E;
378 ++I) {
379 bool LineBreakIsNext = false;
380 const auto &NextI = std::next(I);
381
382 if (NextI != E) {
383 if (NextI->EmitStr == "" &&
384 NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
385 LineBreakIsNext = true;
386 }
387
388 if (I->Flags & MatchTableRecord::MTRF_Indent)
389 Indentation += 2;
390
391 I->emit(OS, LineBreakIsNext, *this);
392 if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
393 OS << std::string(Indentation, ' ');
394
395 if (I->Flags & MatchTableRecord::MTRF_Outdent)
396 Indentation -= 2;
397 }
398 OS << "};\n";
399 }
400};
401
Daniel Sanders8e82af22017-07-27 11:03:45 +0000402unsigned MatchTable::CurrentLabelID = 0;
403
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000404MatchTableRecord MatchTable::LineBreak = {
405 None, "" /* Emit String */, 0 /* Elements */,
406 MatchTableRecord::MTRF_LineBreakFollows};
407
408void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
409 const MatchTable &Table) const {
410 bool UseLineComment =
411 LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
412 if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
413 UseLineComment = false;
414
415 if (Flags & MTRF_Comment)
416 OS << (UseLineComment ? "// " : "/*");
417
418 OS << EmitStr;
419 if (Flags & MTRF_Label)
420 OS << ": @" << Table.getLabelIndex(LabelID);
421
422 if (Flags & MTRF_Comment && !UseLineComment)
423 OS << "*/";
424
425 if (Flags & MTRF_JumpTarget) {
426 if (Flags & MTRF_Comment)
427 OS << " ";
428 OS << Table.getLabelIndex(LabelID);
429 }
430
431 if (Flags & MTRF_CommaFollows) {
432 OS << ",";
433 if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
434 OS << " ";
435 }
436
437 if (Flags & MTRF_LineBreakFollows)
438 OS << "\n";
439}
440
441MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
442 Table.push_back(Value);
443 return Table;
444}
445
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000446//===- Matchers -----------------------------------------------------------===//
447
Daniel Sandersbee57392017-04-04 13:25:23 +0000448class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000449class MatchAction;
450
451/// Generates code to check that a match rule matches.
452class RuleMatcher {
453 /// A list of matchers that all need to succeed for the current rule to match.
454 /// FIXME: This currently supports a single match position but could be
455 /// extended to support multiple positions to support div/rem fusion or
456 /// load-multiple instructions.
457 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
458
459 /// A list of actions that need to be taken when all predicates in this rule
460 /// have succeeded.
461 std::vector<std::unique_ptr<MatchAction>> Actions;
462
Daniel Sanders078572b2017-08-02 11:03:36 +0000463 typedef std::map<const InstructionMatcher *, unsigned>
464 DefinedInsnVariablesMap;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000465 /// A map of instruction matchers to the local variables created by
Daniel Sanders9d662d22017-07-06 10:06:12 +0000466 /// emitCaptureOpcodes().
Daniel Sanders078572b2017-08-02 11:03:36 +0000467 DefinedInsnVariablesMap InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000468
469 /// ID for the next instruction variable defined with defineInsnVar()
470 unsigned NextInsnVarID;
471
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000472 std::vector<Record *> RequiredFeatures;
473
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000474public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000475 RuleMatcher()
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000476 : Matchers(), Actions(), InsnVariableIDs(), NextInsnVarID(0) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000477 RuleMatcher(RuleMatcher &&Other) = default;
478 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000479
Daniel Sanders05540042017-08-08 10:44:31 +0000480 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000481 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000482 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000483
484 template <class Kind, class... Args> Kind &addAction(Args &&... args);
485
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000486 /// Define an instruction without emitting any code to do so.
487 /// This is used for the root of the match.
488 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
489 /// Define an instruction and emit corresponding state-machine opcodes.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000490 unsigned defineInsnVar(MatchTable &Table, const InstructionMatcher &Matcher,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000491 unsigned InsnVarID, unsigned OpIdx);
492 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sanders078572b2017-08-02 11:03:36 +0000493 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
494 return InsnVariableIDs.begin();
495 }
496 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
497 return InsnVariableIDs.end();
498 }
499 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
500 defined_insn_vars() const {
501 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
502 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000503
Daniel Sanders05540042017-08-08 10:44:31 +0000504 const InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
505
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000506 void emitCaptureOpcodes(MatchTable &Table);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000507
Daniel Sanders8e82af22017-07-27 11:03:45 +0000508 void emit(MatchTable &Table);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000509
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000510 /// Compare the priority of this object and B.
511 ///
512 /// Returns true if this object is more important than B.
513 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000514
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000515 /// Report the maximum number of temporary operands needed by the rule
516 /// matcher.
517 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000518
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000519 // FIXME: Remove this as soon as possible
520 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000521};
522
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000523template <class PredicateTy> class PredicateListMatcher {
524private:
525 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
526 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000527
Daniel Sanders2c269f62017-08-24 09:11:20 +0000528 /// Template instantiations should specialize this to return a string to use
529 /// for the comment emitted when there are no predicates.
530 std::string getNoPredicateComment() const;
531
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000532public:
533 /// Construct a new operand predicate and add it to the matcher.
534 template <class Kind, class... Args>
535 Kind &addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000536 Predicates.emplace_back(
537 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000538 return *static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000539 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000540
Daniel Sanders32291982017-06-28 13:50:04 +0000541 typename PredicateVec::const_iterator predicates_begin() const {
542 return Predicates.begin();
543 }
544 typename PredicateVec::const_iterator predicates_end() const {
545 return Predicates.end();
546 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000547 iterator_range<typename PredicateVec::const_iterator> predicates() const {
548 return make_range(predicates_begin(), predicates_end());
549 }
Daniel Sanders32291982017-06-28 13:50:04 +0000550 typename PredicateVec::size_type predicates_size() const {
551 return Predicates.size();
552 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000553
Daniel Sanders9d662d22017-07-06 10:06:12 +0000554 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000555 template <class... Args>
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000556 void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000557 if (Predicates.empty()) {
Daniel Sanders2c269f62017-08-24 09:11:20 +0000558 Table << MatchTable::Comment(getNoPredicateComment())
559 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000560 return;
561 }
562
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000563 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000564 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000565 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000566};
567
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000568/// Generates code to check a predicate of an operand.
569///
570/// Typical predicates include:
571/// * Operand is a particular register.
572/// * Operand is assigned a particular register bank.
573/// * Operand is an MBB.
574class OperandPredicateMatcher {
575public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000576 /// This enum is used for RTTI and also defines the priority that is given to
577 /// the predicate when generating the matcher code. Kinds with higher priority
578 /// must be tested first.
579 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000580 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
581 /// but OPM_Int must have priority over OPM_RegBank since constant integers
582 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000583 enum PredicateKind {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000584 OPM_ComplexPattern,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000585 OPM_IntrinsicID,
Daniel Sanders05540042017-08-08 10:44:31 +0000586 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000587 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000588 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000589 OPM_LLT,
590 OPM_RegBank,
591 OPM_MBB,
592 };
593
594protected:
595 PredicateKind Kind;
596
597public:
598 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000599 virtual ~OperandPredicateMatcher() {}
600
Daniel Sanders759ff412017-02-24 13:58:11 +0000601 PredicateKind getKind() const { return Kind; }
602
Daniel Sandersbee57392017-04-04 13:25:23 +0000603 /// Return the OperandMatcher for the specified operand or nullptr if there
604 /// isn't one by that name in this operand predicate matcher.
605 ///
606 /// InstructionOperandMatcher is the only subclass that can return non-null
607 /// for this.
608 virtual Optional<const OperandMatcher *>
Daniel Sandersdb7ed372017-04-04 13:52:00 +0000609 getOptionalOperand(StringRef SymbolicName) const {
Daniel Sandersbee57392017-04-04 13:25:23 +0000610 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
611 return None;
612 }
613
Daniel Sanders9d662d22017-07-06 10:06:12 +0000614 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sandersbee57392017-04-04 13:25:23 +0000615 ///
Daniel Sanders9d662d22017-07-06 10:06:12 +0000616 /// Only InstructionOperandMatcher needs to do anything for this method the
617 /// rest just walk the tree.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000618 virtual void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +0000619 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000620
Daniel Sanders9d662d22017-07-06 10:06:12 +0000621 /// Emit MatchTable opcodes that check the predicate for the given operand.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000622 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000623 unsigned InsnVarID,
624 unsigned OpIdx) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000625
626 /// Compare the priority of this object and B.
627 ///
628 /// Returns true if this object is more important than B.
Daniel Sanders05540042017-08-08 10:44:31 +0000629 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000630
631 /// Report the maximum number of temporary operands needed by the predicate
632 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000633 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000634};
635
Daniel Sanders2c269f62017-08-24 09:11:20 +0000636template <>
637std::string
638PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
639 return "No operand predicates";
640}
641
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000642/// Generates code to check that an operand is a particular LLT.
643class LLTOperandMatcher : public OperandPredicateMatcher {
644protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000645 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000646
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000647public:
Daniel Sanders032e7f22017-08-17 13:18:35 +0000648 static std::set<LLTCodeGen> KnownTypes;
649
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000650 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders032e7f22017-08-17 13:18:35 +0000651 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {
652 KnownTypes.insert(Ty);
653 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000654
655 static bool classof(const OperandPredicateMatcher *P) {
656 return P->getKind() == OPM_LLT;
657 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000658
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000659 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000660 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000661 Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
662 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
663 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
664 << MatchTable::NamedValue(Ty.getCxxEnumValue())
665 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000666 }
667};
668
Daniel Sanders032e7f22017-08-17 13:18:35 +0000669std::set<LLTCodeGen> LLTOperandMatcher::KnownTypes;
670
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000671/// Generates code to check that an operand is a particular target constant.
672class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
673protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000674 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000675 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000676
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000677 unsigned getAllocatedTemporariesBaseID() const;
678
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000679public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000680 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
681 const Record &TheDef)
682 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
683 TheDef(TheDef) {}
684
685 static bool classof(const OperandPredicateMatcher *P) {
686 return P->getKind() == OPM_ComplexPattern;
687 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000688
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000689 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000690 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000691 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000692 Table << MatchTable::Opcode("GIM_CheckComplexPattern")
693 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
694 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
695 << MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
696 << MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
697 << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000698 }
699
Daniel Sanders2deea182017-04-22 15:11:04 +0000700 unsigned countRendererFns() const override {
701 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000702 }
703};
704
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000705/// Generates code to check that an operand is in a particular register bank.
706class RegisterBankOperandMatcher : public OperandPredicateMatcher {
707protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000708 const CodeGenRegisterClass &RC;
709
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000710public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000711 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
712 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
713
714 static bool classof(const OperandPredicateMatcher *P) {
715 return P->getKind() == OPM_RegBank;
716 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000717
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000718 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000719 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000720 Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
721 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
722 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
723 << MatchTable::Comment("RC")
724 << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
725 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000726 }
727};
728
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000729/// Generates code to check that an operand is a basic block.
730class MBBOperandMatcher : public OperandPredicateMatcher {
731public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000732 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
733
734 static bool classof(const OperandPredicateMatcher *P) {
735 return P->getKind() == OPM_MBB;
736 }
737
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000738 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000739 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000740 Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
741 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
742 << MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000743 }
744};
745
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000746/// Generates code to check that an operand is a G_CONSTANT with a particular
747/// int.
748class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000749protected:
750 int64_t Value;
751
752public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000753 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000754 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
755
756 static bool classof(const OperandPredicateMatcher *P) {
757 return P->getKind() == OPM_Int;
758 }
759
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000760 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000761 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000762 Table << MatchTable::Opcode("GIM_CheckConstantInt")
763 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
764 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
765 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000766 }
767};
768
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000769/// Generates code to check that an operand is a raw int (where MO.isImm() or
770/// MO.isCImm() is true).
771class LiteralIntOperandMatcher : public OperandPredicateMatcher {
772protected:
773 int64_t Value;
774
775public:
776 LiteralIntOperandMatcher(int64_t Value)
777 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
778
779 static bool classof(const OperandPredicateMatcher *P) {
780 return P->getKind() == OPM_LiteralInt;
781 }
782
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000783 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000784 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000785 Table << MatchTable::Opcode("GIM_CheckLiteralInt")
786 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
787 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
788 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000789 }
790};
791
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000792/// Generates code to check that an operand is an intrinsic ID.
793class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
794protected:
795 const CodeGenIntrinsic *II;
796
797public:
798 IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II)
799 : OperandPredicateMatcher(OPM_IntrinsicID), II(II) {}
800
801 static bool classof(const OperandPredicateMatcher *P) {
802 return P->getKind() == OPM_IntrinsicID;
803 }
804
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000805 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000806 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000807 Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
808 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
809 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
810 << MatchTable::NamedValue("Intrinsic::" + II->EnumName)
811 << MatchTable::LineBreak;
Daniel Sandersfe12c0f2017-07-11 08:57:29 +0000812 }
813};
814
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000815/// Generates code to check that a set of predicates match for a particular
816/// operand.
817class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
818protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000819 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000820 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000821 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000822
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000823 /// The index of the first temporary variable allocated to this operand. The
824 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +0000825 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000826 unsigned AllocatedTemporariesBaseID;
827
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000828public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000829 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000830 const std::string &SymbolicName,
831 unsigned AllocatedTemporariesBaseID)
832 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
833 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000834
835 bool hasSymbolicName() const { return !SymbolicName.empty(); }
836 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +0000837 void setSymbolicName(StringRef Name) {
838 assert(SymbolicName.empty() && "Operand already has a symbolic name");
839 SymbolicName = Name;
840 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000841 unsigned getOperandIndex() const { return OpIdx; }
842
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000843 std::string getOperandExpr(unsigned InsnVarID) const {
844 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
845 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +0000846 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000847
Daniel Sandersbee57392017-04-04 13:25:23 +0000848 Optional<const OperandMatcher *>
849 getOptionalOperand(StringRef DesiredSymbolicName) const {
850 assert(!DesiredSymbolicName.empty() && "Cannot lookup unnamed operand");
851 if (DesiredSymbolicName == SymbolicName)
852 return this;
853 for (const auto &OP : predicates()) {
854 const auto &MaybeOperand = OP->getOptionalOperand(DesiredSymbolicName);
855 if (MaybeOperand.hasValue())
856 return MaybeOperand.getValue();
857 }
858 return None;
859 }
860
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000861 InstructionMatcher &getInstructionMatcher() const { return Insn; }
862
Daniel Sanders9d662d22017-07-06 10:06:12 +0000863 /// Emit MatchTable opcodes to capture instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000864 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +0000865 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +0000866 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000867 Predicate->emitCaptureOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +0000868 }
869
Daniel Sanders9d662d22017-07-06 10:06:12 +0000870 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000871 /// InsnVarID matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000872 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000873 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000874 std::string Comment;
875 raw_string_ostream CommentOS(Comment);
876 CommentOS << "MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000877 if (SymbolicName.empty())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000878 CommentOS << "Operand " << OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000879 else
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000880 CommentOS << SymbolicName;
881 Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
882
883 emitPredicateListOpcodes(Table, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000884 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000885
886 /// Compare the priority of this object and B.
887 ///
888 /// Returns true if this object is more important than B.
889 bool isHigherPriorityThan(const OperandMatcher &B) const {
890 // Operand matchers involving more predicates have higher priority.
891 if (predicates_size() > B.predicates_size())
892 return true;
893 if (predicates_size() < B.predicates_size())
894 return false;
895
896 // This assumes that predicates are added in a consistent order.
897 for (const auto &Predicate : zip(predicates(), B.predicates())) {
898 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
899 return true;
900 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
901 return false;
902 }
903
904 return false;
905 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000906
907 /// Report the maximum number of temporary operands needed by the operand
908 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000909 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000910 return std::accumulate(
911 predicates().begin(), predicates().end(), 0,
912 [](unsigned A,
913 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +0000914 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000915 });
916 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000917
918 unsigned getAllocatedTemporariesBaseID() const {
919 return AllocatedTemporariesBaseID;
920 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000921};
922
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000923unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
924 return Operand.getAllocatedTemporariesBaseID();
925}
926
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000927/// Generates code to check a predicate on an instruction.
928///
929/// Typical predicates include:
930/// * The opcode of the instruction is a particular value.
931/// * The nsw/nuw flag is/isn't set.
932class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +0000933protected:
934 /// This enum is used for RTTI and also defines the priority that is given to
935 /// the predicate when generating the matcher code. Kinds with higher priority
936 /// must be tested first.
937 enum PredicateKind {
938 IPM_Opcode,
Daniel Sanders2c269f62017-08-24 09:11:20 +0000939 IPM_ImmPredicate,
Daniel Sanders759ff412017-02-24 13:58:11 +0000940 };
941
942 PredicateKind Kind;
943
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000944public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000945 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000946 virtual ~InstructionPredicateMatcher() {}
947
Daniel Sanders759ff412017-02-24 13:58:11 +0000948 PredicateKind getKind() const { return Kind; }
949
Daniel Sanders9d662d22017-07-06 10:06:12 +0000950 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000951 /// InsnVarID matches the predicate.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000952 virtual void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000953 unsigned InsnVarID) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000954
955 /// Compare the priority of this object and B.
956 ///
957 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +0000958 virtual bool
959 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +0000960 return Kind < B.Kind;
961 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000962
963 /// Report the maximum number of temporary operands needed by the predicate
964 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000965 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000966};
967
Daniel Sanders2c269f62017-08-24 09:11:20 +0000968template <>
969std::string
970PredicateListMatcher<InstructionPredicateMatcher>::getNoPredicateComment() const {
971 return "No instruction predicates";
972}
973
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000974/// Generates code to check the opcode of an instruction.
975class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
976protected:
977 const CodeGenInstruction *I;
978
979public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000980 InstructionOpcodeMatcher(const CodeGenInstruction *I)
981 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000982
Daniel Sanders759ff412017-02-24 13:58:11 +0000983 static bool classof(const InstructionPredicateMatcher *P) {
984 return P->getKind() == IPM_Opcode;
985 }
986
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000987 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000988 unsigned InsnVarID) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000989 Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
990 << MatchTable::IntValue(InsnVarID)
991 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
992 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000993 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000994
995 /// Compare the priority of this object and B.
996 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000997 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +0000998 bool
999 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +00001000 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
1001 return true;
1002 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
1003 return false;
1004
1005 // Prioritize opcodes for cosmetic reasons in the generated source. Although
1006 // this is cosmetic at the moment, we may want to drive a similar ordering
1007 // using instruction frequency information to improve compile time.
1008 if (const InstructionOpcodeMatcher *BO =
1009 dyn_cast<InstructionOpcodeMatcher>(&B))
1010 return I->TheDef->getName() < BO->I->TheDef->getName();
1011
1012 return false;
1013 };
Daniel Sanders05540042017-08-08 10:44:31 +00001014
1015 bool isConstantInstruction() const {
1016 return I->TheDef->getName() == "G_CONSTANT";
1017 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001018};
1019
Daniel Sanders2c269f62017-08-24 09:11:20 +00001020/// Generates code to check that this instruction is a constant whose value
1021/// meets an immediate predicate.
1022///
1023/// Immediates are slightly odd since they are typically used like an operand
1024/// but are represented as an operator internally. We typically write simm8:$src
1025/// in a tablegen pattern, but this is just syntactic sugar for
1026/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1027/// that will be matched and the predicate (which is attached to the imm
1028/// operator) that will be tested. In SelectionDAG this describes a
1029/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
1030///
1031/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1032/// this representation, the immediate could be tested with an
1033/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1034/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1035/// there are two implementation issues with producing that matcher
1036/// configuration from the SelectionDAG pattern:
1037/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1038/// were we to sink the immediate predicate to the operand we would have to
1039/// have two partial implementations of PatFrag support, one for immediates
1040/// and one for non-immediates.
1041/// * At the point we handle the predicate, the OperandMatcher hasn't been
1042/// created yet. If we were to sink the predicate to the OperandMatcher we
1043/// would also have to complicate (or duplicate) the code that descends and
1044/// creates matchers for the subtree.
1045/// Overall, it's simpler to handle it in the place it was found.
1046class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1047protected:
1048 TreePredicateFn Predicate;
1049
1050public:
1051 InstructionImmPredicateMatcher(const TreePredicateFn &Predicate)
1052 : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {}
1053
1054 static bool classof(const InstructionPredicateMatcher *P) {
1055 return P->getKind() == IPM_ImmPredicate;
1056 }
1057
1058 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
1059 unsigned InsnVarID) const override {
1060 Table << MatchTable::Opcode("GIM_CheckImmPredicate")
1061 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1062 << MatchTable::Comment("Predicate")
1063 << MatchTable::NamedValue("GIPFP_" + Predicate.getFnName())
1064 << MatchTable::LineBreak;
1065 }
1066};
1067
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001068/// Generates code to check that a set of predicates and operands match for a
1069/// particular instruction.
1070///
1071/// Typical predicates include:
1072/// * Has a specific opcode.
1073/// * Has an nsw/nuw flag or doesn't.
1074class InstructionMatcher
1075 : public PredicateListMatcher<InstructionPredicateMatcher> {
1076protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001077 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001078
1079 /// The operands to match. All rendered operands must be present even if the
1080 /// condition is always true.
1081 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001082
Daniel Sanders05540042017-08-08 10:44:31 +00001083 std::string SymbolicName;
1084
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001085public:
Daniel Sanders05540042017-08-08 10:44:31 +00001086 InstructionMatcher(StringRef SymbolicName) : SymbolicName(SymbolicName) {}
1087
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001088 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001089 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1090 unsigned AllocatedTemporariesBaseID) {
1091 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
1092 AllocatedTemporariesBaseID));
1093 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001094 }
1095
Daniel Sandersffc7d582017-03-29 15:37:18 +00001096 OperandMatcher &getOperand(unsigned OpIdx) {
1097 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001098 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
1099 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001100 });
1101 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001102 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001103 llvm_unreachable("Failed to lookup operand");
1104 }
1105
Daniel Sandersbee57392017-04-04 13:25:23 +00001106 Optional<const OperandMatcher *>
1107 getOptionalOperand(StringRef SymbolicName) const {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001108 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
Daniel Sandersbee57392017-04-04 13:25:23 +00001109 for (const auto &Operand : Operands) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001110 const auto &OM = Operand->getOptionalOperand(SymbolicName);
Daniel Sandersbee57392017-04-04 13:25:23 +00001111 if (OM.hasValue())
1112 return OM.getValue();
1113 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001114 return None;
1115 }
1116
Daniel Sandersdb7ed372017-04-04 13:52:00 +00001117 const OperandMatcher &getOperand(StringRef SymbolicName) const {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001118 Optional<const OperandMatcher *>OM = getOptionalOperand(SymbolicName);
1119 if (OM.hasValue())
1120 return *OM.getValue();
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001121 llvm_unreachable("Failed to lookup operand");
1122 }
1123
Daniel Sanders05540042017-08-08 10:44:31 +00001124 StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001125 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +00001126 OperandVec::iterator operands_begin() { return Operands.begin(); }
1127 OperandVec::iterator operands_end() { return Operands.end(); }
1128 iterator_range<OperandVec::iterator> operands() {
1129 return make_range(operands_begin(), operands_end());
1130 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001131 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1132 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001133 iterator_range<OperandVec::const_iterator> operands() const {
1134 return make_range(operands_begin(), operands_end());
1135 }
1136
Daniel Sanders9d662d22017-07-06 10:06:12 +00001137 /// Emit MatchTable opcodes to check the shape of the match and capture
1138 /// instructions into the MIs table.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001139 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001140 unsigned InsnID) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001141 Table << MatchTable::Opcode("GIM_CheckNumOperands")
1142 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1143 << MatchTable::Comment("Expected")
1144 << MatchTable::IntValue(getNumOperands()) << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001145 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001146 Operand->emitCaptureOpcodes(Table, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001147 }
1148
Daniel Sanders9d662d22017-07-06 10:06:12 +00001149 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001150 /// InsnVarName matches all the predicates and all the operands.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001151 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001152 unsigned InsnVarID) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001153 emitPredicateListOpcodes(Table, Rule, InsnVarID);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001154 for (const auto &Operand : Operands)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001155 Operand->emitPredicateOpcodes(Table, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001156 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001157
1158 /// Compare the priority of this object and B.
1159 ///
1160 /// Returns true if this object is more important than B.
1161 bool isHigherPriorityThan(const InstructionMatcher &B) const {
1162 // Instruction matchers involving more operands have higher priority.
1163 if (Operands.size() > B.Operands.size())
1164 return true;
1165 if (Operands.size() < B.Operands.size())
1166 return false;
1167
1168 for (const auto &Predicate : zip(predicates(), B.predicates())) {
1169 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1170 return true;
1171 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1172 return false;
1173 }
1174
1175 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001176 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001177 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001178 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001179 return false;
1180 }
1181
1182 return false;
1183 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001184
1185 /// Report the maximum number of temporary operands needed by the instruction
1186 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +00001187 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001188 return std::accumulate(predicates().begin(), predicates().end(), 0,
1189 [](unsigned A,
1190 const std::unique_ptr<InstructionPredicateMatcher>
1191 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001192 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001193 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001194 std::accumulate(
1195 Operands.begin(), Operands.end(), 0,
1196 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001197 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001198 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001199 }
Daniel Sanders05540042017-08-08 10:44:31 +00001200
1201 bool isConstantInstruction() const {
1202 for (const auto &P : predicates())
1203 if (const InstructionOpcodeMatcher *Opcode =
1204 dyn_cast<InstructionOpcodeMatcher>(P.get()))
1205 return Opcode->isConstantInstruction();
1206 return false;
1207 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001208};
1209
Daniel Sandersbee57392017-04-04 13:25:23 +00001210/// Generates code to check that the operand is a register defined by an
1211/// instruction that matches the given instruction matcher.
1212///
1213/// For example, the pattern:
1214/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1215/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1216/// the:
1217/// (G_ADD $src1, $src2)
1218/// subpattern.
1219class InstructionOperandMatcher : public OperandPredicateMatcher {
1220protected:
1221 std::unique_ptr<InstructionMatcher> InsnMatcher;
1222
1223public:
Daniel Sanders05540042017-08-08 10:44:31 +00001224 InstructionOperandMatcher(StringRef SymbolicName)
Daniel Sandersbee57392017-04-04 13:25:23 +00001225 : OperandPredicateMatcher(OPM_Instruction),
Daniel Sanders05540042017-08-08 10:44:31 +00001226 InsnMatcher(new InstructionMatcher(SymbolicName)) {}
Daniel Sandersbee57392017-04-04 13:25:23 +00001227
1228 static bool classof(const OperandPredicateMatcher *P) {
1229 return P->getKind() == OPM_Instruction;
1230 }
1231
1232 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
1233
1234 Optional<const OperandMatcher *>
1235 getOptionalOperand(StringRef SymbolicName) const override {
1236 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
1237 return InsnMatcher->getOptionalOperand(SymbolicName);
1238 }
1239
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001240 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders9d662d22017-07-06 10:06:12 +00001241 unsigned InsnID, unsigned OpIdx) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001242 unsigned InsnVarID = Rule.defineInsnVar(Table, *InsnMatcher, InsnID, OpIdx);
1243 InsnMatcher->emitCaptureOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001244 }
1245
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001246 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001247 unsigned InsnVarID_,
1248 unsigned OpIdx_) const override {
1249 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001250 InsnMatcher->emitPredicateOpcodes(Table, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +00001251 }
1252};
1253
Daniel Sanders43c882c2017-02-01 10:53:10 +00001254//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001255class OperandRenderer {
1256public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001257 enum RendererKind {
1258 OR_Copy,
1259 OR_CopySubReg,
Daniel Sanders05540042017-08-08 10:44:31 +00001260 OR_CopyConstantAsImm,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001261 OR_Imm,
1262 OR_Register,
1263 OR_ComplexPattern
1264 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001265
1266protected:
1267 RendererKind Kind;
1268
1269public:
1270 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
1271 virtual ~OperandRenderer() {}
1272
1273 RendererKind getKind() const { return Kind; }
1274
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001275 virtual void emitRenderOpcodes(MatchTable &Table,
1276 RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001277};
1278
1279/// A CopyRenderer emits code to copy a single operand from an existing
1280/// instruction to the one being built.
1281class CopyRenderer : public OperandRenderer {
1282protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001283 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001284 /// The matcher for the instruction that this operand is copied from.
1285 /// This provides the facility for looking up an a operand by it's name so
1286 /// that it can be used as a source for the instruction being built.
1287 const InstructionMatcher &Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001288 /// The name of the operand.
1289 const StringRef SymbolicName;
1290
1291public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001292 CopyRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
1293 StringRef SymbolicName)
1294 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID), Matched(Matched),
Daniel Sanders05540042017-08-08 10:44:31 +00001295 SymbolicName(SymbolicName) {
1296 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
1297 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001298
1299 static bool classof(const OperandRenderer *R) {
1300 return R->getKind() == OR_Copy;
1301 }
1302
1303 const StringRef getSymbolicName() const { return SymbolicName; }
1304
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001305 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001306 const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001307 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001308 Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
1309 << MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
1310 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1311 << MatchTable::IntValue(Operand.getOperandIndex())
1312 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001313 }
1314};
1315
Daniel Sanders05540042017-08-08 10:44:31 +00001316/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
1317/// an extended immediate operand.
1318class CopyConstantAsImmRenderer : public OperandRenderer {
1319protected:
1320 unsigned NewInsnID;
1321 /// The name of the operand.
1322 const std::string SymbolicName;
1323 bool Signed;
1324
1325public:
1326 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
1327 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
1328 SymbolicName(SymbolicName), Signed(true) {}
1329
1330 static bool classof(const OperandRenderer *R) {
1331 return R->getKind() == OR_CopyConstantAsImm;
1332 }
1333
1334 const StringRef getSymbolicName() const { return SymbolicName; }
1335
1336 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1337 const InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
1338 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
1339 Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
1340 : "GIR_CopyConstantAsUImm")
1341 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1342 << MatchTable::Comment("OldInsnID")
1343 << MatchTable::IntValue(OldInsnVarID)
1344 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
1345 }
1346};
1347
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001348/// A CopySubRegRenderer emits code to copy a single register operand from an
1349/// existing instruction to the one being built and indicate that only a
1350/// subregister should be copied.
1351class CopySubRegRenderer : public OperandRenderer {
1352protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001353 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001354 /// The matcher for the instruction that this operand is copied from.
1355 /// This provides the facility for looking up an a operand by it's name so
1356 /// that it can be used as a source for the instruction being built.
1357 const InstructionMatcher &Matched;
1358 /// The name of the operand.
1359 const StringRef SymbolicName;
1360 /// The subregister to extract.
1361 const CodeGenSubRegIndex *SubReg;
1362
1363public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001364 CopySubRegRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
1365 StringRef SymbolicName, const CodeGenSubRegIndex *SubReg)
1366 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID), Matched(Matched),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001367 SymbolicName(SymbolicName), SubReg(SubReg) {}
1368
1369 static bool classof(const OperandRenderer *R) {
1370 return R->getKind() == OR_CopySubReg;
1371 }
1372
1373 const StringRef getSymbolicName() const { return SymbolicName; }
1374
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001375 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001376 const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001377 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001378 Table << MatchTable::Opcode("GIR_CopySubReg")
1379 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
1380 << MatchTable::Comment("OldInsnID")
1381 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
1382 << MatchTable::IntValue(Operand.getOperandIndex())
1383 << MatchTable::Comment("SubRegIdx")
1384 << MatchTable::IntValue(SubReg->EnumValue)
1385 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001386 }
1387};
1388
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001389/// Adds a specific physical register to the instruction being built.
1390/// This is typically useful for WZR/XZR on AArch64.
1391class AddRegisterRenderer : public OperandRenderer {
1392protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001393 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001394 const Record *RegisterDef;
1395
1396public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001397 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
1398 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
1399 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001400
1401 static bool classof(const OperandRenderer *R) {
1402 return R->getKind() == OR_Register;
1403 }
1404
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001405 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1406 Table << MatchTable::Opcode("GIR_AddRegister")
1407 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1408 << MatchTable::NamedValue(
1409 (RegisterDef->getValue("Namespace")
1410 ? RegisterDef->getValueAsString("Namespace")
1411 : ""),
1412 RegisterDef->getName())
1413 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001414 }
1415};
1416
Daniel Sanders0ed28822017-04-12 08:23:08 +00001417/// Adds a specific immediate to the instruction being built.
1418class ImmRenderer : public OperandRenderer {
1419protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001420 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001421 int64_t Imm;
1422
1423public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001424 ImmRenderer(unsigned InsnID, int64_t Imm)
1425 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001426
1427 static bool classof(const OperandRenderer *R) {
1428 return R->getKind() == OR_Imm;
1429 }
1430
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001431 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1432 Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
1433 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
1434 << MatchTable::IntValue(Imm) << MatchTable::LineBreak;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001435 }
1436};
1437
Daniel Sanders2deea182017-04-22 15:11:04 +00001438/// Adds operands by calling a renderer function supplied by the ComplexPattern
1439/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001440class RenderComplexPatternOperand : public OperandRenderer {
1441private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001442 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001443 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001444 /// The name of the operand.
1445 const StringRef SymbolicName;
1446 /// The renderer number. This must be unique within a rule since it's used to
1447 /// identify a temporary variable to hold the renderer function.
1448 unsigned RendererID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001449
1450 unsigned getNumOperands() const {
1451 return TheDef.getValueAsDag("Operands")->getNumArgs();
1452 }
1453
1454public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001455 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
1456 StringRef SymbolicName, unsigned RendererID)
1457 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sanders2deea182017-04-22 15:11:04 +00001458 SymbolicName(SymbolicName), RendererID(RendererID) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001459
1460 static bool classof(const OperandRenderer *R) {
1461 return R->getKind() == OR_ComplexPattern;
1462 }
1463
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001464 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
1465 Table << MatchTable::Opcode("GIR_ComplexRenderer")
1466 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1467 << MatchTable::Comment("RendererID")
1468 << MatchTable::IntValue(RendererID) << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001469 }
1470};
1471
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001472/// An action taken when all Matcher predicates succeeded for a parent rule.
1473///
1474/// Typical actions include:
1475/// * Changing the opcode of an instruction.
1476/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001477class MatchAction {
1478public:
1479 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001480
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001481 /// Emit the MatchTable opcodes to implement the action.
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001482 ///
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001483 /// \param RecycleInsnID If given, it's an instruction to recycle. The
1484 /// requirements on the instruction vary from action to
1485 /// action.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001486 virtual void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1487 unsigned RecycleInsnID) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001488};
1489
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001490/// Generates a comment describing the matched rule being acted upon.
1491class DebugCommentAction : public MatchAction {
1492private:
1493 const PatternToMatch &P;
1494
1495public:
1496 DebugCommentAction(const PatternToMatch &P) : P(P) {}
1497
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001498 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1499 unsigned RecycleInsnID) const override {
1500 Table << MatchTable::Comment(llvm::to_string(*P.getSrcPattern()) + " => " +
1501 llvm::to_string(*P.getDstPattern()))
1502 << MatchTable::LineBreak;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001503 }
1504};
1505
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001506/// Generates code to build an instruction or mutate an existing instruction
1507/// into the desired instruction when this is possible.
1508class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001509private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001510 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001511 const CodeGenInstruction *I;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001512 const InstructionMatcher &Matched;
1513 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1514
1515 /// True if the instruction can be built solely by mutating the opcode.
1516 bool canMutate() const {
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001517 if (OperandRenderers.size() != Matched.getNumOperands())
1518 return false;
1519
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001520 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001521 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001522 const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName());
1523 if (&Matched != &OM.getInstructionMatcher() ||
1524 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001525 return false;
1526 } else
1527 return false;
1528 }
1529
1530 return true;
1531 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001532
Daniel Sanders43c882c2017-02-01 10:53:10 +00001533public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001534 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001535 const InstructionMatcher &Matched)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001536 : InsnID(InsnID), I(I), Matched(Matched) {}
Daniel Sanders43c882c2017-02-01 10:53:10 +00001537
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001538 template <class Kind, class... Args>
1539 Kind &addRenderer(Args&&... args) {
1540 OperandRenderers.emplace_back(
1541 llvm::make_unique<Kind>(std::forward<Args>(args)...));
1542 return *static_cast<Kind *>(OperandRenderers.back().get());
1543 }
1544
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001545 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1546 unsigned RecycleInsnID) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001547 if (canMutate()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001548 Table << MatchTable::Opcode("GIR_MutateOpcode")
1549 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1550 << MatchTable::Comment("RecycleInsnID")
1551 << MatchTable::IntValue(RecycleInsnID)
1552 << MatchTable::Comment("Opcode")
1553 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1554 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001555
1556 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001557 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001558 auto Namespace = Def->getValue("Namespace")
1559 ? Def->getValueAsString("Namespace")
1560 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001561 Table << MatchTable::Opcode("GIR_AddImplicitDef")
1562 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1563 << MatchTable::NamedValue(Namespace, Def->getName())
1564 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001565 }
1566 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001567 auto Namespace = Use->getValue("Namespace")
1568 ? Use->getValueAsString("Namespace")
1569 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001570 Table << MatchTable::Opcode("GIR_AddImplicitUse")
1571 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1572 << MatchTable::NamedValue(Namespace, Use->getName())
1573 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00001574 }
1575 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001576 return;
1577 }
1578
1579 // TODO: Simple permutation looks like it could be almost as common as
1580 // mutation due to commutative operations.
1581
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001582 Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
1583 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
1584 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
1585 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001586 for (const auto &Renderer : OperandRenderers)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001587 Renderer->emitRenderOpcodes(Table, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001588
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001589 if (I->mayLoad || I->mayStore) {
1590 Table << MatchTable::Opcode("GIR_MergeMemOperands")
1591 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1592 << MatchTable::Comment("MergeInsnID's");
1593 // Emit the ID's for all the instructions that are matched by this rule.
1594 // TODO: Limit this to matched instructions that mayLoad/mayStore or have
1595 // some other means of having a memoperand. Also limit this to
1596 // emitted instructions that expect to have a memoperand too. For
1597 // example, (G_SEXT (G_LOAD x)) that results in separate load and
1598 // sign-extend instructions shouldn't put the memoperand on the
1599 // sign-extend since it has no effect there.
1600 std::vector<unsigned> MergeInsnIDs;
1601 for (const auto &IDMatcherPair : Rule.defined_insn_vars())
1602 MergeInsnIDs.push_back(IDMatcherPair.second);
1603 std::sort(MergeInsnIDs.begin(), MergeInsnIDs.end());
1604 for (const auto &MergeInsnID : MergeInsnIDs)
1605 Table << MatchTable::IntValue(MergeInsnID);
Daniel Sanders05540042017-08-08 10:44:31 +00001606 Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
1607 << MatchTable::LineBreak;
Florian Hahn3bc3ec62017-08-03 14:48:22 +00001608 }
1609
1610 Table << MatchTable::Opcode("GIR_EraseFromParent")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001611 << MatchTable::Comment("InsnID")
1612 << MatchTable::IntValue(RecycleInsnID) << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001613 }
1614};
1615
1616/// Generates code to constrain the operands of an output instruction to the
1617/// register classes specified by the definition of that instruction.
1618class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001619 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001620
1621public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001622 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001623
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001624 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1625 unsigned RecycleInsnID) const override {
1626 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
1627 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1628 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001629 }
1630};
1631
1632/// Generates code to constrain the specified operand of an output instruction
1633/// to the specified register class.
1634class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001635 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001636 unsigned OpIdx;
1637 const CodeGenRegisterClass &RC;
1638
1639public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001640 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001641 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001642 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001643
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001644 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule,
1645 unsigned RecycleInsnID) const override {
1646 Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
1647 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1648 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1649 << MatchTable::Comment("RC " + RC.getName())
1650 << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001651 }
1652};
1653
Daniel Sanders05540042017-08-08 10:44:31 +00001654InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
1655 Matchers.emplace_back(new InstructionMatcher(SymbolicName));
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001656 return *Matchers.back();
1657}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001658
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001659void RuleMatcher::addRequiredFeature(Record *Feature) {
1660 RequiredFeatures.push_back(Feature);
1661}
1662
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001663const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
1664 return RequiredFeatures;
1665}
1666
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001667template <class Kind, class... Args>
1668Kind &RuleMatcher::addAction(Args &&... args) {
1669 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1670 return *static_cast<Kind *>(Actions.back().get());
1671}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001672
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001673unsigned
1674RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
1675 unsigned NewInsnVarID = NextInsnVarID++;
1676 InsnVariableIDs[&Matcher] = NewInsnVarID;
1677 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001678}
1679
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001680unsigned RuleMatcher::defineInsnVar(MatchTable &Table,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001681 const InstructionMatcher &Matcher,
1682 unsigned InsnID, unsigned OpIdx) {
1683 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001684 Table << MatchTable::Opcode("GIM_RecordInsn")
1685 << MatchTable::Comment("DefineMI") << MatchTable::IntValue(NewInsnVarID)
1686 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnID)
1687 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
1688 << MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
1689 << MatchTable::LineBreak;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001690 return NewInsnVarID;
1691}
1692
1693unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
1694 const auto &I = InsnVariableIDs.find(&InsnMatcher);
1695 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001696 return I->second;
1697 llvm_unreachable("Matched Insn was not captured in a local variable");
1698}
1699
Daniel Sanders05540042017-08-08 10:44:31 +00001700const InstructionMatcher &
1701RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
1702 for (const auto &I : InsnVariableIDs)
1703 if (I.first->getSymbolicName() == SymbolicName)
1704 return *I.first;
1705 llvm_unreachable(
1706 ("Failed to lookup instruction " + SymbolicName).str().c_str());
1707}
1708
Daniel Sanders9d662d22017-07-06 10:06:12 +00001709/// Emit MatchTable opcodes to check the shape of the match and capture
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001710/// instructions into local variables.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001711void RuleMatcher::emitCaptureOpcodes(MatchTable &Table) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001712 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001713 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001714 Matchers.front()->emitCaptureOpcodes(Table, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001715}
1716
Daniel Sanders8e82af22017-07-27 11:03:45 +00001717void RuleMatcher::emit(MatchTable &Table) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001718 if (Matchers.empty())
1719 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001720
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001721 // The representation supports rules that require multiple roots such as:
1722 // %ptr(p0) = ...
1723 // %elt0(s32) = G_LOAD %ptr
1724 // %1(p0) = G_ADD %ptr, 4
1725 // %elt1(s32) = G_LOAD p0 %1
1726 // which could be usefully folded into:
1727 // %ptr(p0) = ...
1728 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
1729 // on some targets but we don't need to make use of that yet.
1730 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001731
Daniel Sanders8e82af22017-07-27 11:03:45 +00001732 unsigned LabelID = Table.allocateLabelID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001733 Table << MatchTable::Opcode("GIM_Try", +1)
Daniel Sanders8e82af22017-07-27 11:03:45 +00001734 << MatchTable::Comment("On fail goto") << MatchTable::JumpTarget(LabelID)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001735 << MatchTable::LineBreak;
1736
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001737 if (!RequiredFeatures.empty()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001738 Table << MatchTable::Opcode("GIM_CheckFeatures")
1739 << MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
1740 << MatchTable::LineBreak;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001741 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001742
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001743 emitCaptureOpcodes(Table);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001744
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001745 Matchers.front()->emitPredicateOpcodes(Table, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001746 getInsnVarID(*Matchers.front()));
1747
Daniel Sandersbee57392017-04-04 13:25:23 +00001748 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001749 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00001750 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001751 SmallVector<unsigned, 2> InsnIDs;
1752 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001753 // Skip the root node since it isn't moving anywhere. Everything else is
1754 // sinking to meet it.
1755 if (Pair.first == Matchers.front().get())
1756 continue;
1757
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001758 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00001759 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001760 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00001761
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001762 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001763 // Reject the difficult cases until we have a more accurate check.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001764 Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
1765 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
1766 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00001767
1768 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
1769 // account for unsafe cases.
1770 //
1771 // Example:
1772 // MI1--> %0 = ...
1773 // %1 = ... %0
1774 // MI0--> %2 = ... %0
1775 // It's not safe to erase MI1. We currently handle this by not
1776 // erasing %0 (even when it's dead).
1777 //
1778 // Example:
1779 // MI1--> %0 = load volatile @a
1780 // %1 = load volatile @a
1781 // MI0--> %2 = ... %0
1782 // It's not safe to sink %0's def past %1. We currently handle
1783 // this by rejecting all loads.
1784 //
1785 // Example:
1786 // MI1--> %0 = load @a
1787 // %1 = store @a
1788 // MI0--> %2 = ... %0
1789 // It's not safe to sink %0's def past %1. We currently handle
1790 // this by rejecting all loads.
1791 //
1792 // Example:
1793 // G_CONDBR %cond, @BB1
1794 // BB0:
1795 // MI1--> %0 = load @a
1796 // G_BR @BB1
1797 // BB1:
1798 // MI0--> %2 = ... %0
1799 // It's not always safe to sink %0 across control flow. In this
1800 // case it may introduce a memory fault. We currentl handle this
1801 // by rejecting all loads.
1802 }
1803 }
1804
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001805 for (const auto &MA : Actions)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001806 MA->emitActionOpcodes(Table, *this, 0);
1807 Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
Daniel Sanders8e82af22017-07-27 11:03:45 +00001808 << MatchTable::Label(LabelID);
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001809}
Daniel Sanders43c882c2017-02-01 10:53:10 +00001810
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001811bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
1812 // Rules involving more match roots have higher priority.
1813 if (Matchers.size() > B.Matchers.size())
1814 return true;
1815 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00001816 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001817
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001818 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
1819 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
1820 return true;
1821 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
1822 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001823 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001824
1825 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00001826}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001827
Daniel Sanders2deea182017-04-22 15:11:04 +00001828unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001829 return std::accumulate(
1830 Matchers.begin(), Matchers.end(), 0,
1831 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001832 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001833 });
1834}
1835
Daniel Sanders05540042017-08-08 10:44:31 +00001836bool OperandPredicateMatcher::isHigherPriorityThan(
1837 const OperandPredicateMatcher &B) const {
1838 // Generally speaking, an instruction is more important than an Int or a
1839 // LiteralInt because it can cover more nodes but theres an exception to
1840 // this. G_CONSTANT's are less important than either of those two because they
1841 // are more permissive.
Daniel Sandersedd07842017-08-17 09:26:14 +00001842
1843 const InstructionOperandMatcher *AOM =
1844 dyn_cast<InstructionOperandMatcher>(this);
1845 const InstructionOperandMatcher *BOM =
1846 dyn_cast<InstructionOperandMatcher>(&B);
1847 bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
1848 bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
1849
1850 if (AOM && BOM) {
1851 // The relative priorities between a G_CONSTANT and any other instruction
1852 // don't actually matter but this code is needed to ensure a strict weak
1853 // ordering. This is particularly important on Windows where the rules will
1854 // be incorrectly sorted without it.
1855 if (AIsConstantInsn != BIsConstantInsn)
1856 return AIsConstantInsn < BIsConstantInsn;
1857 return false;
Daniel Sanders05540042017-08-08 10:44:31 +00001858 }
Daniel Sandersedd07842017-08-17 09:26:14 +00001859
1860 if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
1861 return false;
1862 if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
1863 return true;
Daniel Sanders05540042017-08-08 10:44:31 +00001864
1865 return Kind < B.Kind;
Daniel Sanders75b84fc2017-08-08 13:21:26 +00001866}
Daniel Sanders05540042017-08-08 10:44:31 +00001867
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001868//===- GlobalISelEmitter class --------------------------------------------===//
1869
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001870class GlobalISelEmitter {
1871public:
1872 explicit GlobalISelEmitter(RecordKeeper &RK);
1873 void run(raw_ostream &OS);
1874
1875private:
1876 const RecordKeeper &RK;
1877 const CodeGenDAGPatterns CGP;
1878 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001879 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001880
1881 /// Keep track of the equivalence between SDNodes and Instruction.
1882 /// This is defined using 'GINodeEquiv' in the target description.
1883 DenseMap<Record *, const CodeGenInstruction *> NodeEquivs;
1884
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001885 /// Keep track of the equivalence between ComplexPattern's and
1886 /// GIComplexOperandMatcher. Map entries are specified by subclassing
1887 /// GIComplexPatternEquiv.
1888 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
1889
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001890 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001891 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001892
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001893 void gatherNodeEquivs();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001894 const CodeGenInstruction *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001895
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00001896 Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001897 Expected<InstructionMatcher &>
Daniel Sandersc270c502017-03-30 09:36:33 +00001898 createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher,
Daniel Sanders57938df2017-07-11 10:40:18 +00001899 const TreePatternNode *Src,
1900 unsigned &TempOpIdx) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00001901 Error importChildMatcher(InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001902 const TreePatternNode *SrcChild, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00001903 unsigned &TempOpIdx) const;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001904 Expected<BuildMIAction &>
1905 createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst,
1906 const InstructionMatcher &InsnMatcher);
Daniel Sandersc270c502017-03-30 09:36:33 +00001907 Error importExplicitUseRenderer(BuildMIAction &DstMIBuilder,
1908 TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001909 const InstructionMatcher &InsnMatcher) const;
Diana Picus382602f2017-05-17 08:57:28 +00001910 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
1911 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00001912 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00001913 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
1914 const std::vector<Record *> &ImplicitDefs) const;
1915
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001916 /// Analyze pattern \p P, returning a matcher for it if possible.
1917 /// Otherwise, return an Error explaining why we don't support it.
1918 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001919
1920 void declareSubtargetFeature(Record *Predicate);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001921};
1922
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001923void GlobalISelEmitter::gatherNodeEquivs() {
1924 assert(NodeEquivs.empty());
1925 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
1926 NodeEquivs[Equiv->getValueAsDef("Node")] =
1927 &Target.getInstruction(Equiv->getValueAsDef("I"));
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001928
1929 assert(ComplexPatternEquivs.empty());
1930 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
1931 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
1932 if (!SelDAGEquiv)
1933 continue;
1934 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
1935 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001936}
1937
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001938const CodeGenInstruction *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001939 return NodeEquivs.lookup(N);
1940}
1941
1942GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00001943 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()),
1944 CGRegs(RK, Target.getHwModes()) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001945
1946//===- Emitter ------------------------------------------------------------===//
1947
Daniel Sandersc270c502017-03-30 09:36:33 +00001948Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00001949GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00001950 ArrayRef<Predicate> Predicates) {
1951 for (const Predicate &P : Predicates) {
1952 if (!P.Def)
1953 continue;
1954 declareSubtargetFeature(P.Def);
1955 M.addRequiredFeature(P.Def);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001956 }
1957
Daniel Sandersc270c502017-03-30 09:36:33 +00001958 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001959}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001960
Daniel Sanders57938df2017-07-11 10:40:18 +00001961Expected<InstructionMatcher &>
1962GlobalISelEmitter::createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher,
1963 const TreePatternNode *Src,
1964 unsigned &TempOpIdx) const {
Daniel Sanders85ffd362017-07-06 08:12:20 +00001965 const CodeGenInstruction *SrcGIOrNull = nullptr;
1966
Daniel Sandersffc7d582017-03-29 15:37:18 +00001967 // Start with the defined operands (i.e., the results of the root operator).
1968 if (Src->getExtTypes().size() > 1)
1969 return failedImport("Src pattern has multiple results");
1970
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001971 if (Src->isLeaf()) {
1972 Init *SrcInit = Src->getLeafValue();
Daniel Sanders3334cc02017-05-23 20:02:48 +00001973 if (isa<IntInit>(SrcInit)) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001974 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
1975 &Target.getInstruction(RK.getDef("G_CONSTANT")));
1976 } else
Daniel Sanders32291982017-06-28 13:50:04 +00001977 return failedImport(
1978 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001979 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00001980 SrcGIOrNull = findNodeEquiv(Src->getOperator());
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001981 if (!SrcGIOrNull)
1982 return failedImport("Pattern operator lacks an equivalent Instruction" +
1983 explainOperator(Src->getOperator()));
1984 auto &SrcGI = *SrcGIOrNull;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001985
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001986 // The operators look good: match the opcode
1987 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
1988 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001989
1990 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00001991 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
1992 auto OpTyOrNone = VTy.isMachineValueType()
1993 ? MVTToLLT(VTy.getMachineValueType().SimpleTy)
1994 : None;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001995 if (!OpTyOrNone)
1996 return failedImport(
1997 "Result of Src pattern operator has an unsupported type");
1998
1999 // Results don't have a name unless they are the root node. The caller will
2000 // set the name if appropriate.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002001 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002002 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
2003 }
2004
Daniel Sanders2c269f62017-08-24 09:11:20 +00002005 for (const auto &Predicate : Src->getPredicateFns()) {
2006 if (Predicate.isAlwaysTrue())
2007 continue;
2008
2009 if (Predicate.isImmediatePattern()) {
2010 InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
2011 continue;
2012 }
2013
2014 return failedImport("Src pattern child has predicate (" +
2015 explainPredicates(Src) + ")");
2016 }
2017
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002018 if (Src->isLeaf()) {
2019 Init *SrcInit = Src->getLeafValue();
2020 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
2021 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2022 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
2023 } else
Daniel Sanders32291982017-06-28 13:50:04 +00002024 return failedImport(
2025 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002026 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002027 assert(SrcGIOrNull &&
2028 "Expected to have already found an equivalent Instruction");
Daniel Sanders05540042017-08-08 10:44:31 +00002029 if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT") {
2030 // imm still has an operand but we don't need to do anything with it
2031 // here since we don't support ImmLeaf predicates yet. However, we still
2032 // need to note the hidden operand to get GIM_CheckNumOperands correct.
2033 InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
2034 return InsnMatcher;
2035 }
2036
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002037 // Match the used operands (i.e. the children of the operator).
2038 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002039 TreePatternNode *SrcChild = Src->getChild(i);
2040
2041 // For G_INTRINSIC, the operand immediately following the defs is an
2042 // intrinsic ID.
2043 if (SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" && i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002044 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00002045 OperandMatcher &OM =
2046 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00002047 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00002048 continue;
2049 }
2050
2051 return failedImport("Expected IntInit containing instrinsic ID)");
2052 }
2053
2054 if (auto Error =
2055 importChildMatcher(InsnMatcher, SrcChild, OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002056 return std::move(Error);
2057 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002058 }
2059
2060 return InsnMatcher;
2061}
2062
Daniel Sandersc270c502017-03-30 09:36:33 +00002063Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002064 const TreePatternNode *SrcChild,
Daniel Sandersc270c502017-03-30 09:36:33 +00002065 unsigned OpIdx,
2066 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002067 OperandMatcher &OM =
2068 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002069
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002070 ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002071 if (ChildTypes.size() != 1)
2072 return failedImport("Src pattern child has multiple results");
2073
2074 // Check MBB's before the type check since they are not a known type.
2075 if (!SrcChild->isLeaf()) {
2076 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
2077 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
2078 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
2079 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00002080 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002081 }
2082 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00002083 }
2084
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002085 Optional<LLTCodeGen> OpTyOrNone = None;
2086 if (ChildTypes.front().isMachineValueType())
2087 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002088 if (!OpTyOrNone)
Daniel Sanders85ffd362017-07-06 08:12:20 +00002089 return failedImport("Src operand has an unsupported type (" + to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002090 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
2091
Daniel Sandersbee57392017-04-04 13:25:23 +00002092 // Check for nested instructions.
2093 if (!SrcChild->isLeaf()) {
2094 // Map the node to a gMIR instruction.
2095 InstructionOperandMatcher &InsnOperand =
Daniel Sanders05540042017-08-08 10:44:31 +00002096 OM.addPredicate<InstructionOperandMatcher>(SrcChild->getName());
Daniel Sanders57938df2017-07-11 10:40:18 +00002097 auto InsnMatcherOrError = createAndImportSelDAGMatcher(
2098 InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00002099 if (auto Error = InsnMatcherOrError.takeError())
2100 return Error;
2101
2102 return Error::success();
2103 }
2104
Daniel Sandersffc7d582017-03-29 15:37:18 +00002105 // Check for constant immediates.
2106 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002107 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00002108 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002109 }
2110
2111 // Check for def's like register classes or ComplexPattern's.
2112 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
2113 auto *ChildRec = ChildDefInit->getDef();
2114
2115 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002116 if (ChildRec->isSubClassOf("RegisterClass") ||
2117 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002118 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002119 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00002120 return Error::success();
2121 }
2122
Daniel Sandersffc7d582017-03-29 15:37:18 +00002123 // Check for ComplexPattern's.
2124 if (ChildRec->isSubClassOf("ComplexPattern")) {
2125 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
2126 if (ComplexPattern == ComplexPatternEquivs.end())
Daniel Sandersd0656a32017-04-13 09:45:37 +00002127 return failedImport("SelectionDAG ComplexPattern (" +
2128 ChildRec->getName() + ") not mapped to GlobalISel");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002129
Daniel Sanders2deea182017-04-22 15:11:04 +00002130 OM.addPredicate<ComplexPatternOperandMatcher>(OM,
2131 *ComplexPattern->second);
2132 TempOpIdx++;
Daniel Sandersc270c502017-03-30 09:36:33 +00002133 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002134 }
2135
Daniel Sandersd0656a32017-04-13 09:45:37 +00002136 if (ChildRec->isSubClassOf("ImmLeaf")) {
2137 return failedImport(
2138 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
2139 }
2140
Daniel Sandersffc7d582017-03-29 15:37:18 +00002141 return failedImport(
2142 "Src pattern child def is an unsupported tablegen class");
2143 }
2144
2145 return failedImport("Src pattern child is an unsupported kind");
2146}
2147
Daniel Sandersc270c502017-03-30 09:36:33 +00002148Error GlobalISelEmitter::importExplicitUseRenderer(
Daniel Sandersffc7d582017-03-29 15:37:18 +00002149 BuildMIAction &DstMIBuilder, TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002150 const InstructionMatcher &InsnMatcher) const {
Daniel Sanders2c269f62017-08-24 09:11:20 +00002151 if (DstChild->getTransformFn() != nullptr) {
2152 return failedImport("Dst pattern child has transform fn " +
2153 DstChild->getTransformFn()->getName());
2154 }
2155
Daniel Sandersffc7d582017-03-29 15:37:18 +00002156 if (!DstChild->isLeaf()) {
Daniel Sanders05540042017-08-08 10:44:31 +00002157 // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
2158 // inline, but in MI it's just another operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002159 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
2160 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
2161 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002162 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
Daniel Sandersffc7d582017-03-29 15:37:18 +00002163 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00002164 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002165 }
2166 }
Daniel Sanders05540042017-08-08 10:44:31 +00002167
2168 // Similarly, imm is an operator in TreePatternNode's view but must be
2169 // rendered as operands.
2170 // FIXME: The target should be able to choose sign-extended when appropriate
2171 // (e.g. on Mips).
2172 if (DstChild->getOperator()->getName() == "imm") {
2173 DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(0,
2174 DstChild->getName());
2175 return Error::success();
2176 }
2177
Daniel Sanders2c269f62017-08-24 09:11:20 +00002178 return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
Daniel Sandersffc7d582017-03-29 15:37:18 +00002179 }
2180
2181 // Otherwise, we're looking for a bog-standard RegisterClass operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00002182 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
2183 auto *ChildRec = ChildDefInit->getDef();
2184
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002185 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002186 if (ChildTypes.size() != 1)
2187 return failedImport("Dst pattern child has multiple results");
2188
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002189 Optional<LLTCodeGen> OpTyOrNone = None;
2190 if (ChildTypes.front().isMachineValueType())
2191 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002192 if (!OpTyOrNone)
2193 return failedImport("Dst operand has an unsupported type");
2194
2195 if (ChildRec->isSubClassOf("Register")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002196 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, ChildRec);
Daniel Sandersc270c502017-03-30 09:36:33 +00002197 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002198 }
2199
Daniel Sanders658541f2017-04-22 15:53:21 +00002200 if (ChildRec->isSubClassOf("RegisterClass") ||
2201 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002202 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
2203 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00002204 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002205 }
2206
2207 if (ChildRec->isSubClassOf("ComplexPattern")) {
2208 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
2209 if (ComplexPattern == ComplexPatternEquivs.end())
2210 return failedImport(
2211 "SelectionDAG ComplexPattern not mapped to GlobalISel");
2212
Daniel Sanders4f3eb242017-04-05 13:14:03 +00002213 const OperandMatcher &OM = InsnMatcher.getOperand(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00002214 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002215 0, *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00002216 OM.getAllocatedTemporariesBaseID());
Daniel Sandersc270c502017-03-30 09:36:33 +00002217 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002218 }
2219
Daniel Sandersd0656a32017-04-13 09:45:37 +00002220 if (ChildRec->isSubClassOf("SDNodeXForm"))
2221 return failedImport("Dst pattern child def is an unsupported tablegen "
2222 "class (SDNodeXForm)");
2223
Daniel Sandersffc7d582017-03-29 15:37:18 +00002224 return failedImport(
2225 "Dst pattern child def is an unsupported tablegen class");
2226 }
2227
2228 return failedImport("Dst pattern child is an unsupported kind");
2229}
2230
Daniel Sandersc270c502017-03-30 09:36:33 +00002231Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersffc7d582017-03-29 15:37:18 +00002232 RuleMatcher &M, const TreePatternNode *Dst,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002233 const InstructionMatcher &InsnMatcher) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00002234 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00002235 if (!DstOp->isSubClassOf("Instruction")) {
2236 if (DstOp->isSubClassOf("ValueType"))
2237 return failedImport(
2238 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00002239 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00002240 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002241 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002242
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002243 unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs;
2244 unsigned ExpectedDstINumUses = Dst->getNumChildren();
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002245 bool IsExtractSubReg = false;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002246
2247 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002248 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002249 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") {
2250 DstI = &Target.getInstruction(RK.getDef("COPY"));
2251 DstINumUses--; // Ignore the class constraint.
2252 ExpectedDstINumUses--;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002253 } else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") {
2254 DstI = &Target.getInstruction(RK.getDef("COPY"));
2255 IsExtractSubReg = true;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002256 }
2257
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002258 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002259
2260 // Render the explicit defs.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002261 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
2262 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002263 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002264 }
2265
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002266 // EXTRACT_SUBREG needs to use a subregister COPY.
2267 if (IsExtractSubReg) {
2268 if (!Dst->getChild(0)->isLeaf())
2269 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2270
Daniel Sanders32291982017-06-28 13:50:04 +00002271 if (DefInit *SubRegInit =
2272 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002273 CodeGenRegisterClass *RC = CGRegs.getRegClass(
2274 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));
2275 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
2276
2277 const auto &SrcRCDstRCPair =
2278 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2279 if (SrcRCDstRCPair.hasValue()) {
2280 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
2281 if (SrcRCDstRCPair->first != RC)
2282 return failedImport("EXTRACT_SUBREG requires an additional COPY");
2283 }
2284
2285 DstMIBuilder.addRenderer<CopySubRegRenderer>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002286 0, InsnMatcher, Dst->getChild(0)->getName(), SubIdx);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002287 return DstMIBuilder;
2288 }
2289
2290 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
2291 }
2292
Daniel Sandersffc7d582017-03-29 15:37:18 +00002293 // Render the explicit uses.
Daniel Sanders0ed28822017-04-12 08:23:08 +00002294 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00002295 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002296 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002297 const CGIOperandList::OperandInfo &DstIOperand =
2298 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00002299
Diana Picus382602f2017-05-17 08:57:28 +00002300 // If the operand has default values, introduce them now.
2301 // FIXME: Until we have a decent test case that dictates we should do
2302 // otherwise, we're going to assume that operands with default values cannot
2303 // be specified in the patterns. Therefore, adding them will not cause us to
2304 // end up with too many rendered operands.
2305 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00002306 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00002307 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
2308 return std::move(Error);
2309 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002310 continue;
2311 }
2312
2313 if (auto Error = importExplicitUseRenderer(
2314 DstMIBuilder, Dst->getChild(Child), InsnMatcher))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002315 return std::move(Error);
Daniel Sanders0ed28822017-04-12 08:23:08 +00002316 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002317 }
2318
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002319 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00002320 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00002321 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002322 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00002323 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00002324 " default ones");
2325
Daniel Sandersffc7d582017-03-29 15:37:18 +00002326 return DstMIBuilder;
2327}
2328
Diana Picus382602f2017-05-17 08:57:28 +00002329Error GlobalISelEmitter::importDefaultOperandRenderers(
2330 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00002331 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00002332 // Look through ValueType operators.
2333 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
2334 if (const DefInit *DefaultDagOperator =
2335 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
2336 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
2337 DefaultOp = DefaultDagOp->getArg(0);
2338 }
2339 }
2340
2341 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002342 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00002343 continue;
2344 }
2345
2346 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002347 DstMIBuilder.addRenderer<ImmRenderer>(0, DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00002348 continue;
2349 }
2350
2351 return failedImport("Could not add default op");
2352 }
2353
2354 return Error::success();
2355}
2356
Daniel Sandersc270c502017-03-30 09:36:33 +00002357Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00002358 BuildMIAction &DstMIBuilder,
2359 const std::vector<Record *> &ImplicitDefs) const {
2360 if (!ImplicitDefs.empty())
2361 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00002362 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00002363}
2364
2365Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002366 // Keep track of the matchers and actions to emit.
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00002367 RuleMatcher M;
2368 M.addAction<DebugCommentAction>(P);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002369
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002370 if (auto Error = importRulePredicates(M, P.getPredicates()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002371 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002372
2373 // Next, analyze the pattern operators.
2374 TreePatternNode *Src = P.getSrcPattern();
2375 TreePatternNode *Dst = P.getDstPattern();
2376
2377 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00002378 if (auto Err = isTrivialOperatorNode(Dst))
2379 return failedImport("Dst pattern root isn't a trivial operator (" +
2380 toString(std::move(Err)) + ")");
2381 if (auto Err = isTrivialOperatorNode(Src))
2382 return failedImport("Src pattern root isn't a trivial operator (" +
2383 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002384
Daniel Sandersedd07842017-08-17 09:26:14 +00002385 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
2386 unsigned TempOpIdx = 0;
2387 auto InsnMatcherOrError =
2388 createAndImportSelDAGMatcher(InsnMatcherTemp, Src, TempOpIdx);
2389 if (auto Error = InsnMatcherOrError.takeError())
2390 return std::move(Error);
2391 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
2392
2393 if (Dst->isLeaf()) {
2394 Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
2395
2396 const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
2397 if (RCDef) {
2398 // We need to replace the def and all its uses with the specified
2399 // operand. However, we must also insert COPY's wherever needed.
2400 // For now, emit a copy and let the register allocator clean up.
2401 auto &DstI = Target.getInstruction(RK.getDef("COPY"));
2402 const auto &DstIOperand = DstI.Operands[0];
2403
2404 OperandMatcher &OM0 = InsnMatcher.getOperand(0);
2405 OM0.setSymbolicName(DstIOperand.Name);
2406 OM0.addPredicate<RegisterBankOperandMatcher>(RC);
2407
2408 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI, InsnMatcher);
2409 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name);
2410 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, Dst->getName());
2411 M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
2412
2413 // We're done with this pattern! It's eligible for GISel emission; return
2414 // it.
2415 ++NumPatternImported;
2416 return std::move(M);
2417 }
2418
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002419 return failedImport("Dst pattern root isn't a known leaf");
Daniel Sandersedd07842017-08-17 09:26:14 +00002420 }
Daniel Sanders452c8ae2017-05-23 19:33:16 +00002421
Daniel Sandersbee57392017-04-04 13:25:23 +00002422 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002423 Record *DstOp = Dst->getOperator();
2424 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002425 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002426
2427 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002428 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00002429 return failedImport("Src pattern results and dst MI defs are different (" +
2430 to_string(Src->getExtTypes().size()) + " def(s) vs " +
2431 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002432
Daniel Sandersffc7d582017-03-29 15:37:18 +00002433 // The root of the match also has constraints on the register bank so that it
2434 // matches the result instruction.
2435 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002436 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
2437 (void)VTy;
Daniel Sandersffc7d582017-03-29 15:37:18 +00002438
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002439 const auto &DstIOperand = DstI.Operands[OpIdx];
2440 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002441 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
2442 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
2443
2444 if (DstIOpRec == nullptr)
2445 return failedImport(
2446 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002447 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
2448 if (!Dst->getChild(0)->isLeaf())
2449 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
2450
Daniel Sanders32291982017-06-28 13:50:04 +00002451 // We can assume that a subregister is in the same bank as it's super
2452 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002453 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
2454
2455 if (DstIOpRec == nullptr)
2456 return failedImport(
2457 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002458 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00002459 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002460 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00002461 return failedImport("Dst MI def isn't a register class" +
2462 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002463
Daniel Sandersffc7d582017-03-29 15:37:18 +00002464 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
2465 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002466 OM.addPredicate<RegisterBankOperandMatcher>(
2467 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002468 ++OpIdx;
2469 }
2470
Daniel Sandersc270c502017-03-30 09:36:33 +00002471 auto DstMIBuilderOrError =
2472 createAndImportInstructionRenderer(M, Dst, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00002473 if (auto Error = DstMIBuilderOrError.takeError())
2474 return std::move(Error);
2475 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002476
Daniel Sandersffc7d582017-03-29 15:37:18 +00002477 // Render the implicit defs.
2478 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00002479 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00002480 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002481
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002482 // Constrain the registers to classes. This is normally derived from the
2483 // emitted instruction but a few instructions require special handling.
2484 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
2485 // COPY_TO_REGCLASS does not provide operand constraints itself but the
2486 // result is constrained to the class given by the second child.
2487 Record *DstIOpRec =
2488 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
2489
2490 if (DstIOpRec == nullptr)
2491 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
2492
2493 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002494 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002495
2496 // We're done with this pattern! It's eligible for GISel emission; return
2497 // it.
2498 ++NumPatternImported;
2499 return std::move(M);
2500 }
2501
2502 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
2503 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
2504 // instructions, the result register class is controlled by the
2505 // subregisters of the operand. As a result, we must constrain the result
2506 // class rather than check that it's already the right one.
2507 if (!Dst->getChild(0)->isLeaf())
2508 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
2509
Daniel Sanders320390b2017-06-28 15:16:03 +00002510 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
2511 if (!SubRegInit)
2512 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002513
Daniel Sanders320390b2017-06-28 15:16:03 +00002514 // Constrain the result to the same register bank as the operand.
2515 Record *DstIOpRec =
2516 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002517
Daniel Sanders320390b2017-06-28 15:16:03 +00002518 if (DstIOpRec == nullptr)
2519 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002520
Daniel Sanders320390b2017-06-28 15:16:03 +00002521 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002522 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002523
Daniel Sanders320390b2017-06-28 15:16:03 +00002524 // It would be nice to leave this constraint implicit but we're required
2525 // to pick a register class so constrain the result to a register class
2526 // that can hold the correct MVT.
2527 //
2528 // FIXME: This may introduce an extra copy if the chosen class doesn't
2529 // actually contain the subregisters.
2530 assert(Src->getExtTypes().size() == 1 &&
2531 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002532
Daniel Sanders320390b2017-06-28 15:16:03 +00002533 const auto &SrcRCDstRCPair =
2534 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
2535 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002536 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
2537 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
2538
2539 // We're done with this pattern! It's eligible for GISel emission; return
2540 // it.
2541 ++NumPatternImported;
2542 return std::move(M);
2543 }
2544
2545 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002546
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002547 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002548 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002549 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002550}
2551
2552void GlobalISelEmitter::run(raw_ostream &OS) {
2553 // Track the GINodeEquiv definitions.
2554 gatherNodeEquivs();
2555
2556 emitSourceFileHeader(("Global Instruction Selector for the " +
2557 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002558 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002559 // Look through the SelectionDAG patterns we found, possibly emitting some.
2560 for (const PatternToMatch &Pat : CGP.ptms()) {
2561 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002562 auto MatcherOrErr = runOnPattern(Pat);
2563
2564 // The pattern analysis can fail, indicating an unsupported pattern.
2565 // Report that if we've been asked to do so.
2566 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002567 if (WarnOnSkippedPatterns) {
2568 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002569 "Skipped pattern: " + toString(std::move(Err)));
2570 } else {
2571 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002572 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002573 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002574 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002575 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002576
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00002577 Rules.push_back(std::move(MatcherOrErr.get()));
2578 }
2579
Daniel Sanderseb2f5f32017-08-15 15:10:31 +00002580 std::stable_sort(Rules.begin(), Rules.end(),
2581 [&](const RuleMatcher &A, const RuleMatcher &B) {
2582 if (A.isHigherPriorityThan(B)) {
2583 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
2584 "and less important at "
2585 "the same time");
2586 return true;
2587 }
2588 return false;
2589 });
Daniel Sanders759ff412017-02-24 13:58:11 +00002590
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002591 std::vector<Record *> ComplexPredicates =
2592 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
2593 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
2594 [](const Record *A, const Record *B) {
2595 if (A->getName() < B->getName())
2596 return true;
2597 return false;
2598 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002599 unsigned MaxTemporaries = 0;
2600 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00002601 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002602
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002603 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
2604 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
2605 << ";\n"
2606 << "using PredicateBitset = "
2607 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
2608 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
2609
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002610 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
2611 << " mutable MatcherState State;\n"
2612 << " typedef "
2613 "ComplexRendererFn("
2614 << Target.getName()
2615 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
2616 << "const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
2617 "MatcherInfo;\n"
2618 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002619
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002620 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
2621 << ", State(" << MaxTemporaries << "),\n"
Daniel Sanders2c269f62017-08-24 09:11:20 +00002622 << "MatcherInfo({TypeObjects, FeatureBitsets, ImmPredicateFns, {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002623 << " nullptr, // GICP_Invalid\n";
2624 for (const auto &Record : ComplexPredicates)
2625 OS << " &" << Target.getName()
2626 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
2627 << ", // " << Record->getName() << "\n";
2628 OS << "}})\n"
2629 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002630
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002631 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
2632 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
2633 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002634
2635 // Separate subtarget features by how often they must be recomputed.
2636 SubtargetFeatureInfoMap ModuleFeatures;
2637 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
2638 std::inserter(ModuleFeatures, ModuleFeatures.end()),
2639 [](const SubtargetFeatureInfoMap::value_type &X) {
2640 return !X.second.mustRecomputePerFunction();
2641 });
2642 SubtargetFeatureInfoMap FunctionFeatures;
2643 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
2644 std::inserter(FunctionFeatures, FunctionFeatures.end()),
2645 [](const SubtargetFeatureInfoMap::value_type &X) {
2646 return X.second.mustRecomputePerFunction();
2647 });
2648
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002649 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002650 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
2651 ModuleFeatures, OS);
2652 SubtargetFeatureInfo::emitComputeAvailableFeatures(
2653 Target.getName(), "InstructionSelector",
2654 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
2655 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002656
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002657 // Emit a table containing the LLT objects needed by the matcher and an enum
2658 // for the matcher to reference them with.
Daniel Sanders032e7f22017-08-17 13:18:35 +00002659 std::vector<LLTCodeGen> TypeObjects;
2660 for (const auto &Ty : LLTOperandMatcher::KnownTypes)
2661 TypeObjects.push_back(Ty);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002662 std::sort(TypeObjects.begin(), TypeObjects.end());
Daniel Sanders49980702017-08-23 10:09:25 +00002663 OS << "// LLT Objects.\n"
2664 << "enum {\n";
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002665 for (const auto &TypeObject : TypeObjects) {
2666 OS << " ";
2667 TypeObject.emitCxxEnumValue(OS);
2668 OS << ",\n";
2669 }
2670 OS << "};\n"
2671 << "const static LLT TypeObjects[] = {\n";
2672 for (const auto &TypeObject : TypeObjects) {
2673 OS << " ";
2674 TypeObject.emitCxxConstructorCall(OS);
2675 OS << ",\n";
2676 }
2677 OS << "};\n\n";
2678
2679 // Emit a table containing the PredicateBitsets objects needed by the matcher
2680 // and an enum for the matcher to reference them with.
2681 std::vector<std::vector<Record *>> FeatureBitsets;
2682 for (auto &Rule : Rules)
2683 FeatureBitsets.push_back(Rule.getRequiredFeatures());
2684 std::sort(
2685 FeatureBitsets.begin(), FeatureBitsets.end(),
2686 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
2687 if (A.size() < B.size())
2688 return true;
2689 if (A.size() > B.size())
2690 return false;
2691 for (const auto &Pair : zip(A, B)) {
2692 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
2693 return true;
2694 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
2695 return false;
2696 }
2697 return false;
2698 });
2699 FeatureBitsets.erase(
2700 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
2701 FeatureBitsets.end());
Daniel Sanders49980702017-08-23 10:09:25 +00002702 OS << "// Feature bitsets.\n"
2703 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002704 << " GIFBS_Invalid,\n";
2705 for (const auto &FeatureBitset : FeatureBitsets) {
2706 if (FeatureBitset.empty())
2707 continue;
2708 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
2709 }
2710 OS << "};\n"
2711 << "const static PredicateBitset FeatureBitsets[] {\n"
2712 << " {}, // GIFBS_Invalid\n";
2713 for (const auto &FeatureBitset : FeatureBitsets) {
2714 if (FeatureBitset.empty())
2715 continue;
2716 OS << " {";
2717 for (const auto &Feature : FeatureBitset) {
2718 const auto &I = SubtargetFeatures.find(Feature);
2719 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
2720 OS << I->second.getEnumBitName() << ", ";
2721 }
2722 OS << "},\n";
2723 }
2724 OS << "};\n\n";
2725
2726 // Emit complex predicate table and an enum to reference them with.
Daniel Sanders49980702017-08-23 10:09:25 +00002727 OS << "// ComplexPattern predicates.\n"
2728 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002729 << " GICP_Invalid,\n";
2730 for (const auto &Record : ComplexPredicates)
2731 OS << " GICP_" << Record->getName() << ",\n";
2732 OS << "};\n"
2733 << "// See constructor for table contents\n\n";
2734
Daniel Sanders2c269f62017-08-24 09:11:20 +00002735 // Emit imm predicate table and an enum to reference them with.
2736 // The 'Predicate_' part of the name is redundant but eliminating it is more
2737 // trouble than it's worth.
2738 {
2739 OS << "// PatFrag predicates.\n"
2740 << "enum {\n";
Daniel Sanders069bb8d2017-08-24 18:54:16 +00002741 StringRef EnumeratorSeparator = " = GIPFP_Invalid + 1,\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00002742 for (const auto *Record : RK.getAllDerivedDefinitions("PatFrag")) {
2743 if (!Record->getValueAsString("ImmediateCode").empty()) {
2744 OS << " GIPFP_Predicate_" << Record->getName() << EnumeratorSeparator;
2745 EnumeratorSeparator = ",\n";
2746 }
2747 }
2748 OS << "};\n";
2749 }
2750 for (const auto *Record : RK.getAllDerivedDefinitions("PatFrag"))
2751 if (!Record->getValueAsString("ImmediateCode").empty())
2752 OS << " static bool Predicate_" << Record->getName() << "(int64_t Imm) {"
2753 << Record->getValueAsString("ImmediateCode") << " }\n";
Daniel Sanders069bb8d2017-08-24 18:54:16 +00002754 OS << "static InstructionSelector::ImmediatePredicateFn ImmPredicateFns[] = "
2755 "{\n"
2756 << " nullptr,\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00002757 for (const auto *Record : RK.getAllDerivedDefinitions("PatFrag"))
2758 if (!Record->getValueAsString("ImmediateCode").empty())
2759 OS << " Predicate_" << Record->getName() << ",\n";
2760 OS << "};\n";
2761
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002762 OS << "bool " << Target.getName()
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002763 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
2764 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002765 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00002766 << " // FIXME: This should be computed on a per-function basis rather "
2767 "than per-insn.\n"
2768 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
2769 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00002770 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
2771 << " NewMIVector OutMIs;\n"
2772 << " State.MIs.clear();\n"
2773 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002774
Daniel Sanders8e82af22017-07-27 11:03:45 +00002775 MatchTable Table(0);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002776 for (auto &Rule : Rules) {
Daniel Sanders8e82af22017-07-27 11:03:45 +00002777 Rule.emit(Table);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002778 ++NumPatternEmitted;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002779 }
Daniel Sanders8e82af22017-07-27 11:03:45 +00002780 Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
2781 Table.emitDeclaration(OS);
2782 OS << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, ";
2783 Table.emitUse(OS);
2784 OS << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n"
2785 << " return true;\n"
2786 << " }\n\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002787
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002788 OS << " return false;\n"
2789 << "}\n"
2790 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002791
2792 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
2793 << "PredicateBitset AvailableModuleFeatures;\n"
2794 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
2795 << "PredicateBitset getAvailableFeatures() const {\n"
2796 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
2797 << "}\n"
2798 << "PredicateBitset\n"
2799 << "computeAvailableModuleFeatures(const " << Target.getName()
2800 << "Subtarget *Subtarget) const;\n"
2801 << "PredicateBitset\n"
2802 << "computeAvailableFunctionFeatures(const " << Target.getName()
2803 << "Subtarget *Subtarget,\n"
2804 << " const MachineFunction *MF) const;\n"
2805 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
2806
2807 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
2808 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
2809 << "AvailableFunctionFeatures()\n"
2810 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002811}
2812
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002813void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
2814 if (SubtargetFeatures.count(Predicate) == 0)
2815 SubtargetFeatures.emplace(
2816 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
2817}
2818
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002819} // end anonymous namespace
2820
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002821//===----------------------------------------------------------------------===//
2822
2823namespace llvm {
2824void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
2825 GlobalISelEmitter(RK).run(OS);
2826}
2827} // End llvm namespace