string CpuName = cpu_name;
ProcPfmCounters Counters = counters;
}
+
+// Declares the default binding for unbound CPUs for the target.
+class PfmCountersDefaultBinding<ProcPfmCounters counters>
+ : PfmCountersBinding<"", counters> {}
let AssemblyWriters = [GenericAsmWriter, AppleAsmWriter];
let AllowRegisterRenaming = 1;
}
+
+//===----------------------------------------------------------------------===//
+// Pfm Counters
+//===----------------------------------------------------------------------===//
+
+include "AArch64PfmCounters.td"
--- /dev/null
+//===-- 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>;
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)
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)
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,
FeatureFRES, FeatureFRSQRTE,
FeatureMFTB]>;
def : Processor<"g4+", G4PlusItineraries, [Directive7400, FeatureAltivec,
- FeatureFRES, FeatureFRSQRTE,
+ FeatureFRES, FeatureFRSQRTE,
FeatureMFTB]>;
def : ProcessorModel<"970", G5Model,
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,
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,
let AssemblyParserVariants = [PPCAsmParserVariant];
let AllowRegisterRenaming = 1;
}
+
+//===----------------------------------------------------------------------===//
+// Pfm Counters
+//===----------------------------------------------------------------------===//
+
+include "PPCPfmCounters.td"
--- /dev/null
+//===-- 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>;
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;
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:
.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,
// 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
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>>
// 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)
private:
llvm::Expected<std::vector<BenchmarkMeasure>>
runMeasurements(const FunctionExecutor &Executor) const override;
-
- virtual const char *getCounterName() const;
};
} // namespace exegesis
} // namespace llvm
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,
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
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 {
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;
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
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
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Debug.h"
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";
// 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");
});