blob: 9367b5da838995c2d8089c51f0b2e7680e0b4516 [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"
Daniel Sandersf76f3152017-11-16 00:46:35 +000038#include "llvm/Support/CodeGenCoverage.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000039#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"
David Blaikie13e77db2018-03-23 23:58:25 +000042#include "llvm/Support/MachineValueType.h"
Pavel Labath52a82e22017-02-21 09:19:41 +000043#include "llvm/Support/ScopedPrinter.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000044#include "llvm/TableGen/Error.h"
45#include "llvm/TableGen/Record.h"
46#include "llvm/TableGen/TableGenBackend.h"
Daniel Sanders8a4bae92017-03-14 21:32:08 +000047#include <numeric>
Daniel Sandersf76f3152017-11-16 00:46:35 +000048#include <string>
Ahmed Bougacha36f70352016-12-21 23:26:20 +000049using namespace llvm;
50
51#define DEBUG_TYPE "gisel-emitter"
52
53STATISTIC(NumPatternTotal, "Total number of patterns");
Daniel Sandersb41ce2b2017-02-20 14:31:27 +000054STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
55STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
Daniel Sandersf76f3152017-11-16 00:46:35 +000056STATISTIC(NumPatternsTested, "Number of patterns executed according to coverage information");
Ahmed Bougacha36f70352016-12-21 23:26:20 +000057STATISTIC(NumPatternEmitted, "Number of patterns emitted");
58
Daniel Sanders0848b232017-03-27 13:15:13 +000059cl::OptionCategory GlobalISelEmitterCat("Options for -gen-global-isel");
60
Ahmed Bougacha36f70352016-12-21 23:26:20 +000061static cl::opt<bool> WarnOnSkippedPatterns(
62 "warn-on-skipped-patterns",
63 cl::desc("Explain why a pattern was skipped for inclusion "
64 "in the GlobalISel selector"),
Daniel Sanders0848b232017-03-27 13:15:13 +000065 cl::init(false), cl::cat(GlobalISelEmitterCat));
Ahmed Bougacha36f70352016-12-21 23:26:20 +000066
Daniel Sandersf76f3152017-11-16 00:46:35 +000067static cl::opt<bool> GenerateCoverage(
68 "instrument-gisel-coverage",
69 cl::desc("Generate coverage instrumentation for GlobalISel"),
70 cl::init(false), cl::cat(GlobalISelEmitterCat));
71
72static cl::opt<std::string> UseCoverageFile(
73 "gisel-coverage-file", cl::init(""),
74 cl::desc("Specify file to retrieve coverage information from"),
75 cl::cat(GlobalISelEmitterCat));
76
Quentin Colombetec76d9c2017-12-18 19:47:41 +000077static cl::opt<bool> OptimizeMatchTable(
78 "optimize-match-table",
79 cl::desc("Generate an optimized version of the match table"),
80 cl::init(true), cl::cat(GlobalISelEmitterCat));
81
Daniel Sandersbdfebb82017-03-15 20:18:38 +000082namespace {
Ahmed Bougacha36f70352016-12-21 23:26:20 +000083//===- Helper functions ---------------------------------------------------===//
84
Daniel Sanders11300ce2017-10-13 21:28:03 +000085/// Get the name of the enum value used to number the predicate function.
86std::string getEnumNameForPredicate(const TreePredicateFn &Predicate) {
Simon Pilgrim6ecae9f2017-10-14 21:27:53 +000087 return "GIPFP_" + Predicate.getImmTypeIdentifier().str() + "_" +
Daniel Sanders11300ce2017-10-13 21:28:03 +000088 Predicate.getFnName();
89}
90
91/// Get the opcode used to check this predicate.
92std::string getMatchOpcodeForPredicate(const TreePredicateFn &Predicate) {
Simon Pilgrim6ecae9f2017-10-14 21:27:53 +000093 return "GIM_Check" + Predicate.getImmTypeIdentifier().str() + "ImmPredicate";
Daniel Sanders11300ce2017-10-13 21:28:03 +000094}
95
Daniel Sanders52b4ce72017-03-07 23:20:35 +000096/// This class stands in for LLT wherever we want to tablegen-erate an
97/// equivalent at compiler run-time.
98class LLTCodeGen {
99private:
100 LLT Ty;
101
102public:
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000103 LLTCodeGen() = default;
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000104 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
105
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000106 std::string getCxxEnumValue() const {
107 std::string Str;
108 raw_string_ostream OS(Str);
109
110 emitCxxEnumValue(OS);
111 return OS.str();
112 }
113
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000114 void emitCxxEnumValue(raw_ostream &OS) const {
115 if (Ty.isScalar()) {
116 OS << "GILLT_s" << Ty.getSizeInBits();
117 return;
118 }
119 if (Ty.isVector()) {
120 OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
121 return;
122 }
Daniel Sandersa71f4542017-10-16 00:56:30 +0000123 if (Ty.isPointer()) {
124 OS << "GILLT_p" << Ty.getAddressSpace();
125 if (Ty.getSizeInBits() > 0)
126 OS << "s" << Ty.getSizeInBits();
127 return;
128 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000129 llvm_unreachable("Unhandled LLT");
130 }
131
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000132 void emitCxxConstructorCall(raw_ostream &OS) const {
133 if (Ty.isScalar()) {
134 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
135 return;
136 }
137 if (Ty.isVector()) {
Daniel Sanders32291982017-06-28 13:50:04 +0000138 OS << "LLT::vector(" << Ty.getNumElements() << ", "
139 << Ty.getScalarSizeInBits() << ")";
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000140 return;
141 }
Daniel Sandersa71f4542017-10-16 00:56:30 +0000142 if (Ty.isPointer() && Ty.getSizeInBits() > 0) {
143 OS << "LLT::pointer(" << Ty.getAddressSpace() << ", "
144 << Ty.getSizeInBits() << ")";
145 return;
146 }
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000147 llvm_unreachable("Unhandled LLT");
148 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000149
150 const LLT &get() const { return Ty; }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000151
Mandeep Singh Grang1b0e2f22018-04-06 20:18:05 +0000152 /// This ordering is used for std::unique() and llvm::sort(). There's no
Daniel Sanders032e7f22017-08-17 13:18:35 +0000153 /// particular logic behind the order but either A < B or B < A must be
154 /// true if A != B.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000155 bool operator<(const LLTCodeGen &Other) const {
Daniel Sanders032e7f22017-08-17 13:18:35 +0000156 if (Ty.isValid() != Other.Ty.isValid())
157 return Ty.isValid() < Other.Ty.isValid();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000158 if (!Ty.isValid())
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000159 return false;
Daniel Sanders032e7f22017-08-17 13:18:35 +0000160
161 if (Ty.isVector() != Other.Ty.isVector())
162 return Ty.isVector() < Other.Ty.isVector();
163 if (Ty.isScalar() != Other.Ty.isScalar())
164 return Ty.isScalar() < Other.Ty.isScalar();
165 if (Ty.isPointer() != Other.Ty.isPointer())
166 return Ty.isPointer() < Other.Ty.isPointer();
167
168 if (Ty.isPointer() && Ty.getAddressSpace() != Other.Ty.getAddressSpace())
169 return Ty.getAddressSpace() < Other.Ty.getAddressSpace();
170
171 if (Ty.isVector() && Ty.getNumElements() != Other.Ty.getNumElements())
172 return Ty.getNumElements() < Other.Ty.getNumElements();
173
174 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000175 }
Quentin Colombet893e0f12017-12-15 23:24:39 +0000176
177 bool operator==(const LLTCodeGen &B) const { return Ty == B.Ty; }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000178};
179
Daniel Sandersf84bc372018-05-05 20:53:24 +0000180// Track all types that are used so we can emit the corresponding enum.
181std::set<LLTCodeGen> KnownTypes;
182
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000183class InstructionMatcher;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000184/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
185/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000186static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000187 MVT VT(SVT);
Daniel Sandersa71f4542017-10-16 00:56:30 +0000188
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000189 if (VT.isVector() && VT.getVectorNumElements() != 1)
Daniel Sanders32291982017-06-28 13:50:04 +0000190 return LLTCodeGen(
191 LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
Daniel Sandersa71f4542017-10-16 00:56:30 +0000192
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000193 if (VT.isInteger() || VT.isFloatingPoint())
194 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
195 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000196}
197
Daniel Sandersd0656a32017-04-13 09:45:37 +0000198static std::string explainPredicates(const TreePatternNode *N) {
199 std::string Explanation = "";
200 StringRef Separator = "";
201 for (const auto &P : N->getPredicateFns()) {
202 Explanation +=
203 (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
Daniel Sanders76664652017-11-28 22:07:05 +0000204 Separator = ", ";
205
Daniel Sandersd0656a32017-04-13 09:45:37 +0000206 if (P.isAlwaysTrue())
207 Explanation += " always-true";
208 if (P.isImmediatePattern())
209 Explanation += " immediate";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000210
211 if (P.isUnindexed())
212 Explanation += " unindexed";
213
214 if (P.isNonExtLoad())
215 Explanation += " non-extload";
216 if (P.isAnyExtLoad())
217 Explanation += " extload";
218 if (P.isSignExtLoad())
219 Explanation += " sextload";
220 if (P.isZeroExtLoad())
221 Explanation += " zextload";
222
223 if (P.isNonTruncStore())
224 Explanation += " non-truncstore";
225 if (P.isTruncStore())
226 Explanation += " truncstore";
227
228 if (Record *VT = P.getMemoryVT())
229 Explanation += (" MemVT=" + VT->getName()).str();
230 if (Record *VT = P.getScalarMemoryVT())
231 Explanation += (" ScalarVT(MemVT)=" + VT->getName()).str();
Daniel Sanders76664652017-11-28 22:07:05 +0000232
233 if (P.isAtomicOrderingMonotonic())
234 Explanation += " monotonic";
235 if (P.isAtomicOrderingAcquire())
236 Explanation += " acquire";
237 if (P.isAtomicOrderingRelease())
238 Explanation += " release";
239 if (P.isAtomicOrderingAcquireRelease())
240 Explanation += " acq_rel";
241 if (P.isAtomicOrderingSequentiallyConsistent())
242 Explanation += " seq_cst";
Daniel Sanders0c43b3a2017-11-30 21:05:59 +0000243 if (P.isAtomicOrderingAcquireOrStronger())
244 Explanation += " >=acquire";
245 if (P.isAtomicOrderingWeakerThanAcquire())
246 Explanation += " <acquire";
247 if (P.isAtomicOrderingReleaseOrStronger())
248 Explanation += " >=release";
249 if (P.isAtomicOrderingWeakerThanRelease())
250 Explanation += " <release";
Daniel Sandersd0656a32017-04-13 09:45:37 +0000251 }
252 return Explanation;
253}
254
Daniel Sandersd0656a32017-04-13 09:45:37 +0000255std::string explainOperator(Record *Operator) {
256 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000257 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000258
259 if (Operator->isSubClassOf("Intrinsic"))
260 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
261
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000262 if (Operator->isSubClassOf("ComplexPattern"))
263 return (" (Operator is an unmapped ComplexPattern, " + Operator->getName() +
264 ")")
265 .str();
266
Volkan Kelesf7f25682018-01-16 18:44:05 +0000267 if (Operator->isSubClassOf("SDNodeXForm"))
268 return (" (Operator is an unmapped SDNodeXForm, " + Operator->getName() +
269 ")")
270 .str();
271
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000272 return (" (Operator " + Operator->getName() + " not understood)").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000273}
274
275/// Helper function to let the emitter report skip reason error messages.
276static Error failedImport(const Twine &Reason) {
277 return make_error<StringError>(Reason, inconvertibleErrorCode());
278}
279
280static Error isTrivialOperatorNode(const TreePatternNode *N) {
281 std::string Explanation = "";
282 std::string Separator = "";
Daniel Sanders2c269f62017-08-24 09:11:20 +0000283
284 bool HasUnsupportedPredicate = false;
285 for (const auto &Predicate : N->getPredicateFns()) {
286 if (Predicate.isAlwaysTrue())
287 continue;
288
289 if (Predicate.isImmediatePattern())
290 continue;
291
Daniel Sandersf84bc372018-05-05 20:53:24 +0000292 if (Predicate.isNonExtLoad() || Predicate.isAnyExtLoad() ||
293 Predicate.isSignExtLoad() || Predicate.isZeroExtLoad())
Daniel Sandersa71f4542017-10-16 00:56:30 +0000294 continue;
Daniel Sandersd66e0902017-10-23 18:19:24 +0000295
Daniel Sanders76664652017-11-28 22:07:05 +0000296 if (Predicate.isNonTruncStore())
Daniel Sandersd66e0902017-10-23 18:19:24 +0000297 continue;
298
Daniel Sandersf84bc372018-05-05 20:53:24 +0000299 if (Predicate.isLoad() && Predicate.getMemoryVT())
300 continue;
301
Daniel Sanders76664652017-11-28 22:07:05 +0000302 if (Predicate.isLoad() || Predicate.isStore()) {
303 if (Predicate.isUnindexed())
304 continue;
305 }
306
307 if (Predicate.isAtomic() && Predicate.getMemoryVT())
308 continue;
309
310 if (Predicate.isAtomic() &&
311 (Predicate.isAtomicOrderingMonotonic() ||
312 Predicate.isAtomicOrderingAcquire() ||
313 Predicate.isAtomicOrderingRelease() ||
314 Predicate.isAtomicOrderingAcquireRelease() ||
Daniel Sanders0c43b3a2017-11-30 21:05:59 +0000315 Predicate.isAtomicOrderingSequentiallyConsistent() ||
316 Predicate.isAtomicOrderingAcquireOrStronger() ||
317 Predicate.isAtomicOrderingWeakerThanAcquire() ||
318 Predicate.isAtomicOrderingReleaseOrStronger() ||
319 Predicate.isAtomicOrderingWeakerThanRelease()))
Daniel Sandersd66e0902017-10-23 18:19:24 +0000320 continue;
321
Daniel Sanders2c269f62017-08-24 09:11:20 +0000322 HasUnsupportedPredicate = true;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000323 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
324 Separator = ", ";
Daniel Sanders3f267bf2017-10-15 02:06:44 +0000325 Explanation += (Separator + "first-failing:" +
326 Predicate.getOrigPatFragRecord()->getRecord()->getName())
327 .str();
Daniel Sanders2c269f62017-08-24 09:11:20 +0000328 break;
Daniel Sandersd0656a32017-04-13 09:45:37 +0000329 }
330
Volkan Kelesf7f25682018-01-16 18:44:05 +0000331 if (!HasUnsupportedPredicate)
Daniel Sandersd0656a32017-04-13 09:45:37 +0000332 return Error::success();
333
334 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000335}
336
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000337static Record *getInitValueAsRegClass(Init *V) {
338 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
339 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
340 return VDefInit->getDef()->getValueAsDef("RegClass");
341 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
342 return VDefInit->getDef();
343 }
344 return nullptr;
345}
346
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000347std::string
348getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
349 std::string Name = "GIFBS";
350 for (const auto &Feature : FeatureBitset)
351 Name += ("_" + Feature->getName()).str();
352 return Name;
353}
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000354
355//===- MatchTable Helpers -------------------------------------------------===//
356
357class MatchTable;
358
359/// A record to be stored in a MatchTable.
360///
361/// This class represents any and all output that may be required to emit the
362/// MatchTable. Instances are most often configured to represent an opcode or
363/// value that will be emitted to the table with some formatting but it can also
364/// represent commas, comments, and other formatting instructions.
365struct MatchTableRecord {
366 enum RecordFlagsBits {
367 MTRF_None = 0x0,
368 /// Causes EmitStr to be formatted as comment when emitted.
369 MTRF_Comment = 0x1,
370 /// Causes the record value to be followed by a comma when emitted.
371 MTRF_CommaFollows = 0x2,
372 /// Causes the record value to be followed by a line break when emitted.
373 MTRF_LineBreakFollows = 0x4,
374 /// Indicates that the record defines a label and causes an additional
375 /// comment to be emitted containing the index of the label.
376 MTRF_Label = 0x8,
377 /// Causes the record to be emitted as the index of the label specified by
378 /// LabelID along with a comment indicating where that label is.
379 MTRF_JumpTarget = 0x10,
380 /// Causes the formatter to add a level of indentation before emitting the
381 /// record.
382 MTRF_Indent = 0x20,
383 /// Causes the formatter to remove a level of indentation after emitting the
384 /// record.
385 MTRF_Outdent = 0x40,
386 };
387
388 /// When MTRF_Label or MTRF_JumpTarget is used, indicates a label id to
389 /// reference or define.
390 unsigned LabelID;
391 /// The string to emit. Depending on the MTRF_* flags it may be a comment, a
392 /// value, a label name.
393 std::string EmitStr;
394
395private:
396 /// The number of MatchTable elements described by this record. Comments are 0
397 /// while values are typically 1. Values >1 may occur when we need to emit
398 /// values that exceed the size of a MatchTable element.
399 unsigned NumElements;
400
401public:
402 /// A bitfield of RecordFlagsBits flags.
403 unsigned Flags;
404
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000405 /// The actual run-time value, if known
406 int64_t RawValue;
407
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000408 MatchTableRecord(Optional<unsigned> LabelID_, StringRef EmitStr,
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000409 unsigned NumElements, unsigned Flags,
410 int64_t RawValue = std::numeric_limits<int64_t>::min())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000411 : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000412 EmitStr(EmitStr), NumElements(NumElements), Flags(Flags),
413 RawValue(RawValue) {
414
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000415 assert((!LabelID_.hasValue() || LabelID != ~0u) &&
416 "This value is reserved for non-labels");
417 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000418 MatchTableRecord(const MatchTableRecord &Other) = default;
419 MatchTableRecord(MatchTableRecord &&Other) = default;
420
421 /// Useful if a Match Table Record gets optimized out
422 void turnIntoComment() {
423 Flags |= MTRF_Comment;
424 Flags &= ~MTRF_CommaFollows;
425 NumElements = 0;
426 }
427
428 /// For Jump Table generation purposes
429 bool operator<(const MatchTableRecord &Other) const {
430 return RawValue < Other.RawValue;
431 }
432 int64_t getRawValue() const { return RawValue; }
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000433
434 void emit(raw_ostream &OS, bool LineBreakNextAfterThis,
435 const MatchTable &Table) const;
436 unsigned size() const { return NumElements; }
437};
438
Roman Tereshin2d6d3762018-05-02 20:08:14 +0000439class Matcher;
440
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000441/// Holds the contents of a generated MatchTable to enable formatting and the
442/// necessary index tracking needed to support GIM_Try.
443class MatchTable {
444 /// An unique identifier for the table. The generated table will be named
445 /// MatchTable${ID}.
446 unsigned ID;
447 /// The records that make up the table. Also includes comments describing the
448 /// values being emitted and line breaks to format it.
449 std::vector<MatchTableRecord> Contents;
450 /// The currently defined labels.
451 DenseMap<unsigned, unsigned> LabelMap;
452 /// Tracks the sum of MatchTableRecord::NumElements as the table is built.
Roman Tereshin2d6d3762018-05-02 20:08:14 +0000453 unsigned CurrentSize = 0;
Daniel Sanders8e82af22017-07-27 11:03:45 +0000454 /// A unique identifier for a MatchTable label.
Roman Tereshin2d6d3762018-05-02 20:08:14 +0000455 unsigned CurrentLabelID = 0;
Roman Tereshinbeb39312018-05-02 20:15:11 +0000456 /// Determines if the table should be instrumented for rule coverage tracking.
457 bool IsWithCoverage;
Daniel Sanders8e82af22017-07-27 11:03:45 +0000458
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000459public:
460 static MatchTableRecord LineBreak;
461 static MatchTableRecord Comment(StringRef Comment) {
462 return MatchTableRecord(None, Comment, 0, MatchTableRecord::MTRF_Comment);
463 }
464 static MatchTableRecord Opcode(StringRef Opcode, int IndentAdjust = 0) {
465 unsigned ExtraFlags = 0;
466 if (IndentAdjust > 0)
467 ExtraFlags |= MatchTableRecord::MTRF_Indent;
468 if (IndentAdjust < 0)
469 ExtraFlags |= MatchTableRecord::MTRF_Outdent;
470
471 return MatchTableRecord(None, Opcode, 1,
472 MatchTableRecord::MTRF_CommaFollows | ExtraFlags);
473 }
474 static MatchTableRecord NamedValue(StringRef NamedValue) {
475 return MatchTableRecord(None, NamedValue, 1,
476 MatchTableRecord::MTRF_CommaFollows);
477 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000478 static MatchTableRecord NamedValue(StringRef NamedValue, int64_t RawValue) {
479 return MatchTableRecord(None, NamedValue, 1,
480 MatchTableRecord::MTRF_CommaFollows, RawValue);
481 }
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000482 static MatchTableRecord NamedValue(StringRef Namespace,
483 StringRef NamedValue) {
484 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
485 MatchTableRecord::MTRF_CommaFollows);
486 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000487 static MatchTableRecord NamedValue(StringRef Namespace, StringRef NamedValue,
488 int64_t RawValue) {
489 return MatchTableRecord(None, (Namespace + "::" + NamedValue).str(), 1,
490 MatchTableRecord::MTRF_CommaFollows, RawValue);
491 }
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000492 static MatchTableRecord IntValue(int64_t IntValue) {
493 return MatchTableRecord(None, llvm::to_string(IntValue), 1,
494 MatchTableRecord::MTRF_CommaFollows);
495 }
496 static MatchTableRecord Label(unsigned LabelID) {
497 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 0,
498 MatchTableRecord::MTRF_Label |
499 MatchTableRecord::MTRF_Comment |
500 MatchTableRecord::MTRF_LineBreakFollows);
501 }
502 static MatchTableRecord JumpTarget(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000503 return MatchTableRecord(LabelID, "Label " + llvm::to_string(LabelID), 1,
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000504 MatchTableRecord::MTRF_JumpTarget |
505 MatchTableRecord::MTRF_Comment |
506 MatchTableRecord::MTRF_CommaFollows);
507 }
508
Roman Tereshinbeb39312018-05-02 20:15:11 +0000509 static MatchTable buildTable(ArrayRef<Matcher *> Rules, bool WithCoverage);
Roman Tereshin2d6d3762018-05-02 20:08:14 +0000510
Roman Tereshinbeb39312018-05-02 20:15:11 +0000511 MatchTable(bool WithCoverage, unsigned ID = 0)
512 : ID(ID), IsWithCoverage(WithCoverage) {}
513
514 bool isWithCoverage() const { return IsWithCoverage; }
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000515
516 void push_back(const MatchTableRecord &Value) {
517 if (Value.Flags & MatchTableRecord::MTRF_Label)
518 defineLabel(Value.LabelID);
519 Contents.push_back(Value);
520 CurrentSize += Value.size();
521 }
522
Roman Tereshin2d6d3762018-05-02 20:08:14 +0000523 unsigned allocateLabelID() { return CurrentLabelID++; }
Daniel Sanders8e82af22017-07-27 11:03:45 +0000524
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000525 void defineLabel(unsigned LabelID) {
Daniel Sanders8e82af22017-07-27 11:03:45 +0000526 LabelMap.insert(std::make_pair(LabelID, CurrentSize));
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000527 }
528
529 unsigned getLabelIndex(unsigned LabelID) const {
530 const auto I = LabelMap.find(LabelID);
531 assert(I != LabelMap.end() && "Use of undeclared label");
532 return I->second;
533 }
534
Daniel Sanders8e82af22017-07-27 11:03:45 +0000535 void emitUse(raw_ostream &OS) const { OS << "MatchTable" << ID; }
536
537 void emitDeclaration(raw_ostream &OS) const {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000538 unsigned Indentation = 4;
Daniel Sanderscbbbfe42017-07-27 12:47:31 +0000539 OS << " constexpr static int64_t MatchTable" << ID << "[] = {";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000540 LineBreak.emit(OS, true, *this);
541 OS << std::string(Indentation, ' ');
542
543 for (auto I = Contents.begin(), E = Contents.end(); I != E;
544 ++I) {
545 bool LineBreakIsNext = false;
546 const auto &NextI = std::next(I);
547
548 if (NextI != E) {
549 if (NextI->EmitStr == "" &&
550 NextI->Flags == MatchTableRecord::MTRF_LineBreakFollows)
551 LineBreakIsNext = true;
552 }
553
554 if (I->Flags & MatchTableRecord::MTRF_Indent)
555 Indentation += 2;
556
557 I->emit(OS, LineBreakIsNext, *this);
558 if (I->Flags & MatchTableRecord::MTRF_LineBreakFollows)
559 OS << std::string(Indentation, ' ');
560
561 if (I->Flags & MatchTableRecord::MTRF_Outdent)
562 Indentation -= 2;
563 }
564 OS << "};\n";
565 }
566};
567
568MatchTableRecord MatchTable::LineBreak = {
569 None, "" /* Emit String */, 0 /* Elements */,
570 MatchTableRecord::MTRF_LineBreakFollows};
571
572void MatchTableRecord::emit(raw_ostream &OS, bool LineBreakIsNextAfterThis,
573 const MatchTable &Table) const {
574 bool UseLineComment =
575 LineBreakIsNextAfterThis | (Flags & MTRF_LineBreakFollows);
576 if (Flags & (MTRF_JumpTarget | MTRF_CommaFollows))
577 UseLineComment = false;
578
579 if (Flags & MTRF_Comment)
580 OS << (UseLineComment ? "// " : "/*");
581
582 OS << EmitStr;
583 if (Flags & MTRF_Label)
584 OS << ": @" << Table.getLabelIndex(LabelID);
585
586 if (Flags & MTRF_Comment && !UseLineComment)
587 OS << "*/";
588
589 if (Flags & MTRF_JumpTarget) {
590 if (Flags & MTRF_Comment)
591 OS << " ";
592 OS << Table.getLabelIndex(LabelID);
593 }
594
595 if (Flags & MTRF_CommaFollows) {
596 OS << ",";
597 if (!LineBreakIsNextAfterThis && !(Flags & MTRF_LineBreakFollows))
598 OS << " ";
599 }
600
601 if (Flags & MTRF_LineBreakFollows)
602 OS << "\n";
603}
604
605MatchTable &operator<<(MatchTable &Table, const MatchTableRecord &Value) {
606 Table.push_back(Value);
607 return Table;
608}
609
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000610//===- Matchers -----------------------------------------------------------===//
611
Daniel Sandersbee57392017-04-04 13:25:23 +0000612class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000613class MatchAction;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000614class PredicateMatcher;
615class RuleMatcher;
616
617class Matcher {
618public:
619 virtual ~Matcher() = default;
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000620 virtual void optimize() {}
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000621 virtual void emit(MatchTable &Table) = 0;
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000622
623 virtual bool hasFirstCondition() const = 0;
624 virtual const PredicateMatcher &getFirstCondition() const = 0;
625 virtual std::unique_ptr<PredicateMatcher> popFirstCondition() = 0;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000626};
627
Roman Tereshinbeb39312018-05-02 20:15:11 +0000628MatchTable MatchTable::buildTable(ArrayRef<Matcher *> Rules,
629 bool WithCoverage) {
630 MatchTable Table(WithCoverage);
Roman Tereshin2d6d3762018-05-02 20:08:14 +0000631 for (Matcher *Rule : Rules)
632 Rule->emit(Table);
633
634 return Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
635}
636
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000637class GroupMatcher final : public Matcher {
638 /// Conditions that form a common prefix of all the matchers contained.
639 SmallVector<std::unique_ptr<PredicateMatcher>, 1> Conditions;
640
641 /// All the nested matchers, sharing a common prefix.
642 std::vector<Matcher *> Matchers;
643
644 /// An owning collection for any auxiliary matchers created while optimizing
645 /// nested matchers contained.
646 std::vector<std::unique_ptr<Matcher>> MatcherStorage;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000647
648public:
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000649 /// Add a matcher to the collection of nested matchers if it meets the
650 /// requirements, and return true. If it doesn't, do nothing and return false.
651 ///
652 /// Expected to preserve its argument, so it could be moved out later on.
653 bool addMatcher(Matcher &Candidate);
654
655 /// Mark the matcher as fully-built and ensure any invariants expected by both
656 /// optimize() and emit(...) methods. Generally, both sequences of calls
657 /// are expected to lead to a sensible result:
658 ///
659 /// addMatcher(...)*; finalize(); optimize(); emit(...); and
660 /// addMatcher(...)*; finalize(); emit(...);
661 ///
662 /// or generally
663 ///
664 /// addMatcher(...)*; finalize(); { optimize()*; emit(...); }*
665 ///
666 /// Multiple calls to optimize() are expected to be handled gracefully, though
667 /// optimize() is not expected to be idempotent. Multiple calls to finalize()
668 /// aren't generally supported. emit(...) is expected to be non-mutating and
669 /// producing the exact same results upon repeated calls.
670 ///
671 /// addMatcher() calls after the finalize() call are not supported.
672 ///
673 /// finalize() and optimize() are both allowed to mutate the contained
674 /// matchers, so moving them out after finalize() is not supported.
675 void finalize();
Roman Tereshinfedae332018-05-23 02:04:19 +0000676 void optimize() override;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000677 void emit(MatchTable &Table) override;
Quentin Colombet34688b92017-12-18 21:25:53 +0000678
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000679 /// Could be used to move out the matchers added previously, unless finalize()
680 /// has been already called. If any of the matchers are moved out, the group
681 /// becomes safe to destroy, but not safe to re-use for anything else.
682 iterator_range<std::vector<Matcher *>::iterator> matchers() {
683 return make_range(Matchers.begin(), Matchers.end());
Quentin Colombet34688b92017-12-18 21:25:53 +0000684 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000685 size_t size() const { return Matchers.size(); }
686 bool empty() const { return Matchers.empty(); }
687
688 std::unique_ptr<PredicateMatcher> popFirstCondition() override {
689 assert(!Conditions.empty() &&
690 "Trying to pop a condition from a condition-less group");
691 std::unique_ptr<PredicateMatcher> P = std::move(Conditions.front());
692 Conditions.erase(Conditions.begin());
693 return P;
694 }
695 const PredicateMatcher &getFirstCondition() const override {
696 assert(!Conditions.empty() &&
697 "Trying to get a condition from a condition-less group");
698 return *Conditions.front();
699 }
700 bool hasFirstCondition() const override { return !Conditions.empty(); }
701
702private:
703 /// See if a candidate matcher could be added to this group solely by
704 /// analyzing its first condition.
705 bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000706};
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000707
Roman Tereshin0ee082f2018-05-22 19:37:59 +0000708class SwitchMatcher : public Matcher {
709 /// All the nested matchers, representing distinct switch-cases. The first
710 /// conditions (as Matcher::getFirstCondition() reports) of all the nested
711 /// matchers must share the same type and path to a value they check, in other
712 /// words, be isIdenticalDownToValue, but have different values they check
713 /// against.
714 std::vector<Matcher *> Matchers;
715
716 /// The representative condition, with a type and a path (InsnVarID and OpIdx
717 /// in most cases) shared by all the matchers contained.
718 std::unique_ptr<PredicateMatcher> Condition = nullptr;
719
720 /// Temporary set used to check that the case values don't repeat within the
721 /// same switch.
722 std::set<MatchTableRecord> Values;
723
724 /// An owning collection for any auxiliary matchers created while optimizing
725 /// nested matchers contained.
726 std::vector<std::unique_ptr<Matcher>> MatcherStorage;
727
728public:
729 bool addMatcher(Matcher &Candidate);
730
731 void finalize();
732 void emit(MatchTable &Table) override;
733
734 iterator_range<std::vector<Matcher *>::iterator> matchers() {
735 return make_range(Matchers.begin(), Matchers.end());
736 }
737 size_t size() const { return Matchers.size(); }
738 bool empty() const { return Matchers.empty(); }
739
740 std::unique_ptr<PredicateMatcher> popFirstCondition() override {
741 // SwitchMatcher doesn't have a common first condition for its cases, as all
742 // the cases only share a kind of a value (a type and a path to it) they
743 // match, but deliberately differ in the actual value they match.
744 llvm_unreachable("Trying to pop a condition from a condition-less group");
745 }
746 const PredicateMatcher &getFirstCondition() const override {
747 llvm_unreachable("Trying to pop a condition from a condition-less group");
748 }
749 bool hasFirstCondition() const override { return false; }
750
751private:
752 /// See if the predicate type has a Switch-implementation for it.
753 static bool isSupportedPredicateType(const PredicateMatcher &Predicate);
754
755 bool candidateConditionMatches(const PredicateMatcher &Predicate) const;
756
757 /// emit()-helper
758 static void emitPredicateSpecificOpcodes(const PredicateMatcher &P,
759 MatchTable &Table);
760};
761
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000762/// Generates code to check that a match rule matches.
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000763class RuleMatcher : public Matcher {
Daniel Sanders7438b262017-10-31 23:03:18 +0000764public:
Daniel Sanders08464522018-01-29 21:09:12 +0000765 using ActionList = std::list<std::unique_ptr<MatchAction>>;
766 using action_iterator = ActionList::iterator;
Daniel Sanders7438b262017-10-31 23:03:18 +0000767
768protected:
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000769 /// A list of matchers that all need to succeed for the current rule to match.
770 /// FIXME: This currently supports a single match position but could be
771 /// extended to support multiple positions to support div/rem fusion or
772 /// load-multiple instructions.
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000773 using MatchersTy = std::vector<std::unique_ptr<InstructionMatcher>> ;
774 MatchersTy Matchers;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000775
776 /// A list of actions that need to be taken when all predicates in this rule
777 /// have succeeded.
Daniel Sanders08464522018-01-29 21:09:12 +0000778 ActionList Actions;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000779
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000780 using DefinedInsnVariablesMap = std::map<InstructionMatcher *, unsigned>;
Daniel Sandersa7b75262017-10-31 18:50:24 +0000781
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000782 /// A map of instruction matchers to the local variables
Daniel Sanders078572b2017-08-02 11:03:36 +0000783 DefinedInsnVariablesMap InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000784
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000785 using MutatableInsnSet = SmallPtrSet<InstructionMatcher *, 4>;
Daniel Sandersa7b75262017-10-31 18:50:24 +0000786
787 // The set of instruction matchers that have not yet been claimed for mutation
788 // by a BuildMI.
789 MutatableInsnSet MutatableInsns;
790
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000791 /// A map of named operands defined by the matchers that may be referenced by
792 /// the renderers.
793 StringMap<OperandMatcher *> DefinedOperands;
794
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000795 /// ID for the next instruction variable defined with implicitlyDefineInsnVar()
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000796 unsigned NextInsnVarID;
797
Daniel Sanders198447a2017-11-01 00:29:47 +0000798 /// ID for the next output instruction allocated with allocateOutputInsnID()
799 unsigned NextOutputInsnID;
800
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000801 /// ID for the next temporary register ID allocated with allocateTempRegID()
802 unsigned NextTempRegID;
803
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000804 std::vector<Record *> RequiredFeatures;
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000805 std::vector<std::unique_ptr<PredicateMatcher>> EpilogueMatchers;
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000806
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000807 ArrayRef<SMLoc> SrcLoc;
808
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000809 typedef std::tuple<Record *, unsigned, unsigned>
810 DefinedComplexPatternSubOperand;
811 typedef StringMap<DefinedComplexPatternSubOperand>
812 DefinedComplexPatternSubOperandMap;
813 /// A map of Symbolic Names to ComplexPattern sub-operands.
814 DefinedComplexPatternSubOperandMap ComplexSubOperands;
815
Daniel Sandersf76f3152017-11-16 00:46:35 +0000816 uint64_t RuleID;
817 static uint64_t NextRuleID;
818
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000819public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000820 RuleMatcher(ArrayRef<SMLoc> SrcLoc)
Daniel Sandersa7b75262017-10-31 18:50:24 +0000821 : Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(),
Daniel Sanders198447a2017-11-01 00:29:47 +0000822 DefinedOperands(), NextInsnVarID(0), NextOutputInsnID(0),
Daniel Sandersf76f3152017-11-16 00:46:35 +0000823 NextTempRegID(0), SrcLoc(SrcLoc), ComplexSubOperands(),
824 RuleID(NextRuleID++) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000825 RuleMatcher(RuleMatcher &&Other) = default;
826 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000827
Daniel Sandersf76f3152017-11-16 00:46:35 +0000828 uint64_t getRuleID() const { return RuleID; }
829
Daniel Sanders05540042017-08-08 10:44:31 +0000830 InstructionMatcher &addInstructionMatcher(StringRef SymbolicName);
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000831 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000832 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000833
834 template <class Kind, class... Args> Kind &addAction(Args &&... args);
Daniel Sanders7438b262017-10-31 23:03:18 +0000835 template <class Kind, class... Args>
836 action_iterator insertAction(action_iterator InsertPt, Args &&... args);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000837
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000838 /// Define an instruction without emitting any code to do so.
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000839 unsigned implicitlyDefineInsnVar(InstructionMatcher &Matcher);
840
841 unsigned getInsnVarID(InstructionMatcher &InsnMatcher) const;
Daniel Sanders078572b2017-08-02 11:03:36 +0000842 DefinedInsnVariablesMap::const_iterator defined_insn_vars_begin() const {
843 return InsnVariableIDs.begin();
844 }
845 DefinedInsnVariablesMap::const_iterator defined_insn_vars_end() const {
846 return InsnVariableIDs.end();
847 }
848 iterator_range<typename DefinedInsnVariablesMap::const_iterator>
849 defined_insn_vars() const {
850 return make_range(defined_insn_vars_begin(), defined_insn_vars_end());
851 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000852
Daniel Sandersa7b75262017-10-31 18:50:24 +0000853 MutatableInsnSet::const_iterator mutatable_insns_begin() const {
854 return MutatableInsns.begin();
855 }
856 MutatableInsnSet::const_iterator mutatable_insns_end() const {
857 return MutatableInsns.end();
858 }
859 iterator_range<typename MutatableInsnSet::const_iterator>
860 mutatable_insns() const {
861 return make_range(mutatable_insns_begin(), mutatable_insns_end());
862 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000863 void reserveInsnMatcherForMutation(InstructionMatcher *InsnMatcher) {
Daniel Sandersa7b75262017-10-31 18:50:24 +0000864 bool R = MutatableInsns.erase(InsnMatcher);
865 assert(R && "Reserving a mutatable insn that isn't available");
866 (void)R;
867 }
868
Daniel Sanders7438b262017-10-31 23:03:18 +0000869 action_iterator actions_begin() { return Actions.begin(); }
870 action_iterator actions_end() { return Actions.end(); }
871 iterator_range<action_iterator> actions() {
872 return make_range(actions_begin(), actions_end());
873 }
874
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000875 void defineOperand(StringRef SymbolicName, OperandMatcher &OM);
876
Daniel Sandersdf39cba2017-10-15 18:22:54 +0000877 void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern,
878 unsigned RendererID, unsigned SubOperandID) {
879 assert(ComplexSubOperands.count(SymbolicName) == 0 && "Already defined");
880 ComplexSubOperands[SymbolicName] =
881 std::make_tuple(ComplexPattern, RendererID, SubOperandID);
882 }
883 Optional<DefinedComplexPatternSubOperand>
884 getComplexSubOperand(StringRef SymbolicName) const {
885 const auto &I = ComplexSubOperands.find(SymbolicName);
886 if (I == ComplexSubOperands.end())
887 return None;
888 return I->second;
889 }
890
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000891 InstructionMatcher &getInstructionMatcher(StringRef SymbolicName) const;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +0000892 const OperandMatcher &getOperandMatcher(StringRef Name) const;
Daniel Sanders05540042017-08-08 10:44:31 +0000893
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000894 void optimize() override;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000895 void emit(MatchTable &Table) override;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000896
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000897 /// Compare the priority of this object and B.
898 ///
899 /// Returns true if this object is more important than B.
900 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000901
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000902 /// Report the maximum number of temporary operands needed by the rule
903 /// matcher.
904 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000905
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000906 std::unique_ptr<PredicateMatcher> popFirstCondition() override;
907 const PredicateMatcher &getFirstCondition() const override;
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000908 bool hasFirstCondition() const override;
909 unsigned getNumOperands() const;
Roman Tereshin19da6672018-05-22 04:31:50 +0000910 StringRef getOpcode() const;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000911
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000912 // FIXME: Remove this as soon as possible
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000913 InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); }
Daniel Sanders198447a2017-11-01 00:29:47 +0000914
915 unsigned allocateOutputInsnID() { return NextOutputInsnID++; }
Daniel Sanders9cbe7c72017-11-01 19:57:57 +0000916 unsigned allocateTempRegID() { return NextTempRegID++; }
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000917
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000918 iterator_range<MatchersTy::iterator> insnmatchers() {
919 return make_range(Matchers.begin(), Matchers.end());
920 }
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000921 bool insnmatchers_empty() const { return Matchers.empty(); }
922 void insnmatchers_pop_front() { Matchers.erase(Matchers.begin()); }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000923};
924
Daniel Sandersf76f3152017-11-16 00:46:35 +0000925uint64_t RuleMatcher::NextRuleID = 0;
926
Daniel Sanders7438b262017-10-31 23:03:18 +0000927using action_iterator = RuleMatcher::action_iterator;
928
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000929template <class PredicateTy> class PredicateListMatcher {
930private:
Daniel Sanders2c269f62017-08-24 09:11:20 +0000931 /// Template instantiations should specialize this to return a string to use
932 /// for the comment emitted when there are no predicates.
933 std::string getNoPredicateComment() const;
934
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000935protected:
936 using PredicatesTy = std::deque<std::unique_ptr<PredicateTy>>;
937 PredicatesTy Predicates;
Roman Tereshinf0dc9fa2018-05-21 22:04:39 +0000938
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000939 /// Track if the list of predicates was manipulated by one of the optimization
940 /// methods.
941 bool Optimized = false;
942
943public:
944 /// Construct a new predicate and add it to the matcher.
945 template <class Kind, class... Args>
946 Optional<Kind *> addPredicate(Args &&... args);
947
948 typename PredicatesTy::iterator predicates_begin() {
Daniel Sanders32291982017-06-28 13:50:04 +0000949 return Predicates.begin();
950 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000951 typename PredicatesTy::iterator predicates_end() {
Daniel Sanders32291982017-06-28 13:50:04 +0000952 return Predicates.end();
953 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000954 iterator_range<typename PredicatesTy::iterator> predicates() {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000955 return make_range(predicates_begin(), predicates_end());
956 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000957 typename PredicatesTy::size_type predicates_size() const {
Daniel Sanders32291982017-06-28 13:50:04 +0000958 return Predicates.size();
959 }
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000960 bool predicates_empty() const { return Predicates.empty(); }
961
962 std::unique_ptr<PredicateTy> predicates_pop_front() {
963 std::unique_ptr<PredicateTy> Front = std::move(Predicates.front());
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000964 Predicates.pop_front();
965 Optimized = true;
Quentin Colombetec76d9c2017-12-18 19:47:41 +0000966 return Front;
967 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000968
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000969 void prependPredicate(std::unique_ptr<PredicateTy> &&Predicate) {
970 Predicates.push_front(std::move(Predicate));
971 }
972
973 void eraseNullPredicates() {
974 const auto NewEnd =
975 std::stable_partition(Predicates.begin(), Predicates.end(),
976 std::logical_not<std::unique_ptr<PredicateTy>>());
977 if (NewEnd != Predicates.begin()) {
978 Predicates.erase(Predicates.begin(), NewEnd);
979 Optimized = true;
980 }
981 }
982
Daniel Sanders9d662d22017-07-06 10:06:12 +0000983 /// Emit MatchTable opcodes that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000984 template <class... Args>
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000985 void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) {
986 if (Predicates.empty() && !Optimized) {
Daniel Sanders2c269f62017-08-24 09:11:20 +0000987 Table << MatchTable::Comment(getNoPredicateComment())
988 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000989 return;
990 }
991
Roman Tereshinf1aa3482018-05-21 23:28:51 +0000992 for (const auto &Predicate : predicates())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +0000993 Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000994 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000995};
996
Quentin Colombet063d7982017-12-14 23:44:07 +0000997class PredicateMatcher {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000998public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000999 /// This enum is used for RTTI and also defines the priority that is given to
1000 /// the predicate when generating the matcher code. Kinds with higher priority
1001 /// must be tested first.
1002 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001003 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
1004 /// but OPM_Int must have priority over OPM_RegBank since constant integers
1005 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Quentin Colombet063d7982017-12-14 23:44:07 +00001006 ///
1007 /// Note: The relative priority between IPM_ and OPM_ does not matter, they
1008 /// are currently not compared between each other.
Daniel Sanders759ff412017-02-24 13:58:11 +00001009 enum PredicateKind {
Quentin Colombet063d7982017-12-14 23:44:07 +00001010 IPM_Opcode,
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001011 IPM_NumOperands,
Quentin Colombet063d7982017-12-14 23:44:07 +00001012 IPM_ImmPredicate,
1013 IPM_AtomicOrderingMMO,
Daniel Sandersf84bc372018-05-05 20:53:24 +00001014 IPM_MemoryLLTSize,
1015 IPM_MemoryVsLLTSize,
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001016 OPM_SameOperand,
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001017 OPM_ComplexPattern,
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001018 OPM_IntrinsicID,
Daniel Sanders05540042017-08-08 10:44:31 +00001019 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001020 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001021 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +00001022 OPM_LLT,
Daniel Sandersa71f4542017-10-16 00:56:30 +00001023 OPM_PointerToAny,
Daniel Sanders759ff412017-02-24 13:58:11 +00001024 OPM_RegBank,
1025 OPM_MBB,
1026 };
1027
1028protected:
1029 PredicateKind Kind;
Quentin Colombetaad20be2017-12-15 23:07:42 +00001030 unsigned InsnVarID;
1031 unsigned OpIdx;
Daniel Sanders759ff412017-02-24 13:58:11 +00001032
1033public:
Quentin Colombetaad20be2017-12-15 23:07:42 +00001034 PredicateMatcher(PredicateKind Kind, unsigned InsnVarID, unsigned OpIdx = ~0)
1035 : Kind(Kind), InsnVarID(InsnVarID), OpIdx(OpIdx) {}
Quentin Colombet063d7982017-12-14 23:44:07 +00001036
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001037 unsigned getInsnVarID() const { return InsnVarID; }
Quentin Colombetaad20be2017-12-15 23:07:42 +00001038 unsigned getOpIdx() const { return OpIdx; }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001039
Quentin Colombet063d7982017-12-14 23:44:07 +00001040 virtual ~PredicateMatcher() = default;
1041 /// Emit MatchTable opcodes that check the predicate for the given operand.
Quentin Colombetaad20be2017-12-15 23:07:42 +00001042 virtual void emitPredicateOpcodes(MatchTable &Table,
1043 RuleMatcher &Rule) const = 0;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001044
Daniel Sanders759ff412017-02-24 13:58:11 +00001045 PredicateKind getKind() const { return Kind; }
Quentin Colombet893e0f12017-12-15 23:24:39 +00001046
1047 virtual bool isIdentical(const PredicateMatcher &B) const {
Quentin Colombet893e0f12017-12-15 23:24:39 +00001048 return B.getKind() == getKind() && InsnVarID == B.InsnVarID &&
1049 OpIdx == B.OpIdx;
1050 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001051
1052 virtual bool isIdenticalDownToValue(const PredicateMatcher &B) const {
1053 return hasValue() && PredicateMatcher::isIdentical(B);
1054 }
1055
1056 virtual MatchTableRecord getValue() const {
1057 assert(hasValue() && "Can not get a value of a value-less predicate!");
1058 llvm_unreachable("Not implemented yet");
1059 }
1060 virtual bool hasValue() const { return false; }
1061
1062 /// Report the maximum number of temporary operands needed by the predicate
1063 /// matcher.
1064 virtual unsigned countRendererFns() const { return 0; }
Quentin Colombet063d7982017-12-14 23:44:07 +00001065};
1066
1067/// Generates code to check a predicate of an operand.
1068///
1069/// Typical predicates include:
1070/// * Operand is a particular register.
1071/// * Operand is assigned a particular register bank.
1072/// * Operand is an MBB.
1073class OperandPredicateMatcher : public PredicateMatcher {
1074public:
Quentin Colombetaad20be2017-12-15 23:07:42 +00001075 OperandPredicateMatcher(PredicateKind Kind, unsigned InsnVarID,
1076 unsigned OpIdx)
1077 : PredicateMatcher(Kind, InsnVarID, OpIdx) {}
Quentin Colombet063d7982017-12-14 23:44:07 +00001078 virtual ~OperandPredicateMatcher() {}
Daniel Sanders759ff412017-02-24 13:58:11 +00001079
Daniel Sanders759ff412017-02-24 13:58:11 +00001080 /// Compare the priority of this object and B.
1081 ///
1082 /// Returns true if this object is more important than B.
Daniel Sanders05540042017-08-08 10:44:31 +00001083 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001084};
1085
Daniel Sanders2c269f62017-08-24 09:11:20 +00001086template <>
1087std::string
1088PredicateListMatcher<OperandPredicateMatcher>::getNoPredicateComment() const {
1089 return "No operand predicates";
1090}
1091
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001092/// Generates code to check that a register operand is defined by the same exact
1093/// one as another.
1094class SameOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001095 std::string MatchingName;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001096
1097public:
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001098 SameOperandMatcher(unsigned InsnVarID, unsigned OpIdx, StringRef MatchingName)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001099 : OperandPredicateMatcher(OPM_SameOperand, InsnVarID, OpIdx),
1100 MatchingName(MatchingName) {}
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001101
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001102 static bool classof(const PredicateMatcher *P) {
Daniel Sanders1e4569f2017-10-20 20:55:29 +00001103 return P->getKind() == OPM_SameOperand;
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001104 }
1105
Quentin Colombetaad20be2017-12-15 23:07:42 +00001106 void emitPredicateOpcodes(MatchTable &Table,
1107 RuleMatcher &Rule) const override;
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001108
1109 bool isIdentical(const PredicateMatcher &B) const override {
1110 return OperandPredicateMatcher::isIdentical(B) &&
1111 MatchingName == cast<SameOperandMatcher>(&B)->MatchingName;
1112 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001113};
1114
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001115/// Generates code to check that an operand is a particular LLT.
1116class LLTOperandMatcher : public OperandPredicateMatcher {
1117protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +00001118 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001119
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001120public:
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001121 static std::map<LLTCodeGen, unsigned> TypeIDValues;
1122
1123 static void initTypeIDValuesMap() {
1124 TypeIDValues.clear();
1125
1126 unsigned ID = 0;
1127 for (const LLTCodeGen LLTy : KnownTypes)
1128 TypeIDValues[LLTy] = ID++;
1129 }
1130
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001131 LLTOperandMatcher(unsigned InsnVarID, unsigned OpIdx, const LLTCodeGen &Ty)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001132 : OperandPredicateMatcher(OPM_LLT, InsnVarID, OpIdx), Ty(Ty) {
Daniel Sanders032e7f22017-08-17 13:18:35 +00001133 KnownTypes.insert(Ty);
1134 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001135
Quentin Colombet063d7982017-12-14 23:44:07 +00001136 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001137 return P->getKind() == OPM_LLT;
1138 }
Quentin Colombet893e0f12017-12-15 23:24:39 +00001139 bool isIdentical(const PredicateMatcher &B) const override {
1140 return OperandPredicateMatcher::isIdentical(B) &&
1141 Ty == cast<LLTOperandMatcher>(&B)->Ty;
1142 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001143 MatchTableRecord getValue() const override {
1144 const auto VI = TypeIDValues.find(Ty);
1145 if (VI == TypeIDValues.end())
1146 return MatchTable::NamedValue(getTy().getCxxEnumValue());
1147 return MatchTable::NamedValue(getTy().getCxxEnumValue(), VI->second);
1148 }
1149 bool hasValue() const override {
1150 if (TypeIDValues.size() != KnownTypes.size())
1151 initTypeIDValuesMap();
1152 return TypeIDValues.count(Ty);
1153 }
1154
1155 LLTCodeGen getTy() const { return Ty; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001156
Quentin Colombetaad20be2017-12-15 23:07:42 +00001157 void emitPredicateOpcodes(MatchTable &Table,
1158 RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001159 Table << MatchTable::Opcode("GIM_CheckType") << MatchTable::Comment("MI")
1160 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
1161 << MatchTable::IntValue(OpIdx) << MatchTable::Comment("Type")
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001162 << getValue() << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001163 }
1164};
1165
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001166std::map<LLTCodeGen, unsigned> LLTOperandMatcher::TypeIDValues;
1167
Daniel Sandersa71f4542017-10-16 00:56:30 +00001168/// Generates code to check that an operand is a pointer to any address space.
1169///
1170/// In SelectionDAG, the types did not describe pointers or address spaces. As a
1171/// result, iN is used to describe a pointer of N bits to any address space and
1172/// PatFrag predicates are typically used to constrain the address space. There's
1173/// no reliable means to derive the missing type information from the pattern so
1174/// imported rules must test the components of a pointer separately.
1175///
Daniel Sandersea8711b2017-10-16 03:36:29 +00001176/// If SizeInBits is zero, then the pointer size will be obtained from the
1177/// subtarget.
Daniel Sandersa71f4542017-10-16 00:56:30 +00001178class PointerToAnyOperandMatcher : public OperandPredicateMatcher {
1179protected:
1180 unsigned SizeInBits;
1181
1182public:
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001183 PointerToAnyOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1184 unsigned SizeInBits)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001185 : OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx),
1186 SizeInBits(SizeInBits) {}
Daniel Sandersa71f4542017-10-16 00:56:30 +00001187
1188 static bool classof(const OperandPredicateMatcher *P) {
1189 return P->getKind() == OPM_PointerToAny;
1190 }
1191
Quentin Colombetaad20be2017-12-15 23:07:42 +00001192 void emitPredicateOpcodes(MatchTable &Table,
1193 RuleMatcher &Rule) const override {
1194 Table << MatchTable::Opcode("GIM_CheckPointerToAny")
1195 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1196 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1197 << MatchTable::Comment("SizeInBits")
Daniel Sandersa71f4542017-10-16 00:56:30 +00001198 << MatchTable::IntValue(SizeInBits) << MatchTable::LineBreak;
1199 }
1200};
1201
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001202/// Generates code to check that an operand is a particular target constant.
1203class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
1204protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001205 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001206 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001207
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001208 unsigned getAllocatedTemporariesBaseID() const;
1209
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001210public:
Quentin Colombet893e0f12017-12-15 23:24:39 +00001211 bool isIdentical(const PredicateMatcher &B) const override { return false; }
1212
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001213 ComplexPatternOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1214 const OperandMatcher &Operand,
1215 const Record &TheDef)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001216 : OperandPredicateMatcher(OPM_ComplexPattern, InsnVarID, OpIdx),
1217 Operand(Operand), TheDef(TheDef) {}
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001218
Quentin Colombet063d7982017-12-14 23:44:07 +00001219 static bool classof(const PredicateMatcher *P) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001220 return P->getKind() == OPM_ComplexPattern;
1221 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001222
Quentin Colombetaad20be2017-12-15 23:07:42 +00001223 void emitPredicateOpcodes(MatchTable &Table,
1224 RuleMatcher &Rule) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +00001225 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001226 Table << MatchTable::Opcode("GIM_CheckComplexPattern")
1227 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1228 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1229 << MatchTable::Comment("Renderer") << MatchTable::IntValue(ID)
1230 << MatchTable::NamedValue(("GICP_" + TheDef.getName()).str())
1231 << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001232 }
1233
Daniel Sanders2deea182017-04-22 15:11:04 +00001234 unsigned countRendererFns() const override {
1235 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001236 }
1237};
1238
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001239/// Generates code to check that an operand is in a particular register bank.
1240class RegisterBankOperandMatcher : public OperandPredicateMatcher {
1241protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001242 const CodeGenRegisterClass &RC;
1243
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001244public:
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001245 RegisterBankOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1246 const CodeGenRegisterClass &RC)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001247 : OperandPredicateMatcher(OPM_RegBank, InsnVarID, OpIdx), RC(RC) {}
Daniel Sanders759ff412017-02-24 13:58:11 +00001248
Quentin Colombet893e0f12017-12-15 23:24:39 +00001249 bool isIdentical(const PredicateMatcher &B) const override {
1250 return OperandPredicateMatcher::isIdentical(B) &&
1251 RC.getDef() == cast<RegisterBankOperandMatcher>(&B)->RC.getDef();
1252 }
1253
Quentin Colombet063d7982017-12-14 23:44:07 +00001254 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001255 return P->getKind() == OPM_RegBank;
1256 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001257
Quentin Colombetaad20be2017-12-15 23:07:42 +00001258 void emitPredicateOpcodes(MatchTable &Table,
1259 RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001260 Table << MatchTable::Opcode("GIM_CheckRegBankForClass")
1261 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1262 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1263 << MatchTable::Comment("RC")
1264 << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
1265 << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001266 }
1267};
1268
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001269/// Generates code to check that an operand is a basic block.
1270class MBBOperandMatcher : public OperandPredicateMatcher {
1271public:
Quentin Colombetaad20be2017-12-15 23:07:42 +00001272 MBBOperandMatcher(unsigned InsnVarID, unsigned OpIdx)
1273 : OperandPredicateMatcher(OPM_MBB, InsnVarID, OpIdx) {}
Daniel Sanders759ff412017-02-24 13:58:11 +00001274
Quentin Colombet063d7982017-12-14 23:44:07 +00001275 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001276 return P->getKind() == OPM_MBB;
1277 }
1278
Quentin Colombetaad20be2017-12-15 23:07:42 +00001279 void emitPredicateOpcodes(MatchTable &Table,
1280 RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001281 Table << MatchTable::Opcode("GIM_CheckIsMBB") << MatchTable::Comment("MI")
1282 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Op")
1283 << MatchTable::IntValue(OpIdx) << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001284 }
1285};
1286
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001287/// Generates code to check that an operand is a G_CONSTANT with a particular
1288/// int.
1289class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001290protected:
1291 int64_t Value;
1292
1293public:
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001294 ConstantIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001295 : OperandPredicateMatcher(OPM_Int, InsnVarID, OpIdx), Value(Value) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001296
Quentin Colombet893e0f12017-12-15 23:24:39 +00001297 bool isIdentical(const PredicateMatcher &B) const override {
1298 return OperandPredicateMatcher::isIdentical(B) &&
1299 Value == cast<ConstantIntOperandMatcher>(&B)->Value;
1300 }
1301
Quentin Colombet063d7982017-12-14 23:44:07 +00001302 static bool classof(const PredicateMatcher *P) {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001303 return P->getKind() == OPM_Int;
1304 }
1305
Quentin Colombetaad20be2017-12-15 23:07:42 +00001306 void emitPredicateOpcodes(MatchTable &Table,
1307 RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001308 Table << MatchTable::Opcode("GIM_CheckConstantInt")
1309 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1310 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1311 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001312 }
1313};
1314
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001315/// Generates code to check that an operand is a raw int (where MO.isImm() or
1316/// MO.isCImm() is true).
1317class LiteralIntOperandMatcher : public OperandPredicateMatcher {
1318protected:
1319 int64_t Value;
1320
1321public:
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001322 LiteralIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001323 : OperandPredicateMatcher(OPM_LiteralInt, InsnVarID, OpIdx),
1324 Value(Value) {}
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001325
Quentin Colombet893e0f12017-12-15 23:24:39 +00001326 bool isIdentical(const PredicateMatcher &B) const override {
1327 return OperandPredicateMatcher::isIdentical(B) &&
1328 Value == cast<LiteralIntOperandMatcher>(&B)->Value;
1329 }
1330
Quentin Colombet063d7982017-12-14 23:44:07 +00001331 static bool classof(const PredicateMatcher *P) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001332 return P->getKind() == OPM_LiteralInt;
1333 }
1334
Quentin Colombetaad20be2017-12-15 23:07:42 +00001335 void emitPredicateOpcodes(MatchTable &Table,
1336 RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001337 Table << MatchTable::Opcode("GIM_CheckLiteralInt")
1338 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1339 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1340 << MatchTable::IntValue(Value) << MatchTable::LineBreak;
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001341 }
1342};
1343
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001344/// Generates code to check that an operand is an intrinsic ID.
1345class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
1346protected:
1347 const CodeGenIntrinsic *II;
1348
1349public:
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001350 IntrinsicIDOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1351 const CodeGenIntrinsic *II)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001352 : OperandPredicateMatcher(OPM_IntrinsicID, InsnVarID, OpIdx), II(II) {}
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001353
Quentin Colombet893e0f12017-12-15 23:24:39 +00001354 bool isIdentical(const PredicateMatcher &B) const override {
1355 return OperandPredicateMatcher::isIdentical(B) &&
1356 II == cast<IntrinsicIDOperandMatcher>(&B)->II;
1357 }
1358
Quentin Colombet063d7982017-12-14 23:44:07 +00001359 static bool classof(const PredicateMatcher *P) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001360 return P->getKind() == OPM_IntrinsicID;
1361 }
1362
Quentin Colombetaad20be2017-12-15 23:07:42 +00001363 void emitPredicateOpcodes(MatchTable &Table,
1364 RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001365 Table << MatchTable::Opcode("GIM_CheckIntrinsicID")
1366 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1367 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
1368 << MatchTable::NamedValue("Intrinsic::" + II->EnumName)
1369 << MatchTable::LineBreak;
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00001370 }
1371};
1372
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001373/// Generates code to check that a set of predicates match for a particular
1374/// operand.
1375class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
1376protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001377 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001378 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001379 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001380
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001381 /// The index of the first temporary variable allocated to this operand. The
1382 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +00001383 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001384 unsigned AllocatedTemporariesBaseID;
1385
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001386public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001387 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001388 const std::string &SymbolicName,
1389 unsigned AllocatedTemporariesBaseID)
1390 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
1391 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001392
1393 bool hasSymbolicName() const { return !SymbolicName.empty(); }
1394 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001395 void setSymbolicName(StringRef Name) {
1396 assert(SymbolicName.empty() && "Operand already has a symbolic name");
1397 SymbolicName = Name;
1398 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001399
1400 /// Construct a new operand predicate and add it to the matcher.
1401 template <class Kind, class... Args>
1402 Optional<Kind *> addPredicate(Args &&... args) {
1403 if (isSameAsAnotherOperand())
1404 return None;
1405 Predicates.emplace_back(llvm::make_unique<Kind>(
1406 getInsnVarID(), getOpIdx(), std::forward<Args>(args)...));
1407 return static_cast<Kind *>(Predicates.back().get());
1408 }
1409
1410 unsigned getOpIdx() const { return OpIdx; }
Quentin Colombetaad20be2017-12-15 23:07:42 +00001411 unsigned getInsnVarID() const;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001412
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001413 std::string getOperandExpr(unsigned InsnVarID) const {
1414 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
1415 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +00001416 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001417
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001418 InstructionMatcher &getInstructionMatcher() const { return Insn; }
1419
Daniel Sandersa71f4542017-10-16 00:56:30 +00001420 Error addTypeCheckPredicate(const TypeSetByHwMode &VTy,
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001421 bool OperandIsAPointer);
Daniel Sandersa71f4542017-10-16 00:56:30 +00001422
Daniel Sanders9d662d22017-07-06 10:06:12 +00001423 /// Emit MatchTable opcodes that test whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001424 /// InsnVarID matches all the predicates and all the operands.
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001425 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule) {
1426 if (!Optimized) {
1427 std::string Comment;
1428 raw_string_ostream CommentOS(Comment);
1429 CommentOS << "MIs[" << getInsnVarID() << "] ";
1430 if (SymbolicName.empty())
1431 CommentOS << "Operand " << OpIdx;
1432 else
1433 CommentOS << SymbolicName;
1434 Table << MatchTable::Comment(CommentOS.str()) << MatchTable::LineBreak;
1435 }
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001436
Quentin Colombetaad20be2017-12-15 23:07:42 +00001437 emitPredicateListOpcodes(Table, Rule);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001438 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001439
1440 /// Compare the priority of this object and B.
1441 ///
1442 /// Returns true if this object is more important than B.
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001443 bool isHigherPriorityThan(OperandMatcher &B) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001444 // Operand matchers involving more predicates have higher priority.
1445 if (predicates_size() > B.predicates_size())
1446 return true;
1447 if (predicates_size() < B.predicates_size())
1448 return false;
1449
1450 // This assumes that predicates are added in a consistent order.
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001451 for (auto &&Predicate : zip(predicates(), B.predicates())) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001452 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
1453 return true;
1454 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
1455 return false;
1456 }
1457
1458 return false;
1459 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001460
1461 /// Report the maximum number of temporary operands needed by the operand
1462 /// matcher.
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001463 unsigned countRendererFns() {
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001464 return std::accumulate(
1465 predicates().begin(), predicates().end(), 0,
1466 [](unsigned A,
1467 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001468 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001469 });
1470 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001471
1472 unsigned getAllocatedTemporariesBaseID() const {
1473 return AllocatedTemporariesBaseID;
1474 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001475
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001476 bool isSameAsAnotherOperand() {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001477 for (const auto &Predicate : predicates())
1478 if (isa<SameOperandMatcher>(Predicate))
1479 return true;
1480 return false;
1481 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001482};
1483
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001484Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
Quentin Colombetaad20be2017-12-15 23:07:42 +00001485 bool OperandIsAPointer) {
Reid Klecknercfdd4a22017-10-16 20:31:16 +00001486 if (!VTy.isMachineValueType())
1487 return failedImport("unsupported typeset");
1488
1489 if (VTy.getMachineValueType() == MVT::iPTR && OperandIsAPointer) {
1490 addPredicate<PointerToAnyOperandMatcher>(0);
1491 return Error::success();
1492 }
1493
1494 auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
1495 if (!OpTyOrNone)
1496 return failedImport("unsupported type");
1497
1498 if (OperandIsAPointer)
1499 addPredicate<PointerToAnyOperandMatcher>(OpTyOrNone->get().getSizeInBits());
1500 else
1501 addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1502 return Error::success();
1503}
1504
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001505unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
1506 return Operand.getAllocatedTemporariesBaseID();
1507}
1508
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001509/// Generates code to check a predicate on an instruction.
1510///
1511/// Typical predicates include:
1512/// * The opcode of the instruction is a particular value.
1513/// * The nsw/nuw flag is/isn't set.
Quentin Colombet063d7982017-12-14 23:44:07 +00001514class InstructionPredicateMatcher : public PredicateMatcher {
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001515public:
Quentin Colombetaad20be2017-12-15 23:07:42 +00001516 InstructionPredicateMatcher(PredicateKind Kind, unsigned InsnVarID)
1517 : PredicateMatcher(Kind, InsnVarID) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001518 virtual ~InstructionPredicateMatcher() {}
1519
Daniel Sanders759ff412017-02-24 13:58:11 +00001520 /// Compare the priority of this object and B.
1521 ///
1522 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001523 virtual bool
1524 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +00001525 return Kind < B.Kind;
1526 };
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001527};
1528
Daniel Sanders2c269f62017-08-24 09:11:20 +00001529template <>
1530std::string
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001531PredicateListMatcher<PredicateMatcher>::getNoPredicateComment() const {
Daniel Sanders2c269f62017-08-24 09:11:20 +00001532 return "No instruction predicates";
1533}
1534
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001535/// Generates code to check the opcode of an instruction.
1536class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
1537protected:
1538 const CodeGenInstruction *I;
1539
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001540 static DenseMap<const CodeGenInstruction *, unsigned> OpcodeValues;
1541
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001542public:
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001543 static void initOpcodeValuesMap(const CodeGenTarget &Target) {
1544 OpcodeValues.clear();
1545
1546 unsigned OpcodeValue = 0;
1547 for (const CodeGenInstruction *I : Target.getInstructionsByEnumValue())
1548 OpcodeValues[I] = OpcodeValue++;
1549 }
1550
Quentin Colombetaad20be2017-12-15 23:07:42 +00001551 InstructionOpcodeMatcher(unsigned InsnVarID, const CodeGenInstruction *I)
1552 : InstructionPredicateMatcher(IPM_Opcode, InsnVarID), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001553
Quentin Colombet063d7982017-12-14 23:44:07 +00001554 static bool classof(const PredicateMatcher *P) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001555 return P->getKind() == IPM_Opcode;
1556 }
1557
Quentin Colombet893e0f12017-12-15 23:24:39 +00001558 bool isIdentical(const PredicateMatcher &B) const override {
1559 return InstructionPredicateMatcher::isIdentical(B) &&
1560 I == cast<InstructionOpcodeMatcher>(&B)->I;
1561 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001562 MatchTableRecord getValue() const override {
1563 const auto VI = OpcodeValues.find(I);
1564 if (VI != OpcodeValues.end())
1565 return MatchTable::NamedValue(I->Namespace, I->TheDef->getName(),
1566 VI->second);
1567 return MatchTable::NamedValue(I->Namespace, I->TheDef->getName());
1568 }
1569 bool hasValue() const override { return OpcodeValues.count(I); }
Quentin Colombet893e0f12017-12-15 23:24:39 +00001570
Quentin Colombetaad20be2017-12-15 23:07:42 +00001571 void emitPredicateOpcodes(MatchTable &Table,
1572 RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001573 Table << MatchTable::Opcode("GIM_CheckOpcode") << MatchTable::Comment("MI")
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001574 << MatchTable::IntValue(InsnVarID) << getValue()
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00001575 << MatchTable::LineBreak;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001576 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001577
1578 /// Compare the priority of this object and B.
1579 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001580 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +00001581 bool
1582 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +00001583 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
1584 return true;
1585 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
1586 return false;
1587
1588 // Prioritize opcodes for cosmetic reasons in the generated source. Although
1589 // this is cosmetic at the moment, we may want to drive a similar ordering
1590 // using instruction frequency information to improve compile time.
1591 if (const InstructionOpcodeMatcher *BO =
1592 dyn_cast<InstructionOpcodeMatcher>(&B))
1593 return I->TheDef->getName() < BO->I->TheDef->getName();
1594
1595 return false;
1596 };
Daniel Sanders05540042017-08-08 10:44:31 +00001597
1598 bool isConstantInstruction() const {
1599 return I->TheDef->getName() == "G_CONSTANT";
1600 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001601
Roman Tereshin19da6672018-05-22 04:31:50 +00001602 StringRef getOpcode() const { return I->TheDef->getName(); }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001603 unsigned getNumOperands() const { return I->Operands.size(); }
1604
1605 StringRef getOperandType(unsigned OpIdx) const {
1606 return I->Operands[OpIdx].OperandType;
1607 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001608};
1609
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001610DenseMap<const CodeGenInstruction *, unsigned>
1611 InstructionOpcodeMatcher::OpcodeValues;
1612
Roman Tereshin19da6672018-05-22 04:31:50 +00001613class InstructionNumOperandsMatcher final : public InstructionPredicateMatcher {
1614 unsigned NumOperands = 0;
1615
1616public:
1617 InstructionNumOperandsMatcher(unsigned InsnVarID, unsigned NumOperands)
1618 : InstructionPredicateMatcher(IPM_NumOperands, InsnVarID),
1619 NumOperands(NumOperands) {}
1620
1621 static bool classof(const PredicateMatcher *P) {
1622 return P->getKind() == IPM_NumOperands;
1623 }
1624
1625 bool isIdentical(const PredicateMatcher &B) const override {
1626 return InstructionPredicateMatcher::isIdentical(B) &&
1627 NumOperands == cast<InstructionNumOperandsMatcher>(&B)->NumOperands;
1628 }
1629
1630 void emitPredicateOpcodes(MatchTable &Table,
1631 RuleMatcher &Rule) const override {
1632 Table << MatchTable::Opcode("GIM_CheckNumOperands")
1633 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1634 << MatchTable::Comment("Expected")
1635 << MatchTable::IntValue(NumOperands) << MatchTable::LineBreak;
1636 }
1637};
1638
Daniel Sanders2c269f62017-08-24 09:11:20 +00001639/// Generates code to check that this instruction is a constant whose value
1640/// meets an immediate predicate.
1641///
1642/// Immediates are slightly odd since they are typically used like an operand
1643/// but are represented as an operator internally. We typically write simm8:$src
1644/// in a tablegen pattern, but this is just syntactic sugar for
1645/// (imm:i32)<<P:Predicate_simm8>>:$imm which more directly describes the nodes
1646/// that will be matched and the predicate (which is attached to the imm
1647/// operator) that will be tested. In SelectionDAG this describes a
1648/// ConstantSDNode whose internal value will be tested using the simm8 predicate.
1649///
1650/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In
1651/// this representation, the immediate could be tested with an
1652/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a
1653/// OperandPredicateMatcher-subclass to check the Value meets the predicate but
1654/// there are two implementation issues with producing that matcher
1655/// configuration from the SelectionDAG pattern:
1656/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that
1657/// were we to sink the immediate predicate to the operand we would have to
1658/// have two partial implementations of PatFrag support, one for immediates
1659/// and one for non-immediates.
1660/// * At the point we handle the predicate, the OperandMatcher hasn't been
1661/// created yet. If we were to sink the predicate to the OperandMatcher we
1662/// would also have to complicate (or duplicate) the code that descends and
1663/// creates matchers for the subtree.
1664/// Overall, it's simpler to handle it in the place it was found.
1665class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
1666protected:
1667 TreePredicateFn Predicate;
1668
1669public:
Quentin Colombetaad20be2017-12-15 23:07:42 +00001670 InstructionImmPredicateMatcher(unsigned InsnVarID,
1671 const TreePredicateFn &Predicate)
1672 : InstructionPredicateMatcher(IPM_ImmPredicate, InsnVarID),
1673 Predicate(Predicate) {}
Daniel Sanders2c269f62017-08-24 09:11:20 +00001674
Quentin Colombet893e0f12017-12-15 23:24:39 +00001675 bool isIdentical(const PredicateMatcher &B) const override {
1676 return InstructionPredicateMatcher::isIdentical(B) &&
1677 Predicate.getOrigPatFragRecord() ==
1678 cast<InstructionImmPredicateMatcher>(&B)
1679 ->Predicate.getOrigPatFragRecord();
1680 }
1681
Quentin Colombet063d7982017-12-14 23:44:07 +00001682 static bool classof(const PredicateMatcher *P) {
Daniel Sanders2c269f62017-08-24 09:11:20 +00001683 return P->getKind() == IPM_ImmPredicate;
1684 }
1685
Quentin Colombetaad20be2017-12-15 23:07:42 +00001686 void emitPredicateOpcodes(MatchTable &Table,
1687 RuleMatcher &Rule) const override {
Daniel Sanders11300ce2017-10-13 21:28:03 +00001688 Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001689 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1690 << MatchTable::Comment("Predicate")
Daniel Sanders11300ce2017-10-13 21:28:03 +00001691 << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
Daniel Sanders2c269f62017-08-24 09:11:20 +00001692 << MatchTable::LineBreak;
1693 }
1694};
1695
Daniel Sanders76664652017-11-28 22:07:05 +00001696/// Generates code to check that a memory instruction has a atomic ordering
1697/// MachineMemoryOperand.
1698class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001699public:
1700 enum AOComparator {
1701 AO_Exactly,
1702 AO_OrStronger,
1703 AO_WeakerThan,
1704 };
1705
1706protected:
Daniel Sanders76664652017-11-28 22:07:05 +00001707 StringRef Order;
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001708 AOComparator Comparator;
Daniel Sanders76664652017-11-28 22:07:05 +00001709
Daniel Sanders39690bd2017-10-15 02:41:12 +00001710public:
Quentin Colombetaad20be2017-12-15 23:07:42 +00001711 AtomicOrderingMMOPredicateMatcher(unsigned InsnVarID, StringRef Order,
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001712 AOComparator Comparator = AO_Exactly)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001713 : InstructionPredicateMatcher(IPM_AtomicOrderingMMO, InsnVarID),
1714 Order(Order), Comparator(Comparator) {}
Daniel Sanders39690bd2017-10-15 02:41:12 +00001715
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001716 static bool classof(const PredicateMatcher *P) {
Daniel Sanders76664652017-11-28 22:07:05 +00001717 return P->getKind() == IPM_AtomicOrderingMMO;
Daniel Sanders39690bd2017-10-15 02:41:12 +00001718 }
1719
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001720 bool isIdentical(const PredicateMatcher &B) const override {
1721 if (!InstructionPredicateMatcher::isIdentical(B))
1722 return false;
1723 const auto &R = *cast<AtomicOrderingMMOPredicateMatcher>(&B);
1724 return Order == R.Order && Comparator == R.Comparator;
1725 }
1726
Quentin Colombetaad20be2017-12-15 23:07:42 +00001727 void emitPredicateOpcodes(MatchTable &Table,
1728 RuleMatcher &Rule) const override {
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00001729 StringRef Opcode = "GIM_CheckAtomicOrdering";
1730
1731 if (Comparator == AO_OrStronger)
1732 Opcode = "GIM_CheckAtomicOrderingOrStrongerThan";
1733 if (Comparator == AO_WeakerThan)
1734 Opcode = "GIM_CheckAtomicOrderingWeakerThan";
1735
1736 Table << MatchTable::Opcode(Opcode) << MatchTable::Comment("MI")
1737 << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Order")
Daniel Sanders76664652017-11-28 22:07:05 +00001738 << MatchTable::NamedValue(("(int64_t)AtomicOrdering::" + Order).str())
Daniel Sanders39690bd2017-10-15 02:41:12 +00001739 << MatchTable::LineBreak;
1740 }
1741};
1742
Daniel Sandersf84bc372018-05-05 20:53:24 +00001743/// Generates code to check that the size of an MMO is exactly N bytes.
1744class MemorySizePredicateMatcher : public InstructionPredicateMatcher {
1745protected:
1746 unsigned MMOIdx;
1747 uint64_t Size;
1748
1749public:
1750 MemorySizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx, unsigned Size)
1751 : InstructionPredicateMatcher(IPM_MemoryLLTSize, InsnVarID),
1752 MMOIdx(MMOIdx), Size(Size) {}
1753
1754 static bool classof(const PredicateMatcher *P) {
1755 return P->getKind() == IPM_MemoryLLTSize;
1756 }
1757 bool isIdentical(const PredicateMatcher &B) const override {
1758 return InstructionPredicateMatcher::isIdentical(B) &&
1759 MMOIdx == cast<MemorySizePredicateMatcher>(&B)->MMOIdx &&
1760 Size == cast<MemorySizePredicateMatcher>(&B)->Size;
1761 }
1762
1763 void emitPredicateOpcodes(MatchTable &Table,
1764 RuleMatcher &Rule) const override {
1765 Table << MatchTable::Opcode("GIM_CheckMemorySizeEqualTo")
1766 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1767 << MatchTable::Comment("MMO") << MatchTable::IntValue(MMOIdx)
1768 << MatchTable::Comment("Size") << MatchTable::IntValue(Size)
1769 << MatchTable::LineBreak;
1770 }
1771};
1772
1773/// Generates code to check that the size of an MMO is less-than, equal-to, or
1774/// greater than a given LLT.
1775class MemoryVsLLTSizePredicateMatcher : public InstructionPredicateMatcher {
1776public:
1777 enum RelationKind {
1778 GreaterThan,
1779 EqualTo,
1780 LessThan,
1781 };
1782
1783protected:
1784 unsigned MMOIdx;
1785 RelationKind Relation;
1786 unsigned OpIdx;
1787
1788public:
1789 MemoryVsLLTSizePredicateMatcher(unsigned InsnVarID, unsigned MMOIdx,
1790 enum RelationKind Relation,
1791 unsigned OpIdx)
1792 : InstructionPredicateMatcher(IPM_MemoryVsLLTSize, InsnVarID),
1793 MMOIdx(MMOIdx), Relation(Relation), OpIdx(OpIdx) {}
1794
1795 static bool classof(const PredicateMatcher *P) {
1796 return P->getKind() == IPM_MemoryVsLLTSize;
1797 }
1798 bool isIdentical(const PredicateMatcher &B) const override {
1799 return InstructionPredicateMatcher::isIdentical(B) &&
1800 MMOIdx == cast<MemoryVsLLTSizePredicateMatcher>(&B)->MMOIdx &&
1801 Relation == cast<MemoryVsLLTSizePredicateMatcher>(&B)->Relation &&
1802 OpIdx == cast<MemoryVsLLTSizePredicateMatcher>(&B)->OpIdx;
1803 }
1804
1805 void emitPredicateOpcodes(MatchTable &Table,
1806 RuleMatcher &Rule) const override {
1807 Table << MatchTable::Opcode(Relation == EqualTo
1808 ? "GIM_CheckMemorySizeEqualToLLT"
1809 : Relation == GreaterThan
1810 ? "GIM_CheckMemorySizeGreaterThanLLT"
1811 : "GIM_CheckMemorySizeLessThanLLT")
1812 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
1813 << MatchTable::Comment("MMO") << MatchTable::IntValue(MMOIdx)
1814 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
1815 << MatchTable::LineBreak;
1816 }
1817};
1818
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001819/// Generates code to check that a set of predicates and operands match for a
1820/// particular instruction.
1821///
1822/// Typical predicates include:
1823/// * Has a specific opcode.
1824/// * Has an nsw/nuw flag or doesn't.
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001825class InstructionMatcher final : public PredicateListMatcher<PredicateMatcher> {
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001826protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001827 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001828
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001829 RuleMatcher &Rule;
1830
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001831 /// The operands to match. All rendered operands must be present even if the
1832 /// condition is always true.
1833 OperandVec Operands;
Roman Tereshin19da6672018-05-22 04:31:50 +00001834 bool NumOperandsCheck = true;
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001835
Daniel Sanders05540042017-08-08 10:44:31 +00001836 std::string SymbolicName;
Quentin Colombetaad20be2017-12-15 23:07:42 +00001837 unsigned InsnVarID;
Daniel Sanders05540042017-08-08 10:44:31 +00001838
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001839public:
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001840 InstructionMatcher(RuleMatcher &Rule, StringRef SymbolicName)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001841 : Rule(Rule), SymbolicName(SymbolicName) {
1842 // We create a new instruction matcher.
1843 // Get a new ID for that instruction.
1844 InsnVarID = Rule.implicitlyDefineInsnVar(*this);
1845 }
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001846
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001847 /// Construct a new instruction predicate and add it to the matcher.
1848 template <class Kind, class... Args>
1849 Optional<Kind *> addPredicate(Args &&... args) {
1850 Predicates.emplace_back(
1851 llvm::make_unique<Kind>(getInsnVarID(), std::forward<Args>(args)...));
1852 return static_cast<Kind *>(Predicates.back().get());
1853 }
1854
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001855 RuleMatcher &getRuleMatcher() const { return Rule; }
Daniel Sanders05540042017-08-08 10:44:31 +00001856
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001857 unsigned getInsnVarID() const { return InsnVarID; }
Quentin Colombetaad20be2017-12-15 23:07:42 +00001858
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001859 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001860 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
1861 unsigned AllocatedTemporariesBaseID) {
1862 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
1863 AllocatedTemporariesBaseID));
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001864 if (!SymbolicName.empty())
1865 Rule.defineOperand(SymbolicName, *Operands.back());
1866
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001867 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001868 }
1869
Daniel Sandersffc7d582017-03-29 15:37:18 +00001870 OperandMatcher &getOperand(unsigned OpIdx) {
1871 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001872 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001873 return X->getOpIdx() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001874 });
1875 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001876 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001877 llvm_unreachable("Failed to lookup operand");
1878 }
1879
Daniel Sanders05540042017-08-08 10:44:31 +00001880 StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001881 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +00001882 OperandVec::iterator operands_begin() { return Operands.begin(); }
1883 OperandVec::iterator operands_end() { return Operands.end(); }
1884 iterator_range<OperandVec::iterator> operands() {
1885 return make_range(operands_begin(), operands_end());
1886 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001887 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
1888 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001889 iterator_range<OperandVec::const_iterator> operands() const {
1890 return make_range(operands_begin(), operands_end());
1891 }
Quentin Colombetec76d9c2017-12-18 19:47:41 +00001892 bool operands_empty() const { return Operands.empty(); }
1893
1894 void pop_front() { Operands.erase(Operands.begin()); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001895
Roman Tereshin19da6672018-05-22 04:31:50 +00001896 void optimize();
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001897
1898 /// Emit MatchTable opcodes that test whether the instruction named in
1899 /// InsnVarName matches all the predicates and all the operands.
1900 void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule) {
Roman Tereshin19da6672018-05-22 04:31:50 +00001901 if (NumOperandsCheck)
1902 InstructionNumOperandsMatcher(InsnVarID, getNumOperands())
1903 .emitPredicateOpcodes(Table, Rule);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001904
Quentin Colombetaad20be2017-12-15 23:07:42 +00001905 emitPredicateListOpcodes(Table, Rule);
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001906
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001907 for (const auto &Operand : Operands)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001908 Operand->emitPredicateOpcodes(Table, Rule);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001909 }
Daniel Sanders759ff412017-02-24 13:58:11 +00001910
1911 /// Compare the priority of this object and B.
1912 ///
1913 /// Returns true if this object is more important than B.
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001914 bool isHigherPriorityThan(InstructionMatcher &B) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001915 // Instruction matchers involving more operands have higher priority.
1916 if (Operands.size() > B.Operands.size())
1917 return true;
1918 if (Operands.size() < B.Operands.size())
1919 return false;
1920
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001921 for (auto &&P : zip(predicates(), B.predicates())) {
1922 auto L = static_cast<InstructionPredicateMatcher *>(std::get<0>(P).get());
1923 auto R = static_cast<InstructionPredicateMatcher *>(std::get<1>(P).get());
1924 if (L->isHigherPriorityThan(*R))
Daniel Sanders759ff412017-02-24 13:58:11 +00001925 return true;
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001926 if (R->isHigherPriorityThan(*L))
Daniel Sanders759ff412017-02-24 13:58:11 +00001927 return false;
1928 }
1929
1930 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001931 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001932 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001933 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +00001934 return false;
1935 }
1936
1937 return false;
1938 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001939
1940 /// Report the maximum number of temporary operands needed by the instruction
1941 /// matcher.
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001942 unsigned countRendererFns() {
1943 return std::accumulate(
1944 predicates().begin(), predicates().end(), 0,
1945 [](unsigned A,
1946 const std::unique_ptr<PredicateMatcher> &Predicate) {
1947 return A + Predicate->countRendererFns();
1948 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001949 std::accumulate(
1950 Operands.begin(), Operands.end(), 0,
1951 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001952 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001953 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001954 }
Daniel Sanders05540042017-08-08 10:44:31 +00001955
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001956 InstructionOpcodeMatcher &getOpcodeMatcher() {
1957 for (auto &P : predicates())
1958 if (auto *OpMatcher = dyn_cast<InstructionOpcodeMatcher>(P.get()))
1959 return *OpMatcher;
1960 llvm_unreachable("Didn't find an opcode matcher");
1961 }
1962
1963 bool isConstantInstruction() {
1964 return getOpcodeMatcher().isConstantInstruction();
Daniel Sanders05540042017-08-08 10:44:31 +00001965 }
Roman Tereshin19da6672018-05-22 04:31:50 +00001966
1967 StringRef getOpcode() { return getOpcodeMatcher().getOpcode(); }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001968};
1969
Roman Tereshin19da6672018-05-22 04:31:50 +00001970StringRef RuleMatcher::getOpcode() const {
1971 return Matchers.front()->getOpcode();
1972}
1973
Roman Tereshinf1aa3482018-05-21 23:28:51 +00001974unsigned RuleMatcher::getNumOperands() const {
1975 return Matchers.front()->getNumOperands();
1976}
1977
Daniel Sandersbee57392017-04-04 13:25:23 +00001978/// Generates code to check that the operand is a register defined by an
1979/// instruction that matches the given instruction matcher.
1980///
1981/// For example, the pattern:
1982/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
1983/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
1984/// the:
1985/// (G_ADD $src1, $src2)
1986/// subpattern.
1987class InstructionOperandMatcher : public OperandPredicateMatcher {
1988protected:
1989 std::unique_ptr<InstructionMatcher> InsnMatcher;
1990
1991public:
Quentin Colombeteba10cb2017-12-18 22:12:13 +00001992 InstructionOperandMatcher(unsigned InsnVarID, unsigned OpIdx,
1993 RuleMatcher &Rule, StringRef SymbolicName)
Quentin Colombetaad20be2017-12-15 23:07:42 +00001994 : OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx),
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00001995 InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {}
Daniel Sandersbee57392017-04-04 13:25:23 +00001996
Quentin Colombet063d7982017-12-14 23:44:07 +00001997 static bool classof(const PredicateMatcher *P) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001998 return P->getKind() == OPM_Instruction;
1999 }
2000
2001 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
2002
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002003 void emitCaptureOpcodes(MatchTable &Table, RuleMatcher &Rule) const {
2004 const unsigned NewInsnVarID = InsnMatcher->getInsnVarID();
2005 Table << MatchTable::Opcode("GIM_RecordInsn")
2006 << MatchTable::Comment("DefineMI")
2007 << MatchTable::IntValue(NewInsnVarID) << MatchTable::Comment("MI")
2008 << MatchTable::IntValue(getInsnVarID())
2009 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(getOpIdx())
2010 << MatchTable::Comment("MIs[" + llvm::to_string(NewInsnVarID) + "]")
2011 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00002012 }
2013
Quentin Colombetaad20be2017-12-15 23:07:42 +00002014 void emitPredicateOpcodes(MatchTable &Table,
2015 RuleMatcher &Rule) const override {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002016 emitCaptureOpcodes(Table, Rule);
Quentin Colombetaad20be2017-12-15 23:07:42 +00002017 InsnMatcher->emitPredicateOpcodes(Table, Rule);
Daniel Sandersbee57392017-04-04 13:25:23 +00002018 }
Daniel Sanders12e6e702018-01-17 20:34:29 +00002019
2020 bool isHigherPriorityThan(const OperandPredicateMatcher &B) const override {
2021 if (OperandPredicateMatcher::isHigherPriorityThan(B))
2022 return true;
2023 if (B.OperandPredicateMatcher::isHigherPriorityThan(*this))
2024 return false;
2025
2026 if (const InstructionOperandMatcher *BP =
2027 dyn_cast<InstructionOperandMatcher>(&B))
2028 if (InsnMatcher->isHigherPriorityThan(*BP->InsnMatcher))
2029 return true;
2030 return false;
2031 }
Daniel Sandersbee57392017-04-04 13:25:23 +00002032};
2033
Roman Tereshin19da6672018-05-22 04:31:50 +00002034void InstructionMatcher::optimize() {
2035 SmallVector<std::unique_ptr<PredicateMatcher>, 8> Stash;
2036 const auto &OpcMatcher = getOpcodeMatcher();
2037
2038 Stash.push_back(predicates_pop_front());
2039 if (Stash.back().get() == &OpcMatcher) {
2040 if (NumOperandsCheck && OpcMatcher.getNumOperands() < getNumOperands())
2041 Stash.emplace_back(
2042 new InstructionNumOperandsMatcher(InsnVarID, getNumOperands()));
2043 NumOperandsCheck = false;
Roman Tereshinfedae332018-05-23 02:04:19 +00002044
2045 for (auto &OM : Operands)
2046 for (auto &OP : OM->predicates())
2047 if (isa<IntrinsicIDOperandMatcher>(OP)) {
2048 Stash.push_back(std::move(OP));
2049 OM->eraseNullPredicates();
2050 break;
2051 }
Roman Tereshin19da6672018-05-22 04:31:50 +00002052 }
2053
2054 if (InsnVarID > 0) {
2055 assert(!Operands.empty() && "Nested instruction is expected to def a vreg");
2056 for (auto &OP : Operands[0]->predicates())
2057 OP.reset();
2058 Operands[0]->eraseNullPredicates();
2059 }
2060 while (!Stash.empty())
2061 prependPredicate(Stash.pop_back_val());
2062}
2063
Daniel Sanders43c882c2017-02-01 10:53:10 +00002064//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002065class OperandRenderer {
2066public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002067 enum RendererKind {
2068 OR_Copy,
Daniel Sandersd66e0902017-10-23 18:19:24 +00002069 OR_CopyOrAddZeroReg,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002070 OR_CopySubReg,
Daniel Sanders05540042017-08-08 10:44:31 +00002071 OR_CopyConstantAsImm,
Daniel Sanders11300ce2017-10-13 21:28:03 +00002072 OR_CopyFConstantAsFPImm,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002073 OR_Imm,
2074 OR_Register,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002075 OR_TempRegister,
Volkan Kelesf7f25682018-01-16 18:44:05 +00002076 OR_ComplexPattern,
2077 OR_Custom
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002078 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002079
2080protected:
2081 RendererKind Kind;
2082
2083public:
2084 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
2085 virtual ~OperandRenderer() {}
2086
2087 RendererKind getKind() const { return Kind; }
2088
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002089 virtual void emitRenderOpcodes(MatchTable &Table,
2090 RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002091};
2092
2093/// A CopyRenderer emits code to copy a single operand from an existing
2094/// instruction to the one being built.
2095class CopyRenderer : public OperandRenderer {
2096protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002097 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002098 /// The name of the operand.
2099 const StringRef SymbolicName;
2100
2101public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002102 CopyRenderer(unsigned NewInsnID, StringRef SymbolicName)
2103 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID),
Daniel Sanders05540042017-08-08 10:44:31 +00002104 SymbolicName(SymbolicName) {
2105 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
2106 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002107
2108 static bool classof(const OperandRenderer *R) {
2109 return R->getKind() == OR_Copy;
2110 }
2111
2112 const StringRef getSymbolicName() const { return SymbolicName; }
2113
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002114 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002115 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002116 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002117 Table << MatchTable::Opcode("GIR_Copy") << MatchTable::Comment("NewInsnID")
2118 << MatchTable::IntValue(NewInsnID) << MatchTable::Comment("OldInsnID")
2119 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002120 << MatchTable::IntValue(Operand.getOpIdx())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002121 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002122 }
2123};
2124
Daniel Sandersd66e0902017-10-23 18:19:24 +00002125/// A CopyOrAddZeroRegRenderer emits code to copy a single operand from an
2126/// existing instruction to the one being built. If the operand turns out to be
2127/// a 'G_CONSTANT 0' then it replaces the operand with a zero register.
2128class CopyOrAddZeroRegRenderer : public OperandRenderer {
2129protected:
2130 unsigned NewInsnID;
2131 /// The name of the operand.
2132 const StringRef SymbolicName;
2133 const Record *ZeroRegisterDef;
2134
2135public:
2136 CopyOrAddZeroRegRenderer(unsigned NewInsnID,
Daniel Sandersd66e0902017-10-23 18:19:24 +00002137 StringRef SymbolicName, Record *ZeroRegisterDef)
2138 : OperandRenderer(OR_CopyOrAddZeroReg), NewInsnID(NewInsnID),
2139 SymbolicName(SymbolicName), ZeroRegisterDef(ZeroRegisterDef) {
2140 assert(!SymbolicName.empty() && "Cannot copy from an unspecified source");
2141 }
2142
2143 static bool classof(const OperandRenderer *R) {
2144 return R->getKind() == OR_CopyOrAddZeroReg;
2145 }
2146
2147 const StringRef getSymbolicName() const { return SymbolicName; }
2148
2149 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2150 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
2151 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
2152 Table << MatchTable::Opcode("GIR_CopyOrAddZeroReg")
2153 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
2154 << MatchTable::Comment("OldInsnID")
2155 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002156 << MatchTable::IntValue(Operand.getOpIdx())
Daniel Sandersd66e0902017-10-23 18:19:24 +00002157 << MatchTable::NamedValue(
2158 (ZeroRegisterDef->getValue("Namespace")
2159 ? ZeroRegisterDef->getValueAsString("Namespace")
2160 : ""),
2161 ZeroRegisterDef->getName())
2162 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
2163 }
2164};
2165
Daniel Sanders05540042017-08-08 10:44:31 +00002166/// A CopyConstantAsImmRenderer emits code to render a G_CONSTANT instruction to
2167/// an extended immediate operand.
2168class CopyConstantAsImmRenderer : public OperandRenderer {
2169protected:
2170 unsigned NewInsnID;
2171 /// The name of the operand.
2172 const std::string SymbolicName;
2173 bool Signed;
2174
2175public:
2176 CopyConstantAsImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
2177 : OperandRenderer(OR_CopyConstantAsImm), NewInsnID(NewInsnID),
2178 SymbolicName(SymbolicName), Signed(true) {}
2179
2180 static bool classof(const OperandRenderer *R) {
2181 return R->getKind() == OR_CopyConstantAsImm;
2182 }
2183
2184 const StringRef getSymbolicName() const { return SymbolicName; }
2185
2186 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002187 InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
Daniel Sanders05540042017-08-08 10:44:31 +00002188 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
2189 Table << MatchTable::Opcode(Signed ? "GIR_CopyConstantAsSImm"
2190 : "GIR_CopyConstantAsUImm")
2191 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
2192 << MatchTable::Comment("OldInsnID")
2193 << MatchTable::IntValue(OldInsnVarID)
2194 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
2195 }
2196};
2197
Daniel Sanders11300ce2017-10-13 21:28:03 +00002198/// A CopyFConstantAsFPImmRenderer emits code to render a G_FCONSTANT
2199/// instruction to an extended immediate operand.
2200class CopyFConstantAsFPImmRenderer : public OperandRenderer {
2201protected:
2202 unsigned NewInsnID;
2203 /// The name of the operand.
2204 const std::string SymbolicName;
2205
2206public:
2207 CopyFConstantAsFPImmRenderer(unsigned NewInsnID, StringRef SymbolicName)
2208 : OperandRenderer(OR_CopyFConstantAsFPImm), NewInsnID(NewInsnID),
2209 SymbolicName(SymbolicName) {}
2210
2211 static bool classof(const OperandRenderer *R) {
2212 return R->getKind() == OR_CopyFConstantAsFPImm;
2213 }
2214
2215 const StringRef getSymbolicName() const { return SymbolicName; }
2216
2217 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002218 InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
Daniel Sanders11300ce2017-10-13 21:28:03 +00002219 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
2220 Table << MatchTable::Opcode("GIR_CopyFConstantAsFPImm")
2221 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
2222 << MatchTable::Comment("OldInsnID")
2223 << MatchTable::IntValue(OldInsnVarID)
2224 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
2225 }
2226};
2227
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002228/// A CopySubRegRenderer emits code to copy a single register operand from an
2229/// existing instruction to the one being built and indicate that only a
2230/// subregister should be copied.
2231class CopySubRegRenderer : public OperandRenderer {
2232protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002233 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002234 /// The name of the operand.
2235 const StringRef SymbolicName;
2236 /// The subregister to extract.
2237 const CodeGenSubRegIndex *SubReg;
2238
2239public:
Daniel Sandersbd83ad42017-10-24 01:48:34 +00002240 CopySubRegRenderer(unsigned NewInsnID, StringRef SymbolicName,
2241 const CodeGenSubRegIndex *SubReg)
2242 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002243 SymbolicName(SymbolicName), SubReg(SubReg) {}
2244
2245 static bool classof(const OperandRenderer *R) {
2246 return R->getKind() == OR_CopySubReg;
2247 }
2248
2249 const StringRef getSymbolicName() const { return SymbolicName; }
2250
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002251 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002252 const OperandMatcher &Operand = Rule.getOperandMatcher(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002253 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002254 Table << MatchTable::Opcode("GIR_CopySubReg")
2255 << MatchTable::Comment("NewInsnID") << MatchTable::IntValue(NewInsnID)
2256 << MatchTable::Comment("OldInsnID")
2257 << MatchTable::IntValue(OldInsnVarID) << MatchTable::Comment("OpIdx")
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002258 << MatchTable::IntValue(Operand.getOpIdx())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002259 << MatchTable::Comment("SubRegIdx")
2260 << MatchTable::IntValue(SubReg->EnumValue)
2261 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002262 }
2263};
2264
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002265/// Adds a specific physical register to the instruction being built.
2266/// This is typically useful for WZR/XZR on AArch64.
2267class AddRegisterRenderer : public OperandRenderer {
2268protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002269 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002270 const Record *RegisterDef;
2271
2272public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002273 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
2274 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
2275 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002276
2277 static bool classof(const OperandRenderer *R) {
2278 return R->getKind() == OR_Register;
2279 }
2280
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002281 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2282 Table << MatchTable::Opcode("GIR_AddRegister")
2283 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2284 << MatchTable::NamedValue(
2285 (RegisterDef->getValue("Namespace")
2286 ? RegisterDef->getValueAsString("Namespace")
2287 : ""),
2288 RegisterDef->getName())
2289 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002290 }
2291};
2292
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002293/// Adds a specific temporary virtual register to the instruction being built.
2294/// This is used to chain instructions together when emitting multiple
2295/// instructions.
2296class TempRegRenderer : public OperandRenderer {
2297protected:
2298 unsigned InsnID;
2299 unsigned TempRegID;
2300 bool IsDef;
2301
2302public:
2303 TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false)
2304 : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
2305 IsDef(IsDef) {}
2306
2307 static bool classof(const OperandRenderer *R) {
2308 return R->getKind() == OR_TempRegister;
2309 }
2310
2311 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2312 Table << MatchTable::Opcode("GIR_AddTempRegister")
2313 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2314 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
2315 << MatchTable::Comment("TempRegFlags");
2316 if (IsDef)
2317 Table << MatchTable::NamedValue("RegState::Define");
2318 else
2319 Table << MatchTable::IntValue(0);
2320 Table << MatchTable::LineBreak;
2321 }
2322};
2323
Daniel Sanders0ed28822017-04-12 08:23:08 +00002324/// Adds a specific immediate to the instruction being built.
2325class ImmRenderer : public OperandRenderer {
2326protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002327 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002328 int64_t Imm;
2329
2330public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002331 ImmRenderer(unsigned InsnID, int64_t Imm)
2332 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00002333
2334 static bool classof(const OperandRenderer *R) {
2335 return R->getKind() == OR_Imm;
2336 }
2337
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002338 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2339 Table << MatchTable::Opcode("GIR_AddImm") << MatchTable::Comment("InsnID")
2340 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Imm")
2341 << MatchTable::IntValue(Imm) << MatchTable::LineBreak;
Daniel Sanders0ed28822017-04-12 08:23:08 +00002342 }
2343};
2344
Daniel Sanders2deea182017-04-22 15:11:04 +00002345/// Adds operands by calling a renderer function supplied by the ComplexPattern
2346/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002347class RenderComplexPatternOperand : public OperandRenderer {
2348private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002349 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002350 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00002351 /// The name of the operand.
2352 const StringRef SymbolicName;
2353 /// The renderer number. This must be unique within a rule since it's used to
2354 /// identify a temporary variable to hold the renderer function.
2355 unsigned RendererID;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002356 /// When provided, this is the suboperand of the ComplexPattern operand to
2357 /// render. Otherwise all the suboperands will be rendered.
2358 Optional<unsigned> SubOperand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002359
2360 unsigned getNumOperands() const {
2361 return TheDef.getValueAsDag("Operands")->getNumArgs();
2362 }
2363
2364public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002365 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002366 StringRef SymbolicName, unsigned RendererID,
2367 Optional<unsigned> SubOperand = None)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002368 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002369 SymbolicName(SymbolicName), RendererID(RendererID),
2370 SubOperand(SubOperand) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002371
2372 static bool classof(const OperandRenderer *R) {
2373 return R->getKind() == OR_ComplexPattern;
2374 }
2375
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002376 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002377 Table << MatchTable::Opcode(SubOperand.hasValue() ? "GIR_ComplexSubOperandRenderer"
2378 : "GIR_ComplexRenderer")
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002379 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2380 << MatchTable::Comment("RendererID")
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002381 << MatchTable::IntValue(RendererID);
2382 if (SubOperand.hasValue())
2383 Table << MatchTable::Comment("SubOperand")
2384 << MatchTable::IntValue(SubOperand.getValue());
2385 Table << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002386 }
2387};
2388
Volkan Kelesf7f25682018-01-16 18:44:05 +00002389class CustomRenderer : public OperandRenderer {
2390protected:
2391 unsigned InsnID;
2392 const Record &Renderer;
2393 /// The name of the operand.
2394 const std::string SymbolicName;
2395
2396public:
2397 CustomRenderer(unsigned InsnID, const Record &Renderer,
2398 StringRef SymbolicName)
2399 : OperandRenderer(OR_Custom), InsnID(InsnID), Renderer(Renderer),
2400 SymbolicName(SymbolicName) {}
2401
2402 static bool classof(const OperandRenderer *R) {
2403 return R->getKind() == OR_Custom;
2404 }
2405
2406 void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002407 InstructionMatcher &InsnMatcher = Rule.getInstructionMatcher(SymbolicName);
Volkan Kelesf7f25682018-01-16 18:44:05 +00002408 unsigned OldInsnVarID = Rule.getInsnVarID(InsnMatcher);
2409 Table << MatchTable::Opcode("GIR_CustomRenderer")
2410 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2411 << MatchTable::Comment("OldInsnID")
2412 << MatchTable::IntValue(OldInsnVarID)
2413 << MatchTable::Comment("Renderer")
2414 << MatchTable::NamedValue(
2415 "GICR_" + Renderer.getValueAsString("RendererFn").str())
2416 << MatchTable::Comment(SymbolicName) << MatchTable::LineBreak;
2417 }
2418};
2419
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00002420/// An action taken when all Matcher predicates succeeded for a parent rule.
2421///
2422/// Typical actions include:
2423/// * Changing the opcode of an instruction.
2424/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00002425class MatchAction {
2426public:
2427 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002428
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002429 /// Emit the MatchTable opcodes to implement the action.
Daniel Sandersa7b75262017-10-31 18:50:24 +00002430 virtual void emitActionOpcodes(MatchTable &Table,
2431 RuleMatcher &Rule) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00002432};
2433
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00002434/// Generates a comment describing the matched rule being acted upon.
2435class DebugCommentAction : public MatchAction {
2436private:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00002437 std::string S;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00002438
2439public:
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00002440 DebugCommentAction(StringRef S) : S(S) {}
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00002441
Daniel Sandersa7b75262017-10-31 18:50:24 +00002442 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00002443 Table << MatchTable::Comment(S) << MatchTable::LineBreak;
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00002444 }
2445};
2446
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002447/// Generates code to build an instruction or mutate an existing instruction
2448/// into the desired instruction when this is possible.
2449class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00002450private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002451 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002452 const CodeGenInstruction *I;
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002453 InstructionMatcher *Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002454 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
2455
2456 /// True if the instruction can be built solely by mutating the opcode.
Daniel Sandersa7b75262017-10-31 18:50:24 +00002457 bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const {
2458 if (!Insn)
Daniel Sandersab1d1192017-10-24 18:11:54 +00002459 return false;
2460
Daniel Sandersa7b75262017-10-31 18:50:24 +00002461 if (OperandRenderers.size() != Insn->getNumOperands())
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002462 return false;
2463
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002464 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00002465 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002466 const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName());
Daniel Sandersa7b75262017-10-31 18:50:24 +00002467 if (Insn != &OM.getInstructionMatcher() ||
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002468 OM.getOpIdx() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002469 return false;
2470 } else
2471 return false;
2472 }
2473
2474 return true;
2475 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002476
Daniel Sanders43c882c2017-02-01 10:53:10 +00002477public:
Daniel Sandersa7b75262017-10-31 18:50:24 +00002478 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I)
2479 : InsnID(InsnID), I(I), Matched(nullptr) {}
2480
Daniel Sanders08464522018-01-29 21:09:12 +00002481 unsigned getInsnID() const { return InsnID; }
Daniel Sandersdf258e32017-10-31 19:09:29 +00002482 const CodeGenInstruction *getCGI() const { return I; }
2483
Daniel Sandersa7b75262017-10-31 18:50:24 +00002484 void chooseInsnToMutate(RuleMatcher &Rule) {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002485 for (auto *MutateCandidate : Rule.mutatable_insns()) {
Daniel Sandersa7b75262017-10-31 18:50:24 +00002486 if (canMutate(Rule, MutateCandidate)) {
2487 // Take the first one we're offered that we're able to mutate.
2488 Rule.reserveInsnMatcherForMutation(MutateCandidate);
2489 Matched = MutateCandidate;
2490 return;
2491 }
2492 }
2493 }
Daniel Sanders43c882c2017-02-01 10:53:10 +00002494
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002495 template <class Kind, class... Args>
2496 Kind &addRenderer(Args&&... args) {
2497 OperandRenderers.emplace_back(
Daniel Sanders198447a2017-11-01 00:29:47 +00002498 llvm::make_unique<Kind>(InsnID, std::forward<Args>(args)...));
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002499 return *static_cast<Kind *>(OperandRenderers.back().get());
2500 }
2501
Daniel Sandersa7b75262017-10-31 18:50:24 +00002502 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2503 if (Matched) {
2504 assert(canMutate(Rule, Matched) &&
2505 "Arranged to mutate an insn that isn't mutatable");
2506
2507 unsigned RecycleInsnID = Rule.getInsnVarID(*Matched);
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002508 Table << MatchTable::Opcode("GIR_MutateOpcode")
2509 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2510 << MatchTable::Comment("RecycleInsnID")
2511 << MatchTable::IntValue(RecycleInsnID)
2512 << MatchTable::Comment("Opcode")
2513 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
2514 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00002515
2516 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00002517 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00002518 auto Namespace = Def->getValue("Namespace")
2519 ? Def->getValueAsString("Namespace")
2520 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002521 Table << MatchTable::Opcode("GIR_AddImplicitDef")
2522 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2523 << MatchTable::NamedValue(Namespace, Def->getName())
2524 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00002525 }
2526 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00002527 auto Namespace = Use->getValue("Namespace")
2528 ? Use->getValueAsString("Namespace")
2529 : "";
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002530 Table << MatchTable::Opcode("GIR_AddImplicitUse")
2531 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2532 << MatchTable::NamedValue(Namespace, Use->getName())
2533 << MatchTable::LineBreak;
Tim Northover4340d642017-03-20 21:58:23 +00002534 }
2535 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002536 return;
2537 }
2538
2539 // TODO: Simple permutation looks like it could be almost as common as
2540 // mutation due to commutative operations.
2541
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002542 Table << MatchTable::Opcode("GIR_BuildMI") << MatchTable::Comment("InsnID")
2543 << MatchTable::IntValue(InsnID) << MatchTable::Comment("Opcode")
2544 << MatchTable::NamedValue(I->Namespace, I->TheDef->getName())
2545 << MatchTable::LineBreak;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00002546 for (const auto &Renderer : OperandRenderers)
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002547 Renderer->emitRenderOpcodes(Table, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002548
Florian Hahn3bc3ec62017-08-03 14:48:22 +00002549 if (I->mayLoad || I->mayStore) {
2550 Table << MatchTable::Opcode("GIR_MergeMemOperands")
2551 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2552 << MatchTable::Comment("MergeInsnID's");
2553 // Emit the ID's for all the instructions that are matched by this rule.
2554 // TODO: Limit this to matched instructions that mayLoad/mayStore or have
2555 // some other means of having a memoperand. Also limit this to
2556 // emitted instructions that expect to have a memoperand too. For
2557 // example, (G_SEXT (G_LOAD x)) that results in separate load and
2558 // sign-extend instructions shouldn't put the memoperand on the
2559 // sign-extend since it has no effect there.
2560 std::vector<unsigned> MergeInsnIDs;
2561 for (const auto &IDMatcherPair : Rule.defined_insn_vars())
2562 MergeInsnIDs.push_back(IDMatcherPair.second);
Mandeep Singh Grang1b0e2f22018-04-06 20:18:05 +00002563 llvm::sort(MergeInsnIDs.begin(), MergeInsnIDs.end());
Florian Hahn3bc3ec62017-08-03 14:48:22 +00002564 for (const auto &MergeInsnID : MergeInsnIDs)
2565 Table << MatchTable::IntValue(MergeInsnID);
Daniel Sanders05540042017-08-08 10:44:31 +00002566 Table << MatchTable::NamedValue("GIU_MergeMemOperands_EndOfList")
2567 << MatchTable::LineBreak;
Florian Hahn3bc3ec62017-08-03 14:48:22 +00002568 }
2569
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002570 // FIXME: This is a hack but it's sufficient for ISel. We'll need to do
2571 // better for combines. Particularly when there are multiple match
2572 // roots.
2573 if (InsnID == 0)
2574 Table << MatchTable::Opcode("GIR_EraseFromParent")
2575 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2576 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002577 }
2578};
2579
2580/// Generates code to constrain the operands of an output instruction to the
2581/// register classes specified by the definition of that instruction.
2582class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002583 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002584
2585public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002586 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002587
Daniel Sandersa7b75262017-10-31 18:50:24 +00002588 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002589 Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands")
2590 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2591 << MatchTable::LineBreak;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002592 }
2593};
2594
2595/// Generates code to constrain the specified operand of an output instruction
2596/// to the specified register class.
2597class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002598 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002599 unsigned OpIdx;
2600 const CodeGenRegisterClass &RC;
2601
2602public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002603 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002604 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002605 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00002606
Daniel Sandersa7b75262017-10-31 18:50:24 +00002607 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002608 Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
2609 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2610 << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
2611 << MatchTable::Comment("RC " + RC.getName())
2612 << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002613 }
2614};
2615
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002616/// Generates code to create a temporary register which can be used to chain
2617/// instructions together.
2618class MakeTempRegisterAction : public MatchAction {
2619private:
2620 LLTCodeGen Ty;
2621 unsigned TempRegID;
2622
2623public:
2624 MakeTempRegisterAction(const LLTCodeGen &Ty, unsigned TempRegID)
2625 : Ty(Ty), TempRegID(TempRegID) {}
2626
2627 void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
2628 Table << MatchTable::Opcode("GIR_MakeTempReg")
2629 << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
2630 << MatchTable::Comment("TypeID")
2631 << MatchTable::NamedValue(Ty.getCxxEnumValue())
2632 << MatchTable::LineBreak;
2633 }
2634};
2635
Daniel Sanders05540042017-08-08 10:44:31 +00002636InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002637 Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName));
Daniel Sandersa7b75262017-10-31 18:50:24 +00002638 MutatableInsns.insert(Matchers.back().get());
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002639 return *Matchers.back();
2640}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00002641
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002642void RuleMatcher::addRequiredFeature(Record *Feature) {
2643 RequiredFeatures.push_back(Feature);
2644}
2645
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002646const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
2647 return RequiredFeatures;
2648}
2649
Daniel Sanders7438b262017-10-31 23:03:18 +00002650// Emplaces an action of the specified Kind at the end of the action list.
2651//
2652// Returns a reference to the newly created action.
2653//
2654// Like std::vector::emplace_back(), may invalidate all iterators if the new
2655// size exceeds the capacity. Otherwise, only invalidates the past-the-end
2656// iterator.
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002657template <class Kind, class... Args>
2658Kind &RuleMatcher::addAction(Args &&... args) {
2659 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
2660 return *static_cast<Kind *>(Actions.back().get());
2661}
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002662
Daniel Sanders7438b262017-10-31 23:03:18 +00002663// Emplaces an action of the specified Kind before the given insertion point.
2664//
2665// Returns an iterator pointing at the newly created instruction.
2666//
2667// Like std::vector::insert(), may invalidate all iterators if the new size
2668// exceeds the capacity. Otherwise, only invalidates the iterators from the
2669// insertion point onwards.
2670template <class Kind, class... Args>
2671action_iterator RuleMatcher::insertAction(action_iterator InsertPt,
2672 Args &&... args) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002673 return Actions.emplace(InsertPt,
2674 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sanders7438b262017-10-31 23:03:18 +00002675}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002676
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002677unsigned RuleMatcher::implicitlyDefineInsnVar(InstructionMatcher &Matcher) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002678 unsigned NewInsnVarID = NextInsnVarID++;
2679 InsnVariableIDs[&Matcher] = NewInsnVarID;
2680 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002681}
2682
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002683unsigned RuleMatcher::getInsnVarID(InstructionMatcher &InsnMatcher) const {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002684 const auto &I = InsnVariableIDs.find(&InsnMatcher);
2685 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002686 return I->second;
2687 llvm_unreachable("Matched Insn was not captured in a local variable");
2688}
2689
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002690void RuleMatcher::defineOperand(StringRef SymbolicName, OperandMatcher &OM) {
2691 if (DefinedOperands.find(SymbolicName) == DefinedOperands.end()) {
2692 DefinedOperands[SymbolicName] = &OM;
2693 return;
2694 }
2695
2696 // If the operand is already defined, then we must ensure both references in
2697 // the matcher have the exact same node.
2698 OM.addPredicate<SameOperandMatcher>(OM.getSymbolicName());
2699}
2700
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002701InstructionMatcher &
Daniel Sanders05540042017-08-08 10:44:31 +00002702RuleMatcher::getInstructionMatcher(StringRef SymbolicName) const {
2703 for (const auto &I : InsnVariableIDs)
2704 if (I.first->getSymbolicName() == SymbolicName)
2705 return *I.first;
2706 llvm_unreachable(
2707 ("Failed to lookup instruction " + SymbolicName).str().c_str());
2708}
2709
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002710const OperandMatcher &
2711RuleMatcher::getOperandMatcher(StringRef Name) const {
2712 const auto &I = DefinedOperands.find(Name);
2713
2714 if (I == DefinedOperands.end())
2715 PrintFatalError(SrcLoc, "Operand " + Name + " was not declared in matcher");
2716
2717 return *I->second;
2718}
2719
Daniel Sanders8e82af22017-07-27 11:03:45 +00002720void RuleMatcher::emit(MatchTable &Table) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002721 if (Matchers.empty())
2722 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00002723
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002724 // The representation supports rules that require multiple roots such as:
2725 // %ptr(p0) = ...
2726 // %elt0(s32) = G_LOAD %ptr
2727 // %1(p0) = G_ADD %ptr, 4
2728 // %elt1(s32) = G_LOAD p0 %1
2729 // which could be usefully folded into:
2730 // %ptr(p0) = ...
2731 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
2732 // on some targets but we don't need to make use of that yet.
2733 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002734
Daniel Sanders8e82af22017-07-27 11:03:45 +00002735 unsigned LabelID = Table.allocateLabelID();
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002736 Table << MatchTable::Opcode("GIM_Try", +1)
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002737 << MatchTable::Comment("On fail goto")
2738 << MatchTable::JumpTarget(LabelID)
2739 << MatchTable::Comment(("Rule ID " + Twine(RuleID) + " //").str())
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002740 << MatchTable::LineBreak;
2741
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002742 if (!RequiredFeatures.empty()) {
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002743 Table << MatchTable::Opcode("GIM_CheckFeatures")
2744 << MatchTable::NamedValue(getNameForFeatureBitset(RequiredFeatures))
2745 << MatchTable::LineBreak;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002746 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002747
Quentin Colombetaad20be2017-12-15 23:07:42 +00002748 Matchers.front()->emitPredicateOpcodes(Table, *this);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002749
Daniel Sandersbee57392017-04-04 13:25:23 +00002750 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002751 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00002752 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002753 SmallVector<unsigned, 2> InsnIDs;
2754 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002755 // Skip the root node since it isn't moving anywhere. Everything else is
2756 // sinking to meet it.
2757 if (Pair.first == Matchers.front().get())
2758 continue;
2759
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002760 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00002761 }
Mandeep Singh Grang1b0e2f22018-04-06 20:18:05 +00002762 llvm::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00002763
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002764 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00002765 // Reject the difficult cases until we have a more accurate check.
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002766 Table << MatchTable::Opcode("GIM_CheckIsSafeToFold")
2767 << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
2768 << MatchTable::LineBreak;
Daniel Sandersbee57392017-04-04 13:25:23 +00002769
2770 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
2771 // account for unsafe cases.
2772 //
2773 // Example:
2774 // MI1--> %0 = ...
2775 // %1 = ... %0
2776 // MI0--> %2 = ... %0
2777 // It's not safe to erase MI1. We currently handle this by not
2778 // erasing %0 (even when it's dead).
2779 //
2780 // Example:
2781 // MI1--> %0 = load volatile @a
2782 // %1 = load volatile @a
2783 // MI0--> %2 = ... %0
2784 // It's not safe to sink %0's def past %1. We currently handle
2785 // this by rejecting all loads.
2786 //
2787 // Example:
2788 // MI1--> %0 = load @a
2789 // %1 = store @a
2790 // MI0--> %2 = ... %0
2791 // It's not safe to sink %0's def past %1. We currently handle
2792 // this by rejecting all loads.
2793 //
2794 // Example:
2795 // G_CONDBR %cond, @BB1
2796 // BB0:
2797 // MI1--> %0 = load @a
2798 // G_BR @BB1
2799 // BB1:
2800 // MI0--> %2 = ... %0
2801 // It's not always safe to sink %0 across control flow. In this
2802 // case it may introduce a memory fault. We currentl handle this
2803 // by rejecting all loads.
2804 }
2805 }
2806
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002807 for (const auto &PM : EpilogueMatchers)
2808 PM->emitPredicateOpcodes(Table, *this);
2809
Daniel Sandersd93a35a2017-07-05 09:39:33 +00002810 for (const auto &MA : Actions)
Daniel Sandersa7b75262017-10-31 18:50:24 +00002811 MA->emitActionOpcodes(Table, *this);
Daniel Sandersf76f3152017-11-16 00:46:35 +00002812
Roman Tereshinbeb39312018-05-02 20:15:11 +00002813 if (Table.isWithCoverage())
Daniel Sandersf76f3152017-11-16 00:46:35 +00002814 Table << MatchTable::Opcode("GIR_Coverage") << MatchTable::IntValue(RuleID)
2815 << MatchTable::LineBreak;
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002816 else
2817 Table << MatchTable::Comment(("GIR_Coverage, " + Twine(RuleID) + ",").str())
2818 << MatchTable::LineBreak;
Daniel Sandersf76f3152017-11-16 00:46:35 +00002819
Daniel Sanders7aac7cc2017-07-20 09:25:44 +00002820 Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak
Daniel Sanders8e82af22017-07-27 11:03:45 +00002821 << MatchTable::Label(LabelID);
Volkan Keles4f3fa792018-01-25 00:18:52 +00002822 ++NumPatternEmitted;
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002823}
Daniel Sanders43c882c2017-02-01 10:53:10 +00002824
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002825bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
2826 // Rules involving more match roots have higher priority.
2827 if (Matchers.size() > B.Matchers.size())
2828 return true;
2829 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00002830 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002831
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002832 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
2833 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
2834 return true;
2835 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
2836 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002837 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002838
2839 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00002840}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002841
Daniel Sanders2deea182017-04-22 15:11:04 +00002842unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002843 return std::accumulate(
2844 Matchers.begin(), Matchers.end(), 0,
2845 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00002846 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00002847 });
2848}
2849
Daniel Sanders05540042017-08-08 10:44:31 +00002850bool OperandPredicateMatcher::isHigherPriorityThan(
2851 const OperandPredicateMatcher &B) const {
2852 // Generally speaking, an instruction is more important than an Int or a
2853 // LiteralInt because it can cover more nodes but theres an exception to
2854 // this. G_CONSTANT's are less important than either of those two because they
2855 // are more permissive.
Daniel Sandersedd07842017-08-17 09:26:14 +00002856
2857 const InstructionOperandMatcher *AOM =
2858 dyn_cast<InstructionOperandMatcher>(this);
2859 const InstructionOperandMatcher *BOM =
2860 dyn_cast<InstructionOperandMatcher>(&B);
2861 bool AIsConstantInsn = AOM && AOM->getInsnMatcher().isConstantInstruction();
2862 bool BIsConstantInsn = BOM && BOM->getInsnMatcher().isConstantInstruction();
2863
2864 if (AOM && BOM) {
2865 // The relative priorities between a G_CONSTANT and any other instruction
2866 // don't actually matter but this code is needed to ensure a strict weak
2867 // ordering. This is particularly important on Windows where the rules will
2868 // be incorrectly sorted without it.
2869 if (AIsConstantInsn != BIsConstantInsn)
2870 return AIsConstantInsn < BIsConstantInsn;
2871 return false;
Daniel Sanders05540042017-08-08 10:44:31 +00002872 }
Daniel Sandersedd07842017-08-17 09:26:14 +00002873
2874 if (AOM && AIsConstantInsn && (B.Kind == OPM_Int || B.Kind == OPM_LiteralInt))
2875 return false;
2876 if (BOM && BIsConstantInsn && (Kind == OPM_Int || Kind == OPM_LiteralInt))
2877 return true;
Daniel Sanders05540042017-08-08 10:44:31 +00002878
2879 return Kind < B.Kind;
Daniel Sanders75b84fc2017-08-08 13:21:26 +00002880}
Daniel Sanders05540042017-08-08 10:44:31 +00002881
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002882void SameOperandMatcher::emitPredicateOpcodes(MatchTable &Table,
Quentin Colombetaad20be2017-12-15 23:07:42 +00002883 RuleMatcher &Rule) const {
Daniel Sanders1e4569f2017-10-20 20:55:29 +00002884 const OperandMatcher &OtherOM = Rule.getOperandMatcher(MatchingName);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002885 unsigned OtherInsnVarID = Rule.getInsnVarID(OtherOM.getInstructionMatcher());
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002886 assert(OtherInsnVarID == OtherOM.getInstructionMatcher().getInsnVarID());
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002887
2888 Table << MatchTable::Opcode("GIM_CheckIsSameOperand")
2889 << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
2890 << MatchTable::Comment("OpIdx") << MatchTable::IntValue(OpIdx)
2891 << MatchTable::Comment("OtherMI")
2892 << MatchTable::IntValue(OtherInsnVarID)
2893 << MatchTable::Comment("OtherOpIdx")
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002894 << MatchTable::IntValue(OtherOM.getOpIdx())
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00002895 << MatchTable::LineBreak;
2896}
2897
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002898//===- GlobalISelEmitter class --------------------------------------------===//
2899
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002900class GlobalISelEmitter {
2901public:
2902 explicit GlobalISelEmitter(RecordKeeper &RK);
2903 void run(raw_ostream &OS);
2904
2905private:
2906 const RecordKeeper &RK;
2907 const CodeGenDAGPatterns CGP;
2908 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002909 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002910
Daniel Sanders39690bd2017-10-15 02:41:12 +00002911 /// Keep track of the equivalence between SDNodes and Instruction by mapping
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00002912 /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
2913 /// check for attributes on the relation such as CheckMMOIsNonAtomic.
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002914 /// This is defined using 'GINodeEquiv' in the target description.
Daniel Sanders39690bd2017-10-15 02:41:12 +00002915 DenseMap<Record *, Record *> NodeEquivs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002916
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002917 /// Keep track of the equivalence between ComplexPattern's and
2918 /// GIComplexOperandMatcher. Map entries are specified by subclassing
2919 /// GIComplexPatternEquiv.
2920 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
2921
Volkan Kelesf7f25682018-01-16 18:44:05 +00002922 /// Keep track of the equivalence between SDNodeXForm's and
2923 /// GICustomOperandRenderer. Map entries are specified by subclassing
2924 /// GISDNodeXFormEquiv.
2925 DenseMap<const Record *, const Record *> SDNodeXFormEquivs;
2926
Aditya Nandakumarb63e7632018-02-16 22:37:15 +00002927 /// Keep track of Scores of PatternsToMatch similar to how the DAG does.
2928 /// This adds compatibility for RuleMatchers to use this for ordering rules.
2929 DenseMap<uint64_t, int> RuleMatcherScores;
2930
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002931 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002932 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002933
Daniel Sandersf76f3152017-11-16 00:46:35 +00002934 // Rule coverage information.
2935 Optional<CodeGenCoverage> RuleCoverage;
2936
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002937 void gatherOpcodeValues();
2938 void gatherTypeIDValues();
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002939 void gatherNodeEquivs();
Daniel Sanders39690bd2017-10-15 02:41:12 +00002940 Record *findNodeEquiv(Record *N) const;
Daniel Sandersf84bc372018-05-05 20:53:24 +00002941 const CodeGenInstruction *getEquivNode(Record &Equiv,
2942 const TreePatternNode *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002943
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00002944 Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
Daniel Sandersdf39cba2017-10-15 18:22:54 +00002945 Expected<InstructionMatcher &> createAndImportSelDAGMatcher(
2946 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
2947 const TreePatternNode *Src, unsigned &TempOpIdx) const;
2948 Error importComplexPatternOperandMatcher(OperandMatcher &OM, Record *R,
2949 unsigned &TempOpIdx) const;
2950 Error importChildMatcher(RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
Daniel Sandersa71f4542017-10-16 00:56:30 +00002951 const TreePatternNode *SrcChild,
2952 bool OperandIsAPointer, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00002953 unsigned &TempOpIdx) const;
Daniel Sandersdf258e32017-10-31 19:09:29 +00002954
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00002955 Expected<BuildMIAction &>
Daniel Sandersa7b75262017-10-31 18:50:24 +00002956 createAndImportInstructionRenderer(RuleMatcher &M,
2957 const TreePatternNode *Dst);
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002958 Expected<action_iterator> createAndImportSubInstructionRenderer(
2959 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
2960 unsigned TempReg);
Daniel Sanders7438b262017-10-31 23:03:18 +00002961 Expected<action_iterator>
2962 createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M,
2963 const TreePatternNode *Dst);
Daniel Sandersdf258e32017-10-31 19:09:29 +00002964 void importExplicitDefRenderers(BuildMIAction &DstMIBuilder);
Daniel Sanders7438b262017-10-31 23:03:18 +00002965 Expected<action_iterator>
2966 importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M,
2967 BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00002968 const llvm::TreePatternNode *Dst);
Daniel Sanders7438b262017-10-31 23:03:18 +00002969 Expected<action_iterator>
2970 importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
2971 BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00002972 TreePatternNode *DstChild);
Diana Picus382602f2017-05-17 08:57:28 +00002973 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
2974 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00002975 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00002976 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
2977 const std::vector<Record *> &ImplicitDefs) const;
2978
Daniel Sanders11300ce2017-10-13 21:28:03 +00002979 void emitImmPredicates(raw_ostream &OS, StringRef TypeIdentifier,
2980 StringRef Type,
Daniel Sanders649c5852017-10-13 20:42:18 +00002981 std::function<bool(const Record *R)> Filter);
2982
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002983 /// Analyze pattern \p P, returning a matcher for it if possible.
2984 /// Otherwise, return an Error explaining why we don't support it.
2985 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002986
2987 void declareSubtargetFeature(Record *Predicate);
Daniel Sanders7e523672017-11-11 03:23:44 +00002988
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002989 MatchTable buildMatchTable(MutableArrayRef<RuleMatcher> Rules, bool Optimize,
2990 bool WithCoverage);
2991
2992public:
Quentin Colombetec76d9c2017-12-18 19:47:41 +00002993 /// Takes a sequence of \p Rules and group them based on the predicates
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002994 /// they share. \p MatcherStorage is used as a memory container
Hiroshi Inoue501931b2018-01-24 05:04:35 +00002995 /// for the group that are created as part of this process.
Quentin Colombetec76d9c2017-12-18 19:47:41 +00002996 ///
Roman Tereshinf1aa3482018-05-21 23:28:51 +00002997 /// What this optimization does looks like if GroupT = GroupMatcher:
Quentin Colombetec76d9c2017-12-18 19:47:41 +00002998 /// Output without optimization:
2999 /// \verbatim
3000 /// # R1
3001 /// # predicate A
3002 /// # predicate B
3003 /// ...
3004 /// # R2
3005 /// # predicate A // <-- effectively this is going to be checked twice.
3006 /// // Once in R1 and once in R2.
3007 /// # predicate C
3008 /// \endverbatim
3009 /// Output with optimization:
3010 /// \verbatim
3011 /// # Group1_2
3012 /// # predicate A // <-- Check is now shared.
3013 /// # R1
3014 /// # predicate B
3015 /// # R2
3016 /// # predicate C
3017 /// \endverbatim
Roman Tereshinf1aa3482018-05-21 23:28:51 +00003018 template <class GroupT>
3019 static std::vector<Matcher *> optimizeRules(
Roman Tereshin2d6d3762018-05-02 20:08:14 +00003020 ArrayRef<Matcher *> Rules,
Roman Tereshinf1aa3482018-05-21 23:28:51 +00003021 std::vector<std::unique_ptr<Matcher>> &MatcherStorage);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003022};
3023
Roman Tereshinf1aa3482018-05-21 23:28:51 +00003024void GlobalISelEmitter::gatherOpcodeValues() {
3025 InstructionOpcodeMatcher::initOpcodeValuesMap(Target);
3026}
3027
3028void GlobalISelEmitter::gatherTypeIDValues() {
3029 LLTOperandMatcher::initTypeIDValuesMap();
3030}
3031
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003032void GlobalISelEmitter::gatherNodeEquivs() {
3033 assert(NodeEquivs.empty());
3034 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
Daniel Sanders39690bd2017-10-15 02:41:12 +00003035 NodeEquivs[Equiv->getValueAsDef("Node")] = Equiv;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003036
3037 assert(ComplexPatternEquivs.empty());
3038 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
3039 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
3040 if (!SelDAGEquiv)
3041 continue;
3042 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
3043 }
Volkan Kelesf7f25682018-01-16 18:44:05 +00003044
3045 assert(SDNodeXFormEquivs.empty());
3046 for (Record *Equiv : RK.getAllDerivedDefinitions("GISDNodeXFormEquiv")) {
3047 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
3048 if (!SelDAGEquiv)
3049 continue;
3050 SDNodeXFormEquivs[SelDAGEquiv] = Equiv;
3051 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003052}
3053
Daniel Sanders39690bd2017-10-15 02:41:12 +00003054Record *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003055 return NodeEquivs.lookup(N);
3056}
3057
Daniel Sandersf84bc372018-05-05 20:53:24 +00003058const CodeGenInstruction *
3059GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode *N) const {
3060 for (const auto &Predicate : N->getPredicateFns()) {
3061 if (!Equiv.isValueUnset("IfSignExtend") && Predicate.isLoad() &&
3062 Predicate.isSignExtLoad())
3063 return &Target.getInstruction(Equiv.getValueAsDef("IfSignExtend"));
3064 if (!Equiv.isValueUnset("IfZeroExtend") && Predicate.isLoad() &&
3065 Predicate.isZeroExtLoad())
3066 return &Target.getInstruction(Equiv.getValueAsDef("IfZeroExtend"));
3067 }
3068 return &Target.getInstruction(Equiv.getValueAsDef("I"));
3069}
3070
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003071GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Daniel Sandersf84bc372018-05-05 20:53:24 +00003072 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()),
3073 CGRegs(RK, Target.getHwModes()) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003074
3075//===- Emitter ------------------------------------------------------------===//
3076
Daniel Sandersc270c502017-03-30 09:36:33 +00003077Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00003078GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003079 ArrayRef<Predicate> Predicates) {
3080 for (const Predicate &P : Predicates) {
3081 if (!P.Def)
3082 continue;
3083 declareSubtargetFeature(P.Def);
3084 M.addRequiredFeature(P.Def);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00003085 }
3086
Daniel Sandersc270c502017-03-30 09:36:33 +00003087 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003088}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00003089
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00003090Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
3091 RuleMatcher &Rule, InstructionMatcher &InsnMatcher,
3092 const TreePatternNode *Src, unsigned &TempOpIdx) const {
3093 Record *SrcGIEquivOrNull = nullptr;
3094 const CodeGenInstruction *SrcGIOrNull = nullptr;
3095
3096 // Start with the defined operands (i.e., the results of the root operator).
3097 if (Src->getExtTypes().size() > 1)
3098 return failedImport("Src pattern has multiple results");
3099
3100 if (Src->isLeaf()) {
3101 Init *SrcInit = Src->getLeafValue();
3102 if (isa<IntInit>(SrcInit)) {
3103 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
3104 &Target.getInstruction(RK.getDef("G_CONSTANT")));
3105 } else
3106 return failedImport(
3107 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
3108 } else {
3109 SrcGIEquivOrNull = findNodeEquiv(Src->getOperator());
3110 if (!SrcGIEquivOrNull)
3111 return failedImport("Pattern operator lacks an equivalent Instruction" +
3112 explainOperator(Src->getOperator()));
Daniel Sandersf84bc372018-05-05 20:53:24 +00003113 SrcGIOrNull = getEquivNode(*SrcGIEquivOrNull, Src);
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00003114
3115 // The operators look good: match the opcode
3116 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
3117 }
3118
3119 unsigned OpIdx = 0;
3120 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
3121 // Results don't have a name unless they are the root node. The caller will
3122 // set the name if appropriate.
3123 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
3124 if (auto Error = OM.addTypeCheckPredicate(VTy, false /* OperandIsAPointer */))
3125 return failedImport(toString(std::move(Error)) +
3126 " for result of Src pattern operator");
3127 }
3128
Daniel Sanders2c269f62017-08-24 09:11:20 +00003129 for (const auto &Predicate : Src->getPredicateFns()) {
3130 if (Predicate.isAlwaysTrue())
3131 continue;
3132
3133 if (Predicate.isImmediatePattern()) {
3134 InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
3135 continue;
3136 }
3137
Daniel Sandersf84bc372018-05-05 20:53:24 +00003138 // G_LOAD is used for both non-extending and any-extending loads.
3139 if (Predicate.isLoad() && Predicate.isNonExtLoad()) {
3140 InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
3141 0, MemoryVsLLTSizePredicateMatcher::EqualTo, 0);
3142 continue;
3143 }
3144 if (Predicate.isLoad() && Predicate.isAnyExtLoad()) {
3145 InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
3146 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
3147 continue;
3148 }
3149
3150 // No check required. We already did it by swapping the opcode.
3151 if (!SrcGIEquivOrNull->isValueUnset("IfSignExtend") &&
3152 Predicate.isSignExtLoad())
3153 continue;
3154
3155 // No check required. We already did it by swapping the opcode.
3156 if (!SrcGIEquivOrNull->isValueUnset("IfZeroExtend") &&
3157 Predicate.isZeroExtLoad())
Daniel Sandersa71f4542017-10-16 00:56:30 +00003158 continue;
3159
Daniel Sandersd66e0902017-10-23 18:19:24 +00003160 // No check required. G_STORE by itself is a non-extending store.
3161 if (Predicate.isNonTruncStore())
3162 continue;
3163
Daniel Sanders76664652017-11-28 22:07:05 +00003164 if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
3165 if (Predicate.getMemoryVT() != nullptr) {
3166 Optional<LLTCodeGen> MemTyOrNone =
3167 MVTToLLT(getValueType(Predicate.getMemoryVT()));
Daniel Sandersd66e0902017-10-23 18:19:24 +00003168
Daniel Sanders76664652017-11-28 22:07:05 +00003169 if (!MemTyOrNone)
3170 return failedImport("MemVT could not be converted to LLT");
Daniel Sandersd66e0902017-10-23 18:19:24 +00003171
Daniel Sandersf84bc372018-05-05 20:53:24 +00003172 // MMO's work in bytes so we must take care of unusual types like i1
3173 // don't round down.
3174 unsigned MemSizeInBits =
3175 llvm::alignTo(MemTyOrNone->get().getSizeInBits(), 8);
3176
3177 InsnMatcher.addPredicate<MemorySizePredicateMatcher>(
3178 0, MemSizeInBits / 8);
Daniel Sanders76664652017-11-28 22:07:05 +00003179 continue;
3180 }
3181 }
3182
3183 if (Predicate.isLoad() || Predicate.isStore()) {
3184 // No check required. A G_LOAD/G_STORE is an unindexed load.
3185 if (Predicate.isUnindexed())
3186 continue;
3187 }
3188
3189 if (Predicate.isAtomic()) {
3190 if (Predicate.isAtomicOrderingMonotonic()) {
3191 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
3192 "Monotonic");
3193 continue;
3194 }
3195 if (Predicate.isAtomicOrderingAcquire()) {
3196 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Acquire");
3197 continue;
3198 }
3199 if (Predicate.isAtomicOrderingRelease()) {
3200 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("Release");
3201 continue;
3202 }
3203 if (Predicate.isAtomicOrderingAcquireRelease()) {
3204 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
3205 "AcquireRelease");
3206 continue;
3207 }
3208 if (Predicate.isAtomicOrderingSequentiallyConsistent()) {
3209 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
3210 "SequentiallyConsistent");
3211 continue;
3212 }
Daniel Sanders0c43b3a2017-11-30 21:05:59 +00003213
3214 if (Predicate.isAtomicOrderingAcquireOrStronger()) {
3215 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
3216 "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
3217 continue;
3218 }
3219 if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
3220 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
3221 "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
3222 continue;
3223 }
3224
3225 if (Predicate.isAtomicOrderingReleaseOrStronger()) {
3226 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
3227 "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
3228 continue;
3229 }
3230 if (Predicate.isAtomicOrderingWeakerThanRelease()) {
3231 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
3232 "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
3233 continue;
3234 }
Daniel Sandersd66e0902017-10-23 18:19:24 +00003235 }
3236
Daniel Sanders2c269f62017-08-24 09:11:20 +00003237 return failedImport("Src pattern child has predicate (" +
3238 explainPredicates(Src) + ")");
3239 }
Daniel Sanders3c1c4c02017-12-05 05:52:07 +00003240 if (SrcGIEquivOrNull && SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
3241 InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
Daniel Sanders2c269f62017-08-24 09:11:20 +00003242
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003243 if (Src->isLeaf()) {
3244 Init *SrcInit = Src->getLeafValue();
3245 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003246 OperandMatcher &OM =
3247 InsnMatcher.addOperand(OpIdx++, Src->getName(), TempOpIdx);
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003248 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
3249 } else
Daniel Sanders32291982017-06-28 13:50:04 +00003250 return failedImport(
3251 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003252 } else {
Daniel Sanders85ffd362017-07-06 08:12:20 +00003253 assert(SrcGIOrNull &&
3254 "Expected to have already found an equivalent Instruction");
Daniel Sanders11300ce2017-10-13 21:28:03 +00003255 if (SrcGIOrNull->TheDef->getName() == "G_CONSTANT" ||
3256 SrcGIOrNull->TheDef->getName() == "G_FCONSTANT") {
3257 // imm/fpimm still have operands but we don't need to do anything with it
Daniel Sanders05540042017-08-08 10:44:31 +00003258 // here since we don't support ImmLeaf predicates yet. However, we still
3259 // need to note the hidden operand to get GIM_CheckNumOperands correct.
3260 InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
3261 return InsnMatcher;
3262 }
3263
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003264 // Match the used operands (i.e. the children of the operator).
3265 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00003266 TreePatternNode *SrcChild = Src->getChild(i);
3267
Daniel Sandersa71f4542017-10-16 00:56:30 +00003268 // SelectionDAG allows pointers to be represented with iN since it doesn't
3269 // distinguish between pointers and integers but they are different types in GlobalISel.
3270 // Coerce integers to pointers to address space 0 if the context indicates a pointer.
Daniel Sandersc54aa9c2017-11-18 00:16:44 +00003271 bool OperandIsAPointer = SrcGIOrNull->isOperandAPointer(i);
Daniel Sandersa71f4542017-10-16 00:56:30 +00003272
Daniel Sanders28887fe2017-09-19 12:56:36 +00003273 // For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
3274 // following the defs is an intrinsic ID.
3275 if ((SrcGIOrNull->TheDef->getName() == "G_INTRINSIC" ||
3276 SrcGIOrNull->TheDef->getName() == "G_INTRINSIC_W_SIDE_EFFECTS") &&
3277 i == 0) {
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00003278 if (const CodeGenIntrinsic *II = Src->getIntrinsicInfo(CGP)) {
Daniel Sanders85ffd362017-07-06 08:12:20 +00003279 OperandMatcher &OM =
3280 InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx);
Daniel Sandersfe12c0f2017-07-11 08:57:29 +00003281 OM.addPredicate<IntrinsicIDOperandMatcher>(II);
Daniel Sanders85ffd362017-07-06 08:12:20 +00003282 continue;
3283 }
3284
3285 return failedImport("Expected IntInit containing instrinsic ID)");
3286 }
3287
Daniel Sandersa71f4542017-10-16 00:56:30 +00003288 if (auto Error =
3289 importChildMatcher(Rule, InsnMatcher, SrcChild, OperandIsAPointer,
3290 OpIdx++, TempOpIdx))
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003291 return std::move(Error);
3292 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00003293 }
3294
3295 return InsnMatcher;
3296}
3297
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003298Error GlobalISelEmitter::importComplexPatternOperandMatcher(
3299 OperandMatcher &OM, Record *R, unsigned &TempOpIdx) const {
3300 const auto &ComplexPattern = ComplexPatternEquivs.find(R);
3301 if (ComplexPattern == ComplexPatternEquivs.end())
3302 return failedImport("SelectionDAG ComplexPattern (" + R->getName() +
3303 ") not mapped to GlobalISel");
3304
3305 OM.addPredicate<ComplexPatternOperandMatcher>(OM, *ComplexPattern->second);
3306 TempOpIdx++;
3307 return Error::success();
3308}
3309
3310Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule,
3311 InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003312 const TreePatternNode *SrcChild,
Daniel Sandersa71f4542017-10-16 00:56:30 +00003313 bool OperandIsAPointer,
Daniel Sandersc270c502017-03-30 09:36:33 +00003314 unsigned OpIdx,
3315 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00003316 OperandMatcher &OM =
3317 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003318 if (OM.isSameAsAnotherOperand())
3319 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003320
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003321 ArrayRef<TypeSetByHwMode> ChildTypes = SrcChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003322 if (ChildTypes.size() != 1)
3323 return failedImport("Src pattern child has multiple results");
3324
3325 // Check MBB's before the type check since they are not a known type.
3326 if (!SrcChild->isLeaf()) {
3327 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
3328 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
3329 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
3330 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00003331 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003332 }
3333 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00003334 }
3335
Daniel Sandersa71f4542017-10-16 00:56:30 +00003336 if (auto Error =
3337 OM.addTypeCheckPredicate(ChildTypes.front(), OperandIsAPointer))
3338 return failedImport(toString(std::move(Error)) + " for Src operand (" +
3339 to_string(*SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00003340
Daniel Sandersbee57392017-04-04 13:25:23 +00003341 // Check for nested instructions.
3342 if (!SrcChild->isLeaf()) {
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003343 if (SrcChild->getOperator()->isSubClassOf("ComplexPattern")) {
3344 // When a ComplexPattern is used as an operator, it should do the same
3345 // thing as when used as a leaf. However, the children of the operator
3346 // name the sub-operands that make up the complex operand and we must
3347 // prepare to reference them in the renderer too.
3348 unsigned RendererID = TempOpIdx;
3349 if (auto Error = importComplexPatternOperandMatcher(
3350 OM, SrcChild->getOperator(), TempOpIdx))
3351 return Error;
3352
3353 for (unsigned i = 0, e = SrcChild->getNumChildren(); i != e; ++i) {
3354 auto *SubOperand = SrcChild->getChild(i);
3355 if (!SubOperand->getName().empty())
3356 Rule.defineComplexSubOperand(SubOperand->getName(),
3357 SrcChild->getOperator(), RendererID, i);
3358 }
3359
3360 return Error::success();
3361 }
3362
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003363 auto MaybeInsnOperand = OM.addPredicate<InstructionOperandMatcher>(
3364 InsnMatcher.getRuleMatcher(), SrcChild->getName());
3365 if (!MaybeInsnOperand.hasValue()) {
3366 // This isn't strictly true. If the user were to provide exactly the same
3367 // matchers as the original operand then we could allow it. However, it's
3368 // simpler to not permit the redundant specification.
3369 return failedImport("Nested instruction cannot be the same as another operand");
3370 }
3371
Daniel Sandersbee57392017-04-04 13:25:23 +00003372 // Map the node to a gMIR instruction.
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003373 InstructionOperandMatcher &InsnOperand = **MaybeInsnOperand;
Daniel Sanders57938df2017-07-11 10:40:18 +00003374 auto InsnMatcherOrError = createAndImportSelDAGMatcher(
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003375 Rule, InsnOperand.getInsnMatcher(), SrcChild, TempOpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +00003376 if (auto Error = InsnMatcherOrError.takeError())
3377 return Error;
3378
3379 return Error::success();
3380 }
3381
Diana Picusd1b61812017-11-03 10:30:19 +00003382 if (SrcChild->hasAnyPredicate())
3383 return failedImport("Src pattern child has unsupported predicate");
3384
Daniel Sandersffc7d582017-03-29 15:37:18 +00003385 // Check for constant immediates.
3386 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003387 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00003388 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003389 }
3390
3391 // Check for def's like register classes or ComplexPattern's.
3392 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
3393 auto *ChildRec = ChildDefInit->getDef();
3394
3395 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003396 if (ChildRec->isSubClassOf("RegisterClass") ||
3397 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00003398 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003399 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00003400 return Error::success();
3401 }
3402
Daniel Sanders4d4e7652017-10-09 18:14:53 +00003403 // Check for ValueType.
3404 if (ChildRec->isSubClassOf("ValueType")) {
3405 // We already added a type check as standard practice so this doesn't need
3406 // to do anything.
3407 return Error::success();
3408 }
3409
Daniel Sandersffc7d582017-03-29 15:37:18 +00003410 // Check for ComplexPattern's.
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003411 if (ChildRec->isSubClassOf("ComplexPattern"))
3412 return importComplexPatternOperandMatcher(OM, ChildRec, TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003413
Daniel Sandersd0656a32017-04-13 09:45:37 +00003414 if (ChildRec->isSubClassOf("ImmLeaf")) {
3415 return failedImport(
3416 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
3417 }
3418
Daniel Sandersffc7d582017-03-29 15:37:18 +00003419 return failedImport(
3420 "Src pattern child def is an unsupported tablegen class");
3421 }
3422
3423 return failedImport("Src pattern child is an unsupported kind");
3424}
3425
Daniel Sanders7438b262017-10-31 23:03:18 +00003426Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
3427 action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003428 TreePatternNode *DstChild) {
Daniel Sanders2c269f62017-08-24 09:11:20 +00003429
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003430 const auto &SubOperand = Rule.getComplexSubOperand(DstChild->getName());
3431 if (SubOperand.hasValue()) {
3432 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00003433 *std::get<0>(*SubOperand), DstChild->getName(),
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003434 std::get<1>(*SubOperand), std::get<2>(*SubOperand));
Daniel Sanders7438b262017-10-31 23:03:18 +00003435 return InsertPt;
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003436 }
3437
Daniel Sandersffc7d582017-03-29 15:37:18 +00003438 if (!DstChild->isLeaf()) {
Volkan Kelesf7f25682018-01-16 18:44:05 +00003439
3440 if (DstChild->getOperator()->isSubClassOf("SDNodeXForm")) {
3441 auto Child = DstChild->getChild(0);
3442 auto I = SDNodeXFormEquivs.find(DstChild->getOperator());
3443 if (I != SDNodeXFormEquivs.end()) {
3444 DstMIBuilder.addRenderer<CustomRenderer>(*I->second, Child->getName());
3445 return InsertPt;
3446 }
3447 return failedImport("SDNodeXForm " + Child->getName() +
3448 " has no custom renderer");
3449 }
3450
Daniel Sanders05540042017-08-08 10:44:31 +00003451 // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
3452 // inline, but in MI it's just another operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00003453 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
3454 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
3455 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sanders198447a2017-11-01 00:29:47 +00003456 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00003457 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003458 }
3459 }
Daniel Sanders05540042017-08-08 10:44:31 +00003460
3461 // Similarly, imm is an operator in TreePatternNode's view but must be
3462 // rendered as operands.
3463 // FIXME: The target should be able to choose sign-extended when appropriate
3464 // (e.g. on Mips).
3465 if (DstChild->getOperator()->getName() == "imm") {
Daniel Sanders198447a2017-11-01 00:29:47 +00003466 DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00003467 return InsertPt;
Daniel Sanders11300ce2017-10-13 21:28:03 +00003468 } else if (DstChild->getOperator()->getName() == "fpimm") {
3469 DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00003470 DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00003471 return InsertPt;
Daniel Sanders05540042017-08-08 10:44:31 +00003472 }
3473
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003474 if (DstChild->getOperator()->isSubClassOf("Instruction")) {
3475 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
3476 if (ChildTypes.size() != 1)
3477 return failedImport("Dst pattern child has multiple results");
3478
3479 Optional<LLTCodeGen> OpTyOrNone = None;
3480 if (ChildTypes.front().isMachineValueType())
3481 OpTyOrNone =
3482 MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
3483 if (!OpTyOrNone)
3484 return failedImport("Dst operand has an unsupported type");
3485
3486 unsigned TempRegID = Rule.allocateTempRegID();
3487 InsertPt = Rule.insertAction<MakeTempRegisterAction>(
3488 InsertPt, OpTyOrNone.getValue(), TempRegID);
3489 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
3490
3491 auto InsertPtOrError = createAndImportSubInstructionRenderer(
3492 ++InsertPt, Rule, DstChild, TempRegID);
3493 if (auto Error = InsertPtOrError.takeError())
3494 return std::move(Error);
3495 return InsertPtOrError.get();
3496 }
3497
Daniel Sanders2c269f62017-08-24 09:11:20 +00003498 return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild));
Daniel Sandersffc7d582017-03-29 15:37:18 +00003499 }
3500
Daniel Sandersf499b2b2017-11-30 18:48:35 +00003501 // It could be a specific immediate in which case we should just check for
3502 // that immediate.
3503 if (const IntInit *ChildIntInit =
3504 dyn_cast<IntInit>(DstChild->getLeafValue())) {
3505 DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue());
3506 return InsertPt;
3507 }
3508
Daniel Sandersffc7d582017-03-29 15:37:18 +00003509 // Otherwise, we're looking for a bog-standard RegisterClass operand.
Daniel Sandersffc7d582017-03-29 15:37:18 +00003510 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
3511 auto *ChildRec = ChildDefInit->getDef();
3512
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003513 ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003514 if (ChildTypes.size() != 1)
3515 return failedImport("Dst pattern child has multiple results");
3516
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003517 Optional<LLTCodeGen> OpTyOrNone = None;
3518 if (ChildTypes.front().isMachineValueType())
3519 OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003520 if (!OpTyOrNone)
3521 return failedImport("Dst operand has an unsupported type");
3522
3523 if (ChildRec->isSubClassOf("Register")) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003524 DstMIBuilder.addRenderer<AddRegisterRenderer>(ChildRec);
Daniel Sanders7438b262017-10-31 23:03:18 +00003525 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003526 }
3527
Daniel Sanders658541f2017-04-22 15:53:21 +00003528 if (ChildRec->isSubClassOf("RegisterClass") ||
Daniel Sanders4d4e7652017-10-09 18:14:53 +00003529 ChildRec->isSubClassOf("RegisterOperand") ||
3530 ChildRec->isSubClassOf("ValueType")) {
Daniel Sandersd66e0902017-10-23 18:19:24 +00003531 if (ChildRec->isSubClassOf("RegisterOperand") &&
3532 !ChildRec->isValueUnset("GIZeroRegister")) {
3533 DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>(
Daniel Sanders198447a2017-11-01 00:29:47 +00003534 DstChild->getName(), ChildRec->getValueAsDef("GIZeroRegister"));
Daniel Sanders7438b262017-10-31 23:03:18 +00003535 return InsertPt;
Daniel Sandersd66e0902017-10-23 18:19:24 +00003536 }
3537
Daniel Sanders198447a2017-11-01 00:29:47 +00003538 DstMIBuilder.addRenderer<CopyRenderer>(DstChild->getName());
Daniel Sanders7438b262017-10-31 23:03:18 +00003539 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003540 }
3541
3542 if (ChildRec->isSubClassOf("ComplexPattern")) {
3543 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
3544 if (ComplexPattern == ComplexPatternEquivs.end())
3545 return failedImport(
3546 "SelectionDAG ComplexPattern not mapped to GlobalISel");
3547
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003548 const OperandMatcher &OM = Rule.getOperandMatcher(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00003549 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sanders198447a2017-11-01 00:29:47 +00003550 *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00003551 OM.getAllocatedTemporariesBaseID());
Daniel Sanders7438b262017-10-31 23:03:18 +00003552 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003553 }
3554
3555 return failedImport(
3556 "Dst pattern child def is an unsupported tablegen class");
3557 }
3558
3559 return failedImport("Dst pattern child is an unsupported kind");
3560}
3561
Daniel Sandersc270c502017-03-30 09:36:33 +00003562Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersa7b75262017-10-31 18:50:24 +00003563 RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sanders7438b262017-10-31 23:03:18 +00003564 auto InsertPtOrError = createInstructionRenderer(M.actions_end(), M, Dst);
3565 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00003566 return std::move(Error);
3567
Daniel Sanders7438b262017-10-31 23:03:18 +00003568 action_iterator InsertPt = InsertPtOrError.get();
3569 BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
Daniel Sandersdf258e32017-10-31 19:09:29 +00003570
3571 importExplicitDefRenderers(DstMIBuilder);
3572
Daniel Sanders7438b262017-10-31 23:03:18 +00003573 if (auto Error = importExplicitUseRenderers(InsertPt, M, DstMIBuilder, Dst)
3574 .takeError())
Daniel Sandersdf258e32017-10-31 19:09:29 +00003575 return std::move(Error);
3576
3577 return DstMIBuilder;
3578}
3579
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003580Expected<action_iterator>
3581GlobalISelEmitter::createAndImportSubInstructionRenderer(
Daniel Sanders08464522018-01-29 21:09:12 +00003582 const action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst,
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003583 unsigned TempRegID) {
3584 auto InsertPtOrError = createInstructionRenderer(InsertPt, M, Dst);
3585
3586 // TODO: Assert there's exactly one result.
3587
3588 if (auto Error = InsertPtOrError.takeError())
3589 return std::move(Error);
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003590
3591 BuildMIAction &DstMIBuilder =
3592 *static_cast<BuildMIAction *>(InsertPtOrError.get()->get());
3593
3594 // Assign the result to TempReg.
3595 DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true);
3596
Daniel Sanders08464522018-01-29 21:09:12 +00003597 InsertPtOrError =
3598 importExplicitUseRenderers(InsertPtOrError.get(), M, DstMIBuilder, Dst);
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003599 if (auto Error = InsertPtOrError.takeError())
3600 return std::move(Error);
3601
Daniel Sanders08464522018-01-29 21:09:12 +00003602 M.insertAction<ConstrainOperandsToDefinitionAction>(InsertPt,
3603 DstMIBuilder.getInsnID());
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003604 return InsertPtOrError.get();
3605}
3606
Daniel Sanders7438b262017-10-31 23:03:18 +00003607Expected<action_iterator> GlobalISelEmitter::createInstructionRenderer(
3608 action_iterator InsertPt, RuleMatcher &M, const TreePatternNode *Dst) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00003609 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00003610 if (!DstOp->isSubClassOf("Instruction")) {
3611 if (DstOp->isSubClassOf("ValueType"))
3612 return failedImport(
3613 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00003614 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00003615 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003616 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003617
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003618 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003619 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersdf258e32017-10-31 19:09:29 +00003620 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS")
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003621 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sandersdf258e32017-10-31 19:09:29 +00003622 else if (DstI->TheDef->getName() == "EXTRACT_SUBREG")
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003623 DstI = &Target.getInstruction(RK.getDef("COPY"));
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003624 else if (DstI->TheDef->getName() == "REG_SEQUENCE")
3625 return failedImport("Unable to emit REG_SEQUENCE");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003626
Daniel Sanders198447a2017-11-01 00:29:47 +00003627 return M.insertAction<BuildMIAction>(InsertPt, M.allocateOutputInsnID(),
3628 DstI);
Daniel Sandersdf258e32017-10-31 19:09:29 +00003629}
3630
3631void GlobalISelEmitter::importExplicitDefRenderers(
3632 BuildMIAction &DstMIBuilder) {
3633 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003634 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
3635 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sanders198447a2017-11-01 00:29:47 +00003636 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003637 }
Daniel Sandersdf258e32017-10-31 19:09:29 +00003638}
3639
Daniel Sanders7438b262017-10-31 23:03:18 +00003640Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
3641 action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
Daniel Sandersdf258e32017-10-31 19:09:29 +00003642 const llvm::TreePatternNode *Dst) {
3643 const CodeGenInstruction *DstI = DstMIBuilder.getCGI();
3644 CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator());
Daniel Sandersffc7d582017-03-29 15:37:18 +00003645
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003646 // EXTRACT_SUBREG needs to use a subregister COPY.
Daniel Sandersdf258e32017-10-31 19:09:29 +00003647 if (OrigDstI->TheDef->getName() == "EXTRACT_SUBREG") {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003648 if (!Dst->getChild(0)->isLeaf())
3649 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
3650
Daniel Sanders32291982017-06-28 13:50:04 +00003651 if (DefInit *SubRegInit =
3652 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanders9cbe7c72017-11-01 19:57:57 +00003653 Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
3654 if (!RCDef)
3655 return failedImport("EXTRACT_SUBREG child #0 could not "
3656 "be coerced to a register class");
3657
3658 CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003659 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
3660
3661 const auto &SrcRCDstRCPair =
3662 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
3663 if (SrcRCDstRCPair.hasValue()) {
3664 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
3665 if (SrcRCDstRCPair->first != RC)
3666 return failedImport("EXTRACT_SUBREG requires an additional COPY");
3667 }
3668
Daniel Sanders198447a2017-11-01 00:29:47 +00003669 DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
3670 SubIdx);
Daniel Sanders7438b262017-10-31 23:03:18 +00003671 return InsertPt;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003672 }
3673
3674 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
3675 }
3676
Daniel Sandersffc7d582017-03-29 15:37:18 +00003677 // Render the explicit uses.
Daniel Sandersdf258e32017-10-31 19:09:29 +00003678 unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs;
3679 unsigned ExpectedDstINumUses = Dst->getNumChildren();
3680 if (OrigDstI->TheDef->getName() == "COPY_TO_REGCLASS") {
3681 DstINumUses--; // Ignore the class constraint.
3682 ExpectedDstINumUses--;
3683 }
3684
Daniel Sanders0ed28822017-04-12 08:23:08 +00003685 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00003686 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00003687 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003688 const CGIOperandList::OperandInfo &DstIOperand =
3689 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00003690
Diana Picus382602f2017-05-17 08:57:28 +00003691 // If the operand has default values, introduce them now.
3692 // FIXME: Until we have a decent test case that dictates we should do
3693 // otherwise, we're going to assume that operands with default values cannot
3694 // be specified in the patterns. Therefore, adding them will not cause us to
3695 // end up with too many rendered operands.
3696 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00003697 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00003698 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
3699 return std::move(Error);
3700 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00003701 continue;
3702 }
3703
Daniel Sanders7438b262017-10-31 23:03:18 +00003704 auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder,
3705 Dst->getChild(Child));
3706 if (auto Error = InsertPtOrError.takeError())
Daniel Sandersffc7d582017-03-29 15:37:18 +00003707 return std::move(Error);
Daniel Sanders7438b262017-10-31 23:03:18 +00003708 InsertPt = InsertPtOrError.get();
Daniel Sanders0ed28822017-04-12 08:23:08 +00003709 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003710 }
3711
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003712 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00003713 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00003714 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003715 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00003716 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00003717 " default ones");
3718
Daniel Sanders7438b262017-10-31 23:03:18 +00003719 return InsertPt;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003720}
3721
Diana Picus382602f2017-05-17 08:57:28 +00003722Error GlobalISelEmitter::importDefaultOperandRenderers(
3723 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00003724 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00003725 // Look through ValueType operators.
3726 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
3727 if (const DefInit *DefaultDagOperator =
3728 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
3729 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
3730 DefaultOp = DefaultDagOp->getArg(0);
3731 }
3732 }
3733
3734 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003735 DstMIBuilder.addRenderer<AddRegisterRenderer>(DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00003736 continue;
3737 }
3738
3739 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sanders198447a2017-11-01 00:29:47 +00003740 DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00003741 continue;
3742 }
3743
3744 return failedImport("Could not add default op");
3745 }
3746
3747 return Error::success();
3748}
3749
Daniel Sandersc270c502017-03-30 09:36:33 +00003750Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00003751 BuildMIAction &DstMIBuilder,
3752 const std::vector<Record *> &ImplicitDefs) const {
3753 if (!ImplicitDefs.empty())
3754 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00003755 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00003756}
3757
3758Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003759 // Keep track of the matchers and actions to emit.
Aditya Nandakumarb63e7632018-02-16 22:37:15 +00003760 int Score = P.getPatternComplexity(CGP);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003761 RuleMatcher M(P.getSrcRecord()->getLoc());
Aditya Nandakumarb63e7632018-02-16 22:37:15 +00003762 RuleMatcherScores[M.getRuleID()] = Score;
Daniel Sanders6ea17ed2017-10-31 18:07:03 +00003763 M.addAction<DebugCommentAction>(llvm::to_string(*P.getSrcPattern()) +
3764 " => " +
3765 llvm::to_string(*P.getDstPattern()));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003766
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003767 if (auto Error = importRulePredicates(M, P.getPredicates()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003768 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003769
3770 // Next, analyze the pattern operators.
3771 TreePatternNode *Src = P.getSrcPattern();
3772 TreePatternNode *Dst = P.getDstPattern();
3773
3774 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00003775 if (auto Err = isTrivialOperatorNode(Dst))
3776 return failedImport("Dst pattern root isn't a trivial operator (" +
3777 toString(std::move(Err)) + ")");
3778 if (auto Err = isTrivialOperatorNode(Src))
3779 return failedImport("Src pattern root isn't a trivial operator (" +
3780 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003781
Quentin Colombetaad20be2017-12-15 23:07:42 +00003782 // The different predicates and matchers created during
3783 // addInstructionMatcher use the RuleMatcher M to set up their
3784 // instruction ID (InsnVarID) that are going to be used when
3785 // M is going to be emitted.
3786 // However, the code doing the emission still relies on the IDs
3787 // returned during that process by the RuleMatcher when issuing
3788 // the recordInsn opcodes.
3789 // Because of that:
3790 // 1. The order in which we created the predicates
3791 // and such must be the same as the order in which we emit them,
3792 // and
3793 // 2. We need to reset the generation of the IDs in M somewhere between
3794 // addInstructionMatcher and emit
3795 //
3796 // FIXME: Long term, we don't want to have to rely on this implicit
3797 // naming being the same. One possible solution would be to have
3798 // explicit operator for operation capture and reference those.
3799 // The plus side is that it would expose opportunities to share
3800 // the capture accross rules. The downside is that it would
3801 // introduce a dependency between predicates (captures must happen
3802 // before their first use.)
Daniel Sandersedd07842017-08-17 09:26:14 +00003803 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName());
3804 unsigned TempOpIdx = 0;
3805 auto InsnMatcherOrError =
Daniel Sandersdf39cba2017-10-15 18:22:54 +00003806 createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx);
Daniel Sandersedd07842017-08-17 09:26:14 +00003807 if (auto Error = InsnMatcherOrError.takeError())
3808 return std::move(Error);
3809 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
3810
3811 if (Dst->isLeaf()) {
3812 Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue());
3813
3814 const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef);
3815 if (RCDef) {
3816 // We need to replace the def and all its uses with the specified
3817 // operand. However, we must also insert COPY's wherever needed.
3818 // For now, emit a copy and let the register allocator clean up.
3819 auto &DstI = Target.getInstruction(RK.getDef("COPY"));
3820 const auto &DstIOperand = DstI.Operands[0];
3821
3822 OperandMatcher &OM0 = InsnMatcher.getOperand(0);
3823 OM0.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003824 M.defineOperand(OM0.getSymbolicName(), OM0);
Daniel Sandersedd07842017-08-17 09:26:14 +00003825 OM0.addPredicate<RegisterBankOperandMatcher>(RC);
3826
Daniel Sanders198447a2017-11-01 00:29:47 +00003827 auto &DstMIBuilder =
3828 M.addAction<BuildMIAction>(M.allocateOutputInsnID(), &DstI);
3829 DstMIBuilder.addRenderer<CopyRenderer>(DstIOperand.Name);
3830 DstMIBuilder.addRenderer<CopyRenderer>(Dst->getName());
Daniel Sandersedd07842017-08-17 09:26:14 +00003831 M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC);
3832
3833 // We're done with this pattern! It's eligible for GISel emission; return
3834 // it.
3835 ++NumPatternImported;
3836 return std::move(M);
3837 }
3838
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003839 return failedImport("Dst pattern root isn't a known leaf");
Daniel Sandersedd07842017-08-17 09:26:14 +00003840 }
Daniel Sanders452c8ae2017-05-23 19:33:16 +00003841
Daniel Sandersbee57392017-04-04 13:25:23 +00003842 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003843 Record *DstOp = Dst->getOperator();
3844 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003845 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003846
3847 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003848 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00003849 return failedImport("Src pattern results and dst MI defs are different (" +
3850 to_string(Src->getExtTypes().size()) + " def(s) vs " +
3851 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003852
Daniel Sandersffc7d582017-03-29 15:37:18 +00003853 // The root of the match also has constraints on the register bank so that it
3854 // matches the result instruction.
3855 unsigned OpIdx = 0;
Krzysztof Parzyszek779d98e2017-09-14 16:56:21 +00003856 for (const TypeSetByHwMode &VTy : Src->getExtTypes()) {
3857 (void)VTy;
Daniel Sandersffc7d582017-03-29 15:37:18 +00003858
Daniel Sanders066ebbf2017-02-24 15:43:30 +00003859 const auto &DstIOperand = DstI.Operands[OpIdx];
3860 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003861 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3862 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3863
3864 if (DstIOpRec == nullptr)
3865 return failedImport(
3866 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003867 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3868 if (!Dst->getChild(0)->isLeaf())
3869 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
3870
Daniel Sanders32291982017-06-28 13:50:04 +00003871 // We can assume that a subregister is in the same bank as it's super
3872 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003873 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
3874
3875 if (DstIOpRec == nullptr)
3876 return failedImport(
3877 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003878 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00003879 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003880 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00003881 return failedImport("Dst MI def isn't a register class" +
3882 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003883
Daniel Sandersffc7d582017-03-29 15:37:18 +00003884 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
3885 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersbfa9e2c2017-10-14 00:31:58 +00003886 M.defineOperand(OM.getSymbolicName(), OM);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00003887 OM.addPredicate<RegisterBankOperandMatcher>(
3888 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003889 ++OpIdx;
3890 }
3891
Daniel Sandersa7b75262017-10-31 18:50:24 +00003892 auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst);
Daniel Sandersffc7d582017-03-29 15:37:18 +00003893 if (auto Error = DstMIBuilderOrError.takeError())
3894 return std::move(Error);
3895 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003896
Daniel Sandersffc7d582017-03-29 15:37:18 +00003897 // Render the implicit defs.
3898 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00003899 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00003900 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003901
Daniel Sandersa7b75262017-10-31 18:50:24 +00003902 DstMIBuilder.chooseInsnToMutate(M);
3903
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003904 // Constrain the registers to classes. This is normally derived from the
3905 // emitted instruction but a few instructions require special handling.
3906 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
3907 // COPY_TO_REGCLASS does not provide operand constraints itself but the
3908 // result is constrained to the class given by the second child.
3909 Record *DstIOpRec =
3910 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
3911
3912 if (DstIOpRec == nullptr)
3913 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
3914
3915 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003916 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003917
3918 // We're done with this pattern! It's eligible for GISel emission; return
3919 // it.
3920 ++NumPatternImported;
3921 return std::move(M);
3922 }
3923
3924 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
3925 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
3926 // instructions, the result register class is controlled by the
3927 // subregisters of the operand. As a result, we must constrain the result
3928 // class rather than check that it's already the right one.
3929 if (!Dst->getChild(0)->isLeaf())
3930 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
3931
Daniel Sanders320390b2017-06-28 15:16:03 +00003932 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
3933 if (!SubRegInit)
3934 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003935
Daniel Sanders320390b2017-06-28 15:16:03 +00003936 // Constrain the result to the same register bank as the operand.
3937 Record *DstIOpRec =
3938 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003939
Daniel Sanders320390b2017-06-28 15:16:03 +00003940 if (DstIOpRec == nullptr)
3941 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003942
Daniel Sanders320390b2017-06-28 15:16:03 +00003943 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003944 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003945
Daniel Sanders320390b2017-06-28 15:16:03 +00003946 // It would be nice to leave this constraint implicit but we're required
3947 // to pick a register class so constrain the result to a register class
3948 // that can hold the correct MVT.
3949 //
3950 // FIXME: This may introduce an extra copy if the chosen class doesn't
3951 // actually contain the subregisters.
3952 assert(Src->getExtTypes().size() == 1 &&
3953 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00003954
Daniel Sanders320390b2017-06-28 15:16:03 +00003955 const auto &SrcRCDstRCPair =
3956 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
3957 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00003958 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
3959 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
3960
3961 // We're done with this pattern! It's eligible for GISel emission; return
3962 // it.
3963 ++NumPatternImported;
3964 return std::move(M);
3965 }
3966
3967 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00003968
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003969 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00003970 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00003971 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00003972}
3973
Daniel Sanders649c5852017-10-13 20:42:18 +00003974// Emit imm predicate table and an enum to reference them with.
3975// The 'Predicate_' part of the name is redundant but eliminating it is more
3976// trouble than it's worth.
3977void GlobalISelEmitter::emitImmPredicates(
Daniel Sanders11300ce2017-10-13 21:28:03 +00003978 raw_ostream &OS, StringRef TypeIdentifier, StringRef Type,
3979 std::function<bool(const Record *R)> Filter) {
Daniel Sanders649c5852017-10-13 20:42:18 +00003980 std::vector<const Record *> MatchedRecords;
3981 const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
3982 std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
3983 [&](Record *Record) {
3984 return !Record->getValueAsString("ImmediateCode").empty() &&
3985 Filter(Record);
3986 });
3987
Daniel Sanders11300ce2017-10-13 21:28:03 +00003988 if (!MatchedRecords.empty()) {
3989 OS << "// PatFrag predicates.\n"
3990 << "enum {\n";
Daniel Sanders2fed4ff2017-10-13 21:51:20 +00003991 std::string EnumeratorSeparator =
Daniel Sanders11300ce2017-10-13 21:28:03 +00003992 (" = GIPFP_" + TypeIdentifier + "_Invalid + 1,\n").str();
3993 for (const auto *Record : MatchedRecords) {
3994 OS << " GIPFP_" << TypeIdentifier << "_Predicate_" << Record->getName()
3995 << EnumeratorSeparator;
3996 EnumeratorSeparator = ",\n";
3997 }
3998 OS << "};\n";
Daniel Sanders649c5852017-10-13 20:42:18 +00003999 }
Daniel Sanders11300ce2017-10-13 21:28:03 +00004000
Daniel Sanders32de8bb2017-12-20 14:41:51 +00004001 OS << "bool " << Target.getName() << "InstructionSelector::testImmPredicate_"
Aaron Ballman82e17f52017-12-20 20:09:30 +00004002 << TypeIdentifier << "(unsigned PredicateID, " << Type
4003 << " Imm) const {\n";
4004 if (!MatchedRecords.empty())
4005 OS << " switch (PredicateID) {\n";
Daniel Sanders32de8bb2017-12-20 14:41:51 +00004006 for (const auto *Record : MatchedRecords) {
4007 OS << " case GIPFP_" << TypeIdentifier << "_Predicate_"
4008 << Record->getName() << ": {\n"
4009 << " " << Record->getValueAsString("ImmediateCode") << "\n"
4010 << " llvm_unreachable(\"ImmediateCode should have returned\");\n"
4011 << " return false;\n"
4012 << " }\n";
4013 }
Aaron Ballman82e17f52017-12-20 20:09:30 +00004014 if (!MatchedRecords.empty())
4015 OS << " }\n";
4016 OS << " llvm_unreachable(\"Unknown predicate\");\n"
Daniel Sanders32de8bb2017-12-20 14:41:51 +00004017 << " return false;\n"
4018 << "}\n";
Daniel Sanders649c5852017-10-13 20:42:18 +00004019}
4020
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004021template <class GroupT>
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004022std::vector<Matcher *> GlobalISelEmitter::optimizeRules(
Roman Tereshin2d6d3762018-05-02 20:08:14 +00004023 ArrayRef<Matcher *> Rules,
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004024 std::vector<std::unique_ptr<Matcher>> &MatcherStorage) {
4025
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004026 std::vector<Matcher *> OptRules;
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004027 std::unique_ptr<GroupT> CurrentGroup = make_unique<GroupT>();
4028 assert(CurrentGroup->empty() && "Newly created group isn't empty!");
4029 unsigned NumGroups = 0;
4030
4031 auto ProcessCurrentGroup = [&]() {
4032 if (CurrentGroup->empty())
4033 // An empty group is good to be reused:
4034 return;
4035
4036 // If the group isn't large enough to provide any benefit, move all the
4037 // added rules out of it and make sure to re-create the group to properly
4038 // re-initialize it:
4039 if (CurrentGroup->size() < 2)
4040 for (Matcher *M : CurrentGroup->matchers())
4041 OptRules.push_back(M);
4042 else {
4043 CurrentGroup->finalize();
Roman Tereshin8bdf7be2018-05-21 22:21:24 +00004044 OptRules.push_back(CurrentGroup.get());
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004045 MatcherStorage.emplace_back(std::move(CurrentGroup));
4046 ++NumGroups;
Roman Tereshin8bdf7be2018-05-21 22:21:24 +00004047 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004048 CurrentGroup = make_unique<GroupT>();
4049 };
4050 for (Matcher *Rule : Rules) {
4051 // Greedily add as many matchers as possible to the current group:
4052 if (CurrentGroup->addMatcher(*Rule))
4053 continue;
4054
4055 ProcessCurrentGroup();
4056 assert(CurrentGroup->empty() && "A group wasn't properly re-initialized");
4057
4058 // Try to add the pending matcher to a newly created empty group:
4059 if (!CurrentGroup->addMatcher(*Rule))
4060 // If we couldn't add the matcher to an empty group, that group type
4061 // doesn't support that kind of matchers at all, so just skip it:
4062 OptRules.push_back(Rule);
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004063 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004064 ProcessCurrentGroup();
4065
Nicola Zaghen03d0b912018-05-23 15:09:29 +00004066 LLVM_DEBUG(dbgs() << "NumGroups: " << NumGroups << "\n");
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004067 assert(CurrentGroup->empty() && "The last group wasn't properly processed");
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004068 return OptRules;
4069}
4070
Roman Tereshin2d6d3762018-05-02 20:08:14 +00004071MatchTable
4072GlobalISelEmitter::buildMatchTable(MutableArrayRef<RuleMatcher> Rules,
Roman Tereshinbeb39312018-05-02 20:15:11 +00004073 bool Optimize, bool WithCoverage) {
Roman Tereshin2d6d3762018-05-02 20:08:14 +00004074 std::vector<Matcher *> InputRules;
4075 for (Matcher &Rule : Rules)
4076 InputRules.push_back(&Rule);
4077
4078 if (!Optimize)
Roman Tereshinbeb39312018-05-02 20:15:11 +00004079 return MatchTable::buildTable(InputRules, WithCoverage);
Roman Tereshin2d6d3762018-05-02 20:08:14 +00004080
Roman Tereshin77013602018-05-22 16:54:27 +00004081 unsigned CurrentOrdering = 0;
4082 StringMap<unsigned> OpcodeOrder;
4083 for (RuleMatcher &Rule : Rules) {
4084 const StringRef Opcode = Rule.getOpcode();
4085 assert(!Opcode.empty() && "Didn't expect an undefined opcode");
4086 if (OpcodeOrder.count(Opcode) == 0)
4087 OpcodeOrder[Opcode] = CurrentOrdering++;
4088 }
4089
4090 std::stable_sort(InputRules.begin(), InputRules.end(),
4091 [&OpcodeOrder](const Matcher *A, const Matcher *B) {
4092 auto *L = static_cast<const RuleMatcher *>(A);
4093 auto *R = static_cast<const RuleMatcher *>(B);
4094 return std::make_tuple(OpcodeOrder[L->getOpcode()],
4095 L->getNumOperands()) <
4096 std::make_tuple(OpcodeOrder[R->getOpcode()],
4097 R->getNumOperands());
4098 });
4099
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004100 for (Matcher *Rule : InputRules)
4101 Rule->optimize();
4102
4103 std::vector<std::unique_ptr<Matcher>> MatcherStorage;
Roman Tereshin2d6d3762018-05-02 20:08:14 +00004104 std::vector<Matcher *> OptRules =
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004105 optimizeRules<GroupMatcher>(InputRules, MatcherStorage);
4106
4107 for (Matcher *Rule : OptRules)
4108 Rule->optimize();
Roman Tereshin2d6d3762018-05-02 20:08:14 +00004109
Roman Tereshin0ee082f2018-05-22 19:37:59 +00004110 OptRules = optimizeRules<SwitchMatcher>(OptRules, MatcherStorage);
4111
Roman Tereshinbeb39312018-05-02 20:15:11 +00004112 return MatchTable::buildTable(OptRules, WithCoverage);
Roman Tereshin2d6d3762018-05-02 20:08:14 +00004113}
4114
Roman Tereshinfedae332018-05-23 02:04:19 +00004115void GroupMatcher::optimize() {
4116 GlobalISelEmitter::optimizeRules<GroupMatcher>(Matchers, MatcherStorage)
4117 .swap(Matchers);
4118}
4119
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004120void GlobalISelEmitter::run(raw_ostream &OS) {
Daniel Sandersf76f3152017-11-16 00:46:35 +00004121 if (!UseCoverageFile.empty()) {
4122 RuleCoverage = CodeGenCoverage();
4123 auto RuleCoverageBufOrErr = MemoryBuffer::getFile(UseCoverageFile);
4124 if (!RuleCoverageBufOrErr) {
4125 PrintWarning(SMLoc(), "Missing rule coverage data");
4126 RuleCoverage = None;
4127 } else {
4128 if (!RuleCoverage->parse(*RuleCoverageBufOrErr.get(), Target.getName())) {
4129 PrintWarning(SMLoc(), "Ignoring invalid or missing rule coverage data");
4130 RuleCoverage = None;
4131 }
4132 }
4133 }
4134
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004135 // Track the run-time opcode values
4136 gatherOpcodeValues();
4137 // Track the run-time LLT ID values
4138 gatherTypeIDValues();
4139
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004140 // Track the GINodeEquiv definitions.
4141 gatherNodeEquivs();
4142
4143 emitSourceFileHeader(("Global Instruction Selector for the " +
4144 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00004145 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004146 // Look through the SelectionDAG patterns we found, possibly emitting some.
4147 for (const PatternToMatch &Pat : CGP.ptms()) {
4148 ++NumPatternTotal;
Daniel Sanders7e523672017-11-11 03:23:44 +00004149
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00004150 auto MatcherOrErr = runOnPattern(Pat);
4151
4152 // The pattern analysis can fail, indicating an unsupported pattern.
4153 // Report that if we've been asked to do so.
4154 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004155 if (WarnOnSkippedPatterns) {
4156 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00004157 "Skipped pattern: " + toString(std::move(Err)));
4158 } else {
4159 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004160 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00004161 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00004162 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004163 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00004164
Daniel Sandersf76f3152017-11-16 00:46:35 +00004165 if (RuleCoverage) {
4166 if (RuleCoverage->isCovered(MatcherOrErr->getRuleID()))
4167 ++NumPatternsTested;
4168 else
4169 PrintWarning(Pat.getSrcRecord()->getLoc(),
4170 "Pattern is not covered by a test");
4171 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00004172 Rules.push_back(std::move(MatcherOrErr.get()));
4173 }
4174
Volkan Kelesf7f25682018-01-16 18:44:05 +00004175 // Comparison function to order records by name.
4176 auto orderByName = [](const Record *A, const Record *B) {
4177 return A->getName() < B->getName();
4178 };
4179
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004180 std::vector<Record *> ComplexPredicates =
4181 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
Mandeep Singh Grang1b0e2f22018-04-06 20:18:05 +00004182 llvm::sort(ComplexPredicates.begin(), ComplexPredicates.end(), orderByName);
Volkan Kelesf7f25682018-01-16 18:44:05 +00004183
4184 std::vector<Record *> CustomRendererFns =
4185 RK.getAllDerivedDefinitions("GICustomOperandRenderer");
Mandeep Singh Grang1b0e2f22018-04-06 20:18:05 +00004186 llvm::sort(CustomRendererFns.begin(), CustomRendererFns.end(), orderByName);
Volkan Kelesf7f25682018-01-16 18:44:05 +00004187
Daniel Sanders8a4bae92017-03-14 21:32:08 +00004188 unsigned MaxTemporaries = 0;
4189 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00004190 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00004191
Daniel Sanderse7b0d662017-04-21 15:59:56 +00004192 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
4193 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
4194 << ";\n"
4195 << "using PredicateBitset = "
4196 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
4197 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
4198
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004199 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
4200 << " mutable MatcherState State;\n"
4201 << " typedef "
Daniel Sanders1e4569f2017-10-20 20:55:29 +00004202 "ComplexRendererFns("
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004203 << Target.getName()
4204 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
Volkan Kelesf7f25682018-01-16 18:44:05 +00004205
4206 << " typedef void(" << Target.getName()
4207 << "InstructionSelector::*CustomRendererFn)(MachineInstrBuilder &, const "
4208 "MachineInstr&) "
4209 "const;\n"
4210 << " const ISelInfoTy<PredicateBitset, ComplexMatcherMemFn, "
4211 "CustomRendererFn> "
4212 "ISelInfo;\n";
4213 OS << " static " << Target.getName()
Daniel Sandersea8711b2017-10-16 03:36:29 +00004214 << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
Volkan Kelesf7f25682018-01-16 18:44:05 +00004215 << " static " << Target.getName()
4216 << "InstructionSelector::CustomRendererFn CustomRenderers[];\n"
Roman Tereshin2df4c222018-05-02 20:07:15 +00004217 << " bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const "
Daniel Sanders32de8bb2017-12-20 14:41:51 +00004218 "override;\n"
Roman Tereshin2df4c222018-05-02 20:07:15 +00004219 << " bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) "
Daniel Sanders32de8bb2017-12-20 14:41:51 +00004220 "const override;\n"
Roman Tereshin2df4c222018-05-02 20:07:15 +00004221 << " bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat "
Daniel Sanders32de8bb2017-12-20 14:41:51 +00004222 "&Imm) const override;\n"
Roman Tereshin2df4c222018-05-02 20:07:15 +00004223 << " const int64_t *getMatchTable() const override;\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004224 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00004225
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004226 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
4227 << ", State(" << MaxTemporaries << "),\n"
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004228 << "ISelInfo(TypeObjects, NumTypeObjects, FeatureBitsets"
4229 << ", ComplexPredicateFns, CustomRenderers)\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004230 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00004231
Daniel Sanderse7b0d662017-04-21 15:59:56 +00004232 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
4233 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
4234 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00004235
4236 // Separate subtarget features by how often they must be recomputed.
4237 SubtargetFeatureInfoMap ModuleFeatures;
4238 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
4239 std::inserter(ModuleFeatures, ModuleFeatures.end()),
4240 [](const SubtargetFeatureInfoMap::value_type &X) {
4241 return !X.second.mustRecomputePerFunction();
4242 });
4243 SubtargetFeatureInfoMap FunctionFeatures;
4244 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
4245 std::inserter(FunctionFeatures, FunctionFeatures.end()),
4246 [](const SubtargetFeatureInfoMap::value_type &X) {
4247 return X.second.mustRecomputePerFunction();
4248 });
4249
Daniel Sanderse7b0d662017-04-21 15:59:56 +00004250 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00004251 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
4252 ModuleFeatures, OS);
4253 SubtargetFeatureInfo::emitComputeAvailableFeatures(
4254 Target.getName(), "InstructionSelector",
4255 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
4256 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00004257
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004258 // Emit a table containing the LLT objects needed by the matcher and an enum
4259 // for the matcher to reference them with.
Daniel Sanders032e7f22017-08-17 13:18:35 +00004260 std::vector<LLTCodeGen> TypeObjects;
Daniel Sandersf84bc372018-05-05 20:53:24 +00004261 for (const auto &Ty : KnownTypes)
Daniel Sanders032e7f22017-08-17 13:18:35 +00004262 TypeObjects.push_back(Ty);
Mandeep Singh Grang1b0e2f22018-04-06 20:18:05 +00004263 llvm::sort(TypeObjects.begin(), TypeObjects.end());
Daniel Sanders49980702017-08-23 10:09:25 +00004264 OS << "// LLT Objects.\n"
4265 << "enum {\n";
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004266 for (const auto &TypeObject : TypeObjects) {
4267 OS << " ";
4268 TypeObject.emitCxxEnumValue(OS);
4269 OS << ",\n";
4270 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004271 OS << "};\n";
4272 OS << "const static size_t NumTypeObjects = " << TypeObjects.size() << ";\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004273 << "const static LLT TypeObjects[] = {\n";
4274 for (const auto &TypeObject : TypeObjects) {
4275 OS << " ";
4276 TypeObject.emitCxxConstructorCall(OS);
4277 OS << ",\n";
4278 }
4279 OS << "};\n\n";
4280
4281 // Emit a table containing the PredicateBitsets objects needed by the matcher
4282 // and an enum for the matcher to reference them with.
4283 std::vector<std::vector<Record *>> FeatureBitsets;
4284 for (auto &Rule : Rules)
4285 FeatureBitsets.push_back(Rule.getRequiredFeatures());
Mandeep Singh Grang1b0e2f22018-04-06 20:18:05 +00004286 llvm::sort(
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004287 FeatureBitsets.begin(), FeatureBitsets.end(),
4288 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
4289 if (A.size() < B.size())
4290 return true;
4291 if (A.size() > B.size())
4292 return false;
4293 for (const auto &Pair : zip(A, B)) {
4294 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
4295 return true;
4296 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
4297 return false;
4298 }
4299 return false;
4300 });
4301 FeatureBitsets.erase(
4302 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
4303 FeatureBitsets.end());
Daniel Sanders49980702017-08-23 10:09:25 +00004304 OS << "// Feature bitsets.\n"
4305 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004306 << " GIFBS_Invalid,\n";
4307 for (const auto &FeatureBitset : FeatureBitsets) {
4308 if (FeatureBitset.empty())
4309 continue;
4310 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
4311 }
4312 OS << "};\n"
4313 << "const static PredicateBitset FeatureBitsets[] {\n"
4314 << " {}, // GIFBS_Invalid\n";
4315 for (const auto &FeatureBitset : FeatureBitsets) {
4316 if (FeatureBitset.empty())
4317 continue;
4318 OS << " {";
4319 for (const auto &Feature : FeatureBitset) {
4320 const auto &I = SubtargetFeatures.find(Feature);
4321 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
4322 OS << I->second.getEnumBitName() << ", ";
4323 }
4324 OS << "},\n";
4325 }
4326 OS << "};\n\n";
4327
4328 // Emit complex predicate table and an enum to reference them with.
Daniel Sanders49980702017-08-23 10:09:25 +00004329 OS << "// ComplexPattern predicates.\n"
4330 << "enum {\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00004331 << " GICP_Invalid,\n";
4332 for (const auto &Record : ComplexPredicates)
4333 OS << " GICP_" << Record->getName() << ",\n";
4334 OS << "};\n"
4335 << "// See constructor for table contents\n\n";
4336
Daniel Sanders11300ce2017-10-13 21:28:03 +00004337 emitImmPredicates(OS, "I64", "int64_t", [](const Record *R) {
Daniel Sanders649c5852017-10-13 20:42:18 +00004338 bool Unset;
4339 return !R->getValueAsBitOrUnset("IsAPFloat", Unset) &&
4340 !R->getValueAsBit("IsAPInt");
4341 });
Daniel Sanders11300ce2017-10-13 21:28:03 +00004342 emitImmPredicates(OS, "APFloat", "const APFloat &", [](const Record *R) {
4343 bool Unset;
4344 return R->getValueAsBitOrUnset("IsAPFloat", Unset);
4345 });
4346 emitImmPredicates(OS, "APInt", "const APInt &", [](const Record *R) {
4347 return R->getValueAsBit("IsAPInt");
4348 });
Daniel Sandersea8711b2017-10-16 03:36:29 +00004349 OS << "\n";
4350
4351 OS << Target.getName() << "InstructionSelector::ComplexMatcherMemFn\n"
4352 << Target.getName() << "InstructionSelector::ComplexPredicateFns[] = {\n"
4353 << " nullptr, // GICP_Invalid\n";
4354 for (const auto &Record : ComplexPredicates)
4355 OS << " &" << Target.getName()
4356 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
4357 << ", // " << Record->getName() << "\n";
4358 OS << "};\n\n";
Daniel Sanders2c269f62017-08-24 09:11:20 +00004359
Volkan Kelesf7f25682018-01-16 18:44:05 +00004360 OS << "// Custom renderers.\n"
4361 << "enum {\n"
4362 << " GICR_Invalid,\n";
4363 for (const auto &Record : CustomRendererFns)
4364 OS << " GICR_" << Record->getValueAsString("RendererFn") << ", \n";
4365 OS << "};\n";
4366
4367 OS << Target.getName() << "InstructionSelector::CustomRendererFn\n"
4368 << Target.getName() << "InstructionSelector::CustomRenderers[] = {\n"
4369 << " nullptr, // GICP_Invalid\n";
4370 for (const auto &Record : CustomRendererFns)
4371 OS << " &" << Target.getName()
4372 << "InstructionSelector::" << Record->getValueAsString("RendererFn")
4373 << ", // " << Record->getName() << "\n";
4374 OS << "};\n\n";
4375
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004376 std::stable_sort(Rules.begin(), Rules.end(), [&](const RuleMatcher &A,
4377 const RuleMatcher &B) {
Aditya Nandakumarb63e7632018-02-16 22:37:15 +00004378 int ScoreA = RuleMatcherScores[A.getRuleID()];
4379 int ScoreB = RuleMatcherScores[B.getRuleID()];
4380 if (ScoreA > ScoreB)
4381 return true;
4382 if (ScoreB > ScoreA)
4383 return false;
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004384 if (A.isHigherPriorityThan(B)) {
4385 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
4386 "and less important at "
4387 "the same time");
4388 return true;
4389 }
4390 return false;
4391 });
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004392
Roman Tereshin2df4c222018-05-02 20:07:15 +00004393 OS << "bool " << Target.getName()
4394 << "InstructionSelector::selectImpl(MachineInstr &I, CodeGenCoverage "
4395 "&CoverageInfo) const {\n"
4396 << " MachineFunction &MF = *I.getParent()->getParent();\n"
4397 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
4398 << " // FIXME: This should be computed on a per-function basis rather "
4399 "than per-insn.\n"
4400 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
4401 "&MF);\n"
4402 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
4403 << " NewMIVector OutMIs;\n"
4404 << " State.MIs.clear();\n"
4405 << " State.MIs.push_back(&I);\n\n"
4406 << " if (executeMatchTable(*this, OutMIs, State, ISelInfo"
4407 << ", getMatchTable(), TII, MRI, TRI, RBI, AvailableFeatures"
4408 << ", CoverageInfo)) {\n"
4409 << " return true;\n"
4410 << " }\n\n"
4411 << " return false;\n"
4412 << "}\n\n";
4413
Roman Tereshinbeb39312018-05-02 20:15:11 +00004414 const MatchTable Table =
4415 buildMatchTable(Rules, OptimizeMatchTable, GenerateCoverage);
Roman Tereshin2df4c222018-05-02 20:07:15 +00004416 OS << "const int64_t *" << Target.getName()
4417 << "InstructionSelector::getMatchTable() const {\n";
4418 Table.emitDeclaration(OS);
4419 OS << " return ";
4420 Table.emitUse(OS);
4421 OS << ";\n}\n";
4422 OS << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00004423
4424 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
4425 << "PredicateBitset AvailableModuleFeatures;\n"
4426 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
4427 << "PredicateBitset getAvailableFeatures() const {\n"
4428 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
4429 << "}\n"
4430 << "PredicateBitset\n"
4431 << "computeAvailableModuleFeatures(const " << Target.getName()
4432 << "Subtarget *Subtarget) const;\n"
4433 << "PredicateBitset\n"
4434 << "computeAvailableFunctionFeatures(const " << Target.getName()
4435 << "Subtarget *Subtarget,\n"
4436 << " const MachineFunction *MF) const;\n"
4437 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
4438
4439 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
4440 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
4441 << "AvailableFunctionFeatures()\n"
4442 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004443}
4444
Daniel Sanderse7b0d662017-04-21 15:59:56 +00004445void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
4446 if (SubtargetFeatures.count(Predicate) == 0)
4447 SubtargetFeatures.emplace(
4448 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
4449}
4450
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004451void RuleMatcher::optimize() {
4452 for (auto &Item : InsnVariableIDs) {
4453 InstructionMatcher &InsnMatcher = *Item.first;
4454 for (auto &OM : InsnMatcher.operands()) {
4455 // Register Banks checks rarely fail, but often crash as targets usually
4456 // provide only partially defined RegisterBankInfo::getRegBankFromRegClass
4457 // method. Often the problem is hidden as non-optimized MatchTable checks
4458 // banks rather late, most notably after checking target / function /
4459 // module features and a few opcodes. That makes these checks a)
4460 // beneficial to delay until the very end (we don't want to perform a lot
4461 // of checks that all pass and then fail at the very end) b) not safe to
4462 // have as early checks.
4463 for (auto &OP : OM->predicates())
4464 if (isa<RegisterBankOperandMatcher>(OP) ||
4465 isa<ComplexPatternOperandMatcher>(OP))
4466 EpilogueMatchers.emplace_back(std::move(OP));
4467 OM->eraseNullPredicates();
4468 }
4469 InsnMatcher.optimize();
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004470 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004471 llvm::sort(
4472 EpilogueMatchers.begin(), EpilogueMatchers.end(),
4473 [](const std::unique_ptr<PredicateMatcher> &L,
4474 const std::unique_ptr<PredicateMatcher> &R) {
4475 return std::make_tuple(L->getKind(), L->getInsnVarID(), L->getOpIdx()) <
4476 std::make_tuple(R->getKind(), R->getInsnVarID(), R->getOpIdx());
4477 });
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004478}
4479
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004480bool RuleMatcher::hasFirstCondition() const {
4481 if (insnmatchers_empty())
4482 return false;
4483 InstructionMatcher &Matcher = insnmatchers_front();
4484 if (!Matcher.predicates_empty())
4485 return true;
4486 for (auto &OM : Matcher.operands())
4487 for (auto &OP : OM->predicates())
4488 if (!isa<InstructionOperandMatcher>(OP))
4489 return true;
4490 return false;
4491}
4492
4493const PredicateMatcher &RuleMatcher::getFirstCondition() const {
4494 assert(!insnmatchers_empty() &&
4495 "Trying to get a condition from an empty RuleMatcher");
4496
4497 InstructionMatcher &Matcher = insnmatchers_front();
4498 if (!Matcher.predicates_empty())
4499 return **Matcher.predicates_begin();
4500 // If there is no more predicate on the instruction itself, look at its
4501 // operands.
4502 for (auto &OM : Matcher.operands())
4503 for (auto &OP : OM->predicates())
4504 if (!isa<InstructionOperandMatcher>(OP))
4505 return *OP;
4506
4507 llvm_unreachable("Trying to get a condition from an InstructionMatcher with "
4508 "no conditions");
4509}
4510
4511std::unique_ptr<PredicateMatcher> RuleMatcher::popFirstCondition() {
4512 assert(!insnmatchers_empty() &&
4513 "Trying to pop a condition from an empty RuleMatcher");
4514
4515 InstructionMatcher &Matcher = insnmatchers_front();
4516 if (!Matcher.predicates_empty())
4517 return Matcher.predicates_pop_front();
4518 // If there is no more predicate on the instruction itself, look at its
4519 // operands.
4520 for (auto &OM : Matcher.operands())
4521 for (auto &OP : OM->predicates())
4522 if (!isa<InstructionOperandMatcher>(OP)) {
4523 std::unique_ptr<PredicateMatcher> Result = std::move(OP);
4524 OM->eraseNullPredicates();
4525 return Result;
4526 }
4527
4528 llvm_unreachable("Trying to pop a condition from an InstructionMatcher with "
4529 "no conditions");
4530}
4531
4532bool GroupMatcher::candidateConditionMatches(
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004533 const PredicateMatcher &Predicate) const {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004534
4535 if (empty()) {
4536 // Sharing predicates for nested instructions is not supported yet as we
4537 // currently don't hoist the GIM_RecordInsn's properly, therefore we can
4538 // only work on the original root instruction (InsnVarID == 0):
4539 if (Predicate.getInsnVarID() != 0)
4540 return false;
4541 // ... otherwise an empty group can handle any predicate with no specific
4542 // requirements:
4543 return true;
4544 }
4545
4546 const Matcher &Representative = **Matchers.begin();
4547 const auto &RepresentativeCondition = Representative.getFirstCondition();
4548 // ... if not empty, the group can only accomodate matchers with the exact
4549 // same first condition:
4550 return Predicate.isIdentical(RepresentativeCondition);
4551}
4552
4553bool GroupMatcher::addMatcher(Matcher &Candidate) {
4554 if (!Candidate.hasFirstCondition())
4555 return false;
4556
4557 const PredicateMatcher &Predicate = Candidate.getFirstCondition();
4558 if (!candidateConditionMatches(Predicate))
4559 return false;
4560
4561 Matchers.push_back(&Candidate);
4562 return true;
4563}
4564
4565void GroupMatcher::finalize() {
4566 assert(Conditions.empty() && "Already finalized?");
4567 if (empty())
4568 return;
4569
4570 Matcher &FirstRule = **Matchers.begin();
4571
4572 Conditions.push_back(FirstRule.popFirstCondition());
4573 for (unsigned I = 1, E = Matchers.size(); I < E; ++I)
4574 Matchers[I]->popFirstCondition();
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004575}
4576
4577void GroupMatcher::emit(MatchTable &Table) {
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004578 unsigned LabelID = ~0U;
4579 if (!Conditions.empty()) {
4580 LabelID = Table.allocateLabelID();
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004581 Table << MatchTable::Opcode("GIM_Try", +1)
4582 << MatchTable::Comment("On fail goto")
4583 << MatchTable::JumpTarget(LabelID) << MatchTable::LineBreak;
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004584 }
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004585 for (auto &Condition : Conditions)
4586 Condition->emitPredicateOpcodes(
4587 Table, *static_cast<RuleMatcher *>(*Matchers.begin()));
4588
4589 for (const auto &M : Matchers)
4590 M->emit(Table);
4591
4592 // Exit the group
4593 if (!Conditions.empty())
4594 Table << MatchTable::Opcode("GIM_Reject", -1) << MatchTable::LineBreak
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004595 << MatchTable::Label(LabelID);
Quentin Colombetec76d9c2017-12-18 19:47:41 +00004596}
4597
Roman Tereshin0ee082f2018-05-22 19:37:59 +00004598bool SwitchMatcher::isSupportedPredicateType(const PredicateMatcher &P) {
4599 return isa<InstructionOpcodeMatcher>(P);
4600}
4601
4602bool SwitchMatcher::candidateConditionMatches(
4603 const PredicateMatcher &Predicate) const {
4604
4605 if (empty()) {
4606 // Sharing predicates for nested instructions is not supported yet as we
4607 // currently don't hoist the GIM_RecordInsn's properly, therefore we can
4608 // only work on the original root instruction (InsnVarID == 0):
4609 if (Predicate.getInsnVarID() != 0)
4610 return false;
4611 // ... while an attempt to add even a root matcher to an empty SwitchMatcher
4612 // could fail as not all the types of conditions are supported:
4613 if (!isSupportedPredicateType(Predicate))
4614 return false;
4615 // ... or the condition might not have a proper implementation of
4616 // getValue() / isIdenticalDownToValue() yet:
4617 if (!Predicate.hasValue())
4618 return false;
4619 // ... otherwise an empty Switch can accomodate the condition with no
4620 // further requirements:
4621 return true;
4622 }
4623
4624 const Matcher &CaseRepresentative = **Matchers.begin();
4625 const auto &RepresentativeCondition = CaseRepresentative.getFirstCondition();
4626 // Switch-cases must share the same kind of condition and path to the value it
4627 // checks:
4628 if (!Predicate.isIdenticalDownToValue(RepresentativeCondition))
4629 return false;
4630
4631 const auto Value = Predicate.getValue();
4632 // ... but be unique with respect to the actual value they check:
4633 return Values.count(Value) == 0;
4634}
4635
4636bool SwitchMatcher::addMatcher(Matcher &Candidate) {
4637 if (!Candidate.hasFirstCondition())
4638 return false;
4639
4640 const PredicateMatcher &Predicate = Candidate.getFirstCondition();
4641 if (!candidateConditionMatches(Predicate))
4642 return false;
4643 const auto Value = Predicate.getValue();
4644 Values.insert(Value);
4645
4646 Matchers.push_back(&Candidate);
4647 return true;
4648}
4649
4650void SwitchMatcher::finalize() {
4651 assert(Condition == nullptr && "Already finalized");
4652 assert(Values.size() == Matchers.size() && "Broken SwitchMatcher");
4653 if (empty())
4654 return;
4655
4656 std::stable_sort(Matchers.begin(), Matchers.end(),
4657 [](const Matcher *L, const Matcher *R) {
4658 return L->getFirstCondition().getValue() <
4659 R->getFirstCondition().getValue();
4660 });
4661 Condition = Matchers[0]->popFirstCondition();
4662 for (unsigned I = 1, E = Values.size(); I < E; ++I)
4663 Matchers[I]->popFirstCondition();
4664}
4665
4666void SwitchMatcher::emitPredicateSpecificOpcodes(const PredicateMatcher &P,
4667 MatchTable &Table) {
4668 assert(isSupportedPredicateType(P) && "Predicate type is not supported");
4669
4670 if (const auto *Condition = dyn_cast<InstructionOpcodeMatcher>(&P)) {
4671 Table << MatchTable::Opcode("GIM_SwitchOpcode") << MatchTable::Comment("MI")
4672 << MatchTable::IntValue(Condition->getInsnVarID());
4673 return;
4674 }
4675
4676 llvm_unreachable("emitPredicateSpecificOpcodes is broken: can not handle a "
4677 "predicate type that is claimed to be supported");
4678}
4679
4680void SwitchMatcher::emit(MatchTable &Table) {
4681 assert(Values.size() == Matchers.size() && "Broken SwitchMatcher");
4682 if (empty())
4683 return;
4684 assert(Condition != nullptr &&
4685 "Broken SwitchMatcher, hasn't been finalized?");
4686
4687 std::vector<unsigned> LabelIDs(Values.size());
4688 std::generate(LabelIDs.begin(), LabelIDs.end(),
4689 [&Table]() { return Table.allocateLabelID(); });
4690 const unsigned Default = Table.allocateLabelID();
4691
4692 const int64_t LowerBound = Values.begin()->getRawValue();
4693 const int64_t UpperBound = Values.rbegin()->getRawValue() + 1;
4694
4695 emitPredicateSpecificOpcodes(*Condition, Table);
4696
4697 Table << MatchTable::Comment("[") << MatchTable::IntValue(LowerBound)
4698 << MatchTable::IntValue(UpperBound) << MatchTable::Comment(")")
4699 << MatchTable::Comment("default:") << MatchTable::JumpTarget(Default);
4700
4701 int64_t J = LowerBound;
4702 auto VI = Values.begin();
4703 for (unsigned I = 0, E = Values.size(); I < E; ++I) {
4704 auto V = *VI++;
4705 while (J++ < V.getRawValue())
4706 Table << MatchTable::IntValue(0);
4707 V.turnIntoComment();
4708 Table << MatchTable::LineBreak << V << MatchTable::JumpTarget(LabelIDs[I]);
4709 }
4710 Table << MatchTable::LineBreak;
4711
4712 for (unsigned I = 0, E = Values.size(); I < E; ++I) {
4713 Table << MatchTable::Label(LabelIDs[I]);
4714 Matchers[I]->emit(Table);
4715 Table << MatchTable::Opcode("GIM_Reject") << MatchTable::LineBreak;
4716 }
4717 Table << MatchTable::Label(Default);
4718}
4719
Roman Tereshinf1aa3482018-05-21 23:28:51 +00004720unsigned OperandMatcher::getInsnVarID() const { return Insn.getInsnVarID(); }
Quentin Colombetaad20be2017-12-15 23:07:42 +00004721
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00004722} // end anonymous namespace
4723
Ahmed Bougacha36f70352016-12-21 23:26:20 +00004724//===----------------------------------------------------------------------===//
4725
4726namespace llvm {
4727void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
4728 GlobalISelEmitter(RK).run(OS);
4729}
4730} // End llvm namespace