[llvm] [TableGen] Add a backend to generate MacroFusion predicators (PR #72222)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 14 00:37:49 PST 2023
================
@@ -0,0 +1,177 @@
+//===--- MacroFusionPredicatorEmitter.cpp - Generator for MacroFusion ----===//
+//
+// 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
+//
+// MacroFusionPredicatorEmitter implements a TableGen-driven predicators
+// generator for MacroFusion.
+//
+//===---------------------------------------------------------------------===//
+
+#include "CodeGenTarget.h"
+#include "PredicateExpander.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <set>
+#include <vector>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "macro-fusion-predicator"
+
+namespace {
+class MacroFusionPredicatorEmitter {
+ RecordKeeper &Records;
+ CodeGenTarget Target;
+
+ void emitMacroFusionDecl(std::vector<Record *> MacroFusions,
+ PredicateExpander &PE, raw_ostream &OS);
+ void emitMacroFusionImpl(std::vector<Record *> MacroFusions,
+ PredicateExpander &PE, raw_ostream &OS);
+ void emitFirstPredicate(Record *FirstPredicate, PredicateExpander &PE,
+ raw_ostream &OS);
+ void emitSecondPredicate(Record *SecondPredicate, PredicateExpander &PE,
+ raw_ostream &OS);
+ void emitPrologAndEpilog(std::vector<Record *> Predicates,
+ PredicateExpander &PE, raw_ostream &OS);
+
+public:
+ MacroFusionPredicatorEmitter(RecordKeeper &R) : Records(R), Target(R) {}
+
+ void run(raw_ostream &OS);
+};
+} // End anonymous namespace.
+
+void MacroFusionPredicatorEmitter::emitMacroFusionDecl(
+ std::vector<Record *> MacroFusions, PredicateExpander &PE,
+ raw_ostream &OS) {
+ OS << "#ifdef GET_" << Target.getName() << "_MACRO_FUSION_PRED_DECL\n\n";
+
+ for (Record *MacroFusion : MacroFusions) {
+ OS << "bool is" << MacroFusion->getName() << "(const TargetInstrInfo &, "
+ << "const TargetSubtargetInfo &, "
+ << "const MachineInstr *, "
+ << "const MachineInstr &);\n";
+ }
+
+ OS << "\n#endif\n";
+ OS << "#undef GET_" << Target.getName() << "_MACRO_FUSION_PRED_DECL\n";
+}
+
+void MacroFusionPredicatorEmitter::emitMacroFusionImpl(
+ std::vector<Record *> MacroFusions, PredicateExpander &PE,
+ raw_ostream &OS) {
+ OS << "#ifdef GET_" << Target.getName() << "_MACRO_FUSION_PRED_IMPL\n\n";
+
+ for (Record *MacroFusion : MacroFusions) {
+ Record *First = MacroFusion->getValueAsDef("First");
+ Record *Second = MacroFusion->getValueAsDef("Second");
+ std::vector<Record *> Prolog = MacroFusion->getValueAsListOfDefs("Prolog");
+ std::vector<Record *> Epilog = MacroFusion->getValueAsListOfDefs("Epilog");
+
+ OS << "bool is" << MacroFusion->getName() << "(\n";
+ OS.indent(5) << "const TargetInstrInfo &TII,\n";
+ OS.indent(5) << "const TargetSubtargetInfo &STI,\n";
+ OS.indent(5) << "const MachineInstr *FirstMI,\n";
+ OS.indent(5) << "const MachineInstr &SecondMI) {\n";
+ OS.indent(2) << "auto &MRI = SecondMI.getMF()->getRegInfo();\n";
+
+ emitFirstPredicate(First, PE, OS);
+ emitSecondPredicate(Second, PE, OS);
+
+ if (!Prolog.empty())
+ emitPrologAndEpilog(Prolog, PE, OS);
+
+ OS.indent(2) << "if(!matchFirst(FirstMI))\n";
+ OS.indent(2) << " return false;\n";
+ OS.indent(2) << "if(!matchSecond(&SecondMI))\n";
+ OS.indent(2) << " return false;\n";
+
+ if (!Epilog.empty())
+ emitPrologAndEpilog(Epilog, PE, OS);
+
+ OS.indent(2) << "return true;\n";
+ OS << "}\n";
+ }
+
+ OS << "\n#endif\n";
+ OS << "#undef GET_" << Target.getName() << "_MACRO_FUSION_PRED_IMPL\n\n";
+}
+
+void MacroFusionPredicatorEmitter::emitFirstPredicate(Record *FirstPredicate,
+ PredicateExpander &PE,
+ raw_ostream &OS) {
+
+ OS.indent(2) << "auto matchFirst = [&](const MachineInstr* MI) {\n";
+ OS.indent(4) << "return ";
+ PE.expandPredicate(OS, FirstPredicate);
+ OS << ";\n";
+ OS.indent(2) << "};\n";
+}
+
+void MacroFusionPredicatorEmitter::emitSecondPredicate(Record *SecondPredicate,
+ PredicateExpander &PE,
+ raw_ostream &OS) {
+ OS.indent(2) << "auto matchSecond = [&](const MachineInstr* MI) {\n";
----------------
topperc wrote:
`const MachineInstr *MI`
https://github.com/llvm/llvm-project/pull/72222
More information about the llvm-commits
mailing list