b40fbf9cd0e16543eb4a0f82dc5a162b1f73af92
[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     CheckProfitableToFold,
54     CheckLegalToFold
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 public:
132   RecordMatcherNode() : MatcherNodeWithChild(Record) {}
133   
134   static inline bool classof(const MatcherNode *N) {
135     return N->getKind() == Record;
136   }
137   
138   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
139 };
140   
141 /// MoveChildMatcherNode - This tells the interpreter to move into the
142 /// specified child node.
143 class MoveChildMatcherNode : public MatcherNodeWithChild {
144   unsigned ChildNo;
145 public:
146   MoveChildMatcherNode(unsigned childNo)
147   : MatcherNodeWithChild(MoveChild), ChildNo(childNo) {}
148   
149   unsigned getChildNo() const { return ChildNo; }
150   
151   static inline bool classof(const MatcherNode *N) {
152     return N->getKind() == MoveChild;
153   }
154   
155   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
156 };
157   
158 /// MoveParentMatcherNode - This tells the interpreter to move to the parent
159 /// of the current node.
160 class MoveParentMatcherNode : public MatcherNodeWithChild {
161 public:
162   MoveParentMatcherNode()
163   : MatcherNodeWithChild(MoveParent) {}
164   
165   static inline bool classof(const MatcherNode *N) {
166     return N->getKind() == MoveParent;
167   }
168   
169   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
170 };
171
172 /// CheckSameMatcherNode - This checks to see if this node is exactly the same
173 /// node as the specified match that was recorded with 'Record'.  This is used
174 /// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
175 class CheckSameMatcherNode : public MatcherNodeWithChild {
176   unsigned MatchNumber;
177 public:
178   CheckSameMatcherNode(unsigned matchnumber)
179   : MatcherNodeWithChild(CheckSame), MatchNumber(matchnumber) {}
180   
181   unsigned getMatchNumber() const { return MatchNumber; }
182   
183   static inline bool classof(const MatcherNode *N) {
184     return N->getKind() == CheckSame;
185   }
186   
187   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
188 };
189   
190 /// CheckPatternPredicateMatcherNode - This checks the target-specific predicate
191 /// to see if the entire pattern is capable of matching.  This predicate does
192 /// not take a node as input.  This is used for subtarget feature checks etc.
193 class CheckPatternPredicateMatcherNode : public MatcherNodeWithChild {
194   std::string Predicate;
195 public:
196   CheckPatternPredicateMatcherNode(StringRef predicate)
197   : MatcherNodeWithChild(CheckPatternPredicate), Predicate(predicate) {}
198   
199   StringRef getPredicate() const { return Predicate; }
200   
201   static inline bool classof(const MatcherNode *N) {
202     return N->getKind() == CheckPatternPredicate;
203   }
204   
205   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
206 };
207   
208 /// CheckPredicateMatcherNode - This checks the target-specific predicate to
209 /// see if the node is acceptable.
210 class CheckPredicateMatcherNode : public MatcherNodeWithChild {
211   StringRef PredName;
212 public:
213   CheckPredicateMatcherNode(StringRef predname)
214     : MatcherNodeWithChild(CheckPredicate), PredName(predname) {}
215   
216   StringRef getPredicateName() const { return PredName; }
217
218   static inline bool classof(const MatcherNode *N) {
219     return N->getKind() == CheckPredicate;
220   }
221   
222   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
223 };
224   
225   
226 /// CheckOpcodeMatcherNode - This checks to see if the current node has the
227 /// specified opcode, if not it fails to match.
228 class CheckOpcodeMatcherNode : public MatcherNodeWithChild {
229   StringRef OpcodeName;
230 public:
231   CheckOpcodeMatcherNode(StringRef opcodename)
232     : MatcherNodeWithChild(CheckOpcode), OpcodeName(opcodename) {}
233   
234   StringRef getOpcodeName() const { return OpcodeName; }
235   
236   static inline bool classof(const MatcherNode *N) {
237     return N->getKind() == CheckOpcode;
238   }
239   
240   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
241 };
242   
243 /// CheckTypeMatcherNode - This checks to see if the current node has the
244 /// specified type, if not it fails to match.
245 class CheckTypeMatcherNode : public MatcherNodeWithChild {
246   MVT::SimpleValueType Type;
247 public:
248   CheckTypeMatcherNode(MVT::SimpleValueType type)
249     : MatcherNodeWithChild(CheckType), Type(type) {}
250   
251   MVT::SimpleValueType getType() const { return Type; }
252   
253   static inline bool classof(const MatcherNode *N) {
254     return N->getKind() == CheckType;
255   }
256   
257   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
258 };
259
260 /// CheckIntegerMatcherNode - This checks to see if the current node is a
261 /// ConstantSDNode with the specified integer value, if not it fails to match.
262 class CheckIntegerMatcherNode : public MatcherNodeWithChild {
263   int64_t Value;
264 public:
265   CheckIntegerMatcherNode(int64_t value)
266     : MatcherNodeWithChild(CheckInteger), Value(value) {}
267   
268   int64_t getValue() const { return Value; }
269   
270   static inline bool classof(const MatcherNode *N) {
271     return N->getKind() == CheckInteger;
272   }
273   
274   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
275 };
276   
277 /// CheckCondCodeMatcherNode - This checks to see if the current node is a
278 /// CondCodeSDNode with the specified condition, if not it fails to match.
279 class CheckCondCodeMatcherNode : public MatcherNodeWithChild {
280   StringRef CondCodeName;
281 public:
282   CheckCondCodeMatcherNode(StringRef condcodename)
283   : MatcherNodeWithChild(CheckCondCode), CondCodeName(condcodename) {}
284   
285   StringRef getCondCodeName() const { return CondCodeName; }
286   
287   static inline bool classof(const MatcherNode *N) {
288     return N->getKind() == CheckCondCode;
289   }
290   
291   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
292 };
293   
294 /// CheckValueTypeMatcherNode - This checks to see if the current node is a
295 /// VTSDNode with the specified type, if not it fails to match.
296 class CheckValueTypeMatcherNode : public MatcherNodeWithChild {
297   StringRef TypeName;
298 public:
299   CheckValueTypeMatcherNode(StringRef type_name)
300   : MatcherNodeWithChild(CheckValueType), TypeName(type_name) {}
301   
302   StringRef getTypeName() const { return TypeName; }
303
304   static inline bool classof(const MatcherNode *N) {
305     return N->getKind() == CheckValueType;
306   }
307   
308   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
309 };
310   
311   
312   
313 /// CheckComplexPatMatcherNode - This node runs the specified ComplexPattern on
314 /// the current node.
315 class CheckComplexPatMatcherNode : public MatcherNodeWithChild {
316   const ComplexPattern &Pattern;
317 public:
318   CheckComplexPatMatcherNode(const ComplexPattern &pattern)
319   : MatcherNodeWithChild(CheckComplexPat), Pattern(pattern) {}
320   
321   static inline bool classof(const MatcherNode *N) {
322     return N->getKind() == CheckComplexPat;
323   }
324   
325   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
326 };
327   
328 /// CheckAndImmMatcherNode - This checks to see if the current node is an 'and'
329 /// with something equivalent to the specified immediate.
330 class CheckAndImmMatcherNode : public MatcherNodeWithChild {
331   int64_t Value;
332 public:
333   CheckAndImmMatcherNode(int64_t value)
334   : MatcherNodeWithChild(CheckAndImm), Value(value) {}
335   
336   int64_t getValue() const { return Value; }
337   
338   static inline bool classof(const MatcherNode *N) {
339     return N->getKind() == CheckAndImm;
340   }
341   
342   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
343 };
344
345 /// CheckOrImmMatcherNode - This checks to see if the current node is an 'and'
346 /// with something equivalent to the specified immediate.
347 class CheckOrImmMatcherNode : public MatcherNodeWithChild {
348   int64_t Value;
349 public:
350   CheckOrImmMatcherNode(int64_t value)
351     : MatcherNodeWithChild(CheckOrImm), Value(value) {}
352   
353   int64_t getValue() const { return Value; }
354
355   static inline bool classof(const MatcherNode *N) {
356     return N->getKind() == CheckOrImm;
357   }
358   
359   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
360 };
361
362 /// CheckProfitableToFoldMatcherNode - This checks to see if the current node is
363 /// worthwhile to try to fold into a large pattern.
364 class CheckProfitableToFoldMatcherNode : public MatcherNodeWithChild {
365 public:
366   CheckProfitableToFoldMatcherNode()
367   : MatcherNodeWithChild(CheckProfitableToFold) {}
368   
369   static inline bool classof(const MatcherNode *N) {
370     return N->getKind() == CheckProfitableToFold;
371   }
372   
373   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
374 };
375
376 /// CheckLegalToFoldMatcherNode - This checks to see if the current node is
377 /// legal to try to fold into a large pattern.
378 class CheckLegalToFoldMatcherNode : public MatcherNodeWithChild {
379 public:
380   CheckLegalToFoldMatcherNode()
381   : MatcherNodeWithChild(CheckLegalToFold) {}
382   
383   static inline bool classof(const MatcherNode *N) {
384     return N->getKind() == CheckLegalToFold;
385   }
386   
387   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
388 };
389 } // end namespace llvm
390
391 #endif