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