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