Skip to content

[llvm-exegesis] Add tablegen support for validation counters #76652

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
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
24 changes: 24 additions & 0 deletions llvm/include/llvm/Target/TargetPfmCounters.td
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,27 @@ class PfmIssueCounter<string resource_name, string counter>
string ResourceName = resource_name;
}

// Definition of a validation event. A validation event represents a specific
// event that can be measured using performance counters that is interesting
// in regard to the snippet state.
class ValidationEvent <int event_number> {
int EventNumber = event_number;
}

def L1DCacheLoadMiss : ValidationEvent<0>;
def InstructionRetired : ValidationEvent<1>;
def DataTLBLoadMiss : ValidationEvent<2>;
def DataTLBStoreMiss : ValidationEvent<3>;

// PfmValidationCounter provides a mapping between the events that are
// are interesting in regards to the snippet execution environment and
// a concrete performance counter name that can be looked up in libpfm.
class PfmValidationCounter<ValidationEvent event_type, string counter>
: PfmCounter<counter> {
// The name of the event that the validation counter detects.
ValidationEvent EventType = event_type;
}

def NoPfmCounter : PfmCounter <""> {}

// Set of PfmCounters for measuring sched model characteristics.
Expand All @@ -38,6 +59,9 @@ class ProcPfmCounters {
PfmCounter UopsCounter = NoPfmCounter;
// Processors can define how to measure issued uops by defining IssueCounters.
list<PfmIssueCounter> IssueCounters = [];
// Processor can list mappings between validation events and real counters
// to measure the specified events.
list<PfmValidationCounter> ValidationCounters = [];
}

// A binding of a set of counters to a CPU.
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/X86/X86PfmCounters.td
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ def ZnVer2PfmCounters : ProcPfmCounters {
PfmIssueCounter<"Zn2AGU", "ls_dispatch:ld_st_dispatch + ls_dispatch:ld_dispatch + ls_dispatch:store_dispatch">,
PfmIssueCounter<"Zn2Divider", "div_op_count">
];
let ValidationCounters = [
PfmValidationCounter<InstructionRetired, "RETIRED_INSTRUCTIONS">
];
}
def : PfmCountersBinding<"znver2", ZnVer2PfmCounters>;

Expand All @@ -288,6 +291,9 @@ def ZnVer3PfmCounters : ProcPfmCounters {
PfmIssueCounter<"Zn3Store", "ls_dispatch:store_dispatch">,
PfmIssueCounter<"Zn3Divider", "div_op_count">
];
let ValidationCounters = [
PfmValidationCounter<InstructionRetired, "RETIRED_INSTRUCTIONS">
];
}
def : PfmCountersBinding<"znver3", ZnVer3PfmCounters>;

Expand Down
9 changes: 7 additions & 2 deletions llvm/tools/llvm-exegesis/lib/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,15 @@ std::unique_ptr<BenchmarkRunner> ExegesisTarget::createUopsBenchmarkRunner(

static_assert(std::is_trivial_v<PfmCountersInfo>,
"We shouldn't have dynamic initialization here");

const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr,
0u};
0u, nullptr, 0u};
const PfmCountersInfo PfmCountersInfo::Dummy = {
pfm::PerfEvent::DummyEventString, pfm::PerfEvent::DummyEventString, nullptr,
pfm::PerfEvent::DummyEventString,
pfm::PerfEvent::DummyEventString,
nullptr,
0u,
nullptr,
0u};

const PfmCountersInfo &ExegesisTarget::getPfmCounters(StringRef CpuName) const {
Expand Down
10 changes: 10 additions & 0 deletions llvm/tools/llvm-exegesis/lib/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ extern cl::OptionCategory Options;
extern cl::OptionCategory BenchmarkOptions;
extern cl::OptionCategory AnalysisOptions;

enum ValidationEvent {
L1DCacheLoadMiss,
InstructionRetired,
DataTLBLoadMiss,
DataTLBStoreMiss
};

struct PfmCountersInfo {
// An optional name of a performance counter that can be used to measure
// cycles.
Expand All @@ -59,6 +66,9 @@ struct PfmCountersInfo {
const IssueCounter *IssueCounters;
unsigned NumIssueCounters;

const std::pair<ValidationEvent, const char *> *ValidationEvents;
unsigned NumValidationEvents;

static const PfmCountersInfo Default;
static const PfmCountersInfo Dummy;
};
Expand Down
52 changes: 50 additions & 2 deletions llvm/utils/TableGen/ExegesisEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ collectPfmCounters(const RecordKeeper &Records) {
"duplicate ResourceName " + ResourceName);
AddPfmCounterName(IssueCounter);
}

for (const Record *ValidationCounter :
Def->getValueAsListOfDefs("ValidationCounters"))
AddPfmCounterName(ValidationCounter);

AddPfmCounterName(Def->getValueAsDef("CycleCounter"));
AddPfmCounterName(Def->getValueAsDef("UopsCounter"));
}
Expand All @@ -100,6 +105,17 @@ ExegesisEmitter::ExegesisEmitter(RecordKeeper &RK)
Target = std::string(Targets[0]->getName());
}

struct ValidationCounterInfo {
int64_t EventNumber;
StringRef EventName;
unsigned PfmCounterID;
};

bool EventNumberLess(const ValidationCounterInfo &LHS,
const ValidationCounterInfo &RHS) {
return LHS.EventNumber < RHS.EventNumber;
}

void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,
unsigned &IssueCountersTableOffset,
raw_ostream &OS) const {
Expand All @@ -109,6 +125,31 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,
Def.getValueAsDef("UopsCounter")->getValueAsString("Counter");
const size_t NumIssueCounters =
Def.getValueAsListOfDefs("IssueCounters").size();
const size_t NumValidationCounters =
Def.getValueAsListOfDefs("ValidationCounters").size();

// Emit Validation Counters Array
if (NumValidationCounters != 0) {
std::vector<ValidationCounterInfo> ValidationCounters;
ValidationCounters.reserve(NumValidationCounters);
for (const Record *ValidationCounter :
Def.getValueAsListOfDefs("ValidationCounters")) {
ValidationCounters.push_back(
{ValidationCounter->getValueAsDef("EventType")
->getValueAsInt("EventNumber"),
ValidationCounter->getValueAsDef("EventType")->getName(),
getPfmCounterId(ValidationCounter->getValueAsString("Counter"))});
}
std::sort(ValidationCounters.begin(), ValidationCounters.end(),
EventNumberLess);
OS << "\nstatic const std::pair<ValidationEvent, const char*> " << Target
<< Def.getName() << "ValidationCounters[] = {\n";
for (const ValidationCounterInfo &VCI : ValidationCounters) {
OS << " { " << VCI.EventName << ", " << Target << "PfmCounterNames["
<< VCI.PfmCounterID << "]},\n";
}
OS << "};\n";
}

OS << "\nstatic const PfmCountersInfo " << Target << Def.getName()
<< " = {\n";
Expand All @@ -129,10 +170,17 @@ void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,

// Issue Counters
if (NumIssueCounters == 0)
OS << " nullptr, // No issue counters.\n 0\n";
OS << " nullptr, 0, // No issue counters\n";
else
OS << " " << Target << "PfmIssueCounters + " << IssueCountersTableOffset
<< ", " << NumIssueCounters << " // Issue counters.\n";
<< ", " << NumIssueCounters << ", // Issue counters.\n";

// Validation Counters
if (NumValidationCounters == 0)
OS << " nullptr, 0 // No validation counters.\n";
else
OS << " " << Target << Def.getName() << "ValidationCounters, "
<< NumValidationCounters << " // Validation counters.\n";

OS << "};\n";
IssueCountersTableOffset += NumIssueCounters;
Expand Down