ab84168bd8b900165de8c6f49f795c6d63694218
[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/ADT/SmallVector.h"
17 #include "llvm/Support/Casting.h"
18
19 namespace llvm {
20   class CodeGenDAGPatterns;
21   class MatcherNode;
22   class PatternToMatch;
23   class raw_ostream;
24   class ComplexPattern;
25   class Record;
26
27 MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern,
28                                      const CodeGenDAGPatterns &CGP);
29 MatcherNode *OptimizeMatcher(MatcherNode *Matcher);
30 void EmitMatcherTable(const MatcherNode *Matcher, raw_ostream &OS);
31
32   
33 /// MatcherNode - Base class for all the the DAG ISel Matcher representation
34 /// nodes.
35 class MatcherNode {
36   // The next matcher node that is executed after this one.  Null if this is the
37   // last stage of a match.
38   OwningPtr<MatcherNode> Next;
39 public:
40   enum KindTy {
41     // Matcher state manipulation.
42     Push,                 // Push a checking scope.
43     RecordNode,           // Record the current node.
44     RecordChild,          // Record a child of the current node.
45     RecordMemRef,         // Record the memref in the current node.
46     CaptureFlagInput,     // If the current node has an input flag, save it.
47     MoveChild,            // Move current node to specified child.
48     MoveParent,           // Move current node to parent.
49     
50     // Predicate checking.
51     CheckSame,            // Fail if not same as prev match.
52     CheckPatternPredicate,
53     CheckPredicate,       // Fail if node predicate fails.
54     CheckOpcode,          // Fail if not opcode.
55     CheckMultiOpcode,     // Fail if not in opcode list.
56     CheckType,            // Fail if not correct type.
57     CheckInteger,         // Fail if wrong val.
58     CheckCondCode,        // Fail if not condcode.
59     CheckValueType,
60     CheckComplexPat,
61     CheckAndImm,
62     CheckOrImm,
63     CheckFoldableChainNode,
64     CheckChainCompatible,
65     
66     // Node creation/emisssion.
67     EmitInteger,          // Create a TargetConstant
68     EmitStringInteger,    // Create a TargetConstant from a string.
69     EmitRegister,         // Create a register.
70     EmitConvertToTarget,  // Convert a imm/fpimm to target imm/fpimm
71     EmitMergeInputChains, // Merge together a chains for an input.
72     EmitCopyToReg,        // Emit a copytoreg into a physreg.
73     EmitNode,             // Create a DAG node
74     EmitNodeXForm,        // Run a SDNodeXForm
75     MarkFlagResults,      // Indicate which interior nodes have flag results.
76     CompleteMatch         // Finish a match and update the results.
77   };
78   const KindTy Kind;
79
80 protected:
81   MatcherNode(KindTy K) : Kind(K) {}
82 public:
83   virtual ~MatcherNode() {}
84   
85   KindTy getKind() const { return Kind; }
86
87   MatcherNode *getNext() { return Next.get(); }
88   const MatcherNode *getNext() const { return Next.get(); }
89   void setNext(MatcherNode *C) { Next.reset(C); }
90   MatcherNode *takeNext() { return Next.take(); }
91
92   OwningPtr<MatcherNode> &getNextPtr() { return Next; }
93   
94   static inline bool classof(const MatcherNode *) { return true; }
95   
96   virtual void print(raw_ostream &OS, unsigned indent = 0) const = 0;
97   void dump() const;
98 protected:
99   void printNext(raw_ostream &OS, unsigned indent) const;
100 };
101   
102 /// PushMatcherNode - This pushes a failure scope on the stack and evaluates
103 /// 'Next'.  If 'Next' fails to match, it pops its scope and attempts to
104 /// match 'Failure'.
105 class PushMatcherNode : public MatcherNode {
106   OwningPtr<MatcherNode> Failure;
107 public:
108   PushMatcherNode(MatcherNode *next = 0, MatcherNode *failure = 0)
109     : MatcherNode(Push), Failure(failure) {
110     setNext(next);
111   }
112   
113   MatcherNode *getFailure() { return Failure.get(); }
114   const MatcherNode *getFailure() const { return Failure.get(); }
115   void setFailure(MatcherNode *N) { Failure.reset(N); }
116   OwningPtr<MatcherNode> &getFailurePtr() { return Failure; }
117
118   static inline bool classof(const MatcherNode *N) {
119     return N->getKind() == Push;
120   }
121   
122   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
123 };
124
125 /// RecordMatcherNode - Save the current node in the operand list.
126 class RecordMatcherNode : public MatcherNode {
127   /// WhatFor - This is a string indicating why we're recording this.  This
128   /// should only be used for comment generation not anything semantic.
129   std::string WhatFor;
130 public:
131   RecordMatcherNode(const std::string &whatfor)
132     : MatcherNode(RecordNode), WhatFor(whatfor) {}
133   
134   const std::string &getWhatFor() const { return WhatFor; }
135   
136   static inline bool classof(const MatcherNode *N) {
137     return N->getKind() == RecordNode;
138   }
139   
140   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
141 };
142   
143 /// RecordChildMatcherNode - Save a numbered child of the current node, or fail
144 /// the match if it doesn't exist.  This is logically equivalent to:
145 ///    MoveChild N + RecordNode + MoveParent.
146 class RecordChildMatcherNode : public MatcherNode {
147   unsigned ChildNo;
148   
149   /// WhatFor - This is a string indicating why we're recording this.  This
150   /// should only be used for comment generation not anything semantic.
151   std::string WhatFor;
152 public:
153   RecordChildMatcherNode(unsigned childno, const std::string &whatfor)
154   : MatcherNode(RecordChild), ChildNo(childno), WhatFor(whatfor) {}
155   
156   unsigned getChildNo() const { return ChildNo; }
157   const std::string &getWhatFor() const { return WhatFor; }
158   
159   static inline bool classof(const MatcherNode *N) {
160     return N->getKind() == RecordChild;
161   }
162   
163   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
164 };
165   
166 /// RecordMemRefMatcherNode - Save the current node's memref.
167 class RecordMemRefMatcherNode : public MatcherNode {
168 public:
169   RecordMemRefMatcherNode() : MatcherNode(RecordMemRef) {}
170   
171   static inline bool classof(const MatcherNode *N) {
172     return N->getKind() == RecordMemRef;
173   }
174   
175   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
176 };
177
178   
179 /// CaptureFlagInputMatcherNode - If the current record has a flag input, record
180 /// it so that it is used as an input to the generated code.
181 class CaptureFlagInputMatcherNode : public MatcherNode {
182 public:
183   CaptureFlagInputMatcherNode()
184     : MatcherNode(CaptureFlagInput) {}
185   
186   static inline bool classof(const MatcherNode *N) {
187     return N->getKind() == CaptureFlagInput;
188   }
189   
190   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
191 };
192   
193 /// MoveChildMatcherNode - This tells the interpreter to move into the
194 /// specified child node.
195 class MoveChildMatcherNode : public MatcherNode {
196   unsigned ChildNo;
197 public:
198   MoveChildMatcherNode(unsigned childNo)
199   : MatcherNode(MoveChild), ChildNo(childNo) {}
200   
201   unsigned getChildNo() const { return ChildNo; }
202   
203   static inline bool classof(const MatcherNode *N) {
204     return N->getKind() == MoveChild;
205   }
206   
207   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
208 };
209   
210 /// MoveParentMatcherNode - This tells the interpreter to move to the parent
211 /// of the current node.
212 class MoveParentMatcherNode : public MatcherNode {
213 public:
214   MoveParentMatcherNode()
215   : MatcherNode(MoveParent) {}
216   
217   static inline bool classof(const MatcherNode *N) {
218     return N->getKind() == MoveParent;
219   }
220   
221   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
222 };
223
224 /// CheckSameMatcherNode - This checks to see if this node is exactly the same
225 /// node as the specified match that was recorded with 'Record'.  This is used
226 /// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
227 class CheckSameMatcherNode : public MatcherNode {
228   unsigned MatchNumber;
229 public:
230   CheckSameMatcherNode(unsigned matchnumber)
231   : MatcherNode(CheckSame), MatchNumber(matchnumber) {}
232   
233   unsigned getMatchNumber() const { return MatchNumber; }
234   
235   static inline bool classof(const MatcherNode *N) {
236     return N->getKind() == CheckSame;
237   }
238   
239   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
240 };
241   
242 /// CheckPatternPredicateMatcherNode - This checks the target-specific predicate
243 /// to see if the entire pattern is capable of matching.  This predicate does
244 /// not take a node as input.  This is used for subtarget feature checks etc.
245 class CheckPatternPredicateMatcherNode : public MatcherNode {
246   std::string Predicate;
247 public:
248   CheckPatternPredicateMatcherNode(StringRef predicate)
249   : MatcherNode(CheckPatternPredicate), Predicate(predicate) {}
250   
251   StringRef getPredicate() const { return Predicate; }
252   
253   static inline bool classof(const MatcherNode *N) {
254     return N->getKind() == CheckPatternPredicate;
255   }
256   
257   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
258 };
259   
260 /// CheckPredicateMatcherNode - This checks the target-specific predicate to
261 /// see if the node is acceptable.
262 class CheckPredicateMatcherNode : public MatcherNode {
263   StringRef PredName;
264 public:
265   CheckPredicateMatcherNode(StringRef predname)
266     : MatcherNode(CheckPredicate), PredName(predname) {}
267   
268   StringRef getPredicateName() const { return PredName; }
269
270   static inline bool classof(const MatcherNode *N) {
271     return N->getKind() == CheckPredicate;
272   }
273   
274   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
275 };
276   
277   
278 /// CheckOpcodeMatcherNode - This checks to see if the current node has the
279 /// specified opcode, if not it fails to match.
280 class CheckOpcodeMatcherNode : public MatcherNode {
281   StringRef OpcodeName;
282 public:
283   CheckOpcodeMatcherNode(StringRef opcodename)
284     : MatcherNode(CheckOpcode), OpcodeName(opcodename) {}
285   
286   StringRef getOpcodeName() const { return OpcodeName; }
287   
288   static inline bool classof(const MatcherNode *N) {
289     return N->getKind() == CheckOpcode;
290   }
291   
292   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
293 };
294   
295 /// CheckMultiOpcodeMatcherNode - This checks to see if the current node has one
296 /// of the specified opcode, if not it fails to match.
297 class CheckMultiOpcodeMatcherNode : public MatcherNode {
298   SmallVector<StringRef, 4> OpcodeNames;
299 public:
300   CheckMultiOpcodeMatcherNode(const StringRef *opcodes, unsigned numops)
301   : MatcherNode(CheckMultiOpcode), OpcodeNames(opcodes, opcodes+numops) {}
302   
303   unsigned getNumOpcodeNames() const { return OpcodeNames.size(); }
304   StringRef getOpcodeName(unsigned i) const { return OpcodeNames[i]; }
305   
306   static inline bool classof(const MatcherNode *N) {
307     return N->getKind() == CheckMultiOpcode;
308   }
309   
310   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
311 };
312   
313   
314   
315 /// CheckTypeMatcherNode - This checks to see if the current node has the
316 /// specified type, if not it fails to match.
317 class CheckTypeMatcherNode : public MatcherNode {
318   MVT::SimpleValueType Type;
319 public:
320   CheckTypeMatcherNode(MVT::SimpleValueType type)
321     : MatcherNode(CheckType), Type(type) {}
322   
323   MVT::SimpleValueType getType() const { return Type; }
324   
325   static inline bool classof(const MatcherNode *N) {
326     return N->getKind() == CheckType;
327   }
328   
329   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
330 };
331
332 /// CheckIntegerMatcherNode - This checks to see if the current node is a
333 /// ConstantSDNode with the specified integer value, if not it fails to match.
334 class CheckIntegerMatcherNode : public MatcherNode {
335   int64_t Value;
336 public:
337   CheckIntegerMatcherNode(int64_t value)
338     : MatcherNode(CheckInteger), Value(value) {}
339   
340   int64_t getValue() const { return Value; }
341   
342   static inline bool classof(const MatcherNode *N) {
343     return N->getKind() == CheckInteger;
344   }
345   
346   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
347 };
348   
349 /// CheckCondCodeMatcherNode - This checks to see if the current node is a
350 /// CondCodeSDNode with the specified condition, if not it fails to match.
351 class CheckCondCodeMatcherNode : public MatcherNode {
352   StringRef CondCodeName;
353 public:
354   CheckCondCodeMatcherNode(StringRef condcodename)
355   : MatcherNode(CheckCondCode), CondCodeName(condcodename) {}
356   
357   StringRef getCondCodeName() const { return CondCodeName; }
358   
359   static inline bool classof(const MatcherNode *N) {
360     return N->getKind() == CheckCondCode;
361   }
362   
363   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
364 };
365   
366 /// CheckValueTypeMatcherNode - This checks to see if the current node is a
367 /// VTSDNode with the specified type, if not it fails to match.
368 class CheckValueTypeMatcherNode : public MatcherNode {
369   StringRef TypeName;
370 public:
371   CheckValueTypeMatcherNode(StringRef type_name)
372   : MatcherNode(CheckValueType), TypeName(type_name) {}
373   
374   StringRef getTypeName() const { return TypeName; }
375
376   static inline bool classof(const MatcherNode *N) {
377     return N->getKind() == CheckValueType;
378   }
379   
380   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
381 };
382   
383   
384   
385 /// CheckComplexPatMatcherNode - This node runs the specified ComplexPattern on
386 /// the current node.
387 class CheckComplexPatMatcherNode : public MatcherNode {
388   const ComplexPattern &Pattern;
389 public:
390   CheckComplexPatMatcherNode(const ComplexPattern &pattern)
391   : MatcherNode(CheckComplexPat), Pattern(pattern) {}
392   
393   const ComplexPattern &getPattern() const { return Pattern; }
394   
395   static inline bool classof(const MatcherNode *N) {
396     return N->getKind() == CheckComplexPat;
397   }
398   
399   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
400 };
401   
402 /// CheckAndImmMatcherNode - This checks to see if the current node is an 'and'
403 /// with something equivalent to the specified immediate.
404 class CheckAndImmMatcherNode : public MatcherNode {
405   int64_t Value;
406 public:
407   CheckAndImmMatcherNode(int64_t value)
408   : MatcherNode(CheckAndImm), Value(value) {}
409   
410   int64_t getValue() const { return Value; }
411   
412   static inline bool classof(const MatcherNode *N) {
413     return N->getKind() == CheckAndImm;
414   }
415   
416   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
417 };
418
419 /// CheckOrImmMatcherNode - This checks to see if the current node is an 'and'
420 /// with something equivalent to the specified immediate.
421 class CheckOrImmMatcherNode : public MatcherNode {
422   int64_t Value;
423 public:
424   CheckOrImmMatcherNode(int64_t value)
425     : MatcherNode(CheckOrImm), Value(value) {}
426   
427   int64_t getValue() const { return Value; }
428
429   static inline bool classof(const MatcherNode *N) {
430     return N->getKind() == CheckOrImm;
431   }
432   
433   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
434 };
435
436 /// CheckFoldableChainNodeMatcherNode - This checks to see if the current node
437 /// (which defines a chain operand) is safe to fold into a larger pattern.
438 class CheckFoldableChainNodeMatcherNode : public MatcherNode {
439 public:
440   CheckFoldableChainNodeMatcherNode()
441     : MatcherNode(CheckFoldableChainNode) {}
442   
443   static inline bool classof(const MatcherNode *N) {
444     return N->getKind() == CheckFoldableChainNode;
445   }
446   
447   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
448 };
449
450 /// CheckChainCompatibleMatcherNode - Verify that the current node's chain
451 /// operand is 'compatible' with the specified recorded node's.
452 class CheckChainCompatibleMatcherNode : public MatcherNode {
453   unsigned PreviousOp;
454 public:
455   CheckChainCompatibleMatcherNode(unsigned previousop)
456     : MatcherNode(CheckChainCompatible), PreviousOp(previousop) {}
457   
458   unsigned getPreviousOp() const { return PreviousOp; }
459   
460   static inline bool classof(const MatcherNode *N) {
461     return N->getKind() == CheckChainCompatible;
462   }
463   
464   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
465 };
466   
467 /// EmitIntegerMatcherNode - This creates a new TargetConstant.
468 class EmitIntegerMatcherNode : public MatcherNode {
469   int64_t Val;
470   MVT::SimpleValueType VT;
471 public:
472   EmitIntegerMatcherNode(int64_t val, MVT::SimpleValueType vt)
473   : MatcherNode(EmitInteger), Val(val), VT(vt) {}
474   
475   int64_t getValue() const { return Val; }
476   MVT::SimpleValueType getVT() const { return VT; }
477   
478   static inline bool classof(const MatcherNode *N) {
479     return N->getKind() == EmitInteger;
480   }
481   
482   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
483 };
484
485 /// EmitStringIntegerMatcherNode - A target constant whose value is represented
486 /// by a string.
487 class EmitStringIntegerMatcherNode : public MatcherNode {
488   std::string Val;
489   MVT::SimpleValueType VT;
490 public:
491   EmitStringIntegerMatcherNode(const std::string &val, MVT::SimpleValueType vt)
492     : MatcherNode(EmitStringInteger), Val(val), VT(vt) {}
493   
494   const std::string &getValue() const { return Val; }
495   MVT::SimpleValueType getVT() const { return VT; }
496   
497   static inline bool classof(const MatcherNode *N) {
498     return N->getKind() == EmitStringInteger;
499   }
500   
501   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
502 };
503   
504 /// EmitRegisterMatcherNode - This creates a new TargetConstant.
505 class EmitRegisterMatcherNode : public MatcherNode {
506   /// Reg - The def for the register that we're emitting.  If this is null, then
507   /// this is a reference to zero_reg.
508   Record *Reg;
509   MVT::SimpleValueType VT;
510 public:
511   EmitRegisterMatcherNode(Record *reg, MVT::SimpleValueType vt)
512     : MatcherNode(EmitRegister), Reg(reg), VT(vt) {}
513   
514   Record *getReg() const { return Reg; }
515   MVT::SimpleValueType getVT() const { return VT; }
516   
517   static inline bool classof(const MatcherNode *N) {
518     return N->getKind() == EmitRegister;
519   }
520   
521   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
522 };
523
524 /// EmitConvertToTargetMatcherNode - Emit an operation that reads a specified
525 /// recorded node and converts it from being a ISD::Constant to
526 /// ISD::TargetConstant, likewise for ConstantFP.
527 class EmitConvertToTargetMatcherNode : public MatcherNode {
528   unsigned Slot;
529 public:
530   EmitConvertToTargetMatcherNode(unsigned slot)
531     : MatcherNode(EmitConvertToTarget), Slot(slot) {}
532   
533   unsigned getSlot() const { return Slot; }
534   
535   static inline bool classof(const MatcherNode *N) {
536     return N->getKind() == EmitConvertToTarget;
537   }
538   
539   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
540 };
541   
542 /// EmitMergeInputChainsMatcherNode - Emit a node that merges a list of input
543 /// chains together with a token factor.  The list of nodes are the nodes in the
544 /// matched pattern that have chain input/outputs.  This node adds all input
545 /// chains of these nodes if they are not themselves a node in the pattern.
546 class EmitMergeInputChainsMatcherNode : public MatcherNode {
547   SmallVector<unsigned, 3> ChainNodes;
548 public:
549   EmitMergeInputChainsMatcherNode(const unsigned *nodes, unsigned NumNodes)
550   : MatcherNode(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {}
551   
552   unsigned getNumNodes() const { return ChainNodes.size(); }
553   
554   unsigned getNode(unsigned i) const {
555     assert(i < ChainNodes.size());
556     return ChainNodes[i];
557   }  
558   
559   static inline bool classof(const MatcherNode *N) {
560     return N->getKind() == EmitMergeInputChains;
561   }
562   
563   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
564 };
565   
566 /// EmitCopyToRegMatcherNode - Emit a CopyToReg node from a value to a physreg,
567 /// pushing the chain and flag results.
568 ///
569 class EmitCopyToRegMatcherNode : public MatcherNode {
570   unsigned SrcSlot; // Value to copy into the physreg.
571   Record *DestPhysReg;
572 public:
573   EmitCopyToRegMatcherNode(unsigned srcSlot, Record *destPhysReg)
574   : MatcherNode(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}
575   
576   unsigned getSrcSlot() const { return SrcSlot; }
577   Record *getDestPhysReg() const { return DestPhysReg; }
578   
579   static inline bool classof(const MatcherNode *N) {
580     return N->getKind() == EmitCopyToReg;
581   }
582   
583   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
584 };
585   
586     
587   
588 /// EmitNodeXFormMatcherNode - Emit an operation that runs an SDNodeXForm on a
589 /// recorded node and records the result.
590 class EmitNodeXFormMatcherNode : public MatcherNode {
591   unsigned Slot;
592   Record *NodeXForm;
593 public:
594   EmitNodeXFormMatcherNode(unsigned slot, Record *nodeXForm)
595   : MatcherNode(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {}
596   
597   unsigned getSlot() const { return Slot; }
598   Record *getNodeXForm() const { return NodeXForm; }
599   
600   static inline bool classof(const MatcherNode *N) {
601     return N->getKind() == EmitNodeXForm;
602   }
603   
604   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
605 };
606   
607 /// EmitNodeMatcherNode - This signals a successful match and generates a node.
608 class EmitNodeMatcherNode : public MatcherNode {
609   std::string OpcodeName;
610   const SmallVector<MVT::SimpleValueType, 3> VTs;
611   const SmallVector<unsigned, 6> Operands;
612   bool HasChain, HasFlag, HasMemRefs;
613   
614   /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1.
615   /// If this is a varidic node, this is set to the number of fixed arity
616   /// operands in the root of the pattern.  The rest are appended to this node.
617   int NumFixedArityOperands;
618 public:
619   EmitNodeMatcherNode(const std::string &opcodeName,
620                       const MVT::SimpleValueType *vts, unsigned numvts,
621                       const unsigned *operands, unsigned numops,
622                       bool hasChain, bool hasFlag, bool hasmemrefs,
623                       int numfixedarityoperands)
624     : MatcherNode(EmitNode), OpcodeName(opcodeName),
625       VTs(vts, vts+numvts), Operands(operands, operands+numops),
626       HasChain(hasChain), HasFlag(hasFlag), HasMemRefs(hasmemrefs),
627       NumFixedArityOperands(numfixedarityoperands) {}
628   
629   const std::string &getOpcodeName() const { return OpcodeName; }
630   
631   unsigned getNumVTs() const { return VTs.size(); }
632   MVT::SimpleValueType getVT(unsigned i) const {
633     assert(i < VTs.size());
634     return VTs[i];
635   }
636   
637   unsigned getNumOperands() const { return Operands.size(); }
638   unsigned getOperand(unsigned i) const {
639     assert(i < Operands.size());
640     return Operands[i];
641   }  
642   
643   bool hasChain() const { return HasChain; }
644   bool hasFlag() const { return HasFlag; }
645   bool hasMemRefs() const { return HasMemRefs; }
646   int getNumFixedArityOperands() const { return NumFixedArityOperands; }
647   
648   static inline bool classof(const MatcherNode *N) {
649     return N->getKind() == EmitNode;
650   }
651   
652   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
653 };
654   
655 /// MarkFlagResultsMatcherNode - This node indicates which non-root nodes in the
656 /// pattern produce flags.  This allows CompleteMatchMatcherNode to update them
657 /// with the output flag of the resultant code.
658 class MarkFlagResultsMatcherNode : public MatcherNode {
659   SmallVector<unsigned, 3> FlagResultNodes;
660 public:
661   MarkFlagResultsMatcherNode(const unsigned *nodes, unsigned NumNodes)
662   : MatcherNode(MarkFlagResults), FlagResultNodes(nodes, nodes+NumNodes) {}
663   
664   unsigned getNumNodes() const { return FlagResultNodes.size(); }
665   
666   unsigned getNode(unsigned i) const {
667     assert(i < FlagResultNodes.size());
668     return FlagResultNodes[i];
669   }  
670   
671   static inline bool classof(const MatcherNode *N) {
672     return N->getKind() == MarkFlagResults;
673   }
674   
675   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
676 };
677
678 /// CompleteMatchMatcherNode - Complete a match by replacing the results of the
679 /// pattern with the newly generated nodes.  This also prints a comment
680 /// indicating the source and dest patterns.
681 class CompleteMatchMatcherNode : public MatcherNode {
682   SmallVector<unsigned, 2> Results;
683   const PatternToMatch &Pattern;
684 public:
685   CompleteMatchMatcherNode(const unsigned *results, unsigned numresults,
686                            const PatternToMatch &pattern)
687   : MatcherNode(CompleteMatch), Results(results, results+numresults),
688     Pattern(pattern) {}
689
690   unsigned getNumResults() const { return Results.size(); }
691   unsigned getResult(unsigned R) const { return Results[R]; }
692   const PatternToMatch &getPattern() const { return Pattern; }
693   
694   static inline bool classof(const MatcherNode *N) {
695     return N->getKind() == CompleteMatch;
696   }
697   
698   virtual void print(raw_ostream &OS, unsigned indent = 0) const;
699 };
700  
701   
702 } // end namespace llvm
703
704 #endif