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