From c0ce4d9ba0b26b6b56024dd93bb12df40a211bd3 Mon Sep 17 00:00:00 2001 From: wangpc Date: Tue, 14 Nov 2023 10:48:27 +0800 Subject: [PATCH] [TableGen] Integrate TableGen-based macro fusion `Fusion` is inherited from `SubtargetFuture` now. Each definition of `Fusion` will define a `SubtargetFuture` accordingly. Two methods `enableMacroFusion` and `getMacroFusions` are added to `TargetSubtargetInfo`. `enableMacroFusion` indicates whether macro fusion shoule be enabled and `getMacroFusions` returns a list of `MacroFusionPredTy` that will be evaluated by MacroFusionMution. `enableMacroFusion` and `getMacroFusions` will be auto-generated if the target has `Fusion` definitions. --- .../llvm/CodeGen/TargetSubtargetInfo.h | 7 ++ llvm/include/llvm/Target/Target.td | 92 +++++++++---------- llvm/include/llvm/Target/TargetSchedule.td | 37 ++++---- llvm/test/TableGen/MacroFusion.td | 22 ++++- llvm/utils/TableGen/CodeGenTarget.cpp | 1 + llvm/utils/TableGen/CodeGenTarget.h | 6 ++ llvm/utils/TableGen/SubtargetEmitter.cpp | 42 +++++++++ 7 files changed, 143 insertions(+), 64 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h index 55ef95c2854319..84b89336db58a5 100644 --- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h +++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MacroFusion.h" #include "llvm/CodeGen/PBQPRAConstraint.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/IR/GlobalValue.h" @@ -323,6 +324,12 @@ class TargetSubtargetInfo : public MCSubtargetInfo { /// helps removing redundant copies generated by register allocator when /// handling complex eviction chains. virtual bool enableSpillageCopyElimination() const { return false; } + + /// Enable macro fusion for this subtarget. + virtual bool enableMacroFusion() const { return false; } + + /// Get the list of MacroFusion predicates. + virtual std::vector getMacroFusions() const { return {}; }; }; } // end namespace llvm diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index 3b1d2f45267e9e..0d97a47190b196 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -459,6 +459,52 @@ class DwarfRegAlias { Register DwarfAlias = reg; } +//===----------------------------------------------------------------------===// +// SubtargetFeature - A characteristic of the chip set. +// +class SubtargetFeature i = []> { + // Name - Feature name. Used by command line (-mattr=) to determine the + // appropriate target chip. + // + string Name = n; + + // FieldName - Field in XXXSubtarget to be set by feature. + // + string FieldName = f; + + // Value - Value the XXXSubtarget field to be set to by feature. + // + // A value of "true" or "false" implies the field is a bool. Otherwise, + // it is assumed to be an integer. the integer value may be the name of an + // enum constant. If multiple features use the same integer field, the + // field will be set to the maximum value of all enabled features that + // share the field. + // + string Value = v; + + // Desc - Feature description. Used by command line (-mattr=) to display help + // information. + // + string Desc = d; + + // Implies - Features that this feature implies are present. If one of those + // features isn't set, then this one shouldn't be set either. + // + list Implies = i; +} + +/// Specifies a Subtarget feature that this instruction is deprecated on. +class Deprecated { + SubtargetFeature DeprecatedFeatureMask = dep; +} + +/// A custom predicate used to determine if an instruction is +/// deprecated or not. +class ComplexDeprecationPredicate { + string ComplexDeprecationPredicate = dep; +} + //===----------------------------------------------------------------------===// // Pull in the common support for MCPredicate (portable scheduling predicates). // @@ -1680,52 +1726,6 @@ class Target { int AllowRegisterRenaming = 0; } -//===----------------------------------------------------------------------===// -// SubtargetFeature - A characteristic of the chip set. -// -class SubtargetFeature i = []> { - // Name - Feature name. Used by command line (-mattr=) to determine the - // appropriate target chip. - // - string Name = n; - - // FieldName - Field in XXXSubtarget to be set by feature. - // - string FieldName = f; - - // Value - Value the XXXSubtarget field to be set to by feature. - // - // A value of "true" or "false" implies the field is a bool. Otherwise, - // it is assumed to be an integer. the integer value may be the name of an - // enum constant. If multiple features use the same integer field, the - // field will be set to the maximum value of all enabled features that - // share the field. - // - string Value = v; - - // Desc - Feature description. Used by command line (-mattr=) to display help - // information. - // - string Desc = d; - - // Implies - Features that this feature implies are present. If one of those - // features isn't set, then this one shouldn't be set either. - // - list Implies = i; -} - -/// Specifies a Subtarget feature that this instruction is deprecated on. -class Deprecated { - SubtargetFeature DeprecatedFeatureMask = dep; -} - -/// A custom predicate used to determine if an instruction is -/// deprecated or not. -class ComplexDeprecationPredicate { - string ComplexDeprecationPredicate = dep; -} - //===----------------------------------------------------------------------===// // Processor chip sets - These values represent each of the chip sets supported // by the scheduler. Each Processor definition requires corresponding diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td index 2016d452afb6f3..032de728517827 100644 --- a/llvm/include/llvm/Target/TargetSchedule.td +++ b/llvm/include/llvm/Target/TargetSchedule.td @@ -658,7 +658,8 @@ def OneUse : OneUsePred; // return true; // } // ``` -class Fusion predicates> { +class Fusion predicates> + : SubtargetFeature { list Predicates = predicates; } @@ -679,21 +680,23 @@ class Fusion predicates> { // return true; // } // ``` -class SimpleFusion prolog = [], list epilog = []> - : Fusion, - WildcardTrue, - FirstFusionPredicateWithMCInstPredicate, - SecondFusionPredicateWithMCInstPredicate< - CheckAny<[ - CheckIsVRegOperand<0>, - CheckSameRegOperand<0, 1> - ]>>, - OneUse, - TieReg<0, 1>, - ], - epilog)>; + : Fusion, + WildcardTrue, + FirstFusionPredicateWithMCInstPredicate, + SecondFusionPredicateWithMCInstPredicate< + CheckAny<[ + CheckIsVRegOperand<0>, + CheckSameRegOperand<0, 1> + ]>>, + OneUse, + TieReg<0, 1>, + ], + epilog)>; diff --git a/llvm/test/TableGen/MacroFusion.td b/llvm/test/TableGen/MacroFusion.td index f984a142839c95..1ac8dd1e92e9ba 100644 --- a/llvm/test/TableGen/MacroFusion.td +++ b/llvm/test/TableGen/MacroFusion.td @@ -1,4 +1,5 @@ // RUN: llvm-tblgen -gen-macro-fusion-pred -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-PREDICATOR +// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-SUBTARGET include "llvm/Target/Target.td" @@ -33,7 +34,8 @@ let Namespace = "Test" in { def Inst0 : TestInst<0>; def Inst1 : TestInst<1>; -def TestFusion: SimpleFusion, +def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion", + CheckOpcode<[Inst0]>, CheckAll<[ CheckOpcode<[Inst1]>, CheckRegOperand<0, X0> @@ -95,3 +97,21 @@ def TestFusion: SimpleFusion, // CHECK-PREDICATOR-NEXT: } // end namespace llvm // CHECK-PREDICATOR-EMPTY: // CHECK-PREDICATOR-NEXT: #endif + +// Check that we have generated target subfeature. +// CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion + +// Check that we have generated `enableMacroFusion()` and `getMacroFusions()` function. +// CHECK-SUBTARGET: bool enableMacroFusion() const override; +// CHECK-SUBTARGET: std::vector getMacroFusions() const override; + +// CHECK-SUBTARGET: bool TestGenSubtargetInfo::enableMacroFusion() const { +// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) return true; +// CHECK-SUBTARGET-NEXT: return false; +// CHECK-SUBTARGET-NEXT: } + +// CHECK-SUBTARGET: std::vector TestGenSubtargetInfo::getMacroFusions() const { +// CHECK-SUBTARGET-NEXT: std::vector Fusions; +// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion); +// CHECK-SUBTARGET-NEXT: return Fusions; +// CHECK-SUBTARGET-NEXT: } diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index 53efa66f9dfc1b..37fa30349eea9f 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -291,6 +291,7 @@ CodeGenTarget::CodeGenTarget(RecordKeeper &records) if (Targets.size() != 1) PrintFatalError("Multiple subclasses of Target defined!"); TargetRec = Targets[0]; + MacroFusions = Records.getAllDerivedDefinitions("Fusion"); } CodeGenTarget::~CodeGenTarget() { diff --git a/llvm/utils/TableGen/CodeGenTarget.h b/llvm/utils/TableGen/CodeGenTarget.h index a2b559d53b19c2..d7388dceca37fe 100644 --- a/llvm/utils/TableGen/CodeGenTarget.h +++ b/llvm/utils/TableGen/CodeGenTarget.h @@ -64,6 +64,8 @@ class CodeGenTarget { mutable std::vector RegAltNameIndices; mutable SmallVector LegalValueTypes; CodeGenHwModes CGH; + std::vector MacroFusions; + void ReadRegAltNameIndices() const; void ReadInstructions() const; void ReadLegalValueTypes() const; @@ -149,6 +151,10 @@ class CodeGenTarget { const CodeGenHwModes &getHwModes() const { return CGH; } + bool hasMacroFusion() const { return !MacroFusions.empty(); } + + const std::vector getMacroFusions() const { return MacroFusions; } + private: DenseMap> & getInstructions() const { diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index f7a7172d61fc61..2da35a735aceb5 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -133,6 +133,8 @@ class SubtargetEmitter { void EmitMCInstrAnalysisPredicateFunctions(raw_ostream &OS); void EmitSchedModel(raw_ostream &OS); + void emitGetMacroFusions(const std::string &ClassName, raw_ostream &OS); + void emitEnableMacroFusion(const std::string &ClassName, raw_ostream &OS); void EmitHwModeCheck(const std::string &ClassName, raw_ostream &OS); void ParseFeaturesFunction(raw_ostream &OS); @@ -1786,6 +1788,39 @@ void SubtargetEmitter::EmitHwModeCheck(const std::string &ClassName, OS << " return 0;\n}\n"; } +void SubtargetEmitter::emitEnableMacroFusion(const std::string &ClassName, + raw_ostream &OS) { + if (!TGT.hasMacroFusion()) + return; + + OS << "bool " << ClassName << "::enableMacroFusion() const {\n"; + for (auto *Fusion : TGT.getMacroFusions()) + OS.indent(2) << "if (hasFeature(" << Target + << "::" << Fusion->getNameInitAsString() + << ")) return true;\n"; + + OS.indent(2) << "return false;\n"; + OS << "}\n"; +} + +void SubtargetEmitter::emitGetMacroFusions(const std::string &ClassName, + raw_ostream &OS) { + if (!TGT.hasMacroFusion()) + return; + + OS << "std::vector " << ClassName + << "::getMacroFusions() const {\n"; + OS.indent(2) << "std::vector Fusions;\n"; + for (auto *Fusion : TGT.getMacroFusions()) { + std::string Name = Fusion->getNameInitAsString(); + OS.indent(2) << "if (hasFeature(" << Target << "::" << Name + << ")) Fusions.push_back(llvm::is" << Name << ");\n"; + } + + OS.indent(2) << "return Fusions;\n"; + OS << "}\n"; +} + // Produces a subtarget specific function for parsing // the subtarget features string. void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { @@ -1987,6 +2022,11 @@ void SubtargetEmitter::run(raw_ostream &OS) { << " const;\n"; if (TGT.getHwModes().getNumModeIds() > 1) OS << " unsigned getHwMode() const override;\n"; + if (TGT.hasMacroFusion()) { + OS << " bool enableMacroFusion() const override;\n"; + OS << " std::vector getMacroFusions() const " + "override;\n"; + } STIPredicateExpander PE(Target); PE.setByRef(false); @@ -2044,6 +2084,8 @@ void SubtargetEmitter::run(raw_ostream &OS) { EmitSchedModelHelpers(ClassName, OS); EmitHwModeCheck(ClassName, OS); + emitEnableMacroFusion(ClassName, OS); + emitGetMacroFusions(ClassName, OS); OS << "} // end namespace llvm\n\n";