//===- DAGISelMatcher.h - Representation of DAG pattern matcher -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef TBLGEN_DAGISELMATCHER_H
#define TBLGEN_DAGISELMATCHER_H

#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/Casting.h"

namespace llvm {
  struct CodeGenRegister;
  class CodeGenDAGPatterns;
  class Matcher;
  class PatternToMatch;
  class raw_ostream;
  class ComplexPattern;
  class Record;
  class SDNodeInfo;
  class TreePredicateFn;
  class TreePattern;

Matcher *ConvertPatternToMatcher(const PatternToMatch &Pattern,unsigned Variant,
                                 const CodeGenDAGPatterns &CGP);
Matcher *OptimizeMatcher(Matcher *Matcher, const CodeGenDAGPatterns &CGP);
void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
                      raw_ostream &OS);


/// Matcher - Base class for all the DAG ISel Matcher representation
/// nodes.
class Matcher {
  // The next matcher node that is executed after this one.  Null if this is the
  // last stage of a match.
  OwningPtr<Matcher> Next;
  virtual void anchor();
public:
  enum KindTy {
    // Matcher state manipulation.
    Scope,                // Push a checking scope.
    RecordNode,           // Record the current node.
    RecordChild,          // Record a child of the current node.
    RecordMemRef,         // Record the memref in the current node.
    CaptureGlueInput,     // If the current node has an input glue, save it.
    MoveChild,            // Move current node to specified child.
    MoveParent,           // Move current node to parent.

    // Predicate checking.
    CheckSame,            // Fail if not same as prev match.
    CheckChildSame,       // Fail if child not same as prev match.
    CheckPatternPredicate,
    CheckPredicate,       // Fail if node predicate fails.
    CheckOpcode,          // Fail if not opcode.
    SwitchOpcode,         // Dispatch based on opcode.
    CheckType,            // Fail if not correct type.
    SwitchType,           // Dispatch based on type.
    CheckChildType,       // Fail if child has wrong type.
    CheckInteger,         // Fail if wrong val.
    CheckCondCode,        // Fail if not condcode.
    CheckValueType,
    CheckComplexPat,
    CheckAndImm,
    CheckOrImm,
    CheckFoldableChainNode,

    // Node creation/emisssion.
    EmitInteger,          // Create a TargetConstant
    EmitStringInteger,    // Create a TargetConstant from a string.
    EmitRegister,         // Create a register.
    EmitConvertToTarget,  // Convert a imm/fpimm to target imm/fpimm
    EmitMergeInputChains, // Merge together a chains for an input.
    EmitCopyToReg,        // Emit a copytoreg into a physreg.
    EmitNode,             // Create a DAG node
    EmitNodeXForm,        // Run a SDNodeXForm
    MarkGlueResults,      // Indicate which interior nodes have glue results.
    CompleteMatch,        // Finish a match and update the results.
    MorphNodeTo           // Build a node, finish a match and update results.
  };
  const KindTy Kind;

protected:
  Matcher(KindTy K) : Kind(K) {}
public:
  virtual ~Matcher() {}

  KindTy getKind() const { return Kind; }

  Matcher *getNext() { return Next.get(); }
  const Matcher *getNext() const { return Next.get(); }
  void setNext(Matcher *C) { Next.reset(C); }
  Matcher *takeNext() { return Next.take(); }

  OwningPtr<Matcher> &getNextPtr() { return Next; }

  bool isEqual(const Matcher *M) const {
    if (getKind() != M->getKind()) return false;
    return isEqualImpl(M);
  }

  unsigned getHash() const {
    // Clear the high bit so we don't conflict with tombstones etc.
    return ((getHashImpl() << 4) ^ getKind()) & (~0U>>1);
  }

  /// isSafeToReorderWithPatternPredicate - Return true if it is safe to sink a
  /// PatternPredicate node past this one.
  virtual bool isSafeToReorderWithPatternPredicate() const {
    return false;
  }

  /// isSimplePredicateNode - Return true if this is a simple predicate that
  /// operates on the node or its children without potential side effects or a
  /// change of the current node.
  bool isSimplePredicateNode() const {
    switch (getKind()) {
    default: return false;
    case CheckSame:
    case CheckChildSame:
    case CheckPatternPredicate:
    case CheckPredicate:
    case CheckOpcode:
    case CheckType:
    case CheckChildType:
    case CheckInteger:
    case CheckCondCode:
    case CheckValueType:
    case CheckAndImm:
    case CheckOrImm:
    case CheckFoldableChainNode:
      return true;
    }
  }

  /// isSimplePredicateOrRecordNode - Return true if this is a record node or
  /// a simple predicate.
  bool isSimplePredicateOrRecordNode() const {
    return isSimplePredicateNode() ||
           getKind() == RecordNode || getKind() == RecordChild;
  }

  /// unlinkNode - Unlink the specified node from this chain.  If Other == this,
  /// we unlink the next pointer and return it.  Otherwise we unlink Other from
  /// the list and return this.
  Matcher *unlinkNode(Matcher *Other);

  /// canMoveBefore - Return true if this matcher is the same as Other, or if
  /// we can move this matcher past all of the nodes in-between Other and this
  /// node.  Other must be equal to or before this.
  bool canMoveBefore(const Matcher *Other) const;

  /// canMoveBeforeNode - Return true if it is safe to move the current matcher
  /// across the specified one.
  bool canMoveBeforeNode(const Matcher *Other) const;

  /// isContradictory - Return true of these two matchers could never match on
  /// the same node.
  bool isContradictory(const Matcher *Other) const {
    // Since this predicate is reflexive, we canonicalize the ordering so that
    // we always match a node against nodes with kinds that are greater or equal
    // to them.  For example, we'll pass in a CheckType node as an argument to
    // the CheckOpcode method, not the other way around.
    if (getKind() < Other->getKind())
      return isContradictoryImpl(Other);
    return Other->isContradictoryImpl(this);
  }

  void print(raw_ostream &OS, unsigned indent = 0) const;
  void printOne(raw_ostream &OS) const;
  void dump() const;
protected:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const = 0;
  virtual bool isEqualImpl(const Matcher *M) const = 0;
  virtual unsigned getHashImpl() const = 0;
  virtual bool isContradictoryImpl(const Matcher *M) const { return false; }
};

/// ScopeMatcher - This attempts to match each of its children to find the first
/// one that successfully matches.  If one child fails, it tries the next child.
/// If none of the children match then this check fails.  It never has a 'next'.
class ScopeMatcher : public Matcher {
  SmallVector<Matcher*, 4> Children;
public:
  ScopeMatcher(Matcher *const *children, unsigned numchildren)
    : Matcher(Scope), Children(children, children+numchildren) {
  }
  virtual ~ScopeMatcher();

  unsigned getNumChildren() const { return Children.size(); }

  Matcher *getChild(unsigned i) { return Children[i]; }
  const Matcher *getChild(unsigned i) const { return Children[i]; }

  void resetChild(unsigned i, Matcher *N) {
    delete Children[i];
    Children[i] = N;
  }

  Matcher *takeChild(unsigned i) {
    Matcher *Res = Children[i];
    Children[i] = 0;
    return Res;
  }

  void setNumChildren(unsigned NC) {
    if (NC < Children.size()) {
      // delete any children we're about to lose pointers to.
      for (unsigned i = NC, e = Children.size(); i != e; ++i)
        delete Children[i];
    }
    Children.resize(NC);
  }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == Scope;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return false; }
  virtual unsigned getHashImpl() const { return 12312; }
};

/// RecordMatcher - Save the current node in the operand list.
class RecordMatcher : public Matcher {
  /// WhatFor - This is a string indicating why we're recording this.  This
  /// should only be used for comment generation not anything semantic.
  std::string WhatFor;

  /// ResultNo - The slot number in the RecordedNodes vector that this will be,
  /// just printed as a comment.
  unsigned ResultNo;
public:
  RecordMatcher(const std::string &whatfor, unsigned resultNo)
    : Matcher(RecordNode), WhatFor(whatfor), ResultNo(resultNo) {}

  const std::string &getWhatFor() const { return WhatFor; }
  unsigned getResultNo() const { return ResultNo; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == RecordNode;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }
private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return true; }
  virtual unsigned getHashImpl() const { return 0; }
};

/// RecordChildMatcher - Save a numbered child of the current node, or fail
/// the match if it doesn't exist.  This is logically equivalent to:
///    MoveChild N + RecordNode + MoveParent.
class RecordChildMatcher : public Matcher {
  unsigned ChildNo;

  /// WhatFor - This is a string indicating why we're recording this.  This
  /// should only be used for comment generation not anything semantic.
  std::string WhatFor;

  /// ResultNo - The slot number in the RecordedNodes vector that this will be,
  /// just printed as a comment.
  unsigned ResultNo;
public:
  RecordChildMatcher(unsigned childno, const std::string &whatfor,
                     unsigned resultNo)
  : Matcher(RecordChild), ChildNo(childno), WhatFor(whatfor),
    ResultNo(resultNo) {}

  unsigned getChildNo() const { return ChildNo; }
  const std::string &getWhatFor() const { return WhatFor; }
  unsigned getResultNo() const { return ResultNo; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == RecordChild;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<RecordChildMatcher>(M)->getChildNo() == getChildNo();
  }
  virtual unsigned getHashImpl() const { return getChildNo(); }
};

/// RecordMemRefMatcher - Save the current node's memref.
class RecordMemRefMatcher : public Matcher {
public:
  RecordMemRefMatcher() : Matcher(RecordMemRef) {}

  static inline bool classof(const Matcher *N) {
    return N->getKind() == RecordMemRef;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return true; }
  virtual unsigned getHashImpl() const { return 0; }
};


/// CaptureGlueInputMatcher - If the current record has a glue input, record
/// it so that it is used as an input to the generated code.
class CaptureGlueInputMatcher : public Matcher {
public:
  CaptureGlueInputMatcher() : Matcher(CaptureGlueInput) {}

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CaptureGlueInput;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return true; }
  virtual unsigned getHashImpl() const { return 0; }
};

/// MoveChildMatcher - This tells the interpreter to move into the
/// specified child node.
class MoveChildMatcher : public Matcher {
  unsigned ChildNo;
public:
  MoveChildMatcher(unsigned childNo) : Matcher(MoveChild), ChildNo(childNo) {}

  unsigned getChildNo() const { return ChildNo; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == MoveChild;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<MoveChildMatcher>(M)->getChildNo() == getChildNo();
  }
  virtual unsigned getHashImpl() const { return getChildNo(); }
};

/// MoveParentMatcher - This tells the interpreter to move to the parent
/// of the current node.
class MoveParentMatcher : public Matcher {
public:
  MoveParentMatcher() : Matcher(MoveParent) {}

  static inline bool classof(const Matcher *N) {
    return N->getKind() == MoveParent;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return true; }
  virtual unsigned getHashImpl() const { return 0; }
};

/// CheckSameMatcher - This checks to see if this node is exactly the same
/// node as the specified match that was recorded with 'Record'.  This is used
/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
class CheckSameMatcher : public Matcher {
  unsigned MatchNumber;
public:
  CheckSameMatcher(unsigned matchnumber)
    : Matcher(CheckSame), MatchNumber(matchnumber) {}

  unsigned getMatchNumber() const { return MatchNumber; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckSame;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckSameMatcher>(M)->getMatchNumber() == getMatchNumber();
  }
  virtual unsigned getHashImpl() const { return getMatchNumber(); }
};

/// CheckChildSameMatcher - This checks to see if child node is exactly the same
/// node as the specified match that was recorded with 'Record'.  This is used
/// when patterns have the same name in them, like '(mul GPR:$in, GPR:$in)'.
class CheckChildSameMatcher : public Matcher {
  unsigned ChildNo;
  unsigned MatchNumber;
public:
  CheckChildSameMatcher(unsigned childno, unsigned matchnumber)
    : Matcher(CheckChildSame), ChildNo(childno), MatchNumber(matchnumber) {}

  unsigned getChildNo() const { return ChildNo; }
  unsigned getMatchNumber() const { return MatchNumber; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckChildSame;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckChildSameMatcher>(M)->ChildNo == ChildNo &&
           cast<CheckChildSameMatcher>(M)->MatchNumber == MatchNumber;
  }
  virtual unsigned getHashImpl() const { return (MatchNumber << 2) | ChildNo; }
};

/// CheckPatternPredicateMatcher - This checks the target-specific predicate
/// to see if the entire pattern is capable of matching.  This predicate does
/// not take a node as input.  This is used for subtarget feature checks etc.
class CheckPatternPredicateMatcher : public Matcher {
  std::string Predicate;
public:
  CheckPatternPredicateMatcher(StringRef predicate)
    : Matcher(CheckPatternPredicate), Predicate(predicate) {}

  StringRef getPredicate() const { return Predicate; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckPatternPredicate;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckPatternPredicateMatcher>(M)->getPredicate() == Predicate;
  }
  virtual unsigned getHashImpl() const;
};

/// CheckPredicateMatcher - This checks the target-specific predicate to
/// see if the node is acceptable.
class CheckPredicateMatcher : public Matcher {
  TreePattern *Pred;
public:
  CheckPredicateMatcher(const TreePredicateFn &pred);

  TreePredicateFn getPredicate() const;

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckPredicate;
  }

  // TODO: Ok?
  //virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckPredicateMatcher>(M)->Pred == Pred;
  }
  virtual unsigned getHashImpl() const;
};


/// CheckOpcodeMatcher - This checks to see if the current node has the
/// specified opcode, if not it fails to match.
class CheckOpcodeMatcher : public Matcher {
  const SDNodeInfo &Opcode;
public:
  CheckOpcodeMatcher(const SDNodeInfo &opcode)
    : Matcher(CheckOpcode), Opcode(opcode) {}

  const SDNodeInfo &getOpcode() const { return Opcode; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckOpcode;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const;
  virtual unsigned getHashImpl() const;
  virtual bool isContradictoryImpl(const Matcher *M) const;
};

/// SwitchOpcodeMatcher - Switch based on the current node's opcode, dispatching
/// to one matcher per opcode.  If the opcode doesn't match any of the cases,
/// then the match fails.  This is semantically equivalent to a Scope node where
/// every child does a CheckOpcode, but is much faster.
class SwitchOpcodeMatcher : public Matcher {
  SmallVector<std::pair<const SDNodeInfo*, Matcher*>, 8> Cases;
public:
  SwitchOpcodeMatcher(const std::pair<const SDNodeInfo*, Matcher*> *cases,
                      unsigned numcases)
    : Matcher(SwitchOpcode), Cases(cases, cases+numcases) {}

  static inline bool classof(const Matcher *N) {
    return N->getKind() == SwitchOpcode;
  }

  unsigned getNumCases() const { return Cases.size(); }

  const SDNodeInfo &getCaseOpcode(unsigned i) const { return *Cases[i].first; }
  Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
  const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return false; }
  virtual unsigned getHashImpl() const { return 4123; }
};

/// CheckTypeMatcher - This checks to see if the current node has the
/// specified type at the specified result, if not it fails to match.
class CheckTypeMatcher : public Matcher {
  MVT::SimpleValueType Type;
  unsigned ResNo;
public:
  CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno)
    : Matcher(CheckType), Type(type), ResNo(resno) {}

  MVT::SimpleValueType getType() const { return Type; }
  unsigned getResNo() const { return ResNo; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckType;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckTypeMatcher>(M)->Type == Type;
  }
  virtual unsigned getHashImpl() const { return Type; }
  virtual bool isContradictoryImpl(const Matcher *M) const;
};

/// SwitchTypeMatcher - Switch based on the current node's type, dispatching
/// to one matcher per case.  If the type doesn't match any of the cases,
/// then the match fails.  This is semantically equivalent to a Scope node where
/// every child does a CheckType, but is much faster.
class SwitchTypeMatcher : public Matcher {
  SmallVector<std::pair<MVT::SimpleValueType, Matcher*>, 8> Cases;
public:
  SwitchTypeMatcher(const std::pair<MVT::SimpleValueType, Matcher*> *cases,
                    unsigned numcases)
  : Matcher(SwitchType), Cases(cases, cases+numcases) {}

  static inline bool classof(const Matcher *N) {
    return N->getKind() == SwitchType;
  }

  unsigned getNumCases() const { return Cases.size(); }

  MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; }
  Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; }
  const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return false; }
  virtual unsigned getHashImpl() const { return 4123; }
};


/// CheckChildTypeMatcher - This checks to see if a child node has the
/// specified type, if not it fails to match.
class CheckChildTypeMatcher : public Matcher {
  unsigned ChildNo;
  MVT::SimpleValueType Type;
public:
  CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type)
    : Matcher(CheckChildType), ChildNo(childno), Type(type) {}

  unsigned getChildNo() const { return ChildNo; }
  MVT::SimpleValueType getType() const { return Type; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckChildType;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckChildTypeMatcher>(M)->ChildNo == ChildNo &&
           cast<CheckChildTypeMatcher>(M)->Type == Type;
  }
  virtual unsigned getHashImpl() const { return (Type << 3) | ChildNo; }
  virtual bool isContradictoryImpl(const Matcher *M) const;
};


/// CheckIntegerMatcher - This checks to see if the current node is a
/// ConstantSDNode with the specified integer value, if not it fails to match.
class CheckIntegerMatcher : public Matcher {
  int64_t Value;
public:
  CheckIntegerMatcher(int64_t value)
    : Matcher(CheckInteger), Value(value) {}

  int64_t getValue() const { return Value; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckInteger;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckIntegerMatcher>(M)->Value == Value;
  }
  virtual unsigned getHashImpl() const { return Value; }
  virtual bool isContradictoryImpl(const Matcher *M) const;
};

/// CheckCondCodeMatcher - This checks to see if the current node is a
/// CondCodeSDNode with the specified condition, if not it fails to match.
class CheckCondCodeMatcher : public Matcher {
  StringRef CondCodeName;
public:
  CheckCondCodeMatcher(StringRef condcodename)
    : Matcher(CheckCondCode), CondCodeName(condcodename) {}

  StringRef getCondCodeName() const { return CondCodeName; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckCondCode;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckCondCodeMatcher>(M)->CondCodeName == CondCodeName;
  }
  virtual unsigned getHashImpl() const;
};

/// CheckValueTypeMatcher - This checks to see if the current node is a
/// VTSDNode with the specified type, if not it fails to match.
class CheckValueTypeMatcher : public Matcher {
  StringRef TypeName;
public:
  CheckValueTypeMatcher(StringRef type_name)
    : Matcher(CheckValueType), TypeName(type_name) {}

  StringRef getTypeName() const { return TypeName; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckValueType;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckValueTypeMatcher>(M)->TypeName == TypeName;
  }
  virtual unsigned getHashImpl() const;
  bool isContradictoryImpl(const Matcher *M) const;
};



/// CheckComplexPatMatcher - This node runs the specified ComplexPattern on
/// the current node.
class CheckComplexPatMatcher : public Matcher {
  const ComplexPattern &Pattern;

  /// MatchNumber - This is the recorded nodes slot that contains the node we
  /// want to match against.
  unsigned MatchNumber;

  /// Name - The name of the node we're matching, for comment emission.
  std::string Name;

  /// FirstResult - This is the first slot in the RecordedNodes list that the
  /// result of the match populates.
  unsigned FirstResult;
public:
  CheckComplexPatMatcher(const ComplexPattern &pattern, unsigned matchnumber,
                         const std::string &name, unsigned firstresult)
    : Matcher(CheckComplexPat), Pattern(pattern), MatchNumber(matchnumber),
      Name(name), FirstResult(firstresult) {}

  const ComplexPattern &getPattern() const { return Pattern; }
  unsigned getMatchNumber() const { return MatchNumber; }

  const std::string getName() const { return Name; }
  unsigned getFirstResult() const { return FirstResult; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckComplexPat;
  }

  // Not safe to move a pattern predicate past a complex pattern.
  virtual bool isSafeToReorderWithPatternPredicate() const { return false; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return &cast<CheckComplexPatMatcher>(M)->Pattern == &Pattern &&
           cast<CheckComplexPatMatcher>(M)->MatchNumber == MatchNumber;
  }
  virtual unsigned getHashImpl() const {
    return (unsigned)(intptr_t)&Pattern ^ MatchNumber;
  }
};

/// CheckAndImmMatcher - This checks to see if the current node is an 'and'
/// with something equivalent to the specified immediate.
class CheckAndImmMatcher : public Matcher {
  int64_t Value;
public:
  CheckAndImmMatcher(int64_t value)
    : Matcher(CheckAndImm), Value(value) {}

  int64_t getValue() const { return Value; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckAndImm;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckAndImmMatcher>(M)->Value == Value;
  }
  virtual unsigned getHashImpl() const { return Value; }
};

/// CheckOrImmMatcher - This checks to see if the current node is an 'and'
/// with something equivalent to the specified immediate.
class CheckOrImmMatcher : public Matcher {
  int64_t Value;
public:
  CheckOrImmMatcher(int64_t value)
    : Matcher(CheckOrImm), Value(value) {}

  int64_t getValue() const { return Value; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckOrImm;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CheckOrImmMatcher>(M)->Value == Value;
  }
  virtual unsigned getHashImpl() const { return Value; }
};

/// CheckFoldableChainNodeMatcher - This checks to see if the current node
/// (which defines a chain operand) is safe to fold into a larger pattern.
class CheckFoldableChainNodeMatcher : public Matcher {
public:
  CheckFoldableChainNodeMatcher()
    : Matcher(CheckFoldableChainNode) {}

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CheckFoldableChainNode;
  }

  virtual bool isSafeToReorderWithPatternPredicate() const { return true; }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const { return true; }
  virtual unsigned getHashImpl() const { return 0; }
};

/// EmitIntegerMatcher - This creates a new TargetConstant.
class EmitIntegerMatcher : public Matcher {
  int64_t Val;
  MVT::SimpleValueType VT;
public:
  EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt)
    : Matcher(EmitInteger), Val(val), VT(vt) {}

  int64_t getValue() const { return Val; }
  MVT::SimpleValueType getVT() const { return VT; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitInteger;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<EmitIntegerMatcher>(M)->Val == Val &&
           cast<EmitIntegerMatcher>(M)->VT == VT;
  }
  virtual unsigned getHashImpl() const { return (Val << 4) | VT; }
};

/// EmitStringIntegerMatcher - A target constant whose value is represented
/// by a string.
class EmitStringIntegerMatcher : public Matcher {
  std::string Val;
  MVT::SimpleValueType VT;
public:
  EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt)
    : Matcher(EmitStringInteger), Val(val), VT(vt) {}

  const std::string &getValue() const { return Val; }
  MVT::SimpleValueType getVT() const { return VT; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitStringInteger;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<EmitStringIntegerMatcher>(M)->Val == Val &&
           cast<EmitStringIntegerMatcher>(M)->VT == VT;
  }
  virtual unsigned getHashImpl() const;
};

/// EmitRegisterMatcher - This creates a new TargetConstant.
class EmitRegisterMatcher : public Matcher {
  /// Reg - The def for the register that we're emitting.  If this is null, then
  /// this is a reference to zero_reg.
  const CodeGenRegister *Reg;
  MVT::SimpleValueType VT;
public:
  EmitRegisterMatcher(const CodeGenRegister *reg, MVT::SimpleValueType vt)
    : Matcher(EmitRegister), Reg(reg), VT(vt) {}

  const CodeGenRegister *getReg() const { return Reg; }
  MVT::SimpleValueType getVT() const { return VT; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitRegister;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<EmitRegisterMatcher>(M)->Reg == Reg &&
           cast<EmitRegisterMatcher>(M)->VT == VT;
  }
  virtual unsigned getHashImpl() const {
    return ((unsigned)(intptr_t)Reg) << 4 | VT;
  }
};

/// EmitConvertToTargetMatcher - Emit an operation that reads a specified
/// recorded node and converts it from being a ISD::Constant to
/// ISD::TargetConstant, likewise for ConstantFP.
class EmitConvertToTargetMatcher : public Matcher {
  unsigned Slot;
public:
  EmitConvertToTargetMatcher(unsigned slot)
    : Matcher(EmitConvertToTarget), Slot(slot) {}

  unsigned getSlot() const { return Slot; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitConvertToTarget;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<EmitConvertToTargetMatcher>(M)->Slot == Slot;
  }
  virtual unsigned getHashImpl() const { return Slot; }
};

/// EmitMergeInputChainsMatcher - Emit a node that merges a list of input
/// chains together with a token factor.  The list of nodes are the nodes in the
/// matched pattern that have chain input/outputs.  This node adds all input
/// chains of these nodes if they are not themselves a node in the pattern.
class EmitMergeInputChainsMatcher : public Matcher {
  SmallVector<unsigned, 3> ChainNodes;
public:
  EmitMergeInputChainsMatcher(const unsigned *nodes, unsigned NumNodes)
    : Matcher(EmitMergeInputChains), ChainNodes(nodes, nodes+NumNodes) {}

  unsigned getNumNodes() const { return ChainNodes.size(); }

  unsigned getNode(unsigned i) const {
    assert(i < ChainNodes.size());
    return ChainNodes[i];
  }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitMergeInputChains;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<EmitMergeInputChainsMatcher>(M)->ChainNodes == ChainNodes;
  }
  virtual unsigned getHashImpl() const;
};

/// EmitCopyToRegMatcher - Emit a CopyToReg node from a value to a physreg,
/// pushing the chain and glue results.
///
class EmitCopyToRegMatcher : public Matcher {
  unsigned SrcSlot; // Value to copy into the physreg.
  Record *DestPhysReg;
public:
  EmitCopyToRegMatcher(unsigned srcSlot, Record *destPhysReg)
    : Matcher(EmitCopyToReg), SrcSlot(srcSlot), DestPhysReg(destPhysReg) {}

  unsigned getSrcSlot() const { return SrcSlot; }
  Record *getDestPhysReg() const { return DestPhysReg; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitCopyToReg;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<EmitCopyToRegMatcher>(M)->SrcSlot == SrcSlot &&
           cast<EmitCopyToRegMatcher>(M)->DestPhysReg == DestPhysReg;
  }
  virtual unsigned getHashImpl() const {
    return SrcSlot ^ ((unsigned)(intptr_t)DestPhysReg << 4);
  }
};



/// EmitNodeXFormMatcher - Emit an operation that runs an SDNodeXForm on a
/// recorded node and records the result.
class EmitNodeXFormMatcher : public Matcher {
  unsigned Slot;
  Record *NodeXForm;
public:
  EmitNodeXFormMatcher(unsigned slot, Record *nodeXForm)
    : Matcher(EmitNodeXForm), Slot(slot), NodeXForm(nodeXForm) {}

  unsigned getSlot() const { return Slot; }
  Record *getNodeXForm() const { return NodeXForm; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitNodeXForm;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<EmitNodeXFormMatcher>(M)->Slot == Slot &&
           cast<EmitNodeXFormMatcher>(M)->NodeXForm == NodeXForm;
  }
  virtual unsigned getHashImpl() const {
    return Slot ^ ((unsigned)(intptr_t)NodeXForm << 4);
  }
};

/// EmitNodeMatcherCommon - Common class shared between EmitNode and
/// MorphNodeTo.
class EmitNodeMatcherCommon : public Matcher {
  std::string OpcodeName;
  const SmallVector<MVT::SimpleValueType, 3> VTs;
  const SmallVector<unsigned, 6> Operands;
  bool HasChain, HasInGlue, HasOutGlue, HasMemRefs;

  /// NumFixedArityOperands - If this is a fixed arity node, this is set to -1.
  /// If this is a varidic node, this is set to the number of fixed arity
  /// operands in the root of the pattern.  The rest are appended to this node.
  int NumFixedArityOperands;
public:
  EmitNodeMatcherCommon(const std::string &opcodeName,
                        const MVT::SimpleValueType *vts, unsigned numvts,
                        const unsigned *operands, unsigned numops,
                        bool hasChain, bool hasInGlue, bool hasOutGlue,
                        bool hasmemrefs,
                        int numfixedarityoperands, bool isMorphNodeTo)
    : Matcher(isMorphNodeTo ? MorphNodeTo : EmitNode), OpcodeName(opcodeName),
      VTs(vts, vts+numvts), Operands(operands, operands+numops),
      HasChain(hasChain), HasInGlue(hasInGlue), HasOutGlue(hasOutGlue),
      HasMemRefs(hasmemrefs), NumFixedArityOperands(numfixedarityoperands) {}

  const std::string &getOpcodeName() const { return OpcodeName; }

  unsigned getNumVTs() const { return VTs.size(); }
  MVT::SimpleValueType getVT(unsigned i) const {
    assert(i < VTs.size());
    return VTs[i];
  }

  unsigned getNumOperands() const { return Operands.size(); }
  unsigned getOperand(unsigned i) const {
    assert(i < Operands.size());
    return Operands[i];
  }

  const SmallVectorImpl<MVT::SimpleValueType> &getVTList() const { return VTs; }
  const SmallVectorImpl<unsigned> &getOperandList() const { return Operands; }


  bool hasChain() const { return HasChain; }
  bool hasInFlag() const { return HasInGlue; }
  bool hasOutFlag() const { return HasOutGlue; }
  bool hasMemRefs() const { return HasMemRefs; }
  int getNumFixedArityOperands() const { return NumFixedArityOperands; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitNode || N->getKind() == MorphNodeTo;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const;
  virtual unsigned getHashImpl() const;
};

/// EmitNodeMatcher - This signals a successful match and generates a node.
class EmitNodeMatcher : public EmitNodeMatcherCommon {
  virtual void anchor();
  unsigned FirstResultSlot;
public:
  EmitNodeMatcher(const std::string &opcodeName,
                  const MVT::SimpleValueType *vts, unsigned numvts,
                  const unsigned *operands, unsigned numops,
                  bool hasChain, bool hasInFlag, bool hasOutFlag,
                  bool hasmemrefs,
                  int numfixedarityoperands, unsigned firstresultslot)
  : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
                          hasInFlag, hasOutFlag, hasmemrefs,
                          numfixedarityoperands, false),
    FirstResultSlot(firstresultslot) {}

  unsigned getFirstResultSlot() const { return FirstResultSlot; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == EmitNode;
  }

};

class MorphNodeToMatcher : public EmitNodeMatcherCommon {
  virtual void anchor();
  const PatternToMatch &Pattern;
public:
  MorphNodeToMatcher(const std::string &opcodeName,
                     const MVT::SimpleValueType *vts, unsigned numvts,
                     const unsigned *operands, unsigned numops,
                     bool hasChain, bool hasInFlag, bool hasOutFlag,
                     bool hasmemrefs,
                     int numfixedarityoperands, const PatternToMatch &pattern)
    : EmitNodeMatcherCommon(opcodeName, vts, numvts, operands, numops, hasChain,
                            hasInFlag, hasOutFlag, hasmemrefs,
                            numfixedarityoperands, true),
      Pattern(pattern) {
  }

  const PatternToMatch &getPattern() const { return Pattern; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == MorphNodeTo;
  }
};

/// MarkGlueResultsMatcher - This node indicates which non-root nodes in the
/// pattern produce glue.  This allows CompleteMatchMatcher to update them
/// with the output glue of the resultant code.
class MarkGlueResultsMatcher : public Matcher {
  SmallVector<unsigned, 3> GlueResultNodes;
public:
  MarkGlueResultsMatcher(const unsigned *nodes, unsigned NumNodes)
    : Matcher(MarkGlueResults), GlueResultNodes(nodes, nodes+NumNodes) {}

  unsigned getNumNodes() const { return GlueResultNodes.size(); }

  unsigned getNode(unsigned i) const {
    assert(i < GlueResultNodes.size());
    return GlueResultNodes[i];
  }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == MarkGlueResults;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<MarkGlueResultsMatcher>(M)->GlueResultNodes == GlueResultNodes;
  }
  virtual unsigned getHashImpl() const;
};

/// CompleteMatchMatcher - Complete a match by replacing the results of the
/// pattern with the newly generated nodes.  This also prints a comment
/// indicating the source and dest patterns.
class CompleteMatchMatcher : public Matcher {
  SmallVector<unsigned, 2> Results;
  const PatternToMatch &Pattern;
public:
  CompleteMatchMatcher(const unsigned *results, unsigned numresults,
                       const PatternToMatch &pattern)
  : Matcher(CompleteMatch), Results(results, results+numresults),
    Pattern(pattern) {}

  unsigned getNumResults() const { return Results.size(); }
  unsigned getResult(unsigned R) const { return Results[R]; }
  const PatternToMatch &getPattern() const { return Pattern; }

  static inline bool classof(const Matcher *N) {
    return N->getKind() == CompleteMatch;
  }

private:
  virtual void printImpl(raw_ostream &OS, unsigned indent) const;
  virtual bool isEqualImpl(const Matcher *M) const {
    return cast<CompleteMatchMatcher>(M)->Results == Results &&
          &cast<CompleteMatchMatcher>(M)->Pattern == &Pattern;
  }
  virtual unsigned getHashImpl() const;
};

} // end namespace llvm

#endif
