Emulate the current isel's "IsChainCompatible" logic for now.
[oota-llvm.git] / utils / TableGen / DAGISelMatcher.h
1 //===- DAGISelMatcher.h - Representation of DAG pattern matcher -----------===//
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 TBLGEN_DAGISELMATCHER_H
11 #define TBLGEN_DAGISELMATCHER_H
12
13 #include "llvm/CodeGen/ValueTypes.h"
14 #include "llvm/ADT/OwningPtr.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/Casting.h"
17
18 namespace llvm {
19   class CodeGenDAGPatterns;
20   class MatcherNode;
21   class PatternToMatch;
22   class raw_ostream;
23   class ComplexPattern;
24
25 MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern,
26                                      const CodeGenDAGPatterns &CGP);
27
28 void EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &OS);
29
30   
31 /// MatcherNode - Base class for all the the DAG ISel Matcher representation
32 /// nodes.
33 class MatcherNode {
34 public:
35   enum KindTy {
36     EmitNode,
37     Push,           // [Push, Dest0, Dest1, Dest2, Dest3]
38     Record,         // [Record]
39     MoveChild,      // [MoveChild, Child#]
40     MoveParent,     // [MoveParent]
41     
42     CheckSame,      // [CheckSame, N]         Fail if not same as prev match.
43     CheckPatternPredicate,
44     CheckPredicate, // [CheckPredicate, P]    Fail if predicate fails.
45     CheckOpcode,    // [CheckOpcode, Opcode]  Fail if not opcode.
46     CheckType,      // [CheckType, MVT]       Fail if not correct type.
47     CheckInteger,   // [CheckInteger, int0,int1,int2,...int7] Fail if wrong val.
48     CheckCondCode,  // [CheckCondCode, CondCode] Fail if not condcode.
49     CheckValueType,
50     CheckComplexPat,
51     CheckAndImm,
52     CheckOrImm,
53     CheckFoldableChainNode,
54     CheckChainCompatible
55   };
56   const KindTy Kind;
57   
58 protected:
59   MatcherNode(KindTy K) : Kind(K) {}
60 public:
61   virtual ~MatcherNode() {}
62   
63   KindTy getKind() const { return Kind; }
64   
65   
66   static inline bool classof(const MatcherNode *) { return true; }
67   
68   virtual void print(raw_ostream &OS, unsigned indent = 0) const = 0;
69   void dump() const;
70 };
71   
72 /// EmitNodeMatcherNode - This signals a successful match and generates a node.
73 class EmitNodeMatcherNode : public MatcherNode {
74   const PatternToMatch &Pattern;
75 public:
76   EmitNodeMatcherNode(const PatternToMatch &pattern)
77     : MatcherNode(EmitNode), Pattern(pattern) {}
78
79   const PatternToMatch &getPattern() const { return Pattern; }
80
81   static inline bool classof(const MatcherNode *N) {
82     return N->getKind() == EmitNode;
83   }
84
85   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
86 };
87
88 /// MatcherNodeWithChild - Every node accept the final accept state has a child
89 /// that is executed after the node runs.  This class captures this commonality.
90 class MatcherNodeWithChild : public MatcherNode {
91   OwningPtr<MatcherNode> Child;
92 public:
93   MatcherNodeWithChild(KindTy K) : MatcherNode(K) {}
94   
95   MatcherNode *getChild() { return Child.get(); }
96   const MatcherNode *getChild() const { return Child.get(); }
97   void setChild(MatcherNode *C) { Child.reset(C); }
98   
99   static inline bool classof(const MatcherNode *N) {
100     return N->getKind() != EmitNode;
101   }
102   
103 protected:
104   void printChild(raw_ostream &OS, unsigned indent) const;
105 };
106
107 /// PushMatcherNode - This pushes a failure scope on the stack and evaluates
108 /// 'child'.  If 'child' fails to match, it pops its scope and attempts to
109 /// match 'Failure'.
110 class PushMatcherNode : public MatcherNodeWithChild {
111   OwningPtr<MatcherNode> Failure;
112 public:
113   PushMatcherNode(MatcherNode *child = 0, MatcherNode *failure = 0)
114     : MatcherNodeWithChild(Push), Failure(failure) {
115     setChild(child);
116   }
117   
118   MatcherNode *getFailure() { return Failure.get(); }
119   const MatcherNode *getFailure() const { return Failure.get(); }
120   void setFailure(MatcherNode *N) { Failure.reset(N); }
121
122   static inline bool classof(const MatcherNode *N) {
123     return N->getKind() == Push;
124   }
125   
126   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
127 };
128
129 /// RecordMatcherNode - Save the current node in the operand list.
130 class RecordMatcherNode : public MatcherNodeWithChild {
131   /// WhatFor - This is a string indicating why we're recording this.  This
132   /// should only be used for comment generation not anything semantic.
133   std::string WhatFor;
134 public:
135   RecordMatcherNode(const std::string &whatfor)
136     : MatcherNodeWithChild(Record), WhatFor(whatfor) {}
137   
138   const std::string &getWhatFor() const { return WhatFor; }
139   
140   static inline bool classof(const MatcherNode *N) {
141     return N->getKind() == Record;
142   }
143   
144   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
145 };
146   
147 /// MoveChildMatcherNode - This tells the interpreter to move into the
148 /// specified child node.
149 class MoveChildMatcherNode : public MatcherNodeWithChild {
150   unsigned ChildNo;
151 public:
152   MoveChildMatcherNode(unsigned childNo)
153   : MatcherNodeWithChild(MoveChild), ChildNo(childNo) {}
154   
155   unsigned getChildNo() const { return ChildNo; }
156   
157   static inline bool classof(const MatcherNode *N) {
158     return N->getKind() == MoveChild;
159   }
160   
161   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
162 };
163   
164 /// MoveParentMatcherNode - This tells the interpreter to move to the parent
165 /// of the current node.
166 class MoveParentMatcherNode : public MatcherNodeWithChild {
167 public:
168   MoveParentMatcherNode()
169   : MatcherNodeWithChild(MoveParent) {}
170   
171   static inline bool classof(const MatcherNode *N) {
172     return N->getKind() == MoveParent;
173   }
174   
175   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
176 };
177
178 /// CheckSameMatcherNode - This checks to see if this node is exactly the same
179 /// node as the specified match that was recorded with 'Record'.  This is used
180 /// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
181 class CheckSameMatcherNode : public MatcherNodeWithChild {
182   unsigned MatchNumber;
183 public:
184   CheckSameMatcherNode(unsigned matchnumber)
185   : MatcherNodeWithChild(CheckSame), MatchNumber(matchnumber) {}
186   
187   unsigned getMatchNumber() const { return MatchNumber; }
188   
189   static inline bool classof(const MatcherNode *N) {
190     return N->getKind() == CheckSame;
191   }
192   
193   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
194 };
195   
196 /// CheckPatternPredicateMatcherNode - This checks the target-specific predicate
197 /// to see if the entire pattern is capable of matching.  This predicate does
198 /// not take a node as input.  This is used for subtarget feature checks etc.
199 class CheckPatternPredicateMatcherNode : public MatcherNodeWithChild {
200   std::string Predicate;
201 public:
202   CheckPatternPredicateMatcherNode(StringRef predicate)
203   : MatcherNodeWithChild(CheckPatternPredicate), Predicate(predicate) {}
204   
205   StringRef getPredicate() const { return Predicate; }
206   
207   static inline bool classof(const MatcherNode *N) {
208     return N->getKind() == CheckPatternPredicate;
209   }
210   
211   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
212 };
213   
214 /// CheckPredicateMatcherNode - This checks the target-specific predicate to
215 /// see if the node is acceptable.
216 class CheckPredicateMatcherNode : public MatcherNodeWithChild {
217   StringRef PredName;
218 public:
219   CheckPredicateMatcherNode(StringRef predname)
220     : MatcherNodeWithChild(CheckPredicate), PredName(predname) {}
221   
222   StringRef getPredicateName() const { return PredName; }
223
224   static inline bool classof(const MatcherNode *N) {
225     return N->getKind() == CheckPredicate;
226   }
227   
228   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
229 };
230   
231   
232 /// CheckOpcodeMatcherNode - This checks to see if the current node has the
233 /// specified opcode, if not it fails to match.
234 class CheckOpcodeMatcherNode : public MatcherNodeWithChild {
235   StringRef OpcodeName;
236 public:
237   CheckOpcodeMatcherNode(StringRef opcodename)
238     : MatcherNodeWithChild(CheckOpcode), OpcodeName(opcodename) {}
239   
240   StringRef getOpcodeName() const { return OpcodeName; }
241   
242   static inline bool classof(const MatcherNode *N) {
243     return N->getKind() == CheckOpcode;
244   }
245   
246   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
247 };
248   
249 /// CheckTypeMatcherNode - This checks to see if the current node has the
250 /// specified type, if not it fails to match.
251 class CheckTypeMatcherNode : public MatcherNodeWithChild {
252   MVT::SimpleValueType Type;
253 public:
254   CheckTypeMatcherNode(MVT::SimpleValueType type)
255     : MatcherNodeWithChild(CheckType), Type(type) {}
256   
257   MVT::SimpleValueType getType() const { return Type; }
258   
259   static inline bool classof(const MatcherNode *N) {
260     return N->getKind() == CheckType;
261   }
262   
263   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
264 };
265
266 /// CheckIntegerMatcherNode - This checks to see if the current node is a
267 /// ConstantSDNode with the specified integer value, if not it fails to match.
268 class CheckIntegerMatcherNode : public MatcherNodeWithChild {
269   int64_t Value;
270 public:
271   CheckIntegerMatcherNode(int64_t value)
272     : MatcherNodeWithChild(CheckInteger), Value(value) {}
273   
274   int64_t getValue() const { return Value; }
275   
276   static inline bool classof(const MatcherNode *N) {
277     return N->getKind() == CheckInteger;
278   }
279   
280   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
281 };
282   
283 /// CheckCondCodeMatcherNode - This checks to see if the current node is a
284 /// CondCodeSDNode with the specified condition, if not it fails to match.
285 class CheckCondCodeMatcherNode : public MatcherNodeWithChild {
286   StringRef CondCodeName;
287 public:
288   CheckCondCodeMatcherNode(StringRef condcodename)
289   : MatcherNodeWithChild(CheckCondCode), CondCodeName(condcodename) {}
290   
291   StringRef getCondCodeName() const { return CondCodeName; }
292   
293   static inline bool classof(const MatcherNode *N) {
294     return N->getKind() == CheckCondCode;
295   }
296   
297   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
298 };
299   
300 /// CheckValueTypeMatcherNode - This checks to see if the current node is a
301 /// VTSDNode with the specified type, if not it fails to match.
302 class CheckValueTypeMatcherNode : public MatcherNodeWithChild {
303   StringRef TypeName;
304 public:
305   CheckValueTypeMatcherNode(StringRef type_name)
306   : MatcherNodeWithChild(CheckValueType), TypeName(type_name) {}
307   
308   StringRef getTypeName() const { return TypeName; }
309
310   static inline bool classof(const MatcherNode *N) {
311     return N->getKind() == CheckValueType;
312   }
313   
314   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
315 };
316   
317   
318   
319 /// CheckComplexPatMatcherNode - This node runs the specified ComplexPattern on
320 /// the current node.
321 class CheckComplexPatMatcherNode : public MatcherNodeWithChild {
322   const ComplexPattern &Pattern;
323 public:
324   CheckComplexPatMatcherNode(const ComplexPattern &pattern)
325   : MatcherNodeWithChild(CheckComplexPat), Pattern(pattern) {}
326   
327   const ComplexPattern &getPattern() const { return Pattern; }
328   
329   static inline bool classof(const MatcherNode *N) {
330     return N->getKind() == CheckComplexPat;
331   }
332   
333   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
334 };
335   
336 /// CheckAndImmMatcherNode - This checks to see if the current node is an 'and'
337 /// with something equivalent to the specified immediate.
338 class CheckAndImmMatcherNode : public MatcherNodeWithChild {
339   int64_t Value;
340 public:
341   CheckAndImmMatcherNode(int64_t value)
342   : MatcherNodeWithChild(CheckAndImm), Value(value) {}
343   
344   int64_t getValue() const { return Value; }
345   
346   static inline bool classof(const MatcherNode *N) {
347     return N->getKind() == CheckAndImm;
348   }
349   
350   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
351 };
352
353 /// CheckOrImmMatcherNode - This checks to see if the current node is an 'and'
354 /// with something equivalent to the specified immediate.
355 class CheckOrImmMatcherNode : public MatcherNodeWithChild {
356   int64_t Value;
357 public:
358   CheckOrImmMatcherNode(int64_t value)
359     : MatcherNodeWithChild(CheckOrImm), Value(value) {}
360   
361   int64_t getValue() const { return Value; }
362
363   static inline bool classof(const MatcherNode *N) {
364     return N->getKind() == CheckOrImm;
365   }
366   
367   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
368 };
369
370 /// CheckFoldableChainNodeMatcherNode - This checks to see if the current node
371 /// (which defines a chain operand) is safe to fold into a larger pattern.
372 class CheckFoldableChainNodeMatcherNode : public MatcherNodeWithChild {
373 public:
374   CheckFoldableChainNodeMatcherNode()
375     : MatcherNodeWithChild(CheckFoldableChainNode) {}
376   
377   static inline bool classof(const MatcherNode *N) {
378     return N->getKind() == CheckFoldableChainNode;
379   }
380   
381   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
382 };
383
384 /// CheckChainCompatibleMatcherNode - Verify that the current node's chain
385 /// operand is 'compatible' with the specified recorded node's.
386 class CheckChainCompatibleMatcherNode : public MatcherNodeWithChild {
387   unsigned PreviousOp;
388 public:
389   CheckChainCompatibleMatcherNode(unsigned previousop)
390     : MatcherNodeWithChild(CheckChainCompatible), PreviousOp(previousop) {}
391   
392   unsigned getPreviousOp() const { return PreviousOp; }
393   
394   static inline bool classof(const MatcherNode *N) {
395     return N->getKind() == CheckChainCompatible;
396   }
397   
398   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
399 };
400   
401   
402
403 } // end namespace llvm
404
405 #endif