1//===- DAGISelMatcher.h - Representation of DAG pattern matcher -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_UTILS_TABLEGEN_COMMON_DAGISELMATCHER_H
10#define LLVM_UTILS_TABLEGEN_COMMON_DAGISELMATCHER_H
11
12#include "Common/InfoByHwMode.h"
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/SmallVector.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/CodeGenTypes/MachineValueType.h"
17#include "llvm/Support/Casting.h"
18#include <cassert>
19#include <cstddef>
20#include <memory>
21#include <string>
22#include <utility>
23
24namespace llvm {
25class CodeGenRegister;
26class CodeGenDAGPatterns;
27class CodeGenInstruction;
28class Matcher;
29class MatcherList;
30class PatternToMatch;
31class raw_ostream;
32class ComplexPattern;
33class Record;
34class SDNodeInfo;
35class TreePredicateFn;
36class TreePattern;
37
38MatcherList ConvertPatternToMatcherList(const PatternToMatch &Pattern,
39 unsigned Variant,
40 const CodeGenDAGPatterns &CGP);
41void OptimizeMatcher(MatcherList &ML, const CodeGenDAGPatterns &CGP);
42void EmitMatcherTable(MatcherList &ML, const CodeGenDAGPatterns &CGP,
43 raw_ostream &OS);
44
45/// Base class that holds a pointer to the next entry in the MatcherList.
46/// Separated from Matcher so that we can have an instance of it in
47/// MatcherList.
48class MatcherBase {
49 friend class MatcherList;
50
51 Matcher *Next = nullptr;
52};
53
54/// Matcher - Base class for all the DAG ISel Matcher representation
55/// nodes.
56class Matcher : public MatcherBase {
57 virtual void anchor();
58
59public:
60 enum KindTy {
61 // Matcher state manipulation.
62 Scope, // Push a checking scope.
63 RecordNode, // Record the current node.
64 RecordChild, // Record a child of the current node.
65 RecordMemRef, // Record the memref in the current node.
66 CaptureGlueInput, // If the current node has an input glue, save it.
67 MoveChild, // Move current node to specified child.
68 MoveSibling, // Move current node to specified sibling.
69 MoveParent, // Move current node to parent.
70
71 // Predicate checking.
72 CheckSame, // Fail if not same as prev match.
73 CheckChildSame, // Fail if child not same as prev match.
74 CheckPatternPredicate,
75 CheckPredicate, // Fail if node predicate fails.
76 CheckOpcode, // Fail if not opcode.
77 SwitchOpcode, // Dispatch based on opcode.
78 CheckType, // Fail if not correct type.
79 SwitchType, // Dispatch based on type.
80 CheckChildType, // Fail if child has wrong type.
81 CheckInteger, // Fail if wrong val.
82 CheckChildInteger, // Fail if child is wrong val.
83 CheckCondCode, // Fail if not condcode.
84 CheckChild2CondCode, // Fail if child is wrong condcode.
85 CheckValueType,
86 CheckComplexPat,
87 CheckAndImm,
88 CheckOrImm,
89 CheckImmAllOnesV,
90 CheckImmAllZerosV,
91 CheckUndef,
92 CheckFoldableChainNode,
93
94 // Node creation/emisssion.
95 EmitInteger, // Create a TargetConstant
96 EmitRegister, // Create a register.
97 EmitConvertToTarget, // Convert a imm/fpimm to target imm/fpimm
98 EmitMergeInputChains, // Merge together a chains for an input.
99 EmitCopyToReg, // Emit a copytoreg into a physreg.
100 EmitNode, // Create a DAG node
101 EmitNodeXForm, // Run a SDNodeXForm
102 CompleteMatch, // Finish a match and update the results.
103 MorphNodeTo, // Build a node, finish a match and update results.
104
105 // Highest enum value; watch out when adding more.
106 HighestKind = MorphNodeTo
107 };
108 const KindTy Kind;
109
110protected:
111 Matcher(KindTy K) : Kind(K) {}
112
113public:
114 virtual ~Matcher() = default;
115
116 KindTy getKind() const { return Kind; }
117
118 bool isEqual(const Matcher *M) const {
119 if (getKind() != M->getKind())
120 return false;
121 return isEqualImpl(M);
122 }
123
124 /// isSimplePredicateNode - Return true if this is a simple predicate that
125 /// operates on the node or its children without potential side effects or a
126 /// change of the current node.
127 bool isSimplePredicateNode() const {
128 switch (getKind()) {
129 default:
130 return false;
131 case CheckSame:
132 case CheckChildSame:
133 case CheckPatternPredicate:
134 case CheckPredicate:
135 case CheckOpcode:
136 case CheckType:
137 case CheckChildType:
138 case CheckInteger:
139 case CheckChildInteger:
140 case CheckCondCode:
141 case CheckChild2CondCode:
142 case CheckValueType:
143 case CheckAndImm:
144 case CheckOrImm:
145 case CheckImmAllOnesV:
146 case CheckImmAllZerosV:
147 case CheckUndef:
148 case CheckFoldableChainNode:
149 return true;
150 }
151 }
152
153 /// isSimplePredicateOrRecordNode - Return true if this is a record node or
154 /// a simple predicate.
155 bool isSimplePredicateOrRecordNode() const {
156 return isSimplePredicateNode() || getKind() == RecordNode ||
157 getKind() == RecordChild;
158 }
159
160 /// canMoveBeforeNode - Return true if it is safe to move the current
161 /// matcher across the specified one.
162 bool canMoveBeforeNode(const Matcher *Other) const;
163
164 /// isContradictory - Return true of these two matchers could never match on
165 /// the same node.
166 bool isContradictory(const Matcher *Other) const {
167 // Since this predicate is reflexive, we canonicalize the ordering so that
168 // we always match a node against nodes with kinds that are greater or
169 // equal to them. For example, we'll pass in a CheckType node as an
170 // argument to the CheckOpcode method, not the other way around.
171 if (getKind() < Other->getKind())
172 return isContradictoryImpl(M: Other);
173 return Other->isContradictoryImpl(M: this);
174 }
175
176 void printOne(raw_ostream &OS, indent Indent = indent(0)) const;
177 void dump() const;
178
179protected:
180 virtual void printImpl(raw_ostream &OS, indent Indent) const = 0;
181 virtual bool isEqualImpl(const Matcher *M) const = 0;
182 virtual bool isContradictoryImpl(const Matcher *M) const { return false; }
183};
184
185/// Manages a singly linked list of Matcher objects. Interface based on
186/// std::forward_list. Once a Matcher is added to a list, it cannot be removed.
187/// It can only be erased or spliced to another position in this list or another
188/// list.
189class MatcherList {
190 MatcherBase BeforeBegin;
191
192 // Emitted size of all of the nodes in this list.
193 unsigned Size = 0;
194
195public:
196 MatcherList() = default;
197 MatcherList(const MatcherList &RHS) = delete;
198 MatcherList(MatcherList &&RHS) {
199 splice_after(Pos: before_begin(), X&: RHS);
200 Size = RHS.Size;
201 RHS.Size = 0;
202 }
203 ~MatcherList() { clear(); }
204
205 MatcherList &operator=(const MatcherList &) = delete;
206 MatcherList &operator=(MatcherList &&RHS) {
207 clear();
208 splice_after(Pos: before_begin(), X&: RHS);
209 Size = RHS.Size;
210 RHS.Size = 0;
211 return *this;
212 }
213
214 void clear() {
215 for (Matcher *P = BeforeBegin.Next; P != nullptr;) {
216 Matcher *Next = P->Next;
217 delete P;
218 P = Next;
219 }
220 BeforeBegin.Next = nullptr;
221 Size = 0;
222 }
223
224 template <bool IsConst> class iterator_impl {
225 friend class MatcherList;
226 using Base = std::conditional_t<IsConst, const MatcherBase, MatcherBase>;
227
228 Base *Pointer;
229
230 explicit iterator_impl(Base *P) { Pointer = P; }
231
232 public:
233 using iterator_category = std::forward_iterator_tag;
234 using value_type = std::conditional_t<IsConst, const Matcher *, Matcher *>;
235 using difference_type = std::ptrdiff_t;
236 using pointer = value_type *;
237 using reference = value_type &;
238
239 iterator_impl &operator++() {
240 Pointer = Pointer->Next;
241 return *this;
242 }
243
244 iterator_impl operator++(int) {
245 iterator Tmp(*this);
246 Pointer = Pointer->Next;
247 return Tmp;
248 }
249
250 value_type operator*() const { return static_cast<value_type>(Pointer); }
251
252 value_type operator->() const { return operator*(); }
253
254 bool operator==(const iterator_impl &X) const {
255 return Pointer == X.Pointer;
256 }
257 bool operator!=(const iterator_impl &X) const { return !operator==(X); }
258
259 // Allow conversion to a const iterator.
260 operator iterator_impl<true>() const {
261 return iterator_impl<true>(Pointer);
262 }
263 };
264
265 using iterator = iterator_impl<false>;
266 using const_iterator = iterator_impl<true>;
267
268 /// Return an iterator before the first Matcher in the list. This iterator
269 /// cannot be dereferenced. Incrementing returns the iterator to begin().
270 iterator before_begin() { return iterator(&BeforeBegin); }
271 const_iterator before_begin() const { return const_iterator(&BeforeBegin); }
272
273 iterator begin() { return iterator(BeforeBegin.Next); }
274 const_iterator begin() const { return const_iterator(BeforeBegin.Next); }
275
276 iterator end() { return iterator(nullptr); }
277 const_iterator end() const { return const_iterator(nullptr); }
278
279 Matcher *front() { return *begin(); }
280 const Matcher *front() const { return *begin(); }
281
282 bool empty() const { return BeforeBegin.Next == nullptr; }
283
284 void push_front(Matcher *M) { insert_after(Pos: before_begin(), N: M); }
285
286 /// Delete the first Matcher from the list.
287 void pop_front() {
288 assert(Size == 0 && "Should not modify list once size is set");
289 assert(!empty());
290 Matcher *N = BeforeBegin.Next;
291 BeforeBegin.Next = N->Next;
292 delete N;
293 }
294
295 /// Insert the matcher \p N into this list after \p Pos.
296 iterator insert_after(iterator Pos, Matcher *N) {
297 assert(Size == 0 && "Should not modify list once size is set");
298 N->Next = Pos.Pointer->Next;
299 Pos.Pointer->Next = N;
300 return iterator(N);
301 }
302
303 /// Insert Matchers in the range [F, L) into this list.
304 template <class InIt> iterator insert_after(iterator Pos, InIt F, InIt L) {
305 MatcherBase *R = Pos.Pointer;
306 if (F != L) {
307 Matcher *First = *F;
308 Matcher *Last = First;
309
310 // Link the Matchers together.
311 for (++F; F != L; ++F, Last = Last->Next)
312 Last->Next = *F;
313
314 // Insert them into the list.
315 Last->Next = R->Next;
316 R->Next = First;
317 R = Last;
318 }
319
320 return iterator(R);
321 }
322
323 /// Insert multiple matchers into this list.
324 iterator insert_after(iterator Pos, std::initializer_list<Matcher *> IL) {
325 return insert_after(Pos, F: IL.begin(), L: IL.end());
326 }
327
328 /// Erase the Matcher after \p Pos.
329 iterator erase_after(iterator Pos) {
330 assert(Size == 0 && "Should not modify list once size is set");
331 MatcherBase *P = Pos.Pointer;
332 Matcher *N = P->Next;
333 P->Next = N->Next;
334 delete N;
335 return iterator(P->Next);
336 }
337
338 iterator erase_after(iterator F, iterator L) {
339 Matcher *E = static_cast<Matcher *>(L.Pointer);
340 if (F != L) {
341 Matcher *N = F.Pointer->Next;
342 if (N != E) {
343 F.Pointer->Next = E;
344 do {
345 Matcher *Tmp = N->Next;
346 delete N;
347 N = Tmp;
348 } while (N != E);
349 }
350 }
351 return iterator(E);
352 }
353
354 /// Splice the contents of list \p X after \p Pos in this list.
355 void splice_after(iterator Pos, MatcherList &X) {
356 assert(Size == 0 && "Should not modify list once size is set");
357 if (!X.empty()) {
358 if (Pos.Pointer->Next != nullptr) {
359 auto LM1 = X.before_begin();
360 while (LM1.Pointer->Next != nullptr)
361 ++LM1;
362 LM1.Pointer->Next = Pos.Pointer->Next;
363 }
364 Pos.Pointer->Next = X.BeforeBegin.Next;
365 X.BeforeBegin.Next = nullptr;
366 }
367 }
368
369 /// Splice the Matcher after \p I into this list after \p Pos.
370 void splice_after(iterator Pos, MatcherList &, iterator I) {
371 assert(Size == 0 && "Should not modify list once size is set");
372 auto LM1 = std::next(x: I);
373 if (Pos != I && Pos != LM1) {
374 I.Pointer->Next = LM1.Pointer->Next;
375 LM1.Pointer->Next = Pos.Pointer->Next;
376 Pos.Pointer->Next = static_cast<Matcher *>(LM1.Pointer);
377 }
378 }
379
380 /// Splice the Matchers in the range (\p F, \p L) into this list after \p Pos.
381 void splice_after(iterator Pos, MatcherList &, iterator F, iterator L) {
382 assert(Size == 0 && "Should not modify list once size is set");
383 if (F != L && Pos != F) {
384 auto LM1 = F;
385 while (LM1.Pointer->Next != L.Pointer)
386 ++LM1;
387 if (F != LM1) {
388 LM1.Pointer->Next = Pos.Pointer->Next;
389 Pos.Pointer->Next = F.Pointer->Next;
390 F.Pointer->Next = static_cast<Matcher *>(L.Pointer);
391 }
392 }
393 }
394
395 void setSize(unsigned Sz) { Size = Sz; }
396 unsigned getSize() const { return Size; }
397
398 void print(raw_ostream &OS, indent Indent = indent(0)) const;
399 void dump() const;
400};
401
402/// ScopeMatcher - This attempts to match each of its children to find the first
403/// one that successfully matches. If one child fails, it tries the next child.
404/// If none of the children match then this check fails. It never has a 'next'.
405class ScopeMatcher : public Matcher {
406 SmallVector<MatcherList, 4> Children;
407
408public:
409 ScopeMatcher(SmallVectorImpl<MatcherList> &&children)
410 : Matcher(Scope), Children(std::move(children)) {}
411
412 unsigned getNumChildren() const { return Children.size(); }
413
414 MatcherList &getChild(unsigned i) { return Children[i]; }
415 const MatcherList &getChild(unsigned i) const { return Children[i]; }
416
417 SmallVectorImpl<MatcherList> &getChildren() { return Children; }
418
419 static bool classof(const Matcher *N) { return N->getKind() == Scope; }
420
421private:
422 void printImpl(raw_ostream &OS, indent Indent) const override;
423 bool isEqualImpl(const Matcher *M) const override { return false; }
424};
425
426/// RecordMatcher - Save the current node in the operand list.
427class RecordMatcher : public Matcher {
428 /// WhatFor - This is a string indicating why we're recording this. This
429 /// should only be used for comment generation not anything semantic.
430 std::string WhatFor;
431
432 /// ResultNo - The slot number in the RecordedNodes vector that this will be,
433 /// just printed as a comment.
434 unsigned ResultNo;
435
436public:
437 RecordMatcher(const std::string &whatfor, unsigned resultNo)
438 : Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {}
439
440 const std::string &getWhatFor() const { return WhatFor; }
441 unsigned getResultNo() const { return ResultNo; }
442
443 static bool classof(const Matcher *N) { return N->getKind() == RecordNode; }
444
445private:
446 void printImpl(raw_ostream &OS, indent Indent) const override;
447 bool isEqualImpl(const Matcher *M) const override { return true; }
448};
449
450/// RecordChildMatcher - Save a numbered child of the current node, or fail
451/// the match if it doesn't exist. This is logically equivalent to:
452/// MoveChild N + RecordNode + MoveParent.
453class RecordChildMatcher : public Matcher {
454 unsigned ChildNo;
455
456 /// WhatFor - This is a string indicating why we're recording this. This
457 /// should only be used for comment generation not anything semantic.
458 std::string WhatFor;
459
460 /// ResultNo - The slot number in the RecordedNodes vector that this will be,
461 /// just printed as a comment.
462 unsigned ResultNo;
463
464public:
465 RecordChildMatcher(unsigned childno, const std::string &whatfor,
466 unsigned resultNo)
467 : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor),
468 ResultNo(resultNo) {}
469
470 unsigned getChildNo() const { return ChildNo; }
471 const std::string &getWhatFor() const { return WhatFor; }
472 unsigned getResultNo() const { return ResultNo; }
473
474 static bool classof(const Matcher *N) { return N->getKind() == RecordChild; }
475
476private:
477 void printImpl(raw_ostream &OS, indent Indent) const override;
478 bool isEqualImpl(const Matcher *M) const override {
479 return cast<RecordChildMatcher>(Val: M)->getChildNo() == getChildNo();
480 }
481};
482
483/// RecordMemRefMatcher - Save the current node's memref.
484class RecordMemRefMatcher : public Matcher {
485public:
486 RecordMemRefMatcher() : Matcher(RecordMemRef) {}
487
488 static bool classof(const Matcher *N) { return N->getKind() == RecordMemRef; }
489
490private:
491 void printImpl(raw_ostream &OS, indent Indent) const override;
492 bool isEqualImpl(const Matcher *M) const override { return true; }
493};
494
495/// CaptureGlueInputMatcher - If the current record has a glue input, record
496/// it so that it is used as an input to the generated code.
497class CaptureGlueInputMatcher : public Matcher {
498public:
499 CaptureGlueInputMatcher() : Matcher(CaptureGlueInput) {}
500
501 static bool classof(const Matcher *N) {
502 return N->getKind() == CaptureGlueInput;
503 }
504
505private:
506 void printImpl(raw_ostream &OS, indent Indent) const override;
507 bool isEqualImpl(const Matcher *M) const override { return true; }
508};
509
510/// MoveChildMatcher - This tells the interpreter to move into the
511/// specified child node.
512class MoveChildMatcher : public Matcher {
513 unsigned ChildNo;
514
515public:
516 MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {}
517
518 unsigned getChildNo() const { return ChildNo; }
519
520 static bool classof(const Matcher *N) { return N->getKind() == MoveChild; }
521
522private:
523 void printImpl(raw_ostream &OS, indent Indent) const override;
524 bool isEqualImpl(const Matcher *M) const override {
525 return cast<MoveChildMatcher>(Val: M)->getChildNo() == getChildNo();
526 }
527};
528
529/// MoveSiblingMatcher - This tells the interpreter to move into the
530/// specified sibling node.
531class MoveSiblingMatcher : public Matcher {
532 unsigned SiblingNo;
533
534public:
535 MoveSiblingMatcher(unsigned SiblingNo)
536 : Matcher(MoveSibling), SiblingNo(SiblingNo) {}
537
538 unsigned getSiblingNo() const { return SiblingNo; }
539
540 static bool classof(const Matcher *N) { return N->getKind() == MoveSibling; }
541
542private:
543 void printImpl(raw_ostream &OS, indent Indent) const override;
544 bool isEqualImpl(const Matcher *M) const override {
545 return cast<MoveSiblingMatcher>(Val: M)->getSiblingNo() == getSiblingNo();
546 }
547};
548
549/// MoveParentMatcher - This tells the interpreter to move to the parent
550/// of the current node.
551class MoveParentMatcher : public Matcher {
552public:
553 MoveParentMatcher() : Matcher(MoveParent) {}
554
555 static bool classof(const Matcher *N) { return N->getKind() == MoveParent; }
556
557private:
558 void printImpl(raw_ostream &OS, indent Indent) const override;
559 bool isEqualImpl(const Matcher *M) const override { return true; }
560};
561
562/// CheckSameMatcher - This checks to see if this node is exactly the same
563/// node as the specified match that was recorded with 'Record'. This is used
564/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
565class CheckSameMatcher : public Matcher {
566 unsigned MatchNumber;
567
568public:
569 CheckSameMatcher(unsigned matchnumber)
570 : Matcher(CheckSame), MatchNumber(matchnumber) {}
571
572 unsigned getMatchNumber() const { return MatchNumber; }
573
574 static bool classof(const Matcher *N) { return N->getKind() == CheckSame; }
575
576private:
577 void printImpl(raw_ostream &OS, indent Indent) const override;
578 bool isEqualImpl(const Matcher *M) const override {
579 return cast<CheckSameMatcher>(Val: M)->getMatchNumber() == getMatchNumber();
580 }
581};
582
583/// CheckChildSameMatcher - This checks to see if child node is exactly the same
584/// node as the specified match that was recorded with 'Record'. This is used
585/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
586class CheckChildSameMatcher : public Matcher {
587 unsigned ChildNo;
588 unsigned MatchNumber;
589
590public:
591 CheckChildSameMatcher(unsigned childno, unsigned matchnumber)
592 : Matcher(CheckChildSame), ChildNo(childno), MatchNumber(matchnumber) {}
593
594 unsigned getChildNo() const { return ChildNo; }
595 unsigned getMatchNumber() const { return MatchNumber; }
596
597 static bool classof(const Matcher *N) {
598 return N->getKind() == CheckChildSame;
599 }
600
601private:
602 void printImpl(raw_ostream &OS, indent Indent) const override;
603 bool isEqualImpl(const Matcher *M) const override {
604 return cast<CheckChildSameMatcher>(Val: M)->ChildNo == ChildNo &&
605 cast<CheckChildSameMatcher>(Val: M)->MatchNumber == MatchNumber;
606 }
607};
608
609/// CheckPatternPredicateMatcher - This checks the target-specific predicate
610/// to see if the entire pattern is capable of matching. This predicate does
611/// not take a node as input. This is used for subtarget feature checks etc.
612class CheckPatternPredicateMatcher : public Matcher {
613 std::string Predicate;
614
615public:
616 CheckPatternPredicateMatcher(StringRef predicate)
617 : Matcher(CheckPatternPredicate), Predicate(predicate) {}
618
619 StringRef getPredicate() const { return Predicate; }
620
621 static bool classof(const Matcher *N) {
622 return N->getKind() == CheckPatternPredicate;
623 }
624
625private:
626 void printImpl(raw_ostream &OS, indent Indent) const override;
627 bool isEqualImpl(const Matcher *M) const override {
628 return cast<CheckPatternPredicateMatcher>(Val: M)->getPredicate() == Predicate;
629 }
630};
631
632/// CheckPredicateMatcher - This checks the target-specific predicate to
633/// see if the node is acceptable.
634class CheckPredicateMatcher : public Matcher {
635 TreePattern *Pred;
636 const SmallVector<unsigned, 4> Operands;
637
638public:
639 CheckPredicateMatcher(const TreePredicateFn &pred,
640 ArrayRef<unsigned> Operands);
641
642 TreePredicateFn getPredicate() const;
643 unsigned getNumOperands() const;
644 unsigned getOperandNo(unsigned i) const;
645
646 static bool classof(const Matcher *N) {
647 return N->getKind() == CheckPredicate;
648 }
649
650private:
651 void printImpl(raw_ostream &OS, indent Indent) const override;
652 bool isEqualImpl(const Matcher *M) const override {
653 return cast<CheckPredicateMatcher>(Val: M)->Pred == Pred;
654 }
655};
656
657/// CheckOpcodeMatcher - This checks to see if the current node has the
658/// specified opcode, if not it fails to match.
659class CheckOpcodeMatcher : public Matcher {
660 const SDNodeInfo &Opcode;
661
662public:
663 CheckOpcodeMatcher(const SDNodeInfo &opcode)
664 : Matcher(CheckOpcode), Opcode(opcode) {}
665
666 const SDNodeInfo &getOpcode() const { return Opcode; }
667
668 static bool classof(const Matcher *N) { return N->getKind() == CheckOpcode; }
669
670private:
671 void printImpl(raw_ostream &OS, indent Indent) const override;
672 bool isEqualImpl(const Matcher *M) const override;
673 bool isContradictoryImpl(const Matcher *M) const override;
674};
675
676/// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching
677/// to one matcher per opcode. If the opcode doesn't match any of the cases,
678/// then the match fails. This is semantically equivalent to a Scope node where
679/// every child does a CheckOpcode, but is much faster.
680class SwitchOpcodeMatcher : public Matcher {
681 SmallVector<std::pair<const SDNodeInfo *, MatcherList>, 8> Cases;
682
683public:
684 SwitchOpcodeMatcher(
685 SmallVectorImpl<std::pair<const SDNodeInfo *, MatcherList>> &&cases)
686 : Matcher(SwitchOpcode), Cases(std::move(cases)) {}
687
688 static bool classof(const Matcher *N) { return N->getKind() == SwitchOpcode; }
689
690 unsigned getNumCases() const { return Cases.size(); }
691
692 const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; }
693 MatcherList &getCaseMatcher(unsigned i) { return Cases[i].second; }
694 const MatcherList &getCaseMatcher(unsigned i) const {
695 return Cases[i].second;
696 }
697
698private:
699 void printImpl(raw_ostream &OS, indent Indent) const override;
700 bool isEqualImpl(const Matcher *M) const override { return false; }
701};
702
703/// CheckTypeMatcher - This checks to see if the current node has the
704/// specified type at the specified result, if not it fails to match.
705class CheckTypeMatcher : public Matcher {
706 ValueTypeByHwMode Type;
707 unsigned ResNo;
708
709public:
710 CheckTypeMatcher(ValueTypeByHwMode type, unsigned resno)
711 : Matcher(CheckType), Type(std::move(type)), ResNo(resno) {}
712
713 const ValueTypeByHwMode &getType() const { return Type; }
714 unsigned getResNo() const { return ResNo; }
715
716 static bool classof(const Matcher *N) { return N->getKind() == CheckType; }
717
718private:
719 void printImpl(raw_ostream &OS, indent Indent) const override;
720 bool isEqualImpl(const Matcher *M) const override {
721 return cast<CheckTypeMatcher>(Val: M)->Type == Type;
722 }
723 bool isContradictoryImpl(const Matcher *M) const override;
724};
725
726/// SwitchTypeMatcher - Switch based on the current node's type, dispatching
727/// to one matcher per case. If the type doesn't match any of the cases,
728/// then the match fails. This is semantically equivalent to a Scope node where
729/// every child does a CheckType, but is much faster.
730class SwitchTypeMatcher : public Matcher {
731 SmallVector<std::pair<MVT, MatcherList>, 8> Cases;
732
733public:
734 SwitchTypeMatcher(SmallVectorImpl<std::pair<MVT, MatcherList>> &&cases)
735 : Matcher(SwitchType), Cases(std::move(cases)) {}
736
737 static bool classof(const Matcher *N) { return N->getKind() == SwitchType; }
738
739 unsigned getNumCases() const { return Cases.size(); }
740
741 MVT getCaseType(unsigned i) const { return Cases[i].first; }
742 MatcherList &getCaseMatcher(unsigned i) { return Cases[i].second; }
743 const MatcherList &getCaseMatcher(unsigned i) const {
744 return Cases[i].second;
745 }
746
747private:
748 void printImpl(raw_ostream &OS, indent Indent) const override;
749 bool isEqualImpl(const Matcher *M) const override { return false; }
750};
751
752/// CheckChildTypeMatcher - This checks to see if a child node has the
753/// specified type, if not it fails to match.
754class CheckChildTypeMatcher : public Matcher {
755 unsigned ChildNo;
756 ValueTypeByHwMode Type;
757
758public:
759 CheckChildTypeMatcher(unsigned childno, ValueTypeByHwMode type)
760 : Matcher(CheckChildType), ChildNo(childno), Type(std::move(type)) {}
761
762 unsigned getChildNo() const { return ChildNo; }
763 const ValueTypeByHwMode &getType() const { return Type; }
764
765 static bool classof(const Matcher *N) {
766 return N->getKind() == CheckChildType;
767 }
768
769private:
770 void printImpl(raw_ostream &OS, indent Indent) const override;
771 bool isEqualImpl(const Matcher *M) const override {
772 return cast<CheckChildTypeMatcher>(Val: M)->ChildNo == ChildNo &&
773 cast<CheckChildTypeMatcher>(Val: M)->Type == Type;
774 }
775 bool isContradictoryImpl(const Matcher *M) const override;
776};
777
778/// CheckIntegerMatcher - This checks to see if the current node is a
779/// ConstantSDNode with the specified integer value, if not it fails to match.
780class CheckIntegerMatcher : public Matcher {
781 int64_t Value;
782
783public:
784 CheckIntegerMatcher(int64_t value) : Matcher(CheckInteger), Value(value) {}
785
786 int64_t getValue() const { return Value; }
787
788 static bool classof(const Matcher *N) { return N->getKind() == CheckInteger; }
789
790private:
791 void printImpl(raw_ostream &OS, indent Indent) const override;
792 bool isEqualImpl(const Matcher *M) const override {
793 return cast<CheckIntegerMatcher>(Val: M)->Value == Value;
794 }
795 bool isContradictoryImpl(const Matcher *M) const override;
796};
797
798/// CheckChildIntegerMatcher - This checks to see if the child node is a
799/// ConstantSDNode with a specified integer value, if not it fails to match.
800class CheckChildIntegerMatcher : public Matcher {
801 unsigned ChildNo;
802 int64_t Value;
803
804public:
805 CheckChildIntegerMatcher(unsigned childno, int64_t value)
806 : Matcher(CheckChildInteger), ChildNo(childno), Value(value) {}
807
808 unsigned getChildNo() const { return ChildNo; }
809 int64_t getValue() const { return Value; }
810
811 static bool classof(const Matcher *N) {
812 return N->getKind() == CheckChildInteger;
813 }
814
815private:
816 void printImpl(raw_ostream &OS, indent Indent) const override;
817 bool isEqualImpl(const Matcher *M) const override {
818 return cast<CheckChildIntegerMatcher>(Val: M)->ChildNo == ChildNo &&
819 cast<CheckChildIntegerMatcher>(Val: M)->Value == Value;
820 }
821 bool isContradictoryImpl(const Matcher *M) const override;
822};
823
824/// CheckCondCodeMatcher - This checks to see if the current node is a
825/// CondCodeSDNode with the specified condition, if not it fails to match.
826class CheckCondCodeMatcher : public Matcher {
827 StringRef CondCodeName;
828
829public:
830 CheckCondCodeMatcher(StringRef condcodename)
831 : Matcher(CheckCondCode), CondCodeName(condcodename) {}
832
833 StringRef getCondCodeName() const { return CondCodeName; }
834
835 static bool classof(const Matcher *N) {
836 return N->getKind() == CheckCondCode;
837 }
838
839private:
840 void printImpl(raw_ostream &OS, indent Indent) const override;
841 bool isEqualImpl(const Matcher *M) const override {
842 return cast<CheckCondCodeMatcher>(Val: M)->CondCodeName == CondCodeName;
843 }
844 bool isContradictoryImpl(const Matcher *M) const override;
845};
846
847/// CheckChild2CondCodeMatcher - This checks to see if child 2 node is a
848/// CondCodeSDNode with the specified condition, if not it fails to match.
849class CheckChild2CondCodeMatcher : public Matcher {
850 StringRef CondCodeName;
851
852public:
853 CheckChild2CondCodeMatcher(StringRef condcodename)
854 : Matcher(CheckChild2CondCode), CondCodeName(condcodename) {}
855
856 StringRef getCondCodeName() const { return CondCodeName; }
857
858 static bool classof(const Matcher *N) {
859 return N->getKind() == CheckChild2CondCode;
860 }
861
862private:
863 void printImpl(raw_ostream &OS, indent Indent) const override;
864 bool isEqualImpl(const Matcher *M) const override {
865 return cast<CheckChild2CondCodeMatcher>(Val: M)->CondCodeName == CondCodeName;
866 }
867 bool isContradictoryImpl(const Matcher *M) const override;
868};
869
870/// CheckValueTypeMatcher - This checks to see if the current node is a
871/// VTSDNode with the specified type, if not it fails to match.
872class CheckValueTypeMatcher : public Matcher {
873 MVT VT;
874
875public:
876 CheckValueTypeMatcher(MVT SimpleVT) : Matcher(CheckValueType), VT(SimpleVT) {}
877
878 MVT getVT() const { return VT; }
879
880 static bool classof(const Matcher *N) {
881 return N->getKind() == CheckValueType;
882 }
883
884private:
885 void printImpl(raw_ostream &OS, indent Indent) const override;
886 bool isEqualImpl(const Matcher *M) const override {
887 return cast<CheckValueTypeMatcher>(Val: M)->VT == VT;
888 }
889 bool isContradictoryImpl(const Matcher *M) const override;
890};
891
892/// CheckComplexPatMatcher - This node runs the specified ComplexPattern on
893/// the current node.
894class CheckComplexPatMatcher : public Matcher {
895 const ComplexPattern &Pattern;
896
897 /// MatchNumber - This is the recorded nodes slot that contains the node we
898 /// want to match against.
899 unsigned MatchNumber;
900
901 /// Name - The name of the node we're matching, for comment emission.
902 StringRef Name;
903
904 /// FirstResult - This is the first slot in the RecordedNodes list that the
905 /// result of the match populates.
906 unsigned FirstResult;
907
908public:
909 CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber,
910 StringRef name, unsigned firstresult)
911 : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber),
912 Name(name), FirstResult(firstresult) {}
913
914 const ComplexPattern &getPattern() const { return Pattern; }
915 unsigned getMatchNumber() const { return MatchNumber; }
916
917 StringRef getName() const { return Name; }
918 unsigned getFirstResult() const { return FirstResult; }
919
920 static bool classof(const Matcher *N) {
921 return N->getKind() == CheckComplexPat;
922 }
923
924private:
925 void printImpl(raw_ostream &OS, indent Indent) const override;
926 bool isEqualImpl(const Matcher *M) const override {
927 return &cast<CheckComplexPatMatcher>(Val: M)->Pattern == &Pattern &&
928 cast<CheckComplexPatMatcher>(Val: M)->MatchNumber == MatchNumber;
929 }
930};
931
932/// CheckAndImmMatcher - This checks to see if the current node is an 'and'
933/// with something equivalent to the specified immediate.
934class CheckAndImmMatcher : public Matcher {
935 int64_t Value;
936
937public:
938 CheckAndImmMatcher(int64_t value) : Matcher(CheckAndImm), Value(value) {}
939
940 int64_t getValue() const { return Value; }
941
942 static bool classof(const Matcher *N) { return N->getKind() == CheckAndImm; }
943
944private:
945 void printImpl(raw_ostream &OS, indent Indent) const override;
946 bool isEqualImpl(const Matcher *M) const override {
947 return cast<CheckAndImmMatcher>(Val: M)->Value == Value;
948 }
949};
950
951/// CheckOrImmMatcher - This checks to see if the current node is an 'and'
952/// with something equivalent to the specified immediate.
953class CheckOrImmMatcher : public Matcher {
954 int64_t Value;
955
956public:
957 CheckOrImmMatcher(int64_t value) : Matcher(CheckOrImm), Value(value) {}
958
959 int64_t getValue() const { return Value; }
960
961 static bool classof(const Matcher *N) { return N->getKind() == CheckOrImm; }
962
963private:
964 void printImpl(raw_ostream &OS, indent Indent) const override;
965 bool isEqualImpl(const Matcher *M) const override {
966 return cast<CheckOrImmMatcher>(Val: M)->Value == Value;
967 }
968};
969
970/// CheckImmAllOnesVMatcher - This checks if the current node is a build_vector
971/// or splat_vector of all ones.
972class CheckImmAllOnesVMatcher : public Matcher {
973public:
974 CheckImmAllOnesVMatcher() : Matcher(CheckImmAllOnesV) {}
975
976 static bool classof(const Matcher *N) {
977 return N->getKind() == CheckImmAllOnesV;
978 }
979
980private:
981 void printImpl(raw_ostream &OS, indent Indent) const override;
982 bool isEqualImpl(const Matcher *M) const override { return true; }
983 bool isContradictoryImpl(const Matcher *M) const override;
984};
985
986/// CheckImmAllZerosVMatcher - This checks if the current node is a
987/// build_vector or splat_vector of all zeros.
988class CheckImmAllZerosVMatcher : public Matcher {
989public:
990 CheckImmAllZerosVMatcher() : Matcher(CheckImmAllZerosV) {}
991
992 static bool classof(const Matcher *N) {
993 return N->getKind() == CheckImmAllZerosV;
994 }
995
996private:
997 void printImpl(raw_ostream &OS, indent Indent) const override;
998 bool isEqualImpl(const Matcher *M) const override { return true; }
999 bool isContradictoryImpl(const Matcher *M) const override;
1000};
1001
1002/// CheckUndefMatcher - This checks if the current node is undef or poison,
1003/// i.e. SDNode::isUndef() (ISD::UNDEF or ISD::POISON).
1004class CheckUndefMatcher : public Matcher {
1005public:
1006 CheckUndefMatcher() : Matcher(CheckUndef) {}
1007
1008 static bool classof(const Matcher *N) { return N->getKind() == CheckUndef; }
1009
1010private:
1011 void printImpl(raw_ostream &OS, indent Indent) const override;
1012 bool isEqualImpl(const Matcher *M) const override { return true; }
1013 bool isContradictoryImpl(const Matcher *M) const override;
1014};
1015
1016/// CheckFoldableChainNodeMatcher - This checks to see if the current node
1017/// (which defines a chain operand) is safe to fold into a larger pattern.
1018class CheckFoldableChainNodeMatcher : public Matcher {
1019public:
1020 CheckFoldableChainNodeMatcher() : Matcher(CheckFoldableChainNode) {}
1021
1022 static bool classof(const Matcher *N) {
1023 return N->getKind() == CheckFoldableChainNode;
1024 }
1025
1026private:
1027 void printImpl(raw_ostream &OS, indent Indent) const override;
1028 bool isEqualImpl(const Matcher *M) const override { return true; }
1029};
1030
1031/// EmitIntegerMatcher - This creates a new TargetConstant.
1032class EmitIntegerMatcher : public Matcher {
1033 // Optional string to give the value a symbolic name for readability.
1034 std::string Str;
1035 int64_t Val;
1036 ValueTypeByHwMode VT;
1037
1038 unsigned ResultNo;
1039
1040public:
1041 EmitIntegerMatcher(int64_t val, ValueTypeByHwMode vt, unsigned resultNo)
1042 : Matcher(EmitInteger), Val(val), VT(std::move(vt)), ResultNo(resultNo) {}
1043 EmitIntegerMatcher(const std::string &str, int64_t val, MVT vt,
1044 unsigned resultNo)
1045 : Matcher(EmitInteger), Str(str), Val(val), VT(vt), ResultNo(resultNo) {}
1046
1047 const std::string &getString() const { return Str; }
1048 int64_t getValue() const { return Val; }
1049 const ValueTypeByHwMode &getVT() const { return VT; }
1050 unsigned getResultNo() const { return ResultNo; }
1051
1052 static bool classof(const Matcher *N) { return N->getKind() == EmitInteger; }
1053
1054private:
1055 void printImpl(raw_ostream &OS, indent Indent) const override;
1056 bool isEqualImpl(const Matcher *M) const override {
1057 return cast<EmitIntegerMatcher>(Val: M)->Val == Val &&
1058 cast<EmitIntegerMatcher>(Val: M)->VT == VT &&
1059 cast<EmitIntegerMatcher>(Val: M)->Str == Str;
1060 }
1061};
1062
1063/// EmitRegisterMatcher - This creates a new TargetConstant.
1064class EmitRegisterMatcher : public Matcher {
1065 /// Reg - The def for the register that we're emitting. If this is null, then
1066 /// this is a reference to zero_reg.
1067 const CodeGenRegister *Reg;
1068 ValueTypeByHwMode VT;
1069
1070 unsigned ResultNo;
1071
1072public:
1073 EmitRegisterMatcher(const CodeGenRegister *reg, ValueTypeByHwMode vt,
1074 unsigned resultNo)
1075 : Matcher(EmitRegister), Reg(reg), VT(std::move(vt)), ResultNo(resultNo) {
1076 }
1077
1078 const CodeGenRegister *getReg() const { return Reg; }
1079 const ValueTypeByHwMode &getVT() const { return VT; }
1080 unsigned getResultNo() const { return ResultNo; }
1081
1082 static bool classof(const Matcher *N) { return N->getKind() == EmitRegister; }
1083
1084private:
1085 void printImpl(raw_ostream &OS, indent Indent) const override;
1086 bool isEqualImpl(const Matcher *M) const override {
1087 return cast<EmitRegisterMatcher>(Val: M)->Reg == Reg &&
1088 cast<EmitRegisterMatcher>(Val: M)->VT == VT;
1089 }
1090};
1091
1092/// EmitConvertToTargetMatcher - Emit an operation that reads a specified
1093/// recorded node and converts it from being a ISD::Constant to
1094/// ISD::TargetConstant, likewise for ConstantFP.
1095class EmitConvertToTargetMatcher : public Matcher {
1096 // Recorded Node
1097 unsigned Slot;
1098
1099 // Result
1100 unsigned ResultNo;
1101
1102public:
1103 EmitConvertToTargetMatcher(unsigned slot, unsigned resultNo)
1104 : Matcher(EmitConvertToTarget), Slot(slot), ResultNo(resultNo) {}
1105
1106 unsigned getSlot() const { return Slot; }
1107 unsigned getResultNo() const { return ResultNo; }
1108
1109 static bool classof(const Matcher *N) {
1110 return N->getKind() == EmitConvertToTarget;
1111 }
1112
1113private:
1114 void printImpl(raw_ostream &OS, indent Indent) const override;
1115 bool isEqualImpl(const Matcher *M) const override {
1116 return cast<EmitConvertToTargetMatcher>(Val: M)->Slot == Slot;
1117 }
1118};
1119
1120/// EmitMergeInputChainsMatcher - Emit a node that merges a list of input
1121/// chains together with a token factor. The list of nodes are the nodes in the
1122/// matched pattern that have chain input/outputs. This node adds all input
1123/// chains of these nodes if they are not themselves a node in the pattern.
1124class EmitMergeInputChainsMatcher : public Matcher {
1125 SmallVector<unsigned, 3> ChainNodes;
1126
1127public:
1128 EmitMergeInputChainsMatcher(ArrayRef<unsigned> nodes)
1129 : Matcher(EmitMergeInputChains), ChainNodes(nodes) {}
1130
1131 unsigned getNumNodes() const { return ChainNodes.size(); }
1132
1133 unsigned getNode(unsigned i) const {
1134 assert(i < ChainNodes.size());
1135 return ChainNodes[i];
1136 }
1137
1138 static bool classof(const Matcher *N) {
1139 return N->getKind() == EmitMergeInputChains;
1140 }
1141
1142private:
1143 void printImpl(raw_ostream &OS, indent Indent) const override;
1144 bool isEqualImpl(const Matcher *M) const override {
1145 return cast<EmitMergeInputChainsMatcher>(Val: M)->ChainNodes == ChainNodes;
1146 }
1147};
1148
1149/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,
1150/// pushing the chain and glue results.
1151///
1152class EmitCopyToRegMatcher : public Matcher {
1153 // Value to copy into the physreg.
1154 unsigned SrcSlot;
1155 // Register Destination
1156 const CodeGenRegister *DestPhysReg;
1157
1158public:
1159 EmitCopyToRegMatcher(unsigned srcSlot, const CodeGenRegister *destPhysReg)
1160 : Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}
1161
1162 unsigned getSrcSlot() const { return SrcSlot; }
1163 const CodeGenRegister *getDestPhysReg() const { return DestPhysReg; }
1164
1165 static bool classof(const Matcher *N) {
1166 return N->getKind() == EmitCopyToReg;
1167 }
1168
1169private:
1170 void printImpl(raw_ostream &OS, indent Indent) const override;
1171 bool isEqualImpl(const Matcher *M) const override {
1172 return cast<EmitCopyToRegMatcher>(Val: M)->SrcSlot == SrcSlot &&
1173 cast<EmitCopyToRegMatcher>(Val: M)->DestPhysReg == DestPhysReg;
1174 }
1175};
1176
1177/// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a
1178/// recorded node and records the result.
1179class EmitNodeXFormMatcher : public Matcher {
1180 // Recorded Node
1181 unsigned Slot;
1182 // Transform
1183 const Record *NodeXForm;
1184
1185 // Result
1186 unsigned ResultNo;
1187
1188public:
1189 EmitNodeXFormMatcher(unsigned slot, const Record *nodeXForm,
1190 unsigned resultNo)
1191 : Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm),
1192 ResultNo(resultNo) {}
1193
1194 unsigned getSlot() const { return Slot; }
1195 const Record *getNodeXForm() const { return NodeXForm; }
1196 unsigned getResultNo() const { return ResultNo; }
1197
1198 static bool classof(const Matcher *N) {
1199 return N->getKind() == EmitNodeXForm;
1200 }
1201
1202private:
1203 void printImpl(raw_ostream &OS, indent Indent) const override;
1204 bool isEqualImpl(const Matcher *M) const override {
1205 return cast<EmitNodeXFormMatcher>(Val: M)->Slot == Slot &&
1206 cast<EmitNodeXFormMatcher>(Val: M)->NodeXForm == NodeXForm;
1207 }
1208};
1209
1210/// EmitNodeMatcherCommon - Common class shared between EmitNode and
1211/// MorphNodeTo.
1212class EmitNodeMatcherCommon : public Matcher {
1213 const CodeGenInstruction &CGI;
1214 const SmallVector<ValueTypeByHwMode, 3> VTs;
1215 const SmallVector<unsigned, 6> Operands;
1216 bool HasChain, HasInGlue, HasOutGlue, HasMemRefs;
1217
1218 /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1.
1219 /// If this is a varidic node, this is set to the number of fixed arity
1220 /// operands in the root of the pattern. The rest are appended to this node.
1221 int NumFixedArityOperands;
1222
1223public:
1224 EmitNodeMatcherCommon(const CodeGenInstruction &cgi,
1225 ArrayRef<ValueTypeByHwMode> vts,
1226 ArrayRef<unsigned> operands, bool hasChain,
1227 bool hasInGlue, bool hasOutGlue, bool hasmemrefs,
1228 int numfixedarityoperands, bool isMorphNodeTo)
1229 : Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), CGI(cgi), VTs(vts),
1230 Operands(operands), HasChain(hasChain), HasInGlue(hasInGlue),
1231 HasOutGlue(hasOutGlue), HasMemRefs(hasmemrefs),
1232 NumFixedArityOperands(numfixedarityoperands) {}
1233
1234 const CodeGenInstruction &getInstruction() const { return CGI; }
1235
1236 unsigned getNumVTs() const { return VTs.size(); }
1237 const ValueTypeByHwMode &getVT(unsigned i) const {
1238 assert(i < VTs.size());
1239 return VTs[i];
1240 }
1241
1242 unsigned getNumOperands() const { return Operands.size(); }
1243 unsigned getOperand(unsigned i) const {
1244 assert(i < Operands.size());
1245 return Operands[i];
1246 }
1247
1248 ArrayRef<ValueTypeByHwMode> getVTList() const { return VTs; }
1249 ArrayRef<unsigned> getOperandList() const { return Operands; }
1250
1251 bool hasChain() const { return HasChain; }
1252 bool hasInGlue() const { return HasInGlue; }
1253 bool hasOutGlue() const { return HasOutGlue; }
1254 bool hasMemRefs() const { return HasMemRefs; }
1255 int getNumFixedArityOperands() const { return NumFixedArityOperands; }
1256
1257 static bool classof(const Matcher *N) {
1258 return N->getKind() == EmitNode || N->getKind() == MorphNodeTo;
1259 }
1260
1261private:
1262 void printImpl(raw_ostream &OS, indent Indent) const override;
1263 bool isEqualImpl(const Matcher *M) const override;
1264};
1265
1266/// EmitNodeMatcher - This signals a successful match and generates a node.
1267class EmitNodeMatcher : public EmitNodeMatcherCommon {
1268 void anchor() override;
1269 unsigned FirstResultSlot;
1270
1271public:
1272 EmitNodeMatcher(const CodeGenInstruction &cgi,
1273 ArrayRef<ValueTypeByHwMode> vts, ArrayRef<unsigned> operands,
1274 bool hasChain, bool hasInGlue, bool hasOutGlue,
1275 bool hasmemrefs, int numfixedarityoperands,
1276 unsigned firstresultslot)
1277 : EmitNodeMatcherCommon(cgi, vts, operands, hasChain, hasInGlue,
1278 hasOutGlue, hasmemrefs, numfixedarityoperands,
1279 false),
1280 FirstResultSlot(firstresultslot) {}
1281
1282 unsigned getFirstResultSlot() const { return FirstResultSlot; }
1283
1284 static bool classof(const Matcher *N) { return N->getKind() == EmitNode; }
1285};
1286
1287class MorphNodeToMatcher : public EmitNodeMatcherCommon {
1288 void anchor() override;
1289 const PatternToMatch &Pattern;
1290
1291public:
1292 MorphNodeToMatcher(const CodeGenInstruction &cgi,
1293 ArrayRef<ValueTypeByHwMode> vts,
1294 ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue,
1295 bool hasOutGlue, bool hasmemrefs,
1296 int numfixedarityoperands, const PatternToMatch &pattern)
1297 : EmitNodeMatcherCommon(cgi, vts, operands, hasChain, hasInGlue,
1298 hasOutGlue, hasmemrefs, numfixedarityoperands,
1299 true),
1300 Pattern(pattern) {}
1301
1302 const PatternToMatch &getPattern() const { return Pattern; }
1303
1304 static bool classof(const Matcher *N) { return N->getKind() == MorphNodeTo; }
1305};
1306
1307/// CompleteMatchMatcher - Complete a match by replacing the results of the
1308/// pattern with the newly generated nodes. This also prints a comment
1309/// indicating the source and dest patterns.
1310class CompleteMatchMatcher : public Matcher {
1311 SmallVector<unsigned, 2> Results;
1312 const PatternToMatch &Pattern;
1313
1314public:
1315 CompleteMatchMatcher(ArrayRef<unsigned> results,
1316 const PatternToMatch &pattern)
1317 : Matcher(CompleteMatch), Results(results), Pattern(pattern) {}
1318
1319 unsigned getNumResults() const { return Results.size(); }
1320 unsigned getResult(unsigned R) const { return Results[R]; }
1321 const PatternToMatch &getPattern() const { return Pattern; }
1322
1323 static bool classof(const Matcher *N) {
1324 return N->getKind() == CompleteMatch;
1325 }
1326
1327private:
1328 void printImpl(raw_ostream &OS, indent Indent) const override;
1329 bool isEqualImpl(const Matcher *M) const override {
1330 return cast<CompleteMatchMatcher>(Val: M)->Results == Results &&
1331 &cast<CompleteMatchMatcher>(Val: M)->Pattern == &Pattern;
1332 }
1333};
1334
1335} // end namespace llvm
1336
1337#endif // LLVM_UTILS_TABLEGEN_COMMON_DAGISELMATCHER_H
1338