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