//===- DAGISelMatcher.cpp - Representation of DAG pattern matcher ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DAGISelMatcher.h"
#include "Common/CodeGenDAGPatterns.h"
#include "Common/CodeGenInstruction.h"
#include "Common/CodeGenRegisters.h"
#include "Common/CodeGenTarget.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"
using namespace llvm;

void Matcher::anchor() {}

void Matcher::dump() const { print(errs()); }

void Matcher::print(raw_ostream &OS, indent Indent) const {
  printImpl(OS, Indent);
  if (Next)
    return Next->print(OS, Indent);
}

void Matcher::printOne(raw_ostream &OS) const { printImpl(OS, indent(0)); }

/// 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 *Matcher::unlinkNode(Matcher *Other) {
  if (this == Other)
    return takeNext();

  // Scan until we find the predecessor of Other.
  Matcher *Cur = this;
  for (; Cur && Cur->getNext() != Other; Cur = Cur->getNext())
    /*empty*/;

  if (!Cur)
    return nullptr;
  Cur->takeNext();
  Cur->setNext(Other->takeNext());
  return this;
}

/// 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 Matcher::canMoveBefore(const Matcher *Other) const {
  for (;; Other = Other->getNext()) {
    assert(Other && "Other didn't come before 'this'?");
    if (this == Other)
      return true;

    // We have to be able to move this node across the Other node.
    if (!canMoveBeforeNode(Other))
      return false;
  }
}

/// canMoveBeforeNode - Return true if it is safe to move the current matcher
/// across the specified one.
bool Matcher::canMoveBeforeNode(const Matcher *Other) const {
  // We can move simple predicates before record nodes.
  if (isSimplePredicateNode())
    return Other->isSimplePredicateOrRecordNode();

  // We can move record nodes across simple predicates.
  if (isSimplePredicateOrRecordNode())
    return isSimplePredicateNode();

  // We can't move record nodes across each other etc.
  return false;
}

ScopeMatcher::~ScopeMatcher() {
  for (Matcher *C : Children)
    delete C;
}

SwitchOpcodeMatcher::~SwitchOpcodeMatcher() {
  for (auto &C : Cases)
    delete C.second;
}

SwitchTypeMatcher::~SwitchTypeMatcher() {
  for (auto &C : Cases)
    delete C.second;
}

CheckPredicateMatcher::CheckPredicateMatcher(const TreePredicateFn &pred,
                                             ArrayRef<unsigned> Ops)
    : Matcher(CheckPredicate), Pred(pred.getOrigPatFragRecord()),
      Operands(Ops) {}

TreePredicateFn CheckPredicateMatcher::getPredicate() const {
  return TreePredicateFn(Pred);
}

unsigned CheckPredicateMatcher::getNumOperands() const {
  return Operands.size();
}

unsigned CheckPredicateMatcher::getOperandNo(unsigned i) const {
  assert(i < Operands.size());
  return Operands[i];
}

// printImpl methods.

void ScopeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "Scope\n";
  for (const Matcher *C : Children) {
    if (!C)
      OS << Indent + 1 << "NULL POINTER\n";
    else
      C->print(OS, Indent + 2);
  }
}

void RecordMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "Record\n";
}

void RecordChildMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "RecordChild: " << ChildNo << '\n';
}

void RecordMemRefMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "RecordMemRef\n";
}

void CaptureGlueInputMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CaptureGlueInput\n";
}

void MoveChildMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "MoveChild " << ChildNo << '\n';
}

void MoveSiblingMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "MoveSibling " << SiblingNo << '\n';
}

void MoveParentMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "MoveParent\n";
}

void CheckSameMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckSame " << MatchNumber << '\n';
}

void CheckChildSameMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckChild" << ChildNo << "Same\n";
}

void CheckPatternPredicateMatcher::printImpl(raw_ostream &OS,
                                             indent Indent) const {
  OS << Indent << "CheckPatternPredicate " << Predicate << '\n';
}

void CheckPredicateMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckPredicate " << getPredicate().getFnName() << '\n';
}

void CheckOpcodeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckOpcode " << Opcode.getEnumName() << '\n';
}

void SwitchOpcodeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "SwitchOpcode: {\n";
  for (const auto &C : Cases) {
    OS << Indent << "case " << C.first->getEnumName() << ":\n";
    C.second->print(OS, Indent + 2);
  }
  OS << Indent << "}\n";
}

void CheckTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckType " << getEnumName(Type) << ", ResNo=" << ResNo
     << '\n';
}

void SwitchTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "SwitchType: {\n";
  for (const auto &C : Cases) {
    OS << Indent << "case " << getEnumName(C.first) << ":\n";
    C.second->print(OS, Indent + 2);
  }
  OS << Indent << "}\n";
}

void CheckChildTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckChildType " << ChildNo << " " << getEnumName(Type)
     << '\n';
}

void CheckIntegerMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckInteger " << Value << '\n';
}

void CheckChildIntegerMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckChildInteger " << ChildNo << " " << Value << '\n';
}

void CheckCondCodeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckCondCode ISD::" << CondCodeName << '\n';
}

void CheckChild2CondCodeMatcher::printImpl(raw_ostream &OS,
                                           indent Indent) const {
  OS << Indent << "CheckChild2CondCode ISD::" << CondCodeName << '\n';
}

void CheckValueTypeMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckValueType " << getEnumName(VT) << '\n';
}

void CheckComplexPatMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckComplexPat " << Pattern.getSelectFunc() << '\n';
}

void CheckAndImmMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckAndImm " << Value << '\n';
}

void CheckOrImmMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckOrImm " << Value << '\n';
}

void CheckFoldableChainNodeMatcher::printImpl(raw_ostream &OS,
                                              indent Indent) const {
  OS << Indent << "CheckFoldableChainNode\n";
}

void CheckImmAllOnesVMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckAllOnesV\n";
}

void CheckImmAllZerosVMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CheckAllZerosV\n";
}

void EmitIntegerMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "EmitInteger " << Val << " VT=" << getEnumName(VT) << '\n';
}

void EmitRegisterMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "EmitRegister ";
  if (Reg)
    OS << Reg->getName();
  else
    OS << "zero_reg";
  OS << " VT=" << getEnumName(VT) << '\n';
}

void EmitConvertToTargetMatcher::printImpl(raw_ostream &OS,
                                           indent Indent) const {
  OS << Indent << "EmitConvertToTarget " << Slot << '\n';
}

void EmitMergeInputChainsMatcher::printImpl(raw_ostream &OS,
                                            indent Indent) const {
  OS << Indent << "EmitMergeInputChains <todo: args>\n";
}

void EmitCopyToRegMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "EmitCopyToReg <todo: args>\n";
}

void EmitNodeXFormMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "EmitNodeXForm " << NodeXForm->getName() << " Slot=" << Slot
     << '\n';
}

void EmitNodeMatcherCommon::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent;
  OS << (isa<MorphNodeToMatcher>(this) ? "MorphNodeTo: " : "EmitNode: ")
     << CGI.Namespace << "::" << CGI.getName() << ": <todo flags> ";

  for (MVT VT : VTs)
    OS << ' ' << getEnumName(VT);
  OS << '(';
  for (unsigned Operand : Operands)
    OS << Operand << ' ';
  OS << ")\n";
}

void CompleteMatchMatcher::printImpl(raw_ostream &OS, indent Indent) const {
  OS << Indent << "CompleteMatch <todo args>\n";
  OS << Indent << "Src = " << Pattern.getSrcPattern() << "\n";
  OS << Indent << "Dst = " << Pattern.getDstPattern() << "\n";
}

bool CheckOpcodeMatcher::isEqualImpl(const Matcher *M) const {
  // Note: pointer equality isn't enough here, we have to check the enum names
  // to ensure that the nodes are for the same opcode.
  return cast<CheckOpcodeMatcher>(M)->Opcode.getEnumName() ==
         Opcode.getEnumName();
}

bool EmitNodeMatcherCommon::isEqualImpl(const Matcher *m) const {
  const EmitNodeMatcherCommon *M = cast<EmitNodeMatcherCommon>(m);
  return &M->CGI == &CGI && M->VTs == VTs && M->Operands == Operands &&
         M->HasChain == HasChain && M->HasInGlue == HasInGlue &&
         M->HasOutGlue == HasOutGlue && M->HasMemRefs == HasMemRefs &&
         M->NumFixedArityOperands == NumFixedArityOperands;
}

void EmitNodeMatcher::anchor() {}

void MorphNodeToMatcher::anchor() {}

// isContradictoryImpl Implementations.

static bool TypesAreContradictory(MVT T1, MVT T2) {
  // If the two types are the same, then they are the same, so they don't
  // contradict.
  if (T1 == T2)
    return false;

  if (T1 == MVT::pAny)
    return TypesAreContradictory(MVT::iPTR, T2) &&
           TypesAreContradictory(MVT::cPTR, T2);

  if (T2 == MVT::pAny)
    return TypesAreContradictory(T1, MVT::iPTR) &&
           TypesAreContradictory(T1, MVT::cPTR);

  // If either type is about iPtr, then they don't conflict unless the other
  // one is not a scalar integer type.
  if (T1 == MVT::iPTR)
    return !T2.isInteger() || T2.isVector();

  if (T2 == MVT::iPTR)
    return !T1.isInteger() || T1.isVector();

  if (T1 == MVT::cPTR)
    return !T2.isCheriCapability() || T2.isVector();

  if (T2 == MVT::cPTR)
    return !T1.isCheriCapability() || T1.isVector();

  // Otherwise, they are two different non-iPTR/cPTR types, they conflict.
  return true;
}

bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const CheckOpcodeMatcher *COM = dyn_cast<CheckOpcodeMatcher>(M)) {
    // One node can't have two different opcodes!
    // Note: pointer equality isn't enough here, we have to check the enum names
    // to ensure that the nodes are for the same opcode.
    return COM->getOpcode().getEnumName() != getOpcode().getEnumName();
  }

  // If the node has a known type, and if the type we're checking for is
  // different, then we know they contradict.  For example, a check for
  // ISD::STORE will never be true at the same time a check for Type i32 is.
  if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M)) {
    // If checking for a result the opcode doesn't have, it can't match.
    if (CT->getResNo() >= getOpcode().getNumResults())
      return true;

    MVT NodeType = getOpcode().getKnownType(CT->getResNo());
    if (NodeType != MVT::Other)
      return TypesAreContradictory(NodeType, CT->getType());
  }

  return false;
}

bool CheckTypeMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const CheckTypeMatcher *CT = dyn_cast<CheckTypeMatcher>(M))
    return TypesAreContradictory(getType(), CT->getType());
  return false;
}

bool CheckChildTypeMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const CheckChildTypeMatcher *CC = dyn_cast<CheckChildTypeMatcher>(M)) {
    // If the two checks are about different nodes, we don't know if they
    // conflict!
    if (CC->getChildNo() != getChildNo())
      return false;

    return TypesAreContradictory(getType(), CC->getType());
  }
  return false;
}

bool CheckIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const CheckIntegerMatcher *CIM = dyn_cast<CheckIntegerMatcher>(M))
    return CIM->getValue() != getValue();
  return false;
}

bool CheckChildIntegerMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const CheckChildIntegerMatcher *CCIM =
          dyn_cast<CheckChildIntegerMatcher>(M)) {
    // If the two checks are about different nodes, we don't know if they
    // conflict!
    if (CCIM->getChildNo() != getChildNo())
      return false;

    return CCIM->getValue() != getValue();
  }
  return false;
}

bool CheckValueTypeMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const CheckValueTypeMatcher *CVT = dyn_cast<CheckValueTypeMatcher>(M))
    return CVT->getVT() != getVT();
  return false;
}

bool CheckImmAllOnesVMatcher::isContradictoryImpl(const Matcher *M) const {
  // AllZeros is contradictory.
  return isa<CheckImmAllZerosVMatcher>(M);
}

bool CheckImmAllZerosVMatcher::isContradictoryImpl(const Matcher *M) const {
  // AllOnes is contradictory.
  return isa<CheckImmAllOnesVMatcher>(M);
}

bool CheckCondCodeMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const auto *CCCM = dyn_cast<CheckCondCodeMatcher>(M))
    return CCCM->getCondCodeName() != getCondCodeName();
  return false;
}

bool CheckChild2CondCodeMatcher::isContradictoryImpl(const Matcher *M) const {
  if (const auto *CCCCM = dyn_cast<CheckChild2CondCodeMatcher>(M))
    return CCCCM->getCondCodeName() != getCondCodeName();
  return false;
}
