[llvm] [TableGen] Split GlobalISelCombinerEmitter into multiple files (PR #73325)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 28 00:52:36 PST 2023


================
@@ -0,0 +1,845 @@
+//===- Patterns.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 "Patterns.h"
+#include "../CodeGenInstruction.h"
+#include "CXXPredicates.h"
+#include "CodeExpander.h"
+#include "CodeExpansions.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+
+namespace llvm {
+namespace gi {
+
+//===- PatternType --------------------------------------------------------===//
+
+std::optional<PatternType> PatternType::get(ArrayRef<SMLoc> DiagLoc,
+                                            const Record *R, Twine DiagCtx) {
+  assert(R);
+  if (R->isSubClassOf("ValueType")) {
+    PatternType PT(PT_ValueType);
+    PT.Data.Def = R;
+    return PT;
+  }
+
+  if (R->isSubClassOf(TypeOfClassName)) {
+    auto RawOpName = R->getValueAsString("OpName");
+    if (!RawOpName.starts_with("$")) {
+      PrintError(DiagLoc, DiagCtx + ": invalid operand name format '" +
+                              RawOpName + "' in " + TypeOfClassName +
+                              ": expected '$' followed by an operand name");
+      return std::nullopt;
+    }
+
+    PatternType PT(PT_TypeOf);
+    PT.Data.Str = RawOpName.drop_front(1);
+    return PT;
+  }
+
+  PrintError(DiagLoc, DiagCtx + ": unknown type '" + R->getName() + "'");
+  return std::nullopt;
+}
+
+PatternType PatternType::getTypeOf(StringRef OpName) {
+  PatternType PT(PT_TypeOf);
+  PT.Data.Str = OpName;
+  return PT;
+}
+
+StringRef PatternType::getTypeOfOpName() const {
+  assert(isTypeOf());
+  return Data.Str;
+}
+
+const Record *PatternType::getLLTRecord() const {
+  assert(isLLT());
+  return Data.Def;
+}
+
+bool PatternType::operator==(const PatternType &Other) const {
+  if (Kind != Other.Kind)
+    return false;
+
+  switch (Kind) {
+  case PT_None:
+    return true;
+  case PT_ValueType:
+    return Data.Def == Other.Data.Def;
+  case PT_TypeOf:
+    return Data.Str == Other.Data.Str;
+  }
+
+  llvm_unreachable("Unknown Type Kind");
+}
+
+std::string PatternType::str() const {
+  switch (Kind) {
+  case PT_None:
+    return "";
+  case PT_ValueType:
+    return Data.Def->getName().str();
+  case PT_TypeOf:
+    return (TypeOfClassName + "<$" + getTypeOfOpName() + ">").str();
+  }
+
+  llvm_unreachable("Unknown type!");
+}
+
+//===- Pattern ------------------------------------------------------------===//
+
+void Pattern::dump() const { return print(dbgs()); }
+
+const char *Pattern::getKindName() const {
+  switch (Kind) {
+  case K_AnyOpcode:
+    return "AnyOpcodePattern";
+  case K_CXX:
+    return "CXXPattern";
+  case K_CodeGenInstruction:
+    return "CodeGenInstructionPattern";
+  case K_PatFrag:
+    return "PatFragPattern";
+  case K_Builtin:
+    return "BuiltinPattern";
+  }
+
+  llvm_unreachable("unknown pattern kind!");
+}
+
+void Pattern::printImpl(raw_ostream &OS, bool PrintName,
+                        function_ref<void()> ContentPrinter) const {
+  OS << "(" << getKindName() << " ";
+  if (PrintName)
+    OS << "name:" << getName() << " ";
+  ContentPrinter();
+  OS << ")";
+}
+
+//===- AnyOpcodePattern ---------------------------------------------------===//
+
+void AnyOpcodePattern::print(raw_ostream &OS, bool PrintName) const {
+  printImpl(OS, PrintName, [&OS, this]() {
+    OS << "["
+       << join(map_range(Insts,
+                         [](const auto *I) { return I->TheDef->getName(); }),
+               ", ")
+       << "]";
+  });
+}
+
+//===- CXXPattern ---------------------------------------------------------===//
+
+CXXPattern::CXXPattern(const StringInit &Code, StringRef Name)
+    : CXXPattern(Code.getAsUnquotedString(), Name) {}
+
+const CXXPredicateCode &
+CXXPattern::expandCode(const CodeExpansions &CE, ArrayRef<SMLoc> Locs,
+                       function_ref<void(raw_ostream &)> AddComment) const {
+  std::string Result;
+  raw_string_ostream OS(Result);
+
+  if (AddComment)
+    AddComment(OS);
+
+  CodeExpander Expander(RawCode, CE, Locs, /*ShowExpansions*/ false);
+  Expander.emit(OS);
+  if (IsApply)
+    return CXXPredicateCode::getApplyCode(std::move(Result));
+  return CXXPredicateCode::getMatchCode(std::move(Result));
+}
+
+void CXXPattern::print(raw_ostream &OS, bool PrintName) const {
+  printImpl(OS, PrintName, [&OS, this] {
+    OS << (IsApply ? "apply" : "match") << " code:\"";
+    printEscapedString(getRawCode(), OS);
+    OS << "\"";
+  });
+}
+
+//===- InstructionOperand -------------------------------------------------===//
+
+std::string InstructionOperand::describe() const {
+  if (!hasImmValue())
+    return "MachineOperand $" + getOperandName().str() + "";
+  std::string Str = "imm " + std::to_string(getImmValue());
+  if (isNamedImmediate())
+    Str += ":$" + getOperandName().str() + "";
+  return Str;
+}
+
+void InstructionOperand::print(raw_ostream &OS) const {
+  if (isDef())
+    OS << "<def>";
+
+  bool NeedsColon = true;
+  if (Type) {
+    if (hasImmValue())
+      OS << "(" << Type.str() << " " << getImmValue() << ")";
+    else
+      OS << Type.str();
+  } else if (hasImmValue())
+    OS << getImmValue();
+  else
+    NeedsColon = false;
+
+  if (isNamedOperand())
+    OS << (NeedsColon ? ":" : "") << "$" << getOperandName();
+}
+
+void InstructionOperand::dump() const { return print(dbgs()); }
+
+//===- InstructionPattern -------------------------------------------------===//
+
+bool InstructionPattern::diagnoseAllSpecialTypes(ArrayRef<SMLoc> Loc,
+                                                 Twine Msg) const {
+  bool HasDiag = false;
+  for (const auto &[Idx, Op] : enumerate(operands())) {
+    if (Op.getType().isSpecial()) {
+      PrintError(Loc, Msg);
+      PrintNote(Loc, "operand " + Twine(Idx) + " of '" + getName() +
+                         "' has type '" + Op.getType().str() + "'");
+      HasDiag = true;
+    }
+  }
+  return HasDiag;
+}
+
+void InstructionPattern::reportUnreachable(ArrayRef<SMLoc> Locs) const {
+  PrintError(Locs, "pattern '" + getName() + "' ('" + getInstName() +
+                       "') is unreachable from the pattern root!");
+}
+
+bool InstructionPattern::checkSemantics(ArrayRef<SMLoc> Loc) {
+  unsigned NumExpectedOperands = getNumInstOperands();
+
+  if (isVariadic()) {
+    if (Operands.size() < NumExpectedOperands) {
+      PrintError(Loc, +"'" + getInstName() + "' expected at least " +
+                          Twine(NumExpectedOperands) + " operands, got " +
+                          Twine(Operands.size()));
+      return false;
+    }
+  } else if (NumExpectedOperands != Operands.size()) {
+    PrintError(Loc, +"'" + getInstName() + "' expected " +
+                        Twine(NumExpectedOperands) + " operands, got " +
+                        Twine(Operands.size()));
+    return false;
+  }
+
+  unsigned OpIdx = 0;
+  unsigned NumDefs = getNumInstDefs();
+  for (auto &Op : Operands)
+    Op.setIsDef(OpIdx++ < NumDefs);
+
+  return true;
+}
+
+void InstructionPattern::print(raw_ostream &OS, bool PrintName) const {
+  printImpl(OS, PrintName, [&OS, this] {
+    OS << getInstName() << " operands:[";
+    StringRef Sep = "";
----------------
arsenm wrote:

Don't need the initializer 

https://github.com/llvm/llvm-project/pull/73325


More information about the llvm-commits mailing list