mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 23:29:51 +00:00
[llvm-exegesis][NFC] Add a way to declare the default counter binding for unbound CPUs for a target.
Summary: This simplifies the code and moves everything to tablegen for consistency. This also prepares the ground for adding issue counters. Reviewers: gchatelet, john.brawn, jsji Subscribers: nemanjai, mgorny, javed.absar, kbarton, tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D54297 llvm-svn: 346489
This commit is contained in:
parent
8e91b0faf1
commit
21390a9b77
@ -44,3 +44,7 @@ class PfmCountersBinding<string cpu_name, ProcPfmCounters counters> {
|
||||
string CpuName = cpu_name;
|
||||
ProcPfmCounters Counters = counters;
|
||||
}
|
||||
|
||||
// Declares the default binding for unbound CPUs for the target.
|
||||
class PfmCountersDefaultBinding<ProcPfmCounters counters>
|
||||
: PfmCountersBinding<"", counters> {}
|
||||
|
@ -626,3 +626,9 @@ def AArch64 : Target {
|
||||
let AssemblyWriters = [GenericAsmWriter, AppleAsmWriter];
|
||||
let AllowRegisterRenaming = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pfm Counters
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "AArch64PfmCounters.td"
|
||||
|
19
lib/Target/AArch64/AArch64PfmCounters.td
Normal file
19
lib/Target/AArch64/AArch64PfmCounters.td
Normal file
@ -0,0 +1,19 @@
|
||||
//===-- AArch64PfmCounters.td - AArch64 Hardware Counters --*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This describes the available hardware counters for AArch64.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CpuCyclesPfmCounter : PfmCounter<"CPU_CYCLES">;
|
||||
|
||||
def DefaultPfmCounters : ProcPfmCounters {
|
||||
let CycleCounter = CpuCyclesPfmCounter;
|
||||
}
|
||||
def : PfmCountersDefaultBinding<DefaultPfmCounters>;
|
@ -15,6 +15,7 @@ tablegen(LLVM AArch64GenRegisterBank.inc -gen-register-bank)
|
||||
tablegen(LLVM AArch64GenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget)
|
||||
tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables)
|
||||
tablegen(LLVM AArch64GenExegesis.inc -gen-exegesis)
|
||||
|
||||
add_public_tablegen_target(AArch64CommonTableGen)
|
||||
|
||||
|
@ -10,6 +10,7 @@ tablegen(LLVM PPCGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM PPCGenMCCodeEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM PPCGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM PPCGenSubtargetInfo.inc -gen-subtarget)
|
||||
tablegen(LLVM PPCGenExegesis.inc -gen-exegesis)
|
||||
|
||||
add_public_tablegen_target(PowerPCCommonTableGen)
|
||||
|
||||
|
@ -305,11 +305,11 @@ def : Processor<"generic", G3Itineraries, [Directive32, FeatureHardFloat,
|
||||
FeatureMFTB]>;
|
||||
def : ProcessorModel<"440", PPC440Model, [Directive440, FeatureISEL,
|
||||
FeatureFRES, FeatureFRSQRTE,
|
||||
FeatureICBT, FeatureBookE,
|
||||
FeatureICBT, FeatureBookE,
|
||||
FeatureMSYNC, FeatureMFTB]>;
|
||||
def : ProcessorModel<"450", PPC440Model, [Directive440, FeatureISEL,
|
||||
FeatureFRES, FeatureFRSQRTE,
|
||||
FeatureICBT, FeatureBookE,
|
||||
FeatureICBT, FeatureBookE,
|
||||
FeatureMSYNC, FeatureMFTB]>;
|
||||
def : Processor<"601", G3Itineraries, [Directive601, FeatureFPU]>;
|
||||
def : Processor<"602", G3Itineraries, [Directive602, FeatureFPU,
|
||||
@ -348,7 +348,7 @@ def : Processor<"7450", G4PlusItineraries, [Directive7400, FeatureAltivec,
|
||||
FeatureFRES, FeatureFRSQRTE,
|
||||
FeatureMFTB]>;
|
||||
def : Processor<"g4+", G4PlusItineraries, [Directive7400, FeatureAltivec,
|
||||
FeatureFRES, FeatureFRSQRTE,
|
||||
FeatureFRES, FeatureFRSQRTE,
|
||||
FeatureMFTB]>;
|
||||
|
||||
def : ProcessorModel<"970", G5Model,
|
||||
@ -369,11 +369,11 @@ def : ProcessorModel<"e500", PPCE500Model,
|
||||
FeatureISEL, FeatureMFTB]>;
|
||||
def : ProcessorModel<"e500mc", PPCE500mcModel,
|
||||
[DirectiveE500mc,
|
||||
FeatureSTFIWX, FeatureICBT, FeatureBookE,
|
||||
FeatureSTFIWX, FeatureICBT, FeatureBookE,
|
||||
FeatureISEL, FeatureMFTB]>;
|
||||
def : ProcessorModel<"e5500", PPCE5500Model,
|
||||
[DirectiveE5500, FeatureMFOCRF, Feature64Bit,
|
||||
FeatureSTFIWX, FeatureICBT, FeatureBookE,
|
||||
FeatureSTFIWX, FeatureICBT, FeatureBookE,
|
||||
FeatureISEL, FeatureMFTB]>;
|
||||
def : ProcessorModel<"a2", PPCA2Model,
|
||||
[DirectiveA2, FeatureICBT, FeatureBookE, FeatureMFOCRF,
|
||||
@ -428,7 +428,7 @@ def : ProcessorModel<"pwr6x", G5Model,
|
||||
FeatureMFTB, DeprecatedDST]>;
|
||||
def : ProcessorModel<"pwr7", P7Model, ProcessorFeatures.Power7FeatureList>;
|
||||
def : ProcessorModel<"pwr8", P8Model, ProcessorFeatures.Power8FeatureList>;
|
||||
def : ProcessorModel<"pwr9", P9Model, ProcessorFeatures.Power9FeatureList>;
|
||||
def : ProcessorModel<"pwr9", P9Model, ProcessorFeatures.Power9FeatureList>;
|
||||
def : Processor<"ppc", G3Itineraries, [Directive32, FeatureHardFloat,
|
||||
FeatureMFTB]>;
|
||||
def : Processor<"ppc32", G3Itineraries, [Directive32, FeatureHardFloat,
|
||||
@ -478,3 +478,9 @@ def PPC : Target {
|
||||
let AssemblyParserVariants = [PPCAsmParserVariant];
|
||||
let AllowRegisterRenaming = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pfm Counters
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "PPCPfmCounters.td"
|
||||
|
19
lib/Target/PowerPC/PPCPfmCounters.td
Normal file
19
lib/Target/PowerPC/PPCPfmCounters.td
Normal file
@ -0,0 +1,19 @@
|
||||
//===-- PPCPfmCounters.td - PPC Hardware Counters ----------*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This describes the available hardware counters for PPC.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CpuCyclesPfmCounter : PfmCounter<"CYCLES">;
|
||||
|
||||
def DefaultPfmCounters : ProcPfmCounters {
|
||||
let CycleCounter = CpuCyclesPfmCounter;
|
||||
}
|
||||
def : PfmCountersDefaultBinding<DefaultPfmCounters>;
|
@ -14,6 +14,10 @@
|
||||
def UnhaltedCoreCyclesPfmCounter : PfmCounter<"unhalted_core_cycles">;
|
||||
def UopsIssuedPfmCounter : PfmCounter<"uops_issued:any">;
|
||||
|
||||
// No default counters on X86.
|
||||
def DefaultPfmCounters : ProcPfmCounters {}
|
||||
def : PfmCountersDefaultBinding<DefaultPfmCounters>;
|
||||
|
||||
def SandyBridgePfmCounters : ProcPfmCounters {
|
||||
let CycleCounter = UnhaltedCoreCyclesPfmCounter;
|
||||
let UopsCounter = UopsIssuedPfmCounter;
|
||||
|
@ -14,22 +14,6 @@
|
||||
namespace llvm {
|
||||
namespace exegesis {
|
||||
|
||||
namespace {
|
||||
|
||||
class AArch64LatencyBenchmarkRunner : public LatencyBenchmarkRunner {
|
||||
public:
|
||||
AArch64LatencyBenchmarkRunner(const LLVMState &State)
|
||||
: LatencyBenchmarkRunner(State) {}
|
||||
|
||||
private:
|
||||
const char *getCounterName() const override {
|
||||
// All AArch64 subtargets have CPU_CYCLES as the cycle counter name
|
||||
return "CPU_CYCLES";
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
|
||||
switch (RegBitWidth) {
|
||||
case 32:
|
||||
@ -50,11 +34,13 @@ static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
|
||||
.addImm(Value.getZExtValue());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
#include "AArch64GenExegesis.inc"
|
||||
|
||||
namespace {
|
||||
|
||||
class ExegesisAArch64Target : public ExegesisTarget {
|
||||
public:
|
||||
ExegesisAArch64Target() : ExegesisTarget({}) {}
|
||||
ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {}
|
||||
|
||||
private:
|
||||
std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
|
||||
@ -76,11 +62,6 @@ private:
|
||||
// Function return is a pseudo-instruction that needs to be expanded
|
||||
PM.add(llvm::createAArch64ExpandPseudoPass());
|
||||
}
|
||||
|
||||
std::unique_ptr<BenchmarkRunner>
|
||||
createLatencyBenchmarkRunner(const LLVMState &State) const override {
|
||||
return llvm::make_unique<AArch64LatencyBenchmarkRunner>(State);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -166,13 +166,6 @@ LatencySnippetGenerator::generateCodeTemplates(const Instruction &Instr) const {
|
||||
return std::move(Results);
|
||||
}
|
||||
|
||||
const char *LatencyBenchmarkRunner::getCounterName() const {
|
||||
const char *CounterName = State.getPfmCounters().CycleCounter;
|
||||
if (!CounterName)
|
||||
llvm::report_fatal_error("sched model does not define a cycle counter");
|
||||
return CounterName;
|
||||
}
|
||||
|
||||
LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
|
||||
|
||||
llvm::Expected<std::vector<BenchmarkMeasure>>
|
||||
@ -182,9 +175,9 @@ LatencyBenchmarkRunner::runMeasurements(
|
||||
// measure several times and take the minimum value.
|
||||
constexpr const int NumMeasurements = 30;
|
||||
int64_t MinValue = std::numeric_limits<int64_t>::max();
|
||||
const char *CounterName = getCounterName();
|
||||
const char *CounterName = State.getPfmCounters().CycleCounter;
|
||||
if (!CounterName)
|
||||
llvm::report_fatal_error("could not determine cycle counter name");
|
||||
llvm::report_fatal_error("sched model does not define a cycle counter");
|
||||
for (size_t I = 0; I < NumMeasurements; ++I) {
|
||||
auto ExpectedCounterValue = Executor.runAndMeasure(CounterName);
|
||||
if (!ExpectedCounterValue)
|
||||
|
@ -40,8 +40,6 @@ public:
|
||||
private:
|
||||
llvm::Expected<std::vector<BenchmarkMeasure>>
|
||||
runMeasurements(const FunctionExecutor &Executor) const override;
|
||||
|
||||
virtual const char *getCounterName() const;
|
||||
};
|
||||
} // namespace exegesis
|
||||
} // namespace llvm
|
||||
|
@ -15,24 +15,12 @@
|
||||
namespace llvm {
|
||||
namespace exegesis {
|
||||
|
||||
namespace {
|
||||
class PowerPCLatencyBenchmarkRunner : public LatencyBenchmarkRunner {
|
||||
public:
|
||||
PowerPCLatencyBenchmarkRunner(const LLVMState &State)
|
||||
: LatencyBenchmarkRunner(State) {}
|
||||
|
||||
private:
|
||||
const char *getCounterName() const override {
|
||||
// All PowerPC subtargets have CYCLES as the cycle counter name
|
||||
return "CYCLES";
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
#include "PPCGenExegesis.inc"
|
||||
|
||||
namespace {
|
||||
class ExegesisPowerPCTarget : public ExegesisTarget {
|
||||
public:
|
||||
ExegesisPowerPCTarget() : ExegesisTarget({}) {}
|
||||
ExegesisPowerPCTarget() : ExegesisTarget(PPCCpuPfmCounters) {}
|
||||
|
||||
private:
|
||||
std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
|
||||
@ -41,10 +29,6 @@ private:
|
||||
bool matchesArch(llvm::Triple::ArchType Arch) const override {
|
||||
return Arch == llvm::Triple::ppc64le;
|
||||
}
|
||||
std::unique_ptr<BenchmarkRunner>
|
||||
createLatencyBenchmarkRunner(const LLVMState &State) const override {
|
||||
return llvm::make_unique<PowerPCLatencyBenchmarkRunner>(State);
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
@ -87,7 +87,8 @@ ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const {
|
||||
|
||||
static_assert(std::is_pod<PfmCountersInfo>::value,
|
||||
"We shouldn't have dynamic initialization here");
|
||||
const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, 0u};
|
||||
const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr,
|
||||
0u};
|
||||
|
||||
const PfmCountersInfo &
|
||||
ExegesisTarget::getPfmCounters(llvm::StringRef CpuName) const {
|
||||
@ -103,7 +104,13 @@ ExegesisTarget::getPfmCounters(llvm::StringRef CpuName) const {
|
||||
std::lower_bound(CpuPfmCounters.begin(), CpuPfmCounters.end(), CpuName);
|
||||
if (Found == CpuPfmCounters.end() ||
|
||||
llvm::StringRef(Found->CpuName) != CpuName) {
|
||||
return PfmCountersInfo::Default;
|
||||
// Use the default.
|
||||
if (CpuPfmCounters.begin() != CpuPfmCounters.end() &&
|
||||
CpuPfmCounters.begin()->CpuName[0] == '\0') {
|
||||
Found = CpuPfmCounters.begin(); // The target specifies a default.
|
||||
} else {
|
||||
return PfmCountersInfo::Default; // No default for the target.
|
||||
}
|
||||
}
|
||||
assert(Found->PCI && "Missing counters");
|
||||
return *Found->PCI;
|
||||
|
@ -59,6 +59,12 @@ TEST_F(AArch64TargetTest, SetRegToConstant) {
|
||||
EXPECT_THAT(Insts, Not(IsEmpty()));
|
||||
}
|
||||
|
||||
TEST_F(AArch64TargetTest, DefaultPfmCounters) {
|
||||
EXPECT_EQ(ExegesisTarget_->getPfmCounters("").CycleCounter, "CPU_CYCLES");
|
||||
EXPECT_EQ(ExegesisTarget_->getPfmCounters("unknown_cpu").CycleCounter,
|
||||
"CPU_CYCLES");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace exegesis
|
||||
} // namespace llvm
|
||||
|
@ -59,6 +59,12 @@ TEST_F(PowerPCTargetTest, SetRegToConstant) {
|
||||
EXPECT_THAT(Insts, Not(IsEmpty()));
|
||||
}
|
||||
|
||||
TEST_F(PowerPCTargetTest, DefaultPfmCounters) {
|
||||
EXPECT_EQ(ExegesisTarget_->getPfmCounters("").CycleCounter, "CYCLES");
|
||||
EXPECT_EQ(ExegesisTarget_->getPfmCounters("unknown_cpu").CycleCounter,
|
||||
"CYCLES");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace exegesis
|
||||
} // namespace llvm
|
||||
|
@ -11,6 +11,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -114,10 +115,6 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,
|
||||
const size_t NumIssueCounters =
|
||||
Def.getValueAsListOfDefs("IssueCounters").size();
|
||||
|
||||
// This is the default, do not emit.
|
||||
if (CycleCounter.empty() && UopsCounter.empty() && NumIssueCounters == 0)
|
||||
return;
|
||||
|
||||
OS << "\nstatic const PfmCountersInfo " << Target << Def.getName()
|
||||
<< " = {\n";
|
||||
|
||||
@ -157,28 +154,35 @@ void ExegesisEmitter::emitPfmCounters(raw_ostream &OS) const {
|
||||
// Emit the IssueCounters table.
|
||||
const auto PfmCounterDefs =
|
||||
Records.getAllDerivedDefinitions("ProcPfmCounters");
|
||||
OS << "static const PfmCountersInfo::IssueCounter " << Target
|
||||
<< "PfmIssueCounters[] = {\n";
|
||||
for (const Record *Def : PfmCounterDefs) {
|
||||
for (const Record *ICDef : Def->getValueAsListOfDefs("IssueCounters"))
|
||||
OS << " { " << Target << "PfmCounterNames["
|
||||
<< getPfmCounterId(ICDef->getValueAsString("Counter")) << "], \""
|
||||
<< ICDef->getValueAsString("ResourceName") << "\"},\n";
|
||||
// Only emit if non-empty.
|
||||
const bool HasAtLeastOnePfmIssueCounter =
|
||||
llvm::any_of(PfmCounterDefs, [](const Record *Def) {
|
||||
return !Def->getValueAsListOfDefs("IssueCounters").empty();
|
||||
});
|
||||
if (HasAtLeastOnePfmIssueCounter) {
|
||||
OS << "static const PfmCountersInfo::IssueCounter " << Target
|
||||
<< "PfmIssueCounters[] = {\n";
|
||||
for (const Record *Def : PfmCounterDefs) {
|
||||
for (const Record *ICDef : Def->getValueAsListOfDefs("IssueCounters"))
|
||||
OS << " { " << Target << "PfmCounterNames["
|
||||
<< getPfmCounterId(ICDef->getValueAsString("Counter")) << "], \""
|
||||
<< ICDef->getValueAsString("ResourceName") << "\"},\n";
|
||||
}
|
||||
OS << "};\n";
|
||||
}
|
||||
|
||||
OS << "};\n";
|
||||
|
||||
// Now generate the PfmCountersInfo.
|
||||
unsigned IssueCountersTableOffset = 0;
|
||||
for (const Record *Def : PfmCounterDefs)
|
||||
emitPfmCountersInfo(*Def, IssueCountersTableOffset, OS);
|
||||
|
||||
OS << "\n";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void ExegesisEmitter::emitPfmCountersLookupTable(raw_ostream &OS) const {
|
||||
std::vector<Record *> Bindings =
|
||||
Records.getAllDerivedDefinitions("PfmCountersBinding");
|
||||
assert(!Bindings.empty() && "there must be at least one binding");
|
||||
llvm::sort(Bindings, [](const Record *L, const Record *R) {
|
||||
return L->getValueAsString("CpuName") < R->getValueAsString("CpuName");
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user