Skip to content

[TableGen] Integrate TableGen-based macro fusion #73115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -323,6 +324,9 @@ class TargetSubtargetInfo : public MCSubtargetInfo {
/// helps removing redundant copies generated by register allocator when
/// handling complex eviction chains.
virtual bool enableSpillageCopyElimination() const { return false; }

/// Get the list of MacroFusion predicates.
virtual std::vector<MacroFusionPredTy> getMacroFusions() const { return {}; };
};

} // end namespace llvm
Expand Down
92 changes: 46 additions & 46 deletions llvm/include/llvm/Target/Target.td
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,52 @@ class DwarfRegAlias<Register reg> {
Register DwarfAlias = reg;
}

//===----------------------------------------------------------------------===//
// SubtargetFeature - A characteristic of the chip set.
//
class SubtargetFeature<string n, string f, string v, string d,
list<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<SubtargetFeature> Implies = i;
}

/// Specifies a Subtarget feature that this instruction is deprecated on.
class Deprecated<SubtargetFeature dep> {
SubtargetFeature DeprecatedFeatureMask = dep;
}

/// A custom predicate used to determine if an instruction is
/// deprecated or not.
class ComplexDeprecationPredicate<string dep> {
string ComplexDeprecationPredicate = dep;
}

//===----------------------------------------------------------------------===//
// Pull in the common support for MCPredicate (portable scheduling predicates).
//
Expand Down Expand Up @@ -1680,52 +1726,6 @@ class Target {
int AllowRegisterRenaming = 0;
}

//===----------------------------------------------------------------------===//
// SubtargetFeature - A characteristic of the chip set.
//
class SubtargetFeature<string n, string f, string v, string d,
list<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<SubtargetFeature> Implies = i;
}

/// Specifies a Subtarget feature that this instruction is deprecated on.
class Deprecated<SubtargetFeature dep> {
SubtargetFeature DeprecatedFeatureMask = dep;
}

/// A custom predicate used to determine if an instruction is
/// deprecated or not.
class ComplexDeprecationPredicate<string dep> {
string ComplexDeprecationPredicate = dep;
}

//===----------------------------------------------------------------------===//
// Processor chip sets - These values represent each of the chip sets supported
// by the scheduler. Each Processor definition requires corresponding
Expand Down
37 changes: 20 additions & 17 deletions llvm/include/llvm/Target/TargetSchedule.td
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,8 @@ def OneUse : OneUsePred;
// return true;
// }
// ```
class Fusion<list<FusionPredicate> predicates> {
class Fusion<string name, string fieldName, string desc, list<FusionPredicate> predicates>
: SubtargetFeature<name, fieldName, "true", desc> {
list<FusionPredicate> Predicates = predicates;
}

Expand All @@ -679,21 +680,23 @@ class Fusion<list<FusionPredicate> predicates> {
// return true;
// }
// ```
class SimpleFusion<MCInstPredicate firstPred, MCInstPredicate secondPred,
class SimpleFusion<string name, string fieldName, string desc,
MCInstPredicate firstPred, MCInstPredicate secondPred,
list<FusionPredicate> prolog = [],
list<FusionPredicate> epilog = []>
: Fusion<!listconcat(
prolog,
[
SecondFusionPredicateWithMCInstPredicate<secondPred>,
WildcardTrue,
FirstFusionPredicateWithMCInstPredicate<firstPred>,
SecondFusionPredicateWithMCInstPredicate<
CheckAny<[
CheckIsVRegOperand<0>,
CheckSameRegOperand<0, 1>
]>>,
OneUse,
TieReg<0, 1>,
],
epilog)>;
: Fusion<name, fieldName, desc,
!listconcat(
prolog,
[
SecondFusionPredicateWithMCInstPredicate<secondPred>,
WildcardTrue,
FirstFusionPredicateWithMCInstPredicate<firstPred>,
SecondFusionPredicateWithMCInstPredicate<
CheckAny<[
CheckIsVRegOperand<0>,
CheckSameRegOperand<0, 1>
]>>,
OneUse,
TieReg<0, 1>,
],
epilog)>;
16 changes: 15 additions & 1 deletion llvm/test/TableGen/MacroFusion.td
Original file line number Diff line number Diff line change
@@ -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"

Expand Down Expand Up @@ -33,7 +34,8 @@ let Namespace = "Test" in {
def Inst0 : TestInst<0>;
def Inst1 : TestInst<1>;

def TestFusion: SimpleFusion<CheckOpcode<[Inst0]>,
def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion",
CheckOpcode<[Inst0]>,
CheckAll<[
CheckOpcode<[Inst1]>,
CheckRegOperand<0, X0>
Expand Down Expand Up @@ -95,3 +97,15 @@ def TestFusion: SimpleFusion<CheckOpcode<[Inst0]>,
// 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 `getMacroFusions()` function.
// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> getMacroFusions() const override;

// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> TestGenSubtargetInfo::getMacroFusions() const {
// CHECK-SUBTARGET-NEXT: std::vector<MacroFusionPredTy> Fusions;
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion);
// CHECK-SUBTARGET-NEXT: return Fusions;
// CHECK-SUBTARGET-NEXT: }
1 change: 1 addition & 0 deletions llvm/utils/TableGen/CodeGenTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
6 changes: 6 additions & 0 deletions llvm/utils/TableGen/CodeGenTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class CodeGenTarget {
mutable std::vector<Record*> RegAltNameIndices;
mutable SmallVector<ValueTypeByHwMode, 8> LegalValueTypes;
CodeGenHwModes CGH;
std::vector<Record *> MacroFusions;

void ReadRegAltNameIndices() const;
void ReadInstructions() const;
void ReadLegalValueTypes() const;
Expand Down Expand Up @@ -149,6 +151,10 @@ class CodeGenTarget {

const CodeGenHwModes &getHwModes() const { return CGH; }

bool hasMacroFusion() const { return !MacroFusions.empty(); }

const std::vector<Record *> getMacroFusions() const { return MacroFusions; }

private:
DenseMap<const Record*, std::unique_ptr<CodeGenInstruction>> &
getInstructions() const {
Expand Down
23 changes: 23 additions & 0 deletions llvm/utils/TableGen/SubtargetEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class SubtargetEmitter {
void EmitMCInstrAnalysisPredicateFunctions(raw_ostream &OS);

void EmitSchedModel(raw_ostream &OS);
void emitGetMacroFusions(const std::string &ClassName, raw_ostream &OS);
void EmitHwModeCheck(const std::string &ClassName, raw_ostream &OS);
void ParseFeaturesFunction(raw_ostream &OS);

Expand Down Expand Up @@ -1786,6 +1787,24 @@ void SubtargetEmitter::EmitHwModeCheck(const std::string &ClassName,
OS << " return 0;\n}\n";
}

void SubtargetEmitter::emitGetMacroFusions(const std::string &ClassName,
raw_ostream &OS) {
if (!TGT.hasMacroFusion())
return;

OS << "std::vector<MacroFusionPredTy> " << ClassName
<< "::getMacroFusions() const {\n";
OS.indent(2) << "std::vector<MacroFusionPredTy> 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) {
Expand Down Expand Up @@ -1987,6 +2006,9 @@ void SubtargetEmitter::run(raw_ostream &OS) {
<< " const;\n";
if (TGT.getHwModes().getNumModeIds() > 1)
OS << " unsigned getHwMode() const override;\n";
if (TGT.hasMacroFusion())
OS << " std::vector<MacroFusionPredTy> getMacroFusions() const "
"override;\n";

STIPredicateExpander PE(Target);
PE.setByRef(false);
Expand Down Expand Up @@ -2044,6 +2066,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {

EmitSchedModelHelpers(ClassName, OS);
EmitHwModeCheck(ClassName, OS);
emitGetMacroFusions(ClassName, OS);

OS << "} // end namespace llvm\n\n";

Expand Down