blob: c7eb7d02c0d6cf742fc882344125bfac3ce6c8f8 [file] [log] [blame]
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001//===- GlobalISelEmitter.cpp - Generate an instruction selector -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11/// This tablegen backend emits code for use by the GlobalISel instruction
12/// selector. See include/llvm/CodeGen/TargetGlobalISel.td.
13///
14/// This file analyzes the patterns recognized by the SelectionDAGISel tablegen
15/// backend, filters out the ones that are unsupported, maps
16/// SelectionDAG-specific constructs to their GlobalISel counterpart
17/// (when applicable: MVT to LLT; SDNode to generic Instruction).
18///
19/// Not all patterns are supported: pass the tablegen invocation
20/// "-warn-on-skipped-patterns" to emit a warning when a pattern is skipped,
21/// as well as why.
22///
23/// The generated file defines a single method:
24/// bool <Target>InstructionSelector::selectImpl(MachineInstr &I) const;
25/// intended to be used in InstructionSelector::select as the first-step
26/// selector for the patterns that don't require complex C++.
27///
28/// FIXME: We'll probably want to eventually define a base
29/// "TargetGenInstructionSelector" class.
30///
31//===----------------------------------------------------------------------===//
32
33#include "CodeGenDAGPatterns.h"
Daniel Sanderse7b0d662017-04-21 15:59:56 +000034#include "SubtargetFeatureInfo.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000035#include "llvm/ADT/Optional.h"
Daniel Sanders0ed28822017-04-12 08:23:08 +000036#include "llvm/ADT/SmallSet.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000037#include "llvm/ADT/Statistic.h"
38#include "llvm/CodeGen/MachineValueType.h"
39#include "llvm/Support/CommandLine.h"
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +000040#include "llvm/Support/Error.h"
Daniel Sanders52b4ce72017-03-07 23:20:35 +000041#include "llvm/Support/LowLevelTypeImpl.h"
Pavel Labath52a82e22017-02-21 09:19:41 +000042#include "llvm/Support/ScopedPrinter.h"
Ahmed Bougacha36f70352016-12-21 23:26:20 +000043#include "llvm/TableGen/Error.h"
44#include "llvm/TableGen/Record.h"
45#include "llvm/TableGen/TableGenBackend.h"
46#include <string>
Daniel Sanders8a4bae92017-03-14 21:32:08 +000047#include <numeric>
Ahmed Bougacha36f70352016-12-21 23:26:20 +000048using namespace llvm;
49
50#define DEBUG_TYPE "gisel-emitter"
51
52STATISTIC(NumPatternTotal, "Total number of patterns");
Daniel Sandersb41ce2b2017-02-20 14:31:27 +000053STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG");
54STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped");
Ahmed Bougacha36f70352016-12-21 23:26:20 +000055STATISTIC(NumPatternEmitted, "Number of patterns emitted");
Daniel Sandersc60abe32017-07-04 15:31:50 +000056/// A unique identifier for a MatchTable.
57static unsigned CurrentMatchTableID = 0;
Ahmed Bougacha36f70352016-12-21 23:26:20 +000058
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 Sandersbdfebb82017-03-15 20:18:38 +000067namespace {
Ahmed Bougacha36f70352016-12-21 23:26:20 +000068//===- Helper functions ---------------------------------------------------===//
69
Daniel Sanders52b4ce72017-03-07 23:20:35 +000070/// This class stands in for LLT wherever we want to tablegen-erate an
71/// equivalent at compiler run-time.
72class LLTCodeGen {
73private:
74 LLT Ty;
75
76public:
77 LLTCodeGen(const LLT &Ty) : Ty(Ty) {}
78
Daniel Sanders6ab0daa2017-07-04 14:35:06 +000079 void emitCxxEnumValue(raw_ostream &OS) const {
80 if (Ty.isScalar()) {
81 OS << "GILLT_s" << Ty.getSizeInBits();
82 return;
83 }
84 if (Ty.isVector()) {
85 OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
86 return;
87 }
88 llvm_unreachable("Unhandled LLT");
89 }
90
Daniel Sanders52b4ce72017-03-07 23:20:35 +000091 void emitCxxConstructorCall(raw_ostream &OS) const {
92 if (Ty.isScalar()) {
93 OS << "LLT::scalar(" << Ty.getSizeInBits() << ")";
94 return;
95 }
96 if (Ty.isVector()) {
Daniel Sanders32291982017-06-28 13:50:04 +000097 OS << "LLT::vector(" << Ty.getNumElements() << ", "
98 << Ty.getScalarSizeInBits() << ")";
Daniel Sanders52b4ce72017-03-07 23:20:35 +000099 return;
100 }
101 llvm_unreachable("Unhandled LLT");
102 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000103
104 const LLT &get() const { return Ty; }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000105
106 /// This ordering is used for std::unique() and std::sort(). There's no
107 /// particular logic behind the order.
108 bool operator<(const LLTCodeGen &Other) const {
109 if (!Ty.isValid())
110 return Other.Ty.isValid();
111 if (Ty.isScalar()) {
112 if (!Other.Ty.isValid())
113 return false;
114 if (Other.Ty.isScalar())
115 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
116 return false;
117 }
118 if (Ty.isVector()) {
119 if (!Other.Ty.isValid() || Other.Ty.isScalar())
120 return false;
121 if (Other.Ty.isVector()) {
122 if (Ty.getNumElements() < Other.Ty.getNumElements())
123 return true;
124 if (Ty.getNumElements() > Other.Ty.getNumElements())
125 return false;
126 return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
127 }
128 return false;
129 }
130 llvm_unreachable("Unhandled LLT");
131 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000132};
133
134class InstructionMatcher;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000135/// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for
136/// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...).
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000137static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000138 MVT VT(SVT);
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000139 if (VT.isVector() && VT.getVectorNumElements() != 1)
Daniel Sanders32291982017-06-28 13:50:04 +0000140 return LLTCodeGen(
141 LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000142 if (VT.isInteger() || VT.isFloatingPoint())
143 return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
144 return None;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000145}
146
Daniel Sandersd0656a32017-04-13 09:45:37 +0000147static std::string explainPredicates(const TreePatternNode *N) {
148 std::string Explanation = "";
149 StringRef Separator = "";
150 for (const auto &P : N->getPredicateFns()) {
151 Explanation +=
152 (Separator + P.getOrigPatFragRecord()->getRecord()->getName()).str();
153 if (P.isAlwaysTrue())
154 Explanation += " always-true";
155 if (P.isImmediatePattern())
156 Explanation += " immediate";
157 }
158 return Explanation;
159}
160
Daniel Sandersd0656a32017-04-13 09:45:37 +0000161std::string explainOperator(Record *Operator) {
162 if (Operator->isSubClassOf("SDNode"))
Craig Topper2b8419a2017-05-31 19:01:11 +0000163 return (" (" + Operator->getValueAsString("Opcode") + ")").str();
Daniel Sandersd0656a32017-04-13 09:45:37 +0000164
165 if (Operator->isSubClassOf("Intrinsic"))
166 return (" (Operator is an Intrinsic, " + Operator->getName() + ")").str();
167
168 return " (Operator not understood)";
169}
170
171/// Helper function to let the emitter report skip reason error messages.
172static Error failedImport(const Twine &Reason) {
173 return make_error<StringError>(Reason, inconvertibleErrorCode());
174}
175
176static Error isTrivialOperatorNode(const TreePatternNode *N) {
177 std::string Explanation = "";
178 std::string Separator = "";
179 if (N->isLeaf()) {
Daniel Sanders3334cc02017-05-23 20:02:48 +0000180 if (isa<IntInit>(N->getLeafValue()))
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000181 return Error::success();
182
Daniel Sandersd0656a32017-04-13 09:45:37 +0000183 Explanation = "Is a leaf";
184 Separator = ", ";
185 }
186
187 if (N->hasAnyPredicate()) {
188 Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")";
189 Separator = ", ";
190 }
191
192 if (N->getTransformFn()) {
193 Explanation += Separator + "Has a transform function";
194 Separator = ", ";
195 }
196
197 if (!N->isLeaf() && !N->hasAnyPredicate() && !N->getTransformFn())
198 return Error::success();
199
200 return failedImport(Explanation);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000201}
202
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +0000203static Record *getInitValueAsRegClass(Init *V) {
204 if (DefInit *VDefInit = dyn_cast<DefInit>(V)) {
205 if (VDefInit->getDef()->isSubClassOf("RegisterOperand"))
206 return VDefInit->getDef()->getValueAsDef("RegClass");
207 if (VDefInit->getDef()->isSubClassOf("RegisterClass"))
208 return VDefInit->getDef();
209 }
210 return nullptr;
211}
212
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000213std::string
214getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
215 std::string Name = "GIFBS";
216 for (const auto &Feature : FeatureBitset)
217 Name += ("_" + Feature->getName()).str();
218 return Name;
219}
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000220//===- Matchers -----------------------------------------------------------===//
221
Daniel Sandersbee57392017-04-04 13:25:23 +0000222class OperandMatcher;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000223class MatchAction;
224
225/// Generates code to check that a match rule matches.
226class RuleMatcher {
227 /// A list of matchers that all need to succeed for the current rule to match.
228 /// FIXME: This currently supports a single match position but could be
229 /// extended to support multiple positions to support div/rem fusion or
230 /// load-multiple instructions.
231 std::vector<std::unique_ptr<InstructionMatcher>> Matchers;
232
233 /// A list of actions that need to be taken when all predicates in this rule
234 /// have succeeded.
235 std::vector<std::unique_ptr<MatchAction>> Actions;
236
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000237 /// A map of instruction matchers to the local variables created by
238 /// emitCxxCaptureStmts().
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000239 std::map<const InstructionMatcher *, unsigned> InsnVariableIDs;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000240
241 /// ID for the next instruction variable defined with defineInsnVar()
242 unsigned NextInsnVarID;
243
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000244 std::vector<Record *> RequiredFeatures;
245
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000246public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000247 RuleMatcher()
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000248 : Matchers(), Actions(), InsnVariableIDs(), NextInsnVarID(0) {}
Zachary Turnerb7dbd872017-03-20 19:56:52 +0000249 RuleMatcher(RuleMatcher &&Other) = default;
250 RuleMatcher &operator=(RuleMatcher &&Other) = default;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000251
252 InstructionMatcher &addInstructionMatcher();
Daniel Sanderse7b0d662017-04-21 15:59:56 +0000253 void addRequiredFeature(Record *Feature);
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000254 const std::vector<Record *> &getRequiredFeatures() const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000255
256 template <class Kind, class... Args> Kind &addAction(Args &&... args);
257
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000258 /// Define an instruction without emitting any code to do so.
259 /// This is used for the root of the match.
260 unsigned implicitlyDefineInsnVar(const InstructionMatcher &Matcher);
261 /// Define an instruction and emit corresponding state-machine opcodes.
262 unsigned defineInsnVar(raw_ostream &OS, const InstructionMatcher &Matcher,
263 unsigned InsnVarID, unsigned OpIdx);
264 unsigned getInsnVarID(const InstructionMatcher &InsnMatcher) const;
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000265
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000266 void emitCxxCaptureStmts(raw_ostream &OS);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000267
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000268 void emit(raw_ostream &OS);
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000269
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000270 /// Compare the priority of this object and B.
271 ///
272 /// Returns true if this object is more important than B.
273 bool isHigherPriorityThan(const RuleMatcher &B) const;
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000274
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000275 /// Report the maximum number of temporary operands needed by the rule
276 /// matcher.
277 unsigned countRendererFns() const;
Daniel Sanders2deea182017-04-22 15:11:04 +0000278
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000279 // FIXME: Remove this as soon as possible
280 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
Daniel Sandersbdfebb82017-03-15 20:18:38 +0000281};
282
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000283template <class PredicateTy> class PredicateListMatcher {
284private:
285 typedef std::vector<std::unique_ptr<PredicateTy>> PredicateVec;
286 PredicateVec Predicates;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000287
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000288public:
289 /// Construct a new operand predicate and add it to the matcher.
290 template <class Kind, class... Args>
291 Kind &addPredicate(Args&&... args) {
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000292 Predicates.emplace_back(
293 llvm::make_unique<Kind>(std::forward<Args>(args)...));
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000294 return *static_cast<Kind *>(Predicates.back().get());
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000295 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000296
Daniel Sanders32291982017-06-28 13:50:04 +0000297 typename PredicateVec::const_iterator predicates_begin() const {
298 return Predicates.begin();
299 }
300 typename PredicateVec::const_iterator predicates_end() const {
301 return Predicates.end();
302 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000303 iterator_range<typename PredicateVec::const_iterator> predicates() const {
304 return make_range(predicates_begin(), predicates_end());
305 }
Daniel Sanders32291982017-06-28 13:50:04 +0000306 typename PredicateVec::size_type predicates_size() const {
307 return Predicates.size();
308 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000309
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000310 /// Emit a C++ expression that tests whether all the predicates are met.
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000311 template <class... Args>
Daniel Sandersf8c804f2017-01-28 11:10:42 +0000312 void emitCxxPredicateListExpr(raw_ostream &OS, Args &&... args) const {
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000313 if (Predicates.empty()) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000314 OS << "// No predicates\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000315 return;
316 }
317
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000318 for (const auto &Predicate : predicates())
Ahmed Bougachab67a3ce2017-01-26 22:07:37 +0000319 Predicate->emitCxxPredicateExpr(OS, std::forward<Args>(args)...);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000320 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000321};
322
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000323/// Generates code to check a predicate of an operand.
324///
325/// Typical predicates include:
326/// * Operand is a particular register.
327/// * Operand is assigned a particular register bank.
328/// * Operand is an MBB.
329class OperandPredicateMatcher {
330public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000331 /// This enum is used for RTTI and also defines the priority that is given to
332 /// the predicate when generating the matcher code. Kinds with higher priority
333 /// must be tested first.
334 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000335 /// The relative priority of OPM_LLT, OPM_RegBank, and OPM_MBB do not matter
336 /// but OPM_Int must have priority over OPM_RegBank since constant integers
337 /// are represented by a virtual register defined by a G_CONSTANT instruction.
Daniel Sanders759ff412017-02-24 13:58:11 +0000338 enum PredicateKind {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000339 OPM_ComplexPattern,
Daniel Sandersbee57392017-04-04 13:25:23 +0000340 OPM_Instruction,
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000341 OPM_Int,
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000342 OPM_LiteralInt,
Daniel Sanders759ff412017-02-24 13:58:11 +0000343 OPM_LLT,
344 OPM_RegBank,
345 OPM_MBB,
346 };
347
348protected:
349 PredicateKind Kind;
350
351public:
352 OperandPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000353 virtual ~OperandPredicateMatcher() {}
354
Daniel Sanders759ff412017-02-24 13:58:11 +0000355 PredicateKind getKind() const { return Kind; }
356
Daniel Sandersbee57392017-04-04 13:25:23 +0000357 /// Return the OperandMatcher for the specified operand or nullptr if there
358 /// isn't one by that name in this operand predicate matcher.
359 ///
360 /// InstructionOperandMatcher is the only subclass that can return non-null
361 /// for this.
362 virtual Optional<const OperandMatcher *>
Daniel Sandersdb7ed372017-04-04 13:52:00 +0000363 getOptionalOperand(StringRef SymbolicName) const {
Daniel Sandersbee57392017-04-04 13:25:23 +0000364 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
365 return None;
366 }
367
368 /// Emit C++ statements to capture instructions into local variables.
369 ///
370 /// Only InstructionOperandMatcher needs to do anything for this method.
371 virtual void emitCxxCaptureStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000372 unsigned InsnVarID, unsigned OpIdx) const {}
Daniel Sandersbee57392017-04-04 13:25:23 +0000373
Daniel Sanderse604ef52017-02-20 15:30:43 +0000374 /// Emit a C++ expression that checks the predicate for the given operand.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000375 virtual void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000376 unsigned InsnVarID,
377 unsigned OpIdx) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000378
379 /// Compare the priority of this object and B.
380 ///
381 /// Returns true if this object is more important than B.
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000382 virtual bool isHigherPriorityThan(const OperandPredicateMatcher &B) const {
383 return Kind < B.Kind;
Daniel Sanders759ff412017-02-24 13:58:11 +0000384 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000385
386 /// Report the maximum number of temporary operands needed by the predicate
387 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000388 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000389};
390
391/// Generates code to check that an operand is a particular LLT.
392class LLTOperandMatcher : public OperandPredicateMatcher {
393protected:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000394 LLTCodeGen Ty;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000395
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000396public:
Daniel Sanders52b4ce72017-03-07 23:20:35 +0000397 LLTOperandMatcher(const LLTCodeGen &Ty)
Daniel Sanders759ff412017-02-24 13:58:11 +0000398 : OperandPredicateMatcher(OPM_LLT), Ty(Ty) {}
399
400 static bool classof(const OperandPredicateMatcher *P) {
401 return P->getKind() == OPM_LLT;
402 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000403
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000404 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000405 unsigned InsnVarID, unsigned OpIdx) const override {
406 OS << " GIM_CheckType, /*MI*/" << InsnVarID << ", /*Op*/" << OpIdx
407 << ", /*Type*/";
408 Ty.emitCxxEnumValue(OS);
409 OS << ", \n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000410 }
411};
412
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000413/// Generates code to check that an operand is a particular target constant.
414class ComplexPatternOperandMatcher : public OperandPredicateMatcher {
415protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000416 const OperandMatcher &Operand;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000417 const Record &TheDef;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000418
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000419 unsigned getAllocatedTemporariesBaseID() const;
420
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000421public:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000422 ComplexPatternOperandMatcher(const OperandMatcher &Operand,
423 const Record &TheDef)
424 : OperandPredicateMatcher(OPM_ComplexPattern), Operand(Operand),
425 TheDef(TheDef) {}
426
427 static bool classof(const OperandPredicateMatcher *P) {
428 return P->getKind() == OPM_ComplexPattern;
429 }
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000430
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000431 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000432 unsigned InsnVarID, unsigned OpIdx) const override {
Daniel Sanders2deea182017-04-22 15:11:04 +0000433 unsigned ID = getAllocatedTemporariesBaseID();
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000434 OS << " GIM_CheckComplexPattern, /*MI*/" << InsnVarID << ", /*Op*/"
435 << OpIdx << ", /*Renderer*/" << ID << ", GICP_"
436 << TheDef.getName() << ",\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000437 }
438
Daniel Sanders2deea182017-04-22 15:11:04 +0000439 unsigned countRendererFns() const override {
440 return 1;
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000441 }
442};
443
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000444/// Generates code to check that an operand is in a particular register bank.
445class RegisterBankOperandMatcher : public OperandPredicateMatcher {
446protected:
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000447 const CodeGenRegisterClass &RC;
448
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000449public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000450 RegisterBankOperandMatcher(const CodeGenRegisterClass &RC)
451 : OperandPredicateMatcher(OPM_RegBank), RC(RC) {}
452
453 static bool classof(const OperandPredicateMatcher *P) {
454 return P->getKind() == OPM_RegBank;
455 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000456
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000457 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000458 unsigned InsnVarID, unsigned OpIdx) const override {
459 OS << " GIM_CheckRegBankForClass, /*MI*/" << InsnVarID << ", /*Op*/"
460 << OpIdx << ", /*RC*/" << RC.getQualifiedName() << "RegClassID,\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000461 }
462};
463
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000464/// Generates code to check that an operand is a basic block.
465class MBBOperandMatcher : public OperandPredicateMatcher {
466public:
Daniel Sanders759ff412017-02-24 13:58:11 +0000467 MBBOperandMatcher() : OperandPredicateMatcher(OPM_MBB) {}
468
469 static bool classof(const OperandPredicateMatcher *P) {
470 return P->getKind() == OPM_MBB;
471 }
472
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000473 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000474 unsigned InsnVarID, unsigned OpIdx) const override {
475 OS << " GIM_CheckIsMBB, /*MI*/" << InsnVarID << ", /*Op*/" << OpIdx << ",\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000476 }
477};
478
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000479/// Generates code to check that an operand is a G_CONSTANT with a particular
480/// int.
481class ConstantIntOperandMatcher : public OperandPredicateMatcher {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000482protected:
483 int64_t Value;
484
485public:
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000486 ConstantIntOperandMatcher(int64_t Value)
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000487 : OperandPredicateMatcher(OPM_Int), Value(Value) {}
488
489 static bool classof(const OperandPredicateMatcher *P) {
490 return P->getKind() == OPM_Int;
491 }
492
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000493 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000494 unsigned InsnVarID, unsigned OpIdx) const override {
495 OS << " GIM_CheckConstantInt, /*MI*/" << InsnVarID << ", /*Op*/"
496 << OpIdx << ", " << Value << ",\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000497 }
498};
499
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000500/// Generates code to check that an operand is a raw int (where MO.isImm() or
501/// MO.isCImm() is true).
502class LiteralIntOperandMatcher : public OperandPredicateMatcher {
503protected:
504 int64_t Value;
505
506public:
507 LiteralIntOperandMatcher(int64_t Value)
508 : OperandPredicateMatcher(OPM_LiteralInt), Value(Value) {}
509
510 static bool classof(const OperandPredicateMatcher *P) {
511 return P->getKind() == OPM_LiteralInt;
512 }
513
514 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000515 unsigned InsnVarID, unsigned OpIdx) const override {
516 OS << " GIM_CheckLiteralInt, /*MI*/" << InsnVarID << ", /*Op*/"
517 << OpIdx << ", " << Value << ",\n";
Daniel Sanders452c8ae2017-05-23 19:33:16 +0000518 }
519};
520
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000521/// Generates code to check that a set of predicates match for a particular
522/// operand.
523class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
524protected:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000525 InstructionMatcher &Insn;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000526 unsigned OpIdx;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000527 std::string SymbolicName;
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000528
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000529 /// The index of the first temporary variable allocated to this operand. The
530 /// number of allocated temporaries can be found with
Daniel Sanders2deea182017-04-22 15:11:04 +0000531 /// countRendererFns().
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000532 unsigned AllocatedTemporariesBaseID;
533
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000534public:
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000535 OperandMatcher(InstructionMatcher &Insn, unsigned OpIdx,
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000536 const std::string &SymbolicName,
537 unsigned AllocatedTemporariesBaseID)
538 : Insn(Insn), OpIdx(OpIdx), SymbolicName(SymbolicName),
539 AllocatedTemporariesBaseID(AllocatedTemporariesBaseID) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000540
541 bool hasSymbolicName() const { return !SymbolicName.empty(); }
542 const StringRef getSymbolicName() const { return SymbolicName; }
Daniel Sandersffc7d582017-03-29 15:37:18 +0000543 void setSymbolicName(StringRef Name) {
544 assert(SymbolicName.empty() && "Operand already has a symbolic name");
545 SymbolicName = Name;
546 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000547 unsigned getOperandIndex() const { return OpIdx; }
548
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000549 std::string getOperandExpr(unsigned InsnVarID) const {
550 return "State.MIs[" + llvm::to_string(InsnVarID) + "]->getOperand(" +
551 llvm::to_string(OpIdx) + ")";
Daniel Sanderse604ef52017-02-20 15:30:43 +0000552 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000553
Daniel Sandersbee57392017-04-04 13:25:23 +0000554 Optional<const OperandMatcher *>
555 getOptionalOperand(StringRef DesiredSymbolicName) const {
556 assert(!DesiredSymbolicName.empty() && "Cannot lookup unnamed operand");
557 if (DesiredSymbolicName == SymbolicName)
558 return this;
559 for (const auto &OP : predicates()) {
560 const auto &MaybeOperand = OP->getOptionalOperand(DesiredSymbolicName);
561 if (MaybeOperand.hasValue())
562 return MaybeOperand.getValue();
563 }
564 return None;
565 }
566
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000567 InstructionMatcher &getInstructionMatcher() const { return Insn; }
568
Daniel Sandersbee57392017-04-04 13:25:23 +0000569 /// Emit C++ statements to capture instructions into local variables.
570 void emitCxxCaptureStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000571 unsigned InsnVarID) const {
Daniel Sandersbee57392017-04-04 13:25:23 +0000572 for (const auto &Predicate : predicates())
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000573 Predicate->emitCxxCaptureStmts(OS, Rule, InsnVarID, OpIdx);
Daniel Sandersbee57392017-04-04 13:25:23 +0000574 }
575
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000576 /// Emit a C++ expression that tests whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000577 /// InsnVarID matches all the predicates and all the operands.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000578 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000579 unsigned InsnVarID) const {
580 OS << " // MIs[" << InsnVarID << "] ";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000581 if (SymbolicName.empty())
582 OS << "Operand " << OpIdx;
583 else
584 OS << SymbolicName;
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000585 OS << "\n";
586 emitCxxPredicateListExpr(OS, Rule, InsnVarID, OpIdx);
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000587 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000588
589 /// Compare the priority of this object and B.
590 ///
591 /// Returns true if this object is more important than B.
592 bool isHigherPriorityThan(const OperandMatcher &B) const {
593 // Operand matchers involving more predicates have higher priority.
594 if (predicates_size() > B.predicates_size())
595 return true;
596 if (predicates_size() < B.predicates_size())
597 return false;
598
599 // This assumes that predicates are added in a consistent order.
600 for (const auto &Predicate : zip(predicates(), B.predicates())) {
601 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
602 return true;
603 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
604 return false;
605 }
606
607 return false;
608 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000609
610 /// Report the maximum number of temporary operands needed by the operand
611 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000612 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000613 return std::accumulate(
614 predicates().begin(), predicates().end(), 0,
615 [](unsigned A,
616 const std::unique_ptr<OperandPredicateMatcher> &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +0000617 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000618 });
619 }
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000620
621 unsigned getAllocatedTemporariesBaseID() const {
622 return AllocatedTemporariesBaseID;
623 }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000624};
625
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000626unsigned ComplexPatternOperandMatcher::getAllocatedTemporariesBaseID() const {
627 return Operand.getAllocatedTemporariesBaseID();
628}
629
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000630/// Generates code to check a predicate on an instruction.
631///
632/// Typical predicates include:
633/// * The opcode of the instruction is a particular value.
634/// * The nsw/nuw flag is/isn't set.
635class InstructionPredicateMatcher {
Daniel Sanders759ff412017-02-24 13:58:11 +0000636protected:
637 /// This enum is used for RTTI and also defines the priority that is given to
638 /// the predicate when generating the matcher code. Kinds with higher priority
639 /// must be tested first.
640 enum PredicateKind {
641 IPM_Opcode,
642 };
643
644 PredicateKind Kind;
645
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000646public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000647 InstructionPredicateMatcher(PredicateKind Kind) : Kind(Kind) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000648 virtual ~InstructionPredicateMatcher() {}
649
Daniel Sanders759ff412017-02-24 13:58:11 +0000650 PredicateKind getKind() const { return Kind; }
651
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000652 /// Emit a C++ expression that tests whether the instruction named in
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000653 /// InsnVarID matches the predicate.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000654 virtual void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000655 unsigned InsnVarID) const = 0;
Daniel Sanders759ff412017-02-24 13:58:11 +0000656
657 /// Compare the priority of this object and B.
658 ///
659 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +0000660 virtual bool
661 isHigherPriorityThan(const InstructionPredicateMatcher &B) const {
Daniel Sanders759ff412017-02-24 13:58:11 +0000662 return Kind < B.Kind;
663 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000664
665 /// Report the maximum number of temporary operands needed by the predicate
666 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000667 virtual unsigned countRendererFns() const { return 0; }
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000668};
669
670/// Generates code to check the opcode of an instruction.
671class InstructionOpcodeMatcher : public InstructionPredicateMatcher {
672protected:
673 const CodeGenInstruction *I;
674
675public:
Daniel Sanders8d4d72f2017-02-24 14:53:35 +0000676 InstructionOpcodeMatcher(const CodeGenInstruction *I)
677 : InstructionPredicateMatcher(IPM_Opcode), I(I) {}
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000678
Daniel Sanders759ff412017-02-24 13:58:11 +0000679 static bool classof(const InstructionPredicateMatcher *P) {
680 return P->getKind() == IPM_Opcode;
681 }
682
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000683 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000684 unsigned InsnVarID) const override {
685 OS << " GIM_CheckOpcode, /*MI*/" << InsnVarID << ", " << I->Namespace
686 << "::" << I->TheDef->getName() << ",\n";
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000687 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000688
689 /// Compare the priority of this object and B.
690 ///
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000691 /// Returns true if this object is more important than B.
Daniel Sanders32291982017-06-28 13:50:04 +0000692 bool
693 isHigherPriorityThan(const InstructionPredicateMatcher &B) const override {
Daniel Sanders759ff412017-02-24 13:58:11 +0000694 if (InstructionPredicateMatcher::isHigherPriorityThan(B))
695 return true;
696 if (B.InstructionPredicateMatcher::isHigherPriorityThan(*this))
697 return false;
698
699 // Prioritize opcodes for cosmetic reasons in the generated source. Although
700 // this is cosmetic at the moment, we may want to drive a similar ordering
701 // using instruction frequency information to improve compile time.
702 if (const InstructionOpcodeMatcher *BO =
703 dyn_cast<InstructionOpcodeMatcher>(&B))
704 return I->TheDef->getName() < BO->I->TheDef->getName();
705
706 return false;
707 };
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000708};
709
710/// Generates code to check that a set of predicates and operands match for a
711/// particular instruction.
712///
713/// Typical predicates include:
714/// * Has a specific opcode.
715/// * Has an nsw/nuw flag or doesn't.
716class InstructionMatcher
717 : public PredicateListMatcher<InstructionPredicateMatcher> {
718protected:
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000719 typedef std::vector<std::unique_ptr<OperandMatcher>> OperandVec;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000720
721 /// The operands to match. All rendered operands must be present even if the
722 /// condition is always true.
723 OperandVec Operands;
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000724
725public:
726 /// Add an operand to the matcher.
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000727 OperandMatcher &addOperand(unsigned OpIdx, const std::string &SymbolicName,
728 unsigned AllocatedTemporariesBaseID) {
729 Operands.emplace_back(new OperandMatcher(*this, OpIdx, SymbolicName,
730 AllocatedTemporariesBaseID));
731 return *Operands.back();
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000732 }
733
Daniel Sandersffc7d582017-03-29 15:37:18 +0000734 OperandMatcher &getOperand(unsigned OpIdx) {
735 auto I = std::find_if(Operands.begin(), Operands.end(),
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000736 [&OpIdx](const std::unique_ptr<OperandMatcher> &X) {
737 return X->getOperandIndex() == OpIdx;
Daniel Sandersffc7d582017-03-29 15:37:18 +0000738 });
739 if (I != Operands.end())
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000740 return **I;
Daniel Sandersffc7d582017-03-29 15:37:18 +0000741 llvm_unreachable("Failed to lookup operand");
742 }
743
Daniel Sandersbee57392017-04-04 13:25:23 +0000744 Optional<const OperandMatcher *>
745 getOptionalOperand(StringRef SymbolicName) const {
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000746 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
Daniel Sandersbee57392017-04-04 13:25:23 +0000747 for (const auto &Operand : Operands) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000748 const auto &OM = Operand->getOptionalOperand(SymbolicName);
Daniel Sandersbee57392017-04-04 13:25:23 +0000749 if (OM.hasValue())
750 return OM.getValue();
751 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000752 return None;
753 }
754
Daniel Sandersdb7ed372017-04-04 13:52:00 +0000755 const OperandMatcher &getOperand(StringRef SymbolicName) const {
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000756 Optional<const OperandMatcher *>OM = getOptionalOperand(SymbolicName);
757 if (OM.hasValue())
758 return *OM.getValue();
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000759 llvm_unreachable("Failed to lookup operand");
760 }
761
762 unsigned getNumOperands() const { return Operands.size(); }
Daniel Sandersbee57392017-04-04 13:25:23 +0000763 OperandVec::iterator operands_begin() { return Operands.begin(); }
764 OperandVec::iterator operands_end() { return Operands.end(); }
765 iterator_range<OperandVec::iterator> operands() {
766 return make_range(operands_begin(), operands_end());
767 }
Daniel Sandersffc7d582017-03-29 15:37:18 +0000768 OperandVec::const_iterator operands_begin() const { return Operands.begin(); }
769 OperandVec::const_iterator operands_end() const { return Operands.end(); }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000770 iterator_range<OperandVec::const_iterator> operands() const {
771 return make_range(operands_begin(), operands_end());
772 }
773
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000774 /// Emit C++ statements to check the shape of the match and capture
775 /// instructions into local variables.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000776 void emitCxxCaptureStmts(raw_ostream &OS, RuleMatcher &Rule,
777 unsigned InsnID) {
778 OS << " GIM_CheckNumOperands, /*MI*/" << InsnID << ", /*Expected*/"
779 << getNumOperands() << ",\n";
780 for (const auto &Operand : Operands)
781 Operand->emitCxxCaptureStmts(OS, Rule, InsnID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000782 }
783
Daniel Sandersdc662ff2017-01-26 11:10:14 +0000784 /// Emit a C++ expression that tests whether the instruction named in
785 /// InsnVarName matches all the predicates and all the operands.
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000786 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000787 unsigned InsnVarID) const {
788 emitCxxPredicateListExpr(OS, Rule, InsnVarID);
789 for (const auto &Operand : Operands)
790 Operand->emitCxxPredicateExpr(OS, Rule, InsnVarID);
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000791 }
Daniel Sanders759ff412017-02-24 13:58:11 +0000792
793 /// Compare the priority of this object and B.
794 ///
795 /// Returns true if this object is more important than B.
796 bool isHigherPriorityThan(const InstructionMatcher &B) const {
797 // Instruction matchers involving more operands have higher priority.
798 if (Operands.size() > B.Operands.size())
799 return true;
800 if (Operands.size() < B.Operands.size())
801 return false;
802
803 for (const auto &Predicate : zip(predicates(), B.predicates())) {
804 if (std::get<0>(Predicate)->isHigherPriorityThan(*std::get<1>(Predicate)))
805 return true;
806 if (std::get<1>(Predicate)->isHigherPriorityThan(*std::get<0>(Predicate)))
807 return false;
808 }
809
810 for (const auto &Operand : zip(Operands, B.Operands)) {
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000811 if (std::get<0>(Operand)->isHigherPriorityThan(*std::get<1>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +0000812 return true;
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000813 if (std::get<1>(Operand)->isHigherPriorityThan(*std::get<0>(Operand)))
Daniel Sanders759ff412017-02-24 13:58:11 +0000814 return false;
815 }
816
817 return false;
818 };
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000819
820 /// Report the maximum number of temporary operands needed by the instruction
821 /// matcher.
Daniel Sanders2deea182017-04-22 15:11:04 +0000822 unsigned countRendererFns() const {
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000823 return std::accumulate(predicates().begin(), predicates().end(), 0,
824 [](unsigned A,
825 const std::unique_ptr<InstructionPredicateMatcher>
826 &Predicate) {
Daniel Sanders2deea182017-04-22 15:11:04 +0000827 return A + Predicate->countRendererFns();
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000828 }) +
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000829 std::accumulate(
830 Operands.begin(), Operands.end(), 0,
831 [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) {
Daniel Sanders2deea182017-04-22 15:11:04 +0000832 return A + Operand->countRendererFns();
Daniel Sanders4f3eb242017-04-05 13:14:03 +0000833 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +0000834 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +0000835};
836
Daniel Sandersbee57392017-04-04 13:25:23 +0000837/// Generates code to check that the operand is a register defined by an
838/// instruction that matches the given instruction matcher.
839///
840/// For example, the pattern:
841/// (set $dst, (G_MUL (G_ADD $src1, $src2), $src3))
842/// would use an InstructionOperandMatcher for operand 1 of the G_MUL to match
843/// the:
844/// (G_ADD $src1, $src2)
845/// subpattern.
846class InstructionOperandMatcher : public OperandPredicateMatcher {
847protected:
848 std::unique_ptr<InstructionMatcher> InsnMatcher;
849
850public:
851 InstructionOperandMatcher()
852 : OperandPredicateMatcher(OPM_Instruction),
853 InsnMatcher(new InstructionMatcher()) {}
854
855 static bool classof(const OperandPredicateMatcher *P) {
856 return P->getKind() == OPM_Instruction;
857 }
858
859 InstructionMatcher &getInsnMatcher() const { return *InsnMatcher; }
860
861 Optional<const OperandMatcher *>
862 getOptionalOperand(StringRef SymbolicName) const override {
863 assert(!SymbolicName.empty() && "Cannot lookup unnamed operand");
864 return InsnMatcher->getOptionalOperand(SymbolicName);
865 }
866
867 void emitCxxCaptureStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000868 unsigned InsnID, unsigned OpIdx) const override {
869 unsigned InsnVarID = Rule.defineInsnVar(OS, *InsnMatcher, InsnID, OpIdx);
870 InsnMatcher->emitCxxCaptureStmts(OS, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +0000871 }
872
873 void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +0000874 unsigned InsnVarID_,
875 unsigned OpIdx_) const override {
876 unsigned InsnVarID = Rule.getInsnVarID(*InsnMatcher);
877 InsnMatcher->emitCxxPredicateExpr(OS, Rule, InsnVarID);
Daniel Sandersbee57392017-04-04 13:25:23 +0000878 }
879};
880
Daniel Sanders43c882c2017-02-01 10:53:10 +0000881//===- Actions ------------------------------------------------------------===//
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000882class OperandRenderer {
883public:
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000884 enum RendererKind {
885 OR_Copy,
886 OR_CopySubReg,
887 OR_Imm,
888 OR_Register,
889 OR_ComplexPattern
890 };
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000891
892protected:
893 RendererKind Kind;
894
895public:
896 OperandRenderer(RendererKind Kind) : Kind(Kind) {}
897 virtual ~OperandRenderer() {}
898
899 RendererKind getKind() const { return Kind; }
900
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000901 virtual void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const = 0;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000902};
903
904/// A CopyRenderer emits code to copy a single operand from an existing
905/// instruction to the one being built.
906class CopyRenderer : public OperandRenderer {
907protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000908 unsigned NewInsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000909 /// The matcher for the instruction that this operand is copied from.
910 /// This provides the facility for looking up an a operand by it's name so
911 /// that it can be used as a source for the instruction being built.
912 const InstructionMatcher &Matched;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000913 /// The name of the operand.
914 const StringRef SymbolicName;
915
916public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000917 CopyRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
918 StringRef SymbolicName)
919 : OperandRenderer(OR_Copy), NewInsnID(NewInsnID), Matched(Matched),
920 SymbolicName(SymbolicName) {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000921
922 static bool classof(const OperandRenderer *R) {
923 return R->getKind() == OR_Copy;
924 }
925
926 const StringRef getSymbolicName() const { return SymbolicName; }
927
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000928 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
929 const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000930 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sandersa6cfce62017-07-05 14:50:18 +0000931 OS << " GIR_Copy, /*NewInsnID*/" << NewInsnID << ", /*OldInsnID*/"
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000932 << OldInsnVarID << ", /*OpIdx*/" << Operand.getOperandIndex() << ", // "
933 << SymbolicName << "\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000934 }
935};
936
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000937/// A CopySubRegRenderer emits code to copy a single register operand from an
938/// existing instruction to the one being built and indicate that only a
939/// subregister should be copied.
940class CopySubRegRenderer : public OperandRenderer {
941protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000942 unsigned NewInsnID;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000943 /// The matcher for the instruction that this operand is copied from.
944 /// This provides the facility for looking up an a operand by it's name so
945 /// that it can be used as a source for the instruction being built.
946 const InstructionMatcher &Matched;
947 /// The name of the operand.
948 const StringRef SymbolicName;
949 /// The subregister to extract.
950 const CodeGenSubRegIndex *SubReg;
951
952public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000953 CopySubRegRenderer(unsigned NewInsnID, const InstructionMatcher &Matched,
954 StringRef SymbolicName, const CodeGenSubRegIndex *SubReg)
955 : OperandRenderer(OR_CopySubReg), NewInsnID(NewInsnID), Matched(Matched),
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000956 SymbolicName(SymbolicName), SubReg(SubReg) {}
957
958 static bool classof(const OperandRenderer *R) {
959 return R->getKind() == OR_CopySubReg;
960 }
961
962 const StringRef getSymbolicName() const { return SymbolicName; }
963
964 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
965 const OperandMatcher &Operand = Matched.getOperand(SymbolicName);
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000966 unsigned OldInsnVarID = Rule.getInsnVarID(Operand.getInstructionMatcher());
Daniel Sandersa6cfce62017-07-05 14:50:18 +0000967 OS << " GIR_CopySubReg, /*NewInsnID*/" << NewInsnID
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000968 << ", /*OldInsnID*/" << OldInsnVarID << ", /*OpIdx*/"
969 << Operand.getOperandIndex() << ", /*SubRegIdx*/" << SubReg->EnumValue
970 << ", // " << SymbolicName << "\n";
Daniel Sanderscc36dbf2017-06-27 10:11:39 +0000971 }
972};
973
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000974/// Adds a specific physical register to the instruction being built.
975/// This is typically useful for WZR/XZR on AArch64.
976class AddRegisterRenderer : public OperandRenderer {
977protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000978 unsigned InsnID;
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000979 const Record *RegisterDef;
980
981public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000982 AddRegisterRenderer(unsigned InsnID, const Record *RegisterDef)
983 : OperandRenderer(OR_Register), InsnID(InsnID), RegisterDef(RegisterDef) {
984 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000985
986 static bool classof(const OperandRenderer *R) {
987 return R->getKind() == OR_Register;
988 }
989
Daniel Sandersb96f40d2017-03-20 15:20:42 +0000990 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sandersd93a35a2017-07-05 09:39:33 +0000991 OS << " GIR_AddRegister, /*InsnID*/" << InsnID << ", "
992 << (RegisterDef->getValue("Namespace")
993 ? RegisterDef->getValueAsString("Namespace")
994 : "")
995 << "::" << RegisterDef->getName() << ",\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +0000996 }
997};
998
Daniel Sanders0ed28822017-04-12 08:23:08 +0000999/// Adds a specific immediate to the instruction being built.
1000class ImmRenderer : public OperandRenderer {
1001protected:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001002 unsigned InsnID;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001003 int64_t Imm;
1004
1005public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001006 ImmRenderer(unsigned InsnID, int64_t Imm)
1007 : OperandRenderer(OR_Imm), InsnID(InsnID), Imm(Imm) {}
Daniel Sanders0ed28822017-04-12 08:23:08 +00001008
1009 static bool classof(const OperandRenderer *R) {
1010 return R->getKind() == OR_Imm;
1011 }
1012
1013 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001014 OS << " GIR_AddImm, /*InsnID*/" << InsnID << ", /*Imm*/" << Imm
1015 << ",\n";
Daniel Sanders0ed28822017-04-12 08:23:08 +00001016 }
1017};
1018
Daniel Sanders2deea182017-04-22 15:11:04 +00001019/// Adds operands by calling a renderer function supplied by the ComplexPattern
1020/// matcher function.
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001021class RenderComplexPatternOperand : public OperandRenderer {
1022private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001023 unsigned InsnID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001024 const Record &TheDef;
Daniel Sanders2deea182017-04-22 15:11:04 +00001025 /// The name of the operand.
1026 const StringRef SymbolicName;
1027 /// The renderer number. This must be unique within a rule since it's used to
1028 /// identify a temporary variable to hold the renderer function.
1029 unsigned RendererID;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001030
1031 unsigned getNumOperands() const {
1032 return TheDef.getValueAsDag("Operands")->getNumArgs();
1033 }
1034
1035public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001036 RenderComplexPatternOperand(unsigned InsnID, const Record &TheDef,
1037 StringRef SymbolicName, unsigned RendererID)
1038 : OperandRenderer(OR_ComplexPattern), InsnID(InsnID), TheDef(TheDef),
Daniel Sanders2deea182017-04-22 15:11:04 +00001039 SymbolicName(SymbolicName), RendererID(RendererID) {}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001040
1041 static bool classof(const OperandRenderer *R) {
1042 return R->getKind() == OR_ComplexPattern;
1043 }
1044
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001045 void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001046 OS << " GIR_ComplexRenderer, /*InsnID*/" << InsnID << ", /*RendererID*/"
1047 << RendererID << ",\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001048 }
1049};
1050
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001051/// An action taken when all Matcher predicates succeeded for a parent rule.
1052///
1053/// Typical actions include:
1054/// * Changing the opcode of an instruction.
1055/// * Adding an operand to an instruction.
Daniel Sanders43c882c2017-02-01 10:53:10 +00001056class MatchAction {
1057public:
1058 virtual ~MatchAction() {}
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001059
1060 /// Emit the C++ statements to implement the action.
1061 ///
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001062 /// \param RecycleInsnID If given, it's an instruction to recycle. The
1063 /// requirements on the instruction vary from action to
1064 /// action.
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001065 virtual void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001066 unsigned RecycleInsnID) const = 0;
Daniel Sanders43c882c2017-02-01 10:53:10 +00001067};
1068
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001069/// Generates a comment describing the matched rule being acted upon.
1070class DebugCommentAction : public MatchAction {
1071private:
1072 const PatternToMatch &P;
1073
1074public:
1075 DebugCommentAction(const PatternToMatch &P) : P(P) {}
1076
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001077 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001078 unsigned RecycleInsnID) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001079 OS << " // " << *P.getSrcPattern() << " => " << *P.getDstPattern()
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001080 << "\n";
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001081 }
1082};
1083
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001084/// Generates code to build an instruction or mutate an existing instruction
1085/// into the desired instruction when this is possible.
1086class BuildMIAction : public MatchAction {
Daniel Sanders43c882c2017-02-01 10:53:10 +00001087private:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001088 unsigned InsnID;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001089 const CodeGenInstruction *I;
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001090 const InstructionMatcher &Matched;
1091 std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers;
1092
1093 /// True if the instruction can be built solely by mutating the opcode.
1094 bool canMutate() const {
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001095 if (OperandRenderers.size() != Matched.getNumOperands())
1096 return false;
1097
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001098 for (const auto &Renderer : enumerate(OperandRenderers)) {
Zachary Turner309a0882017-03-13 16:24:10 +00001099 if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {
Daniel Sanders3016d3c2017-04-22 14:31:28 +00001100 const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName());
1101 if (&Matched != &OM.getInstructionMatcher() ||
1102 OM.getOperandIndex() != Renderer.index())
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001103 return false;
1104 } else
1105 return false;
1106 }
1107
1108 return true;
1109 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001110
Daniel Sanders43c882c2017-02-01 10:53:10 +00001111public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001112 BuildMIAction(unsigned InsnID, const CodeGenInstruction *I,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001113 const InstructionMatcher &Matched)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001114 : InsnID(InsnID), I(I), Matched(Matched) {}
Daniel Sanders43c882c2017-02-01 10:53:10 +00001115
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001116 template <class Kind, class... Args>
1117 Kind &addRenderer(Args&&... args) {
1118 OperandRenderers.emplace_back(
1119 llvm::make_unique<Kind>(std::forward<Args>(args)...));
1120 return *static_cast<Kind *>(OperandRenderers.back().get());
1121 }
1122
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001123 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001124 unsigned RecycleInsnID) const override {
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001125 if (canMutate()) {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001126 OS << " GIR_MutateOpcode, /*InsnID*/" << InsnID
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001127 << ", /*RecycleInsnID*/ " << RecycleInsnID << ", /*Opcode*/"
1128 << I->Namespace << "::" << I->TheDef->getName() << ",\n";
Tim Northover4340d642017-03-20 21:58:23 +00001129
1130 if (!I->ImplicitDefs.empty() || !I->ImplicitUses.empty()) {
Tim Northover4340d642017-03-20 21:58:23 +00001131 for (auto Def : I->ImplicitDefs) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001132 auto Namespace = Def->getValue("Namespace")
1133 ? Def->getValueAsString("Namespace")
1134 : "";
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001135 OS << " GIR_AddImplicitDef, " << InsnID << ", " << Namespace
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001136 << "::" << Def->getName() << ",\n";
Tim Northover4340d642017-03-20 21:58:23 +00001137 }
1138 for (auto Use : I->ImplicitUses) {
Diana Picus8abcbbb2017-05-02 09:40:49 +00001139 auto Namespace = Use->getValue("Namespace")
1140 ? Use->getValueAsString("Namespace")
1141 : "";
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001142 OS << " GIR_AddImplicitUse, " << InsnID << ", " << Namespace
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001143 << "::" << Use->getName() << ",\n";
Tim Northover4340d642017-03-20 21:58:23 +00001144 }
1145 }
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001146 return;
1147 }
1148
1149 // TODO: Simple permutation looks like it could be almost as common as
1150 // mutation due to commutative operations.
1151
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001152 OS << " GIR_BuildMI, /*InsnID*/" << InsnID << ", /*Opcode*/"
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001153 << I->Namespace << "::" << I->TheDef->getName() << ",\n";
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001154 for (const auto &Renderer : OperandRenderers)
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001155 Renderer->emitCxxRenderStmts(OS, Rule);
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001156
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001157 OS << " GIR_MergeMemOperands, /*InsnID*/" << InsnID << ",\n"
1158 << " GIR_EraseFromParent, /*InsnID*/" << RecycleInsnID << ",\n";
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001159 }
1160};
1161
1162/// Generates code to constrain the operands of an output instruction to the
1163/// register classes specified by the definition of that instruction.
1164class ConstrainOperandsToDefinitionAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001165 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001166
1167public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001168 ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001169
1170 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001171 unsigned RecycleInsnID) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001172 OS << " GIR_ConstrainSelectedInstOperands, /*InsnID*/" << InsnID << ",\n";
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001173 }
1174};
1175
1176/// Generates code to constrain the specified operand of an output instruction
1177/// to the specified register class.
1178class ConstrainOperandToRegClassAction : public MatchAction {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001179 unsigned InsnID;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001180 unsigned OpIdx;
1181 const CodeGenRegisterClass &RC;
1182
1183public:
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001184 ConstrainOperandToRegClassAction(unsigned InsnID, unsigned OpIdx,
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001185 const CodeGenRegisterClass &RC)
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001186 : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {}
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001187
1188 void emitCxxActionStmts(raw_ostream &OS, RuleMatcher &Rule,
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001189 unsigned RecycleInsnID) const override {
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001190 OS << " GIR_ConstrainOperandRC, /*InsnID*/" << InsnID << ", /*Op*/"
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001191 << OpIdx << ", /*RC " << RC.getName() << "*/ " << RC.EnumValue << ",\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001192 }
1193};
1194
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001195InstructionMatcher &RuleMatcher::addInstructionMatcher() {
1196 Matchers.emplace_back(new InstructionMatcher());
1197 return *Matchers.back();
1198}
Ahmed Bougacha56ca3a92017-02-04 00:47:10 +00001199
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001200void RuleMatcher::addRequiredFeature(Record *Feature) {
1201 RequiredFeatures.push_back(Feature);
1202}
1203
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001204const std::vector<Record *> &RuleMatcher::getRequiredFeatures() const {
1205 return RequiredFeatures;
1206}
1207
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001208template <class Kind, class... Args>
1209Kind &RuleMatcher::addAction(Args &&... args) {
1210 Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
1211 return *static_cast<Kind *>(Actions.back().get());
1212}
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001213
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001214unsigned
1215RuleMatcher::implicitlyDefineInsnVar(const InstructionMatcher &Matcher) {
1216 unsigned NewInsnVarID = NextInsnVarID++;
1217 InsnVariableIDs[&Matcher] = NewInsnVarID;
1218 return NewInsnVarID;
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001219}
1220
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001221unsigned RuleMatcher::defineInsnVar(raw_ostream &OS,
1222 const InstructionMatcher &Matcher,
1223 unsigned InsnID, unsigned OpIdx) {
1224 unsigned NewInsnVarID = implicitlyDefineInsnVar(Matcher);
1225 OS << " GIM_RecordInsn, /*DefineMI*/" << NewInsnVarID << ", /*MI*/"
1226 << InsnID << ", /*OpIdx*/" << OpIdx << ", // MIs[" << NewInsnVarID
1227 << "]\n";
1228 return NewInsnVarID;
1229}
1230
1231unsigned RuleMatcher::getInsnVarID(const InstructionMatcher &InsnMatcher) const {
1232 const auto &I = InsnVariableIDs.find(&InsnMatcher);
1233 if (I != InsnVariableIDs.end())
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001234 return I->second;
1235 llvm_unreachable("Matched Insn was not captured in a local variable");
1236}
1237
1238/// Emit C++ statements to check the shape of the match and capture
1239/// instructions into local variables.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001240void RuleMatcher::emitCxxCaptureStmts(raw_ostream &OS) {
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001241 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001242 unsigned InsnVarID = implicitlyDefineInsnVar(*Matchers.front());
1243 Matchers.front()->emitCxxCaptureStmts(OS, *this, InsnVarID);
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001244}
1245
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001246void RuleMatcher::emit(raw_ostream &OS) {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001247 if (Matchers.empty())
1248 llvm_unreachable("Unexpected empty matcher!");
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001249
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001250 // The representation supports rules that require multiple roots such as:
1251 // %ptr(p0) = ...
1252 // %elt0(s32) = G_LOAD %ptr
1253 // %1(p0) = G_ADD %ptr, 4
1254 // %elt1(s32) = G_LOAD p0 %1
1255 // which could be usefully folded into:
1256 // %ptr(p0) = ...
1257 // %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
1258 // on some targets but we don't need to make use of that yet.
1259 assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001260
Daniel Sandersc60abe32017-07-04 15:31:50 +00001261 OS << " const static int64_t MatchTable" << CurrentMatchTableID << "[] = {\n";
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001262 if (!RequiredFeatures.empty()) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001263 OS << " GIM_CheckFeatures, " << getNameForFeatureBitset(RequiredFeatures)
1264 << ",\n";
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001265 }
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001266
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001267 emitCxxCaptureStmts(OS);
1268
Daniel Sandersb96f40d2017-03-20 15:20:42 +00001269 Matchers.front()->emitCxxPredicateExpr(OS, *this,
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001270 getInsnVarID(*Matchers.front()));
1271
Daniel Sandersbee57392017-04-04 13:25:23 +00001272 // We must also check if it's safe to fold the matched instructions.
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001273 if (InsnVariableIDs.size() >= 2) {
Galina Kistanova1754fee2017-05-25 01:51:53 +00001274 // Invert the map to create stable ordering (by var names)
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001275 SmallVector<unsigned, 2> InsnIDs;
1276 for (const auto &Pair : InsnVariableIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001277 // Skip the root node since it isn't moving anywhere. Everything else is
1278 // sinking to meet it.
1279 if (Pair.first == Matchers.front().get())
1280 continue;
1281
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001282 InsnIDs.push_back(Pair.second);
Galina Kistanova1754fee2017-05-25 01:51:53 +00001283 }
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001284 std::sort(InsnIDs.begin(), InsnIDs.end());
Galina Kistanova1754fee2017-05-25 01:51:53 +00001285
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00001286 for (const auto &InsnID : InsnIDs) {
Daniel Sandersbee57392017-04-04 13:25:23 +00001287 // Reject the difficult cases until we have a more accurate check.
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001288 OS << " GIM_CheckIsSafeToFold, /*InsnID*/" << InsnID << ",\n";
Daniel Sandersbee57392017-04-04 13:25:23 +00001289
1290 // FIXME: Emit checks to determine it's _actually_ safe to fold and/or
1291 // account for unsafe cases.
1292 //
1293 // Example:
1294 // MI1--> %0 = ...
1295 // %1 = ... %0
1296 // MI0--> %2 = ... %0
1297 // It's not safe to erase MI1. We currently handle this by not
1298 // erasing %0 (even when it's dead).
1299 //
1300 // Example:
1301 // MI1--> %0 = load volatile @a
1302 // %1 = load volatile @a
1303 // MI0--> %2 = ... %0
1304 // It's not safe to sink %0's def past %1. We currently handle
1305 // this by rejecting all loads.
1306 //
1307 // Example:
1308 // MI1--> %0 = load @a
1309 // %1 = store @a
1310 // MI0--> %2 = ... %0
1311 // It's not safe to sink %0's def past %1. We currently handle
1312 // this by rejecting all loads.
1313 //
1314 // Example:
1315 // G_CONDBR %cond, @BB1
1316 // BB0:
1317 // MI1--> %0 = load @a
1318 // G_BR @BB1
1319 // BB1:
1320 // MI0--> %2 = ... %0
1321 // It's not always safe to sink %0 across control flow. In this
1322 // case it may introduce a memory fault. We currentl handle this
1323 // by rejecting all loads.
1324 }
1325 }
1326
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001327 for (const auto &MA : Actions)
1328 MA->emitCxxActionStmts(OS, *this, 0);
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001329 OS << " GIR_Done,\n"
1330 << " };\n"
1331 << " State.MIs.resize(1);\n"
1332 << " DEBUG(dbgs() << \"Processing MatchTable" << CurrentMatchTableID
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001333 << "\\n\");\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00001334 << " if (executeMatchTable(*this, OutMIs, State, MatcherInfo, MatchTable"
1335 << CurrentMatchTableID << ", TII, MRI, TRI, RBI, AvailableFeatures)) {\n"
1336 << " return true;\n"
1337 << " }\n\n";
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001338}
Daniel Sanders43c882c2017-02-01 10:53:10 +00001339
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001340bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const {
1341 // Rules involving more match roots have higher priority.
1342 if (Matchers.size() > B.Matchers.size())
1343 return true;
1344 if (Matchers.size() < B.Matchers.size())
Daniel Sanders759ff412017-02-24 13:58:11 +00001345 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001346
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001347 for (const auto &Matcher : zip(Matchers, B.Matchers)) {
1348 if (std::get<0>(Matcher)->isHigherPriorityThan(*std::get<1>(Matcher)))
1349 return true;
1350 if (std::get<1>(Matcher)->isHigherPriorityThan(*std::get<0>(Matcher)))
1351 return false;
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001352 }
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001353
1354 return false;
Simon Pilgrima7d1da82017-03-15 22:50:47 +00001355}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001356
Daniel Sanders2deea182017-04-22 15:11:04 +00001357unsigned RuleMatcher::countRendererFns() const {
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001358 return std::accumulate(
1359 Matchers.begin(), Matchers.end(), 0,
1360 [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) {
Daniel Sanders2deea182017-04-22 15:11:04 +00001361 return A + Matcher->countRendererFns();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001362 });
1363}
1364
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001365//===- GlobalISelEmitter class --------------------------------------------===//
1366
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001367class GlobalISelEmitter {
1368public:
1369 explicit GlobalISelEmitter(RecordKeeper &RK);
1370 void run(raw_ostream &OS);
1371
1372private:
1373 const RecordKeeper &RK;
1374 const CodeGenDAGPatterns CGP;
1375 const CodeGenTarget &Target;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001376 CodeGenRegBank CGRegs;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001377
1378 /// Keep track of the equivalence between SDNodes and Instruction.
1379 /// This is defined using 'GINodeEquiv' in the target description.
1380 DenseMap<Record *, const CodeGenInstruction *> NodeEquivs;
1381
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001382 /// Keep track of the equivalence between ComplexPattern's and
1383 /// GIComplexOperandMatcher. Map entries are specified by subclassing
1384 /// GIComplexPatternEquiv.
1385 DenseMap<const Record *, const Record *> ComplexPatternEquivs;
1386
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001387 // Map of predicates to their subtarget features.
Daniel Sanderse9fdba32017-04-29 17:30:09 +00001388 SubtargetFeatureInfoMap SubtargetFeatures;
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001389
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001390 void gatherNodeEquivs();
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001391 const CodeGenInstruction *findNodeEquiv(Record *N) const;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001392
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001393 Error importRulePredicates(RuleMatcher &M, ArrayRef<Init *> Predicates);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001394 Expected<InstructionMatcher &>
Daniel Sandersc270c502017-03-30 09:36:33 +00001395 createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher,
1396 const TreePatternNode *Src) const;
1397 Error importChildMatcher(InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001398 const TreePatternNode *SrcChild, unsigned OpIdx,
Daniel Sandersc270c502017-03-30 09:36:33 +00001399 unsigned &TempOpIdx) const;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001400 Expected<BuildMIAction &>
1401 createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst,
1402 const InstructionMatcher &InsnMatcher);
Daniel Sandersc270c502017-03-30 09:36:33 +00001403 Error importExplicitUseRenderer(BuildMIAction &DstMIBuilder,
1404 TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001405 const InstructionMatcher &InsnMatcher) const;
Diana Picus382602f2017-05-17 08:57:28 +00001406 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
1407 DagInit *DefaultOps) const;
Daniel Sandersc270c502017-03-30 09:36:33 +00001408 Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00001409 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
1410 const std::vector<Record *> &ImplicitDefs) const;
1411
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001412 /// Analyze pattern \p P, returning a matcher for it if possible.
1413 /// Otherwise, return an Error explaining why we don't support it.
1414 Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001415
1416 void declareSubtargetFeature(Record *Predicate);
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001417};
1418
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001419void GlobalISelEmitter::gatherNodeEquivs() {
1420 assert(NodeEquivs.empty());
1421 for (Record *Equiv : RK.getAllDerivedDefinitions("GINodeEquiv"))
1422 NodeEquivs[Equiv->getValueAsDef("Node")] =
1423 &Target.getInstruction(Equiv->getValueAsDef("I"));
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001424
1425 assert(ComplexPatternEquivs.empty());
1426 for (Record *Equiv : RK.getAllDerivedDefinitions("GIComplexPatternEquiv")) {
1427 Record *SelDAGEquiv = Equiv->getValueAsDef("SelDAGEquivalent");
1428 if (!SelDAGEquiv)
1429 continue;
1430 ComplexPatternEquivs[SelDAGEquiv] = Equiv;
1431 }
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001432}
1433
Daniel Sandersbdfebb82017-03-15 20:18:38 +00001434const CodeGenInstruction *GlobalISelEmitter::findNodeEquiv(Record *N) const {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001435 return NodeEquivs.lookup(N);
1436}
1437
1438GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001439 : RK(RK), CGP(RK), Target(CGP.getTargetInfo()), CGRegs(RK) {}
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001440
1441//===- Emitter ------------------------------------------------------------===//
1442
Daniel Sandersc270c502017-03-30 09:36:33 +00001443Error
Daniel Sandersffc7d582017-03-29 15:37:18 +00001444GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
Daniel Sanderse7b0d662017-04-21 15:59:56 +00001445 ArrayRef<Init *> Predicates) {
1446 for (const Init *Predicate : Predicates) {
1447 const DefInit *PredicateDef = static_cast<const DefInit *>(Predicate);
1448 declareSubtargetFeature(PredicateDef->getDef());
1449 M.addRequiredFeature(PredicateDef->getDef());
1450 }
1451
Daniel Sandersc270c502017-03-30 09:36:33 +00001452 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001453}
Daniel Sanders8a4bae92017-03-14 21:32:08 +00001454
Daniel Sandersc270c502017-03-30 09:36:33 +00001455Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
1456 InstructionMatcher &InsnMatcher, const TreePatternNode *Src) const {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001457 // Start with the defined operands (i.e., the results of the root operator).
1458 if (Src->getExtTypes().size() > 1)
1459 return failedImport("Src pattern has multiple results");
1460
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001461 if (Src->isLeaf()) {
1462 Init *SrcInit = Src->getLeafValue();
Daniel Sanders3334cc02017-05-23 20:02:48 +00001463 if (isa<IntInit>(SrcInit)) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001464 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(
1465 &Target.getInstruction(RK.getDef("G_CONSTANT")));
1466 } else
Daniel Sanders32291982017-06-28 13:50:04 +00001467 return failedImport(
1468 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001469 } else {
1470 auto SrcGIOrNull = findNodeEquiv(Src->getOperator());
1471 if (!SrcGIOrNull)
1472 return failedImport("Pattern operator lacks an equivalent Instruction" +
1473 explainOperator(Src->getOperator()));
1474 auto &SrcGI = *SrcGIOrNull;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001475
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001476 // The operators look good: match the opcode
1477 InsnMatcher.addPredicate<InstructionOpcodeMatcher>(&SrcGI);
1478 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001479
1480 unsigned OpIdx = 0;
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001481 unsigned TempOpIdx = 0;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001482 for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
1483 auto OpTyOrNone = MVTToLLT(Ty.getConcrete());
1484
1485 if (!OpTyOrNone)
1486 return failedImport(
1487 "Result of Src pattern operator has an unsupported type");
1488
1489 // Results don't have a name unless they are the root node. The caller will
1490 // set the name if appropriate.
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001491 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001492 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1493 }
1494
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001495 if (Src->isLeaf()) {
1496 Init *SrcInit = Src->getLeafValue();
1497 if (IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {
1498 OperandMatcher &OM = InsnMatcher.addOperand(OpIdx++, "", TempOpIdx);
1499 OM.addPredicate<LiteralIntOperandMatcher>(SrcIntInit->getValue());
1500 } else
Daniel Sanders32291982017-06-28 13:50:04 +00001501 return failedImport(
1502 "Unable to deduce gMIR opcode to handle Src (which is a leaf)");
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001503 } else {
1504 // Match the used operands (i.e. the children of the operator).
1505 for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) {
1506 if (auto Error = importChildMatcher(InsnMatcher, Src->getChild(i),
1507 OpIdx++, TempOpIdx))
1508 return std::move(Error);
1509 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001510 }
1511
1512 return InsnMatcher;
1513}
1514
Daniel Sandersc270c502017-03-30 09:36:33 +00001515Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher,
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001516 const TreePatternNode *SrcChild,
Daniel Sandersc270c502017-03-30 09:36:33 +00001517 unsigned OpIdx,
1518 unsigned &TempOpIdx) const {
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001519 OperandMatcher &OM =
1520 InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001521
1522 if (SrcChild->hasAnyPredicate())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001523 return failedImport("Src pattern child has predicate (" +
1524 explainPredicates(SrcChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001525
1526 ArrayRef<EEVT::TypeSet> ChildTypes = SrcChild->getExtTypes();
1527 if (ChildTypes.size() != 1)
1528 return failedImport("Src pattern child has multiple results");
1529
1530 // Check MBB's before the type check since they are not a known type.
1531 if (!SrcChild->isLeaf()) {
1532 if (SrcChild->getOperator()->isSubClassOf("SDNode")) {
1533 auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild->getOperator());
1534 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
1535 OM.addPredicate<MBBOperandMatcher>();
Daniel Sandersc270c502017-03-30 09:36:33 +00001536 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001537 }
1538 }
Daniel Sandersffc7d582017-03-29 15:37:18 +00001539 }
1540
1541 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1542 if (!OpTyOrNone)
Daniel Sandersc244ff62017-05-22 10:14:33 +00001543 return failedImport("Src operand has an unsupported type");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001544 OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone);
1545
Daniel Sandersbee57392017-04-04 13:25:23 +00001546 // Check for nested instructions.
1547 if (!SrcChild->isLeaf()) {
1548 // Map the node to a gMIR instruction.
1549 InstructionOperandMatcher &InsnOperand =
1550 OM.addPredicate<InstructionOperandMatcher>();
1551 auto InsnMatcherOrError =
1552 createAndImportSelDAGMatcher(InsnOperand.getInsnMatcher(), SrcChild);
1553 if (auto Error = InsnMatcherOrError.takeError())
1554 return Error;
1555
1556 return Error::success();
1557 }
1558
Daniel Sandersffc7d582017-03-29 15:37:18 +00001559 // Check for constant immediates.
1560 if (auto *ChildInt = dyn_cast<IntInit>(SrcChild->getLeafValue())) {
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001561 OM.addPredicate<ConstantIntOperandMatcher>(ChildInt->getValue());
Daniel Sandersc270c502017-03-30 09:36:33 +00001562 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001563 }
1564
1565 // Check for def's like register classes or ComplexPattern's.
1566 if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild->getLeafValue())) {
1567 auto *ChildRec = ChildDefInit->getDef();
1568
1569 // Check for register classes.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001570 if (ChildRec->isSubClassOf("RegisterClass") ||
1571 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001572 OM.addPredicate<RegisterBankOperandMatcher>(
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001573 Target.getRegisterClass(getInitValueAsRegClass(ChildDefInit)));
Daniel Sanders658541f2017-04-22 15:53:21 +00001574 return Error::success();
1575 }
1576
Daniel Sandersffc7d582017-03-29 15:37:18 +00001577 // Check for ComplexPattern's.
1578 if (ChildRec->isSubClassOf("ComplexPattern")) {
1579 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1580 if (ComplexPattern == ComplexPatternEquivs.end())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001581 return failedImport("SelectionDAG ComplexPattern (" +
1582 ChildRec->getName() + ") not mapped to GlobalISel");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001583
Daniel Sanders2deea182017-04-22 15:11:04 +00001584 OM.addPredicate<ComplexPatternOperandMatcher>(OM,
1585 *ComplexPattern->second);
1586 TempOpIdx++;
Daniel Sandersc270c502017-03-30 09:36:33 +00001587 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001588 }
1589
Daniel Sandersd0656a32017-04-13 09:45:37 +00001590 if (ChildRec->isSubClassOf("ImmLeaf")) {
1591 return failedImport(
1592 "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
1593 }
1594
Daniel Sandersffc7d582017-03-29 15:37:18 +00001595 return failedImport(
1596 "Src pattern child def is an unsupported tablegen class");
1597 }
1598
1599 return failedImport("Src pattern child is an unsupported kind");
1600}
1601
Daniel Sandersc270c502017-03-30 09:36:33 +00001602Error GlobalISelEmitter::importExplicitUseRenderer(
Daniel Sandersffc7d582017-03-29 15:37:18 +00001603 BuildMIAction &DstMIBuilder, TreePatternNode *DstChild,
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001604 const InstructionMatcher &InsnMatcher) const {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001605 // The only non-leaf child we accept is 'bb': it's an operator because
1606 // BasicBlockSDNode isn't inline, but in MI it's just another operand.
1607 if (!DstChild->isLeaf()) {
1608 if (DstChild->getOperator()->isSubClassOf("SDNode")) {
1609 auto &ChildSDNI = CGP.getSDNodeInfo(DstChild->getOperator());
1610 if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001611 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
Daniel Sandersffc7d582017-03-29 15:37:18 +00001612 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00001613 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001614 }
1615 }
1616 return failedImport("Dst pattern child isn't a leaf node or an MBB");
1617 }
1618
1619 // Otherwise, we're looking for a bog-standard RegisterClass operand.
1620 if (DstChild->hasAnyPredicate())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001621 return failedImport("Dst pattern child has predicate (" +
1622 explainPredicates(DstChild) + ")");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001623
1624 if (auto *ChildDefInit = dyn_cast<DefInit>(DstChild->getLeafValue())) {
1625 auto *ChildRec = ChildDefInit->getDef();
1626
1627 ArrayRef<EEVT::TypeSet> ChildTypes = DstChild->getExtTypes();
1628 if (ChildTypes.size() != 1)
1629 return failedImport("Dst pattern child has multiple results");
1630
1631 auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete());
1632 if (!OpTyOrNone)
1633 return failedImport("Dst operand has an unsupported type");
1634
1635 if (ChildRec->isSubClassOf("Register")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001636 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, ChildRec);
Daniel Sandersc270c502017-03-30 09:36:33 +00001637 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001638 }
1639
Daniel Sanders658541f2017-04-22 15:53:21 +00001640 if (ChildRec->isSubClassOf("RegisterClass") ||
1641 ChildRec->isSubClassOf("RegisterOperand")) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001642 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher,
1643 DstChild->getName());
Daniel Sandersc270c502017-03-30 09:36:33 +00001644 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001645 }
1646
1647 if (ChildRec->isSubClassOf("ComplexPattern")) {
1648 const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec);
1649 if (ComplexPattern == ComplexPatternEquivs.end())
1650 return failedImport(
1651 "SelectionDAG ComplexPattern not mapped to GlobalISel");
1652
Daniel Sanders4f3eb242017-04-05 13:14:03 +00001653 const OperandMatcher &OM = InsnMatcher.getOperand(DstChild->getName());
Daniel Sandersffc7d582017-03-29 15:37:18 +00001654 DstMIBuilder.addRenderer<RenderComplexPatternOperand>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001655 0, *ComplexPattern->second, DstChild->getName(),
Daniel Sanders2deea182017-04-22 15:11:04 +00001656 OM.getAllocatedTemporariesBaseID());
Daniel Sandersc270c502017-03-30 09:36:33 +00001657 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001658 }
1659
Daniel Sandersd0656a32017-04-13 09:45:37 +00001660 if (ChildRec->isSubClassOf("SDNodeXForm"))
1661 return failedImport("Dst pattern child def is an unsupported tablegen "
1662 "class (SDNodeXForm)");
1663
Daniel Sandersffc7d582017-03-29 15:37:18 +00001664 return failedImport(
1665 "Dst pattern child def is an unsupported tablegen class");
1666 }
1667
1668 return failedImport("Dst pattern child is an unsupported kind");
1669}
1670
Daniel Sandersc270c502017-03-30 09:36:33 +00001671Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
Daniel Sandersffc7d582017-03-29 15:37:18 +00001672 RuleMatcher &M, const TreePatternNode *Dst,
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001673 const InstructionMatcher &InsnMatcher) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001674 Record *DstOp = Dst->getOperator();
Daniel Sandersd0656a32017-04-13 09:45:37 +00001675 if (!DstOp->isSubClassOf("Instruction")) {
1676 if (DstOp->isSubClassOf("ValueType"))
1677 return failedImport(
1678 "Pattern operator isn't an instruction (it's a ValueType)");
Daniel Sandersffc7d582017-03-29 15:37:18 +00001679 return failedImport("Pattern operator isn't an instruction");
Daniel Sandersd0656a32017-04-13 09:45:37 +00001680 }
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001681 CodeGenInstruction *DstI = &Target.getInstruction(DstOp);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001682
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001683 unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs;
1684 unsigned ExpectedDstINumUses = Dst->getNumChildren();
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001685 bool IsExtractSubReg = false;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001686
1687 // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001688 // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001689 if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") {
1690 DstI = &Target.getInstruction(RK.getDef("COPY"));
1691 DstINumUses--; // Ignore the class constraint.
1692 ExpectedDstINumUses--;
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001693 } else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") {
1694 DstI = &Target.getInstruction(RK.getDef("COPY"));
1695 IsExtractSubReg = true;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001696 }
1697
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001698 auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001699
1700 // Render the explicit defs.
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001701 for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) {
1702 const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I];
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001703 DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001704 }
1705
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001706 // EXTRACT_SUBREG needs to use a subregister COPY.
1707 if (IsExtractSubReg) {
1708 if (!Dst->getChild(0)->isLeaf())
1709 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
1710
Daniel Sanders32291982017-06-28 13:50:04 +00001711 if (DefInit *SubRegInit =
1712 dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001713 CodeGenRegisterClass *RC = CGRegs.getRegClass(
1714 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()));
1715 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
1716
1717 const auto &SrcRCDstRCPair =
1718 RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
1719 if (SrcRCDstRCPair.hasValue()) {
1720 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
1721 if (SrcRCDstRCPair->first != RC)
1722 return failedImport("EXTRACT_SUBREG requires an additional COPY");
1723 }
1724
1725 DstMIBuilder.addRenderer<CopySubRegRenderer>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001726 0, InsnMatcher, Dst->getChild(0)->getName(), SubIdx);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001727 return DstMIBuilder;
1728 }
1729
1730 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
1731 }
1732
Daniel Sandersffc7d582017-03-29 15:37:18 +00001733 // Render the explicit uses.
Daniel Sanders0ed28822017-04-12 08:23:08 +00001734 unsigned Child = 0;
Diana Picus382602f2017-05-17 08:57:28 +00001735 unsigned NumDefaultOps = 0;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001736 for (unsigned I = 0; I != DstINumUses; ++I) {
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001737 const CGIOperandList::OperandInfo &DstIOperand =
1738 DstI->Operands[DstI->Operands.NumDefs + I];
Daniel Sanders0ed28822017-04-12 08:23:08 +00001739
Diana Picus382602f2017-05-17 08:57:28 +00001740 // If the operand has default values, introduce them now.
1741 // FIXME: Until we have a decent test case that dictates we should do
1742 // otherwise, we're going to assume that operands with default values cannot
1743 // be specified in the patterns. Therefore, adding them will not cause us to
1744 // end up with too many rendered operands.
1745 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
Daniel Sanders0ed28822017-04-12 08:23:08 +00001746 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
Diana Picus382602f2017-05-17 08:57:28 +00001747 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
1748 return std::move(Error);
1749 ++NumDefaultOps;
Daniel Sanders0ed28822017-04-12 08:23:08 +00001750 continue;
1751 }
1752
1753 if (auto Error = importExplicitUseRenderer(
1754 DstMIBuilder, Dst->getChild(Child), InsnMatcher))
Daniel Sandersffc7d582017-03-29 15:37:18 +00001755 return std::move(Error);
Daniel Sanders0ed28822017-04-12 08:23:08 +00001756 ++Child;
Daniel Sandersffc7d582017-03-29 15:37:18 +00001757 }
1758
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001759 if (NumDefaultOps + ExpectedDstINumUses != DstINumUses)
Diana Picuseb2057c2017-05-17 09:25:08 +00001760 return failedImport("Expected " + llvm::to_string(DstINumUses) +
Diana Picus382602f2017-05-17 08:57:28 +00001761 " used operands but found " +
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001762 llvm::to_string(ExpectedDstINumUses) +
Diana Picuseb2057c2017-05-17 09:25:08 +00001763 " explicit ones and " + llvm::to_string(NumDefaultOps) +
Diana Picus382602f2017-05-17 08:57:28 +00001764 " default ones");
1765
Daniel Sandersffc7d582017-03-29 15:37:18 +00001766 return DstMIBuilder;
1767}
1768
Diana Picus382602f2017-05-17 08:57:28 +00001769Error GlobalISelEmitter::importDefaultOperandRenderers(
1770 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
Craig Topper481ff702017-05-29 21:49:34 +00001771 for (const auto *DefaultOp : DefaultOps->getArgs()) {
Diana Picus382602f2017-05-17 08:57:28 +00001772 // Look through ValueType operators.
1773 if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) {
1774 if (const DefInit *DefaultDagOperator =
1775 dyn_cast<DefInit>(DefaultDagOp->getOperator())) {
1776 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
1777 DefaultOp = DefaultDagOp->getArg(0);
1778 }
1779 }
1780
1781 if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001782 DstMIBuilder.addRenderer<AddRegisterRenderer>(0, DefaultDefOp->getDef());
Diana Picus382602f2017-05-17 08:57:28 +00001783 continue;
1784 }
1785
1786 if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001787 DstMIBuilder.addRenderer<ImmRenderer>(0, DefaultIntOp->getValue());
Diana Picus382602f2017-05-17 08:57:28 +00001788 continue;
1789 }
1790
1791 return failedImport("Could not add default op");
1792 }
1793
1794 return Error::success();
1795}
1796
Daniel Sandersc270c502017-03-30 09:36:33 +00001797Error GlobalISelEmitter::importImplicitDefRenderers(
Daniel Sandersffc7d582017-03-29 15:37:18 +00001798 BuildMIAction &DstMIBuilder,
1799 const std::vector<Record *> &ImplicitDefs) const {
1800 if (!ImplicitDefs.empty())
1801 return failedImport("Pattern defines a physical register");
Daniel Sandersc270c502017-03-30 09:36:33 +00001802 return Error::success();
Daniel Sandersffc7d582017-03-29 15:37:18 +00001803}
1804
1805Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001806 // Keep track of the matchers and actions to emit.
Ahmed Bougacha9aa4c102017-02-04 00:47:08 +00001807 RuleMatcher M;
1808 M.addAction<DebugCommentAction>(P);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001809
Daniel Sandersc270c502017-03-30 09:36:33 +00001810 if (auto Error = importRulePredicates(M, P.getPredicates()->getValues()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00001811 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001812
1813 // Next, analyze the pattern operators.
1814 TreePatternNode *Src = P.getSrcPattern();
1815 TreePatternNode *Dst = P.getDstPattern();
1816
1817 // If the root of either pattern isn't a simple operator, ignore it.
Daniel Sandersd0656a32017-04-13 09:45:37 +00001818 if (auto Err = isTrivialOperatorNode(Dst))
1819 return failedImport("Dst pattern root isn't a trivial operator (" +
1820 toString(std::move(Err)) + ")");
1821 if (auto Err = isTrivialOperatorNode(Src))
1822 return failedImport("Src pattern root isn't a trivial operator (" +
1823 toString(std::move(Err)) + ")");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001824
Daniel Sanders452c8ae2017-05-23 19:33:16 +00001825 if (Dst->isLeaf())
1826 return failedImport("Dst pattern root isn't a known leaf");
1827
Daniel Sandersbee57392017-04-04 13:25:23 +00001828 // Start with the defined operands (i.e., the results of the root operator).
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001829 Record *DstOp = Dst->getOperator();
1830 if (!DstOp->isSubClassOf("Instruction"))
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001831 return failedImport("Pattern operator isn't an instruction");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001832
1833 auto &DstI = Target.getInstruction(DstOp);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001834 if (DstI.Operands.NumDefs != Src->getExtTypes().size())
Daniel Sandersd0656a32017-04-13 09:45:37 +00001835 return failedImport("Src pattern results and dst MI defs are different (" +
1836 to_string(Src->getExtTypes().size()) + " def(s) vs " +
1837 to_string(DstI.Operands.NumDefs) + " def(s))");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001838
Daniel Sandersffc7d582017-03-29 15:37:18 +00001839 InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher();
Daniel Sandersc270c502017-03-30 09:36:33 +00001840 auto InsnMatcherOrError = createAndImportSelDAGMatcher(InsnMatcherTemp, Src);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001841 if (auto Error = InsnMatcherOrError.takeError())
1842 return std::move(Error);
1843 InstructionMatcher &InsnMatcher = InsnMatcherOrError.get();
1844
1845 // The root of the match also has constraints on the register bank so that it
1846 // matches the result instruction.
1847 unsigned OpIdx = 0;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001848 for (const EEVT::TypeSet &Ty : Src->getExtTypes()) {
Daniel Sandersffc7d582017-03-29 15:37:18 +00001849 (void)Ty;
1850
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001851 const auto &DstIOperand = DstI.Operands[OpIdx];
1852 Record *DstIOpRec = DstIOperand.Rec;
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001853 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
1854 DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
1855
1856 if (DstIOpRec == nullptr)
1857 return failedImport(
1858 "COPY_TO_REGCLASS operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001859 } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
1860 if (!Dst->getChild(0)->isLeaf())
1861 return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
1862
Daniel Sanders32291982017-06-28 13:50:04 +00001863 // We can assume that a subregister is in the same bank as it's super
1864 // register.
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001865 DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
1866
1867 if (DstIOpRec == nullptr)
1868 return failedImport(
1869 "EXTRACT_SUBREG operand #0 isn't a register class");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001870 } else if (DstIOpRec->isSubClassOf("RegisterOperand"))
Daniel Sanders658541f2017-04-22 15:53:21 +00001871 DstIOpRec = DstIOpRec->getValueAsDef("RegClass");
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001872 else if (!DstIOpRec->isSubClassOf("RegisterClass"))
Daniel Sanders32291982017-06-28 13:50:04 +00001873 return failedImport("Dst MI def isn't a register class" +
1874 to_string(*Dst));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001875
Daniel Sandersffc7d582017-03-29 15:37:18 +00001876 OperandMatcher &OM = InsnMatcher.getOperand(OpIdx);
1877 OM.setSymbolicName(DstIOperand.Name);
Daniel Sandersdc662ff2017-01-26 11:10:14 +00001878 OM.addPredicate<RegisterBankOperandMatcher>(
1879 Target.getRegisterClass(DstIOpRec));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001880 ++OpIdx;
1881 }
1882
Daniel Sandersc270c502017-03-30 09:36:33 +00001883 auto DstMIBuilderOrError =
1884 createAndImportInstructionRenderer(M, Dst, InsnMatcher);
Daniel Sandersffc7d582017-03-29 15:37:18 +00001885 if (auto Error = DstMIBuilderOrError.takeError())
1886 return std::move(Error);
1887 BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get();
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001888
Daniel Sandersffc7d582017-03-29 15:37:18 +00001889 // Render the implicit defs.
1890 // These are only added to the root of the result.
Daniel Sandersc270c502017-03-30 09:36:33 +00001891 if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs()))
Daniel Sandersffc7d582017-03-29 15:37:18 +00001892 return std::move(Error);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001893
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001894 // Constrain the registers to classes. This is normally derived from the
1895 // emitted instruction but a few instructions require special handling.
1896 if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") {
1897 // COPY_TO_REGCLASS does not provide operand constraints itself but the
1898 // result is constrained to the class given by the second child.
1899 Record *DstIOpRec =
1900 getInitValueAsRegClass(Dst->getChild(1)->getLeafValue());
1901
1902 if (DstIOpRec == nullptr)
1903 return failedImport("COPY_TO_REGCLASS operand #1 isn't a register class");
1904
1905 M.addAction<ConstrainOperandToRegClassAction>(
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001906 0, 0, Target.getRegisterClass(DstIOpRec));
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001907
1908 // We're done with this pattern! It's eligible for GISel emission; return
1909 // it.
1910 ++NumPatternImported;
1911 return std::move(M);
1912 }
1913
1914 if (DstI.TheDef->getName() == "EXTRACT_SUBREG") {
1915 // EXTRACT_SUBREG selects into a subregister COPY but unlike most
1916 // instructions, the result register class is controlled by the
1917 // subregisters of the operand. As a result, we must constrain the result
1918 // class rather than check that it's already the right one.
1919 if (!Dst->getChild(0)->isLeaf())
1920 return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
1921
Daniel Sanders320390b2017-06-28 15:16:03 +00001922 DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
1923 if (!SubRegInit)
1924 return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001925
Daniel Sanders320390b2017-06-28 15:16:03 +00001926 // Constrain the result to the same register bank as the operand.
1927 Record *DstIOpRec =
1928 getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001929
Daniel Sanders320390b2017-06-28 15:16:03 +00001930 if (DstIOpRec == nullptr)
1931 return failedImport("EXTRACT_SUBREG operand #1 isn't a register class");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001932
Daniel Sanders320390b2017-06-28 15:16:03 +00001933 CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001934 CodeGenRegisterClass *SrcRC = CGRegs.getRegClass(DstIOpRec);
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001935
Daniel Sanders320390b2017-06-28 15:16:03 +00001936 // It would be nice to leave this constraint implicit but we're required
1937 // to pick a register class so constrain the result to a register class
1938 // that can hold the correct MVT.
1939 //
1940 // FIXME: This may introduce an extra copy if the chosen class doesn't
1941 // actually contain the subregisters.
1942 assert(Src->getExtTypes().size() == 1 &&
1943 "Expected Src of EXTRACT_SUBREG to have one result type");
Daniel Sanderscc36dbf2017-06-27 10:11:39 +00001944
Daniel Sanders320390b2017-06-28 15:16:03 +00001945 const auto &SrcRCDstRCPair =
1946 SrcRC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
1947 assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
Daniel Sandersd93a35a2017-07-05 09:39:33 +00001948 M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
1949 M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
1950
1951 // We're done with this pattern! It's eligible for GISel emission; return
1952 // it.
1953 ++NumPatternImported;
1954 return std::move(M);
1955 }
1956
1957 M.addAction<ConstrainOperandsToDefinitionAction>(0);
Daniel Sandersa6e2ceb2017-06-20 12:36:34 +00001958
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001959 // We're done with this pattern! It's eligible for GISel emission; return it.
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001960 ++NumPatternImported;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001961 return std::move(M);
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001962}
1963
1964void GlobalISelEmitter::run(raw_ostream &OS) {
1965 // Track the GINodeEquiv definitions.
1966 gatherNodeEquivs();
1967
1968 emitSourceFileHeader(("Global Instruction Selector for the " +
1969 Target.getName() + " target").str(), OS);
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001970 std::vector<RuleMatcher> Rules;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001971 // Look through the SelectionDAG patterns we found, possibly emitting some.
1972 for (const PatternToMatch &Pat : CGP.ptms()) {
1973 ++NumPatternTotal;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001974 auto MatcherOrErr = runOnPattern(Pat);
1975
1976 // The pattern analysis can fail, indicating an unsupported pattern.
1977 // Report that if we've been asked to do so.
1978 if (auto Err = MatcherOrErr.takeError()) {
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001979 if (WarnOnSkippedPatterns) {
1980 PrintWarning(Pat.getSrcRecord()->getLoc(),
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001981 "Skipped pattern: " + toString(std::move(Err)));
1982 } else {
1983 consumeError(std::move(Err));
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001984 }
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001985 ++NumPatternImportsSkipped;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001986 continue;
Ahmed Bougacha36f70352016-12-21 23:26:20 +00001987 }
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00001988
Daniel Sandersb41ce2b2017-02-20 14:31:27 +00001989 Rules.push_back(std::move(MatcherOrErr.get()));
1990 }
1991
Daniel Sanders066ebbf2017-02-24 15:43:30 +00001992 std::stable_sort(Rules.begin(), Rules.end(),
1993 [&](const RuleMatcher &A, const RuleMatcher &B) {
Daniel Sanders759ff412017-02-24 13:58:11 +00001994 if (A.isHigherPriorityThan(B)) {
1995 assert(!B.isHigherPriorityThan(A) && "Cannot be more important "
1996 "and less important at "
1997 "the same time");
1998 return true;
1999 }
2000 return false;
2001 });
2002
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002003 std::vector<Record *> ComplexPredicates =
2004 RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
2005 std::sort(ComplexPredicates.begin(), ComplexPredicates.end(),
2006 [](const Record *A, const Record *B) {
2007 if (A->getName() < B->getName())
2008 return true;
2009 return false;
2010 });
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002011 unsigned MaxTemporaries = 0;
2012 for (const auto &Rule : Rules)
Daniel Sanders2deea182017-04-22 15:11:04 +00002013 MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns());
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002014
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002015 OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
2016 << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
2017 << ";\n"
2018 << "using PredicateBitset = "
2019 "llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
2020 << "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
2021
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002022 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"
2023 << " mutable MatcherState State;\n"
2024 << " typedef "
2025 "ComplexRendererFn("
2026 << Target.getName()
2027 << "InstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;\n"
2028 << "const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> "
2029 "MatcherInfo;\n"
2030 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002031
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002032 OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
2033 << ", State(" << MaxTemporaries << "),\n"
2034 << "MatcherInfo({TypeObjects, FeatureBitsets, {\n"
2035 << " nullptr, // GICP_Invalid\n";
2036 for (const auto &Record : ComplexPredicates)
2037 OS << " &" << Target.getName()
2038 << "InstructionSelector::" << Record->getValueAsString("MatcherFn")
2039 << ", // " << Record->getName() << "\n";
2040 OS << "}})\n"
2041 << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002042
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002043 OS << "#ifdef GET_GLOBALISEL_IMPL\n";
2044 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
2045 OS);
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002046
2047 // Separate subtarget features by how often they must be recomputed.
2048 SubtargetFeatureInfoMap ModuleFeatures;
2049 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
2050 std::inserter(ModuleFeatures, ModuleFeatures.end()),
2051 [](const SubtargetFeatureInfoMap::value_type &X) {
2052 return !X.second.mustRecomputePerFunction();
2053 });
2054 SubtargetFeatureInfoMap FunctionFeatures;
2055 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
2056 std::inserter(FunctionFeatures, FunctionFeatures.end()),
2057 [](const SubtargetFeatureInfoMap::value_type &X) {
2058 return X.second.mustRecomputePerFunction();
2059 });
2060
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002061 SubtargetFeatureInfo::emitComputeAvailableFeatures(
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002062 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
2063 ModuleFeatures, OS);
2064 SubtargetFeatureInfo::emitComputeAvailableFeatures(
2065 Target.getName(), "InstructionSelector",
2066 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
2067 "const MachineFunction *MF");
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002068
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002069 // Emit a table containing the LLT objects needed by the matcher and an enum
2070 // for the matcher to reference them with.
2071 std::vector<LLTCodeGen> TypeObjects = {
2072 LLT::scalar(8), LLT::scalar(16), LLT::scalar(32),
2073 LLT::scalar(64), LLT::scalar(80), LLT::vector(8, 1),
2074 LLT::vector(16, 1), LLT::vector(32, 1), LLT::vector(64, 1),
2075 LLT::vector(8, 8), LLT::vector(16, 8), LLT::vector(32, 8),
2076 LLT::vector(64, 8), LLT::vector(4, 16), LLT::vector(8, 16),
2077 LLT::vector(16, 16), LLT::vector(32, 16), LLT::vector(2, 32),
2078 LLT::vector(4, 32), LLT::vector(8, 32), LLT::vector(16, 32),
2079 LLT::vector(2, 64), LLT::vector(4, 64), LLT::vector(8, 64),
2080 };
2081 std::sort(TypeObjects.begin(), TypeObjects.end());
2082 OS << "enum {\n";
2083 for (const auto &TypeObject : TypeObjects) {
2084 OS << " ";
2085 TypeObject.emitCxxEnumValue(OS);
2086 OS << ",\n";
2087 }
2088 OS << "};\n"
2089 << "const static LLT TypeObjects[] = {\n";
2090 for (const auto &TypeObject : TypeObjects) {
2091 OS << " ";
2092 TypeObject.emitCxxConstructorCall(OS);
2093 OS << ",\n";
2094 }
2095 OS << "};\n\n";
2096
2097 // Emit a table containing the PredicateBitsets objects needed by the matcher
2098 // and an enum for the matcher to reference them with.
2099 std::vector<std::vector<Record *>> FeatureBitsets;
2100 for (auto &Rule : Rules)
2101 FeatureBitsets.push_back(Rule.getRequiredFeatures());
2102 std::sort(
2103 FeatureBitsets.begin(), FeatureBitsets.end(),
2104 [&](const std::vector<Record *> &A, const std::vector<Record *> &B) {
2105 if (A.size() < B.size())
2106 return true;
2107 if (A.size() > B.size())
2108 return false;
2109 for (const auto &Pair : zip(A, B)) {
2110 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
2111 return true;
2112 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
2113 return false;
2114 }
2115 return false;
2116 });
2117 FeatureBitsets.erase(
2118 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
2119 FeatureBitsets.end());
2120 OS << "enum {\n"
2121 << " GIFBS_Invalid,\n";
2122 for (const auto &FeatureBitset : FeatureBitsets) {
2123 if (FeatureBitset.empty())
2124 continue;
2125 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
2126 }
2127 OS << "};\n"
2128 << "const static PredicateBitset FeatureBitsets[] {\n"
2129 << " {}, // GIFBS_Invalid\n";
2130 for (const auto &FeatureBitset : FeatureBitsets) {
2131 if (FeatureBitset.empty())
2132 continue;
2133 OS << " {";
2134 for (const auto &Feature : FeatureBitset) {
2135 const auto &I = SubtargetFeatures.find(Feature);
2136 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
2137 OS << I->second.getEnumBitName() << ", ";
2138 }
2139 OS << "},\n";
2140 }
2141 OS << "};\n\n";
2142
2143 // Emit complex predicate table and an enum to reference them with.
2144 OS << "enum {\n"
2145 << " GICP_Invalid,\n";
2146 for (const auto &Record : ComplexPredicates)
2147 OS << " GICP_" << Record->getName() << ",\n";
2148 OS << "};\n"
2149 << "// See constructor for table contents\n\n";
2150
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002151 OS << "bool " << Target.getName()
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002152 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
2153 << " MachineFunction &MF = *I.getParent()->getParent();\n"
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002154 << " MachineRegisterInfo &MRI = MF.getRegInfo();\n"
Daniel Sanders32291982017-06-28 13:50:04 +00002155 << " // FIXME: This should be computed on a per-function basis rather "
2156 "than per-insn.\n"
2157 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, "
2158 "&MF);\n"
Daniel Sandersa6cfce62017-07-05 14:50:18 +00002159 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"
2160 << " NewMIVector OutMIs;\n"
2161 << " State.MIs.clear();\n"
2162 << " State.MIs.push_back(&I);\n\n";
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002163
Daniel Sandersb96f40d2017-03-20 15:20:42 +00002164 for (auto &Rule : Rules) {
Daniel Sanders6ab0daa2017-07-04 14:35:06 +00002165 Rule.emit(OS);
Daniel Sandersc60abe32017-07-04 15:31:50 +00002166 ++CurrentMatchTableID;
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002167 ++NumPatternEmitted;
Daniel Sandersc60abe32017-07-04 15:31:50 +00002168 assert(CurrentMatchTableID == NumPatternEmitted &&
2169 "Statistic deviates from number of emitted tables");
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002170 }
2171
Daniel Sanders8a4bae92017-03-14 21:32:08 +00002172 OS << " return false;\n"
2173 << "}\n"
2174 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
Daniel Sanderse9fdba32017-04-29 17:30:09 +00002175
2176 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
2177 << "PredicateBitset AvailableModuleFeatures;\n"
2178 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
2179 << "PredicateBitset getAvailableFeatures() const {\n"
2180 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
2181 << "}\n"
2182 << "PredicateBitset\n"
2183 << "computeAvailableModuleFeatures(const " << Target.getName()
2184 << "Subtarget *Subtarget) const;\n"
2185 << "PredicateBitset\n"
2186 << "computeAvailableFunctionFeatures(const " << Target.getName()
2187 << "Subtarget *Subtarget,\n"
2188 << " const MachineFunction *MF) const;\n"
2189 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
2190
2191 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
2192 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
2193 << "AvailableFunctionFeatures()\n"
2194 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002195}
2196
Daniel Sanderse7b0d662017-04-21 15:59:56 +00002197void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
2198 if (SubtargetFeatures.count(Predicate) == 0)
2199 SubtargetFeatures.emplace(
2200 Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
2201}
2202
Ahmed Bougacha982c5eb2017-02-10 04:00:17 +00002203} // end anonymous namespace
2204
Ahmed Bougacha36f70352016-12-21 23:26:20 +00002205//===----------------------------------------------------------------------===//
2206
2207namespace llvm {
2208void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS) {
2209 GlobalISelEmitter(RK).run(OS);
2210}
2211} // End llvm namespace