[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