//===- PatternParser.cpp ----------------------------------------*- C++ -*-===//
//
// 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 "Common/GlobalISel/PatternParser.h"
#include "Basic/CodeGenIntrinsics.h"
#include "Common/CodeGenTarget.h"
#include "Common/GlobalISel/CombinerUtils.h"
#include "Common/GlobalISel/Patterns.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"

using namespace llvm;
using namespace gi;

static constexpr StringLiteral MIFlagsEnumClassName = "MIFlagEnum";

namespace {
class PrettyStackTraceParse : public PrettyStackTraceEntry {
  const Record &Def;

public:
  PrettyStackTraceParse(const Record &Def) : Def(Def) {}

  void print(raw_ostream &OS) const override {
    if (Def.isSubClassOf("GICombineRule"))
      OS << "Parsing GICombineRule '" << Def.getName() << '\'';
    else if (Def.isSubClassOf(PatFrag::ClassName))
      OS << "Parsing " << PatFrag::ClassName << " '" << Def.getName() << '\'';
    else
      OS << "Parsing '" << Def.getName() << '\'';
    OS << '\n';
  }
};
} // namespace

bool PatternParser::parsePatternList(
    const DagInit &List,
    function_ref<bool(std::unique_ptr<Pattern>)> ParseAction,
    StringRef Operator, StringRef AnonPatNamePrefix) {
  if (List.getOperatorAsDef(DiagLoc)->getName() != Operator) {
    PrintError(DiagLoc, "Expected " + Operator + " operator");
    return false;
  }

  if (List.getNumArgs() == 0) {
    PrintError(DiagLoc, Operator + " pattern list is empty");
    return false;
  }

  // The match section consists of a list of matchers and predicates. Parse each
  // one and add the equivalent GIMatchDag nodes, predicates, and edges.
  for (unsigned I = 0; I < List.getNumArgs(); ++I) {
    const Init *Arg = List.getArg(I);
    std::string Name = List.getArgName(I)
                           ? List.getArgName(I)->getValue().str()
                           : ("__" + AnonPatNamePrefix + "_" + Twine(I)).str();

    if (auto Pat = parseInstructionPattern(*Arg, Name)) {
      if (!ParseAction(std::move(Pat)))
        return false;
      continue;
    }

    if (auto Pat = parseWipMatchOpcodeMatcher(*Arg, Name)) {
      if (!ParseAction(std::move(Pat)))
        return false;
      continue;
    }

    // Parse arbitrary C++ code
    if (const auto *StringI = dyn_cast<StringInit>(Arg)) {
      auto CXXPat = std::make_unique<CXXPattern>(*StringI, insertStrRef(Name));
      if (!ParseAction(std::move(CXXPat)))
        return false;
      continue;
    }

    PrintError(DiagLoc,
               "Failed to parse pattern: '" + Arg->getAsString() + '\'');
    return false;
  }

  return true;
}

static const CodeGenInstruction &
getInstrForIntrinsic(const CodeGenTarget &CGT, const CodeGenIntrinsic *I) {
  StringRef Opc;
  if (I->isConvergent) {
    Opc = I->hasSideEffects ? "G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS"
                            : "G_INTRINSIC_CONVERGENT";
  } else {
    Opc = I->hasSideEffects ? "G_INTRINSIC_W_SIDE_EFFECTS" : "G_INTRINSIC";
  }

  RecordKeeper &RK = I->TheDef->getRecords();
  return CGT.getInstruction(RK.getDef(Opc));
}

std::unique_ptr<Pattern>
PatternParser::parseInstructionPattern(const Init &Arg, StringRef Name) {
  const DagInit *DagPat = dyn_cast<DagInit>(&Arg);
  if (!DagPat)
    return nullptr;

  std::unique_ptr<InstructionPattern> Pat;
  if (const DagInit *IP = getDagWithOperatorOfSubClass(Arg, "Instruction")) {
    const CodeGenInstruction &Instr =
        CGT.getInstruction(IP->getOperatorAsDef(DiagLoc));
    Pat =
        std::make_unique<CodeGenInstructionPattern>(Instr, insertStrRef(Name));
  } else if (const DagInit *IP =
                 getDagWithOperatorOfSubClass(Arg, "Intrinsic")) {
    const Record *TheDef = IP->getOperatorAsDef(DiagLoc);
    const CodeGenIntrinsic *Intrin = &CGT.getIntrinsic(TheDef);
    const CodeGenInstruction &Instr = getInstrForIntrinsic(CGT, Intrin);
    Pat =
        std::make_unique<CodeGenInstructionPattern>(Instr, insertStrRef(Name));
    cast<CodeGenInstructionPattern>(*Pat).setIntrinsic(Intrin);
  } else if (const DagInit *PFP =
                 getDagWithOperatorOfSubClass(Arg, PatFrag::ClassName)) {
    const Record *Def = PFP->getOperatorAsDef(DiagLoc);
    const PatFrag *PF = parsePatFrag(Def);
    if (!PF)
      return nullptr; // Already diagnosed by parsePatFrag
    Pat = std::make_unique<PatFragPattern>(*PF, insertStrRef(Name));
  } else if (const DagInit *BP =
                 getDagWithOperatorOfSubClass(Arg, BuiltinPattern::ClassName)) {
    Pat = std::make_unique<BuiltinPattern>(*BP->getOperatorAsDef(DiagLoc),
                                           insertStrRef(Name));
  } else {
    return nullptr;
  }

  for (unsigned K = 0; K < DagPat->getNumArgs(); ++K) {
    const Init *Arg = DagPat->getArg(K);
    if (auto *DagArg = getDagWithSpecificOperator(*Arg, "MIFlags")) {
      if (!parseInstructionPatternMIFlags(*Pat, DagArg))
        return nullptr;
      continue;
    }

    if (!parseInstructionPatternOperand(*Pat, Arg, DagPat->getArgName(K)))
      return nullptr;
  }

  if (!Pat->checkSemantics(DiagLoc))
    return nullptr;

  return std::move(Pat);
}

std::unique_ptr<Pattern>
PatternParser::parseWipMatchOpcodeMatcher(const Init &Arg, StringRef Name) {
  const DagInit *Matcher = getDagWithSpecificOperator(Arg, "wip_match_opcode");
  if (!Matcher)
    return nullptr;

  if (Matcher->getNumArgs() == 0) {
    PrintError(DiagLoc, "Empty wip_match_opcode");
    return nullptr;
  }

  // Each argument is an opcode that can match.
  auto Result = std::make_unique<AnyOpcodePattern>(insertStrRef(Name));
  for (const auto &Arg : Matcher->getArgs()) {
    const Record *OpcodeDef = getDefOfSubClass(*Arg, "Instruction");
    if (OpcodeDef) {
      Result->addOpcode(&CGT.getInstruction(OpcodeDef));
      continue;
    }

    PrintError(DiagLoc, "Arguments to wip_match_opcode must be instructions");
    return nullptr;
  }

  return std::move(Result);
}

bool PatternParser::parseInstructionPatternOperand(InstructionPattern &IP,
                                                   const Init *OpInit,
                                                   const StringInit *OpName) {
  const auto ParseErr = [&]() {
    PrintError(DiagLoc,
               "cannot parse operand '" + OpInit->getAsUnquotedString() + "' ");
    if (OpName)
      PrintNote(DiagLoc,
                "operand name is '" + OpName->getAsUnquotedString() + '\'');
    return false;
  };

  // untyped immediate, e.g. 0
  if (const auto *IntImm = dyn_cast<IntInit>(OpInit)) {
    std::string Name = OpName ? OpName->getAsUnquotedString() : "";
    IP.addOperand(IntImm->getValue(), insertStrRef(Name), PatternType());
    return true;
  }

  // typed immediate, e.g. (i32 0)
  if (const auto *DagOp = dyn_cast<DagInit>(OpInit)) {
    if (DagOp->getNumArgs() != 1)
      return ParseErr();

    const Record *TyDef = DagOp->getOperatorAsDef(DiagLoc);
    auto ImmTy = PatternType::get(DiagLoc, TyDef,
                                  "cannot parse immediate '" +
                                      DagOp->getAsUnquotedString() + '\'');
    if (!ImmTy)
      return false;

    if (!IP.hasAllDefs()) {
      PrintError(DiagLoc, "out operand of '" + IP.getInstName() +
                              "' cannot be an immediate");
      return false;
    }

    const auto *Val = dyn_cast<IntInit>(DagOp->getArg(0));
    if (!Val)
      return ParseErr();

    std::string Name = OpName ? OpName->getAsUnquotedString() : "";
    IP.addOperand(Val->getValue(), insertStrRef(Name), *ImmTy);
    return true;
  }

  // Typed operand e.g. $x/$z in (G_FNEG $x, $z)
  if (auto *DefI = dyn_cast<DefInit>(OpInit)) {
    if (!OpName) {
      PrintError(DiagLoc, "expected an operand name after '" +
                              OpInit->getAsString() + '\'');
      return false;
    }
    const Record *Def = DefI->getDef();
    auto Ty = PatternType::get(DiagLoc, Def, "cannot parse operand type");
    if (!Ty)
      return false;
    IP.addOperand(insertStrRef(OpName->getAsUnquotedString()), *Ty);
    return true;
  }

  // Untyped operand e.g. $x/$z in (G_FNEG $x, $z)
  if (isa<UnsetInit>(OpInit)) {
    assert(OpName && "Unset w/ no OpName?");
    IP.addOperand(insertStrRef(OpName->getAsUnquotedString()), PatternType());
    return true;
  }

  return ParseErr();
}

bool PatternParser::parseInstructionPatternMIFlags(InstructionPattern &IP,
                                                   const DagInit *Op) {
  auto *CGIP = dyn_cast<CodeGenInstructionPattern>(&IP);
  if (!CGIP) {
    PrintError(DiagLoc,
               "matching/writing MIFlags is only allowed on CodeGenInstruction "
               "patterns");
    return false;
  }

  const auto CheckFlagEnum = [&](const Record *R) {
    if (!R->isSubClassOf(MIFlagsEnumClassName)) {
      PrintError(DiagLoc, "'" + R->getName() + "' is not a subclass of '" +
                              MIFlagsEnumClassName + "'");
      return false;
    }

    return true;
  };

  if (CGIP->getMIFlagsInfo()) {
    PrintError(DiagLoc, "MIFlags can only be present once on an instruction");
    return false;
  }

  auto &FI = CGIP->getOrCreateMIFlagsInfo();
  for (unsigned K = 0; K < Op->getNumArgs(); ++K) {
    const Init *Arg = Op->getArg(K);

    // Match/set a flag: (MIFlags FmNoNans)
    if (const auto *Def = dyn_cast<DefInit>(Arg)) {
      const Record *R = Def->getDef();
      if (!CheckFlagEnum(R))
        return false;

      FI.addSetFlag(R);
      continue;
    }

    // Do not match a flag/unset a flag: (MIFlags (not FmNoNans))
    if (const DagInit *NotDag = getDagWithSpecificOperator(*Arg, "not")) {
      for (const Init *NotArg : NotDag->getArgs()) {
        const DefInit *DefArg = dyn_cast<DefInit>(NotArg);
        if (!DefArg) {
          PrintError(DiagLoc, "cannot parse '" + NotArg->getAsUnquotedString() +
                                  "': expected a '" + MIFlagsEnumClassName +
                                  "'");
          return false;
        }

        const Record *R = DefArg->getDef();
        if (!CheckFlagEnum(R))
          return false;

        FI.addUnsetFlag(R);
      }

      continue;
    }

    // Copy flags from a matched instruction: (MIFlags $mi)
    if (isa<UnsetInit>(Arg)) {
      FI.addCopyFlag(insertStrRef(Op->getArgName(K)->getAsUnquotedString()));
      continue;
    }
  }

  return true;
}

std::unique_ptr<PatFrag> PatternParser::parsePatFragImpl(const Record *Def) {
  auto StackTrace = PrettyStackTraceParse(*Def);
  if (!Def->isSubClassOf(PatFrag::ClassName))
    return nullptr;

  const DagInit *Ins = Def->getValueAsDag("InOperands");
  if (Ins->getOperatorAsDef(Def->getLoc())->getName() != "ins") {
    PrintError(Def, "expected 'ins' operator for " + PatFrag::ClassName +
                        " in operands list");
    return nullptr;
  }

  const DagInit *Outs = Def->getValueAsDag("OutOperands");
  if (Outs->getOperatorAsDef(Def->getLoc())->getName() != "outs") {
    PrintError(Def, "expected 'outs' operator for " + PatFrag::ClassName +
                        " out operands list");
    return nullptr;
  }

  auto Result = std::make_unique<PatFrag>(*Def);
  if (!parsePatFragParamList(*Outs, [&](StringRef Name, unsigned Kind) {
        Result->addOutParam(insertStrRef(Name), (PatFrag::ParamKind)Kind);
        return true;
      }))
    return nullptr;

  if (!parsePatFragParamList(*Ins, [&](StringRef Name, unsigned Kind) {
        Result->addInParam(insertStrRef(Name), (PatFrag::ParamKind)Kind);
        return true;
      }))
    return nullptr;

  const ListInit *Alts = Def->getValueAsListInit("Alternatives");
  unsigned AltIdx = 0;
  for (const Init *Alt : *Alts) {
    const auto *PatDag = dyn_cast<DagInit>(Alt);
    if (!PatDag) {
      PrintError(Def, "expected dag init for PatFrag pattern alternative");
      return nullptr;
    }

    PatFrag::Alternative &A = Result->addAlternative();
    const auto AddPat = [&](std::unique_ptr<Pattern> Pat) {
      A.Pats.push_back(std::move(Pat));
      return true;
    };

    SaveAndRestore<ArrayRef<SMLoc>> DiagLocSAR(DiagLoc, Def->getLoc());
    if (!parsePatternList(
            *PatDag, AddPat, "pattern",
            /*AnonPatPrefix*/
            (Def->getName() + "_alt" + Twine(AltIdx++) + "_pattern").str()))
      return nullptr;
  }

  if (!Result->buildOperandsTables() || !Result->checkSemantics())
    return nullptr;

  return Result;
}

bool PatternParser::parsePatFragParamList(
    const DagInit &OpsList,
    function_ref<bool(StringRef, unsigned)> ParseAction) {
  for (unsigned K = 0; K < OpsList.getNumArgs(); ++K) {
    const StringInit *Name = OpsList.getArgName(K);
    const Init *Ty = OpsList.getArg(K);

    if (!Name) {
      PrintError(DiagLoc, "all operands must be named'");
      return false;
    }
    const std::string NameStr = Name->getAsUnquotedString();

    PatFrag::ParamKind OpKind;
    if (isSpecificDef(*Ty, "gi_imm"))
      OpKind = PatFrag::PK_Imm;
    else if (isSpecificDef(*Ty, "root"))
      OpKind = PatFrag::PK_Root;
    else if (isa<UnsetInit>(Ty) ||
             isSpecificDef(*Ty, "gi_mo")) // no type = gi_mo.
      OpKind = PatFrag::PK_MachineOperand;
    else {
      PrintError(
          DiagLoc,
          '\'' + NameStr +
              "' operand type was expected to be 'root', 'gi_imm' or 'gi_mo'");
      return false;
    }

    if (!ParseAction(NameStr, (unsigned)OpKind))
      return false;
  }

  return true;
}

const PatFrag *PatternParser::parsePatFrag(const Record *Def) {
  // Cache already parsed PatFrags to avoid doing extra work.
  static DenseMap<const Record *, std::unique_ptr<PatFrag>> ParsedPatFrags;

  auto It = ParsedPatFrags.find(Def);
  if (It != ParsedPatFrags.end()) {
    SeenPatFrags.insert(It->second.get());
    return It->second.get();
  }

  std::unique_ptr<PatFrag> NewPatFrag = parsePatFragImpl(Def);
  if (!NewPatFrag) {
    PrintError(Def, "Could not parse " + PatFrag::ClassName + " '" +
                        Def->getName() + "'");
    // Put a nullptr in the map so we don't attempt parsing this again.
    ParsedPatFrags[Def] = nullptr;
    return nullptr;
  }

  const auto *Res = NewPatFrag.get();
  ParsedPatFrags[Def] = std::move(NewPatFrag);
  SeenPatFrags.insert(Res);
  return Res;
}
