Skip to content

Commit c0ce4d9

Browse files
committed
[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.
1 parent 2642240 commit c0ce4d9

File tree

7 files changed

+143
-64
lines changed

7 files changed

+143
-64
lines changed

llvm/include/llvm/CodeGen/TargetSubtargetInfo.h

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/ADT/ArrayRef.h"
1717
#include "llvm/ADT/SmallVector.h"
1818
#include "llvm/ADT/StringRef.h"
19+
#include "llvm/CodeGen/MacroFusion.h"
1920
#include "llvm/CodeGen/PBQPRAConstraint.h"
2021
#include "llvm/CodeGen/SchedulerRegistry.h"
2122
#include "llvm/IR/GlobalValue.h"
@@ -323,6 +324,12 @@ class TargetSubtargetInfo : public MCSubtargetInfo {
323324
/// helps removing redundant copies generated by register allocator when
324325
/// handling complex eviction chains.
325326
virtual bool enableSpillageCopyElimination() const { return false; }
327+
328+
/// Enable macro fusion for this subtarget.
329+
virtual bool enableMacroFusion() const { return false; }
330+
331+
/// Get the list of MacroFusion predicates.
332+
virtual std::vector<MacroFusionPredTy> getMacroFusions() const { return {}; };
326333
};
327334

328335
} // end namespace llvm

llvm/include/llvm/Target/Target.td

+46-46
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,52 @@ class DwarfRegAlias<Register reg> {
459459
Register DwarfAlias = reg;
460460
}
461461

462+
//===----------------------------------------------------------------------===//
463+
// SubtargetFeature - A characteristic of the chip set.
464+
//
465+
class SubtargetFeature<string n, string f, string v, string d,
466+
list<SubtargetFeature> i = []> {
467+
// Name - Feature name. Used by command line (-mattr=) to determine the
468+
// appropriate target chip.
469+
//
470+
string Name = n;
471+
472+
// FieldName - Field in XXXSubtarget to be set by feature.
473+
//
474+
string FieldName = f;
475+
476+
// Value - Value the XXXSubtarget field to be set to by feature.
477+
//
478+
// A value of "true" or "false" implies the field is a bool. Otherwise,
479+
// it is assumed to be an integer. the integer value may be the name of an
480+
// enum constant. If multiple features use the same integer field, the
481+
// field will be set to the maximum value of all enabled features that
482+
// share the field.
483+
//
484+
string Value = v;
485+
486+
// Desc - Feature description. Used by command line (-mattr=) to display help
487+
// information.
488+
//
489+
string Desc = d;
490+
491+
// Implies - Features that this feature implies are present. If one of those
492+
// features isn't set, then this one shouldn't be set either.
493+
//
494+
list<SubtargetFeature> Implies = i;
495+
}
496+
497+
/// Specifies a Subtarget feature that this instruction is deprecated on.
498+
class Deprecated<SubtargetFeature dep> {
499+
SubtargetFeature DeprecatedFeatureMask = dep;
500+
}
501+
502+
/// A custom predicate used to determine if an instruction is
503+
/// deprecated or not.
504+
class ComplexDeprecationPredicate<string dep> {
505+
string ComplexDeprecationPredicate = dep;
506+
}
507+
462508
//===----------------------------------------------------------------------===//
463509
// Pull in the common support for MCPredicate (portable scheduling predicates).
464510
//
@@ -1680,52 +1726,6 @@ class Target {
16801726
int AllowRegisterRenaming = 0;
16811727
}
16821728

1683-
//===----------------------------------------------------------------------===//
1684-
// SubtargetFeature - A characteristic of the chip set.
1685-
//
1686-
class SubtargetFeature<string n, string f, string v, string d,
1687-
list<SubtargetFeature> i = []> {
1688-
// Name - Feature name. Used by command line (-mattr=) to determine the
1689-
// appropriate target chip.
1690-
//
1691-
string Name = n;
1692-
1693-
// FieldName - Field in XXXSubtarget to be set by feature.
1694-
//
1695-
string FieldName = f;
1696-
1697-
// Value - Value the XXXSubtarget field to be set to by feature.
1698-
//
1699-
// A value of "true" or "false" implies the field is a bool. Otherwise,
1700-
// it is assumed to be an integer. the integer value may be the name of an
1701-
// enum constant. If multiple features use the same integer field, the
1702-
// field will be set to the maximum value of all enabled features that
1703-
// share the field.
1704-
//
1705-
string Value = v;
1706-
1707-
// Desc - Feature description. Used by command line (-mattr=) to display help
1708-
// information.
1709-
//
1710-
string Desc = d;
1711-
1712-
// Implies - Features that this feature implies are present. If one of those
1713-
// features isn't set, then this one shouldn't be set either.
1714-
//
1715-
list<SubtargetFeature> Implies = i;
1716-
}
1717-
1718-
/// Specifies a Subtarget feature that this instruction is deprecated on.
1719-
class Deprecated<SubtargetFeature dep> {
1720-
SubtargetFeature DeprecatedFeatureMask = dep;
1721-
}
1722-
1723-
/// A custom predicate used to determine if an instruction is
1724-
/// deprecated or not.
1725-
class ComplexDeprecationPredicate<string dep> {
1726-
string ComplexDeprecationPredicate = dep;
1727-
}
1728-
17291729
//===----------------------------------------------------------------------===//
17301730
// Processor chip sets - These values represent each of the chip sets supported
17311731
// by the scheduler. Each Processor definition requires corresponding

llvm/include/llvm/Target/TargetSchedule.td

+20-17
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,8 @@ def OneUse : OneUsePred;
658658
// return true;
659659
// }
660660
// ```
661-
class Fusion<list<FusionPredicate> predicates> {
661+
class Fusion<string name, string fieldName, string desc, list<FusionPredicate> predicates>
662+
: SubtargetFeature<name, fieldName, "true", desc> {
662663
list<FusionPredicate> Predicates = predicates;
663664
}
664665

@@ -679,21 +680,23 @@ class Fusion<list<FusionPredicate> predicates> {
679680
// return true;
680681
// }
681682
// ```
682-
class SimpleFusion<MCInstPredicate firstPred, MCInstPredicate secondPred,
683+
class SimpleFusion<string name, string fieldName, string desc,
684+
MCInstPredicate firstPred, MCInstPredicate secondPred,
683685
list<FusionPredicate> prolog = [],
684686
list<FusionPredicate> epilog = []>
685-
: Fusion<!listconcat(
686-
prolog,
687-
[
688-
SecondFusionPredicateWithMCInstPredicate<secondPred>,
689-
WildcardTrue,
690-
FirstFusionPredicateWithMCInstPredicate<firstPred>,
691-
SecondFusionPredicateWithMCInstPredicate<
692-
CheckAny<[
693-
CheckIsVRegOperand<0>,
694-
CheckSameRegOperand<0, 1>
695-
]>>,
696-
OneUse,
697-
TieReg<0, 1>,
698-
],
699-
epilog)>;
687+
: Fusion<name, fieldName, desc,
688+
!listconcat(
689+
prolog,
690+
[
691+
SecondFusionPredicateWithMCInstPredicate<secondPred>,
692+
WildcardTrue,
693+
FirstFusionPredicateWithMCInstPredicate<firstPred>,
694+
SecondFusionPredicateWithMCInstPredicate<
695+
CheckAny<[
696+
CheckIsVRegOperand<0>,
697+
CheckSameRegOperand<0, 1>
698+
]>>,
699+
OneUse,
700+
TieReg<0, 1>,
701+
],
702+
epilog)>;

llvm/test/TableGen/MacroFusion.td

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: llvm-tblgen -gen-macro-fusion-pred -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-PREDICATOR
2+
// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s | FileCheck %s --check-prefix=CHECK-SUBTARGET
23

34
include "llvm/Target/Target.td"
45

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

36-
def TestFusion: SimpleFusion<CheckOpcode<[Inst0]>,
37+
def TestFusion: SimpleFusion<"test-fusion", "HasTestFusion", "Test Fusion",
38+
CheckOpcode<[Inst0]>,
3739
CheckAll<[
3840
CheckOpcode<[Inst1]>,
3941
CheckRegOperand<0, X0>
@@ -95,3 +97,21 @@ def TestFusion: SimpleFusion<CheckOpcode<[Inst0]>,
9597
// CHECK-PREDICATOR-NEXT: } // end namespace llvm
9698
// CHECK-PREDICATOR-EMPTY:
9799
// CHECK-PREDICATOR-NEXT: #endif
100+
101+
// Check that we have generated target subfeature.
102+
// CHECK-SUBTARGET: { "test-fusion", "Test Fusion", Test::TestFusion
103+
104+
// Check that we have generated `enableMacroFusion()` and `getMacroFusions()` function.
105+
// CHECK-SUBTARGET: bool enableMacroFusion() const override;
106+
// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> getMacroFusions() const override;
107+
108+
// CHECK-SUBTARGET: bool TestGenSubtargetInfo::enableMacroFusion() const {
109+
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) return true;
110+
// CHECK-SUBTARGET-NEXT: return false;
111+
// CHECK-SUBTARGET-NEXT: }
112+
113+
// CHECK-SUBTARGET: std::vector<MacroFusionPredTy> TestGenSubtargetInfo::getMacroFusions() const {
114+
// CHECK-SUBTARGET-NEXT: std::vector<MacroFusionPredTy> Fusions;
115+
// CHECK-SUBTARGET-NEXT: if (hasFeature(Test::TestFusion)) Fusions.push_back(llvm::isTestFusion);
116+
// CHECK-SUBTARGET-NEXT: return Fusions;
117+
// CHECK-SUBTARGET-NEXT: }

llvm/utils/TableGen/CodeGenTarget.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ CodeGenTarget::CodeGenTarget(RecordKeeper &records)
291291
if (Targets.size() != 1)
292292
PrintFatalError("Multiple subclasses of Target defined!");
293293
TargetRec = Targets[0];
294+
MacroFusions = Records.getAllDerivedDefinitions("Fusion");
294295
}
295296

296297
CodeGenTarget::~CodeGenTarget() {

llvm/utils/TableGen/CodeGenTarget.h

+6
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class CodeGenTarget {
6464
mutable std::vector<Record*> RegAltNameIndices;
6565
mutable SmallVector<ValueTypeByHwMode, 8> LegalValueTypes;
6666
CodeGenHwModes CGH;
67+
std::vector<Record *> MacroFusions;
68+
6769
void ReadRegAltNameIndices() const;
6870
void ReadInstructions() const;
6971
void ReadLegalValueTypes() const;
@@ -149,6 +151,10 @@ class CodeGenTarget {
149151

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

154+
bool hasMacroFusion() const { return !MacroFusions.empty(); }
155+
156+
const std::vector<Record *> getMacroFusions() const { return MacroFusions; }
157+
152158
private:
153159
DenseMap<const Record*, std::unique_ptr<CodeGenInstruction>> &
154160
getInstructions() const {

llvm/utils/TableGen/SubtargetEmitter.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class SubtargetEmitter {
133133
void EmitMCInstrAnalysisPredicateFunctions(raw_ostream &OS);
134134

135135
void EmitSchedModel(raw_ostream &OS);
136+
void emitGetMacroFusions(const std::string &ClassName, raw_ostream &OS);
137+
void emitEnableMacroFusion(const std::string &ClassName, raw_ostream &OS);
136138
void EmitHwModeCheck(const std::string &ClassName, raw_ostream &OS);
137139
void ParseFeaturesFunction(raw_ostream &OS);
138140

@@ -1786,6 +1788,39 @@ void SubtargetEmitter::EmitHwModeCheck(const std::string &ClassName,
17861788
OS << " return 0;\n}\n";
17871789
}
17881790

1791+
void SubtargetEmitter::emitEnableMacroFusion(const std::string &ClassName,
1792+
raw_ostream &OS) {
1793+
if (!TGT.hasMacroFusion())
1794+
return;
1795+
1796+
OS << "bool " << ClassName << "::enableMacroFusion() const {\n";
1797+
for (auto *Fusion : TGT.getMacroFusions())
1798+
OS.indent(2) << "if (hasFeature(" << Target
1799+
<< "::" << Fusion->getNameInitAsString()
1800+
<< ")) return true;\n";
1801+
1802+
OS.indent(2) << "return false;\n";
1803+
OS << "}\n";
1804+
}
1805+
1806+
void SubtargetEmitter::emitGetMacroFusions(const std::string &ClassName,
1807+
raw_ostream &OS) {
1808+
if (!TGT.hasMacroFusion())
1809+
return;
1810+
1811+
OS << "std::vector<MacroFusionPredTy> " << ClassName
1812+
<< "::getMacroFusions() const {\n";
1813+
OS.indent(2) << "std::vector<MacroFusionPredTy> Fusions;\n";
1814+
for (auto *Fusion : TGT.getMacroFusions()) {
1815+
std::string Name = Fusion->getNameInitAsString();
1816+
OS.indent(2) << "if (hasFeature(" << Target << "::" << Name
1817+
<< ")) Fusions.push_back(llvm::is" << Name << ");\n";
1818+
}
1819+
1820+
OS.indent(2) << "return Fusions;\n";
1821+
OS << "}\n";
1822+
}
1823+
17891824
// Produces a subtarget specific function for parsing
17901825
// the subtarget features string.
17911826
void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
@@ -1987,6 +2022,11 @@ void SubtargetEmitter::run(raw_ostream &OS) {
19872022
<< " const;\n";
19882023
if (TGT.getHwModes().getNumModeIds() > 1)
19892024
OS << " unsigned getHwMode() const override;\n";
2025+
if (TGT.hasMacroFusion()) {
2026+
OS << " bool enableMacroFusion() const override;\n";
2027+
OS << " std::vector<MacroFusionPredTy> getMacroFusions() const "
2028+
"override;\n";
2029+
}
19902030

19912031
STIPredicateExpander PE(Target);
19922032
PE.setByRef(false);
@@ -2044,6 +2084,8 @@ void SubtargetEmitter::run(raw_ostream &OS) {
20442084

20452085
EmitSchedModelHelpers(ClassName, OS);
20462086
EmitHwModeCheck(ClassName, OS);
2087+
emitEnableMacroFusion(ClassName, OS);
2088+
emitGetMacroFusions(ClassName, OS);
20472089

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

0 commit comments

Comments
 (0)