diff options
| author | Clement Courbet <courbet@google.com> | 2018-10-25 07:44:01 +0000 |
|---|---|---|
| committer | Clement Courbet <courbet@google.com> | 2018-10-25 07:44:01 +0000 |
| commit | 41c8af3924ca539faa3ea871f09ab37ba7f3b7d1 (patch) | |
| tree | 068a77624d5c7aa8fd8c0be3ec4457ae58537236 /llvm/tools | |
| parent | 128fcffb062789a77d65ce2966ffa0ef718e3d47 (diff) | |
| download | bcm5719-llvm-41c8af3924ca539faa3ea871f09ab37ba7f3b7d1.tar.gz bcm5719-llvm-41c8af3924ca539faa3ea871f09ab37ba7f3b7d1.zip | |
[MCSched] Bind PFM Counters to the CPUs instead of the SchedModel.
Summary:
The pfm counters are now in the ExegesisTarget rather than the
MCSchedModel (PR39165).
This also compresses the pfm counter tables (PR37068).
Reviewers: RKSimon, gchatelet
Subscribers: mgrang, llvm-commits
Differential Revision: https://reviews.llvm.org/D52932
llvm-svn: 345243
Diffstat (limited to 'llvm/tools')
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 4 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/Latency.cpp | 9 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/LlvmState.cpp | 7 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/LlvmState.h | 8 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/Target.cpp | 27 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/Target.h | 39 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/Uops.cpp | 20 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 6 | ||||
| -rw-r--r-- | llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 11 |
9 files changed, 109 insertions, 22 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index be8f0b41ede..0197420f433 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -53,6 +53,10 @@ static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth, } // namespace class ExegesisAArch64Target : public ExegesisTarget { +public: + ExegesisAArch64Target() : ExegesisTarget({}) {} + +private: std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI, unsigned Reg, const llvm::APInt &Value) const override { diff --git a/llvm/tools/llvm-exegesis/lib/Latency.cpp b/llvm/tools/llvm-exegesis/lib/Latency.cpp index 602b379faf3..3d18e37f4c3 100644 --- a/llvm/tools/llvm-exegesis/lib/Latency.cpp +++ b/llvm/tools/llvm-exegesis/lib/Latency.cpp @@ -12,6 +12,8 @@ #include "Assembler.h" #include "BenchmarkRunner.h" #include "MCInstrDescView.h" +#include "PerfHelper.h" +#include "Target.h" #include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstBuilder.h" @@ -165,12 +167,7 @@ LatencySnippetGenerator::generateCodeTemplates(const Instruction &Instr) const { } const char *LatencyBenchmarkRunner::getCounterName() const { - if (!State.getSubtargetInfo().getSchedModel().hasExtraProcessorInfo()) - llvm::report_fatal_error("sched model is missing extra processor info!"); - const char *CounterName = State.getSubtargetInfo() - .getSchedModel() - .getExtraProcessorInfo() - .PfmCounters.CycleCounter; + const char *CounterName = State.getPfmCounters().CycleCounter; if (!CounterName) llvm::report_fatal_error("sched model does not define a cycle counter"); return CounterName; diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp index 58e9db315d5..b5580c83cf5 100644 --- a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp +++ b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp @@ -36,14 +36,17 @@ LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName) { llvm::errs() << "no exegesis target for " << Triple << ", using default\n"; TheExegesisTarget = &ExegesisTarget::getDefault(); } + PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName); + RATC.reset(new RegisterAliasingTrackerCache( getRegInfo(), getFunctionReservedRegs(getTargetMachine()))); IC.reset(new InstructionsCache(getInstrInfo(), getRATC())); } -LLVMState::LLVMState() +LLVMState::LLVMState(const std::string &CpuName) : LLVMState(llvm::sys::getProcessTriple(), - llvm::sys::getHostCPUName().str()) {} + CpuName.empty() ? llvm::sys::getHostCPUName().str() : CpuName) { +} std::unique_ptr<llvm::LLVMTargetMachine> LLVMState::createTargetMachine() const { diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.h b/llvm/tools/llvm-exegesis/lib/LlvmState.h index 918738551d0..be1e7979a17 100644 --- a/llvm/tools/llvm-exegesis/lib/LlvmState.h +++ b/llvm/tools/llvm-exegesis/lib/LlvmState.h @@ -30,12 +30,14 @@ namespace llvm { namespace exegesis { class ExegesisTarget; +class PfmCountersInfo; // An object to initialize LLVM and prepare objects needed to run the // measurements. class LLVMState { public: - LLVMState(); + // Uses the host triple. If CpuName is empty, uses the host CPU. + LLVMState(const std::string &CpuName); LLVMState(const std::string &Triple, const std::string &CpuName); // For tests. @@ -57,14 +59,18 @@ public: const llvm::MCSubtargetInfo &getSubtargetInfo() const { return *TargetMachine->getMCSubtargetInfo(); } + const RegisterAliasingTrackerCache &getRATC() const { return *RATC; } const InstructionsCache &getIC() const { return *IC; } + const PfmCountersInfo &getPfmCounters() const { return *PfmCounters; } + private: const ExegesisTarget *TheExegesisTarget; std::unique_ptr<const llvm::TargetMachine> TargetMachine; std::unique_ptr<const RegisterAliasingTrackerCache> RATC; std::unique_ptr<const InstructionsCache> IC; + const PfmCountersInfo *PfmCounters; }; } // namespace exegesis diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index b7828a13da0..588c40e8c7f 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -85,10 +85,37 @@ ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const { return llvm::make_unique<UopsBenchmarkRunner>(State); } +static_assert(std::is_pod<PfmCountersInfo>::value, + "We shouldn't have dynamic initialization here"); +const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr}; + +const PfmCountersInfo & +ExegesisTarget::getPfmCounters(llvm::StringRef CpuName) const { + assert(std::is_sorted( + CpuPfmCounters.begin(), CpuPfmCounters.end(), + [](const CpuAndPfmCounters &LHS, const CpuAndPfmCounters &RHS) { + return strcmp(LHS.CpuName, RHS.CpuName) < 0; + }) && + "CpuPfmCounters table is not sorted"); + + // Find entry + auto Found = + std::lower_bound(CpuPfmCounters.begin(), CpuPfmCounters.end(), CpuName); + if (Found == CpuPfmCounters.end() || + llvm::StringRef(Found->CpuName) != CpuName) { + return PfmCountersInfo::Default; + } + assert(Found->PCI && "Missing counters"); + return *Found->PCI; +} + namespace { // Default implementation. class ExegesisDefaultTarget : public ExegesisTarget { +public: + ExegesisDefaultTarget() : ExegesisTarget({}) {} + private: std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI, unsigned Reg, diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 2e94727d78d..a6ec36bebb3 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -31,8 +31,42 @@ namespace llvm { namespace exegesis { +struct PfmCountersInfo { + // An optional name of a performance counter that can be used to measure + // cycles. + const char *const CycleCounter; + + // An optional name of a performance counter that can be used to measure + // uops. + const char *const UopsCounter; + + // An IssueCounter specifies how to measure uops issued to specific proc + // resources. + struct IssueCounter { + const char *const Counter; + // The name of the ProcResource that this counter measures. + const char *const ProcResName; + }; + // An optional list of IssueCounters. + const IssueCounter *const IssueCounters; + const unsigned NumIssueCounters; + + static const PfmCountersInfo Default; +}; + +struct CpuAndPfmCounters { + const char *const CpuName; + const PfmCountersInfo *const PCI; + bool operator<(llvm::StringRef S) const { + return llvm::StringRef(CpuName) < S; + } +}; + class ExegesisTarget { public: + explicit ExegesisTarget(llvm::ArrayRef<CpuAndPfmCounters> CpuPfmCounters) + : CpuPfmCounters(CpuPfmCounters) {} + // Targets can use this to add target-specific passes in assembleToStream(); virtual void addTargetSpecificPasses(llvm::PassManagerBase &PM) const {} @@ -83,6 +117,10 @@ public: virtual ~ExegesisTarget(); + // Returns the Pfm counters for the given CPU (or the default if no pfm + // counters are defined for this CPU). + const PfmCountersInfo &getPfmCounters(llvm::StringRef CpuName) const; + private: virtual bool matchesArch(llvm::Triple::ArchType Arch) const = 0; @@ -98,6 +136,7 @@ private: const LLVMState &State) const; const ExegesisTarget *Next = nullptr; + const llvm::ArrayRef<CpuAndPfmCounters> CpuPfmCounters; }; } // namespace exegesis diff --git a/llvm/tools/llvm-exegesis/lib/Uops.cpp b/llvm/tools/llvm-exegesis/lib/Uops.cpp index 5aa726218c7..9768f4533f7 100644 --- a/llvm/tools/llvm-exegesis/lib/Uops.cpp +++ b/llvm/tools/llvm-exegesis/lib/Uops.cpp @@ -223,24 +223,22 @@ UopsSnippetGenerator::generateCodeTemplates(const Instruction &Instr) const { llvm::Expected<std::vector<BenchmarkMeasure>> UopsBenchmarkRunner::runMeasurements(const FunctionExecutor &Executor) const { - const auto &SchedModel = State.getSubtargetInfo().getSchedModel(); - std::vector<BenchmarkMeasure> Result; - const auto &PfmCounters = SchedModel.getExtraProcessorInfo().PfmCounters; + const PfmCountersInfo &PCI = State.getPfmCounters(); // Uops per port. - for (unsigned ProcResIdx = 1; - ProcResIdx < SchedModel.getNumProcResourceKinds(); ++ProcResIdx) { - const char *const Counters = PfmCounters.IssueCounters[ProcResIdx]; - if (!Counters) + for (const auto *IssueCounter = PCI.IssueCounters, + *IssueCounterEnd = PCI.IssueCounters + PCI.NumIssueCounters; + IssueCounter != IssueCounterEnd; ++IssueCounter) { + if (!IssueCounter->Counter) continue; - auto ExpectedCounterValue = Executor.runAndMeasure(Counters); + auto ExpectedCounterValue = Executor.runAndMeasure(IssueCounter->Counter); if (!ExpectedCounterValue) return ExpectedCounterValue.takeError(); - Result.push_back(BenchmarkMeasure::Create( - SchedModel.getProcResource(ProcResIdx)->Name, *ExpectedCounterValue)); + Result.push_back(BenchmarkMeasure::Create(IssueCounter->ProcResName, + *ExpectedCounterValue)); } // NumMicroOps. - if (const char *const UopsCounter = PfmCounters.UopsCounter) { + if (const char *const UopsCounter = PCI.UopsCounter) { auto ExpectedCounterValue = Executor.runAndMeasure(UopsCounter); if (!ExpectedCounterValue) return ExpectedCounterValue.takeError(); diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 69804849e62..6ae228e1124 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -329,7 +329,13 @@ private: std::vector<llvm::MCInst> Instructions; }; +#include "X86GenExegesis.inc" + class ExegesisX86Target : public ExegesisTarget { +public: + ExegesisX86Target() : ExegesisTarget(X86CpuPfmCounters) {} + +private: void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override { // Lowers FP pseudo-instructions, e.g. ABS_Fp32 -> ABS_F. PM.add(llvm::createX86FloatingPointStackifierPass()); diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp index 689a1e097c6..a28e68ec006 100644 --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -94,6 +94,13 @@ static cl::opt<std::string> AnalysisInconsistenciesOutputFile("analysis-inconsistencies-output-file", cl::desc(""), cl::init("-")); +static cl::opt<std::string> + CpuName("mcpu", + cl::desc( + "cpu name to use for pfm counters, leave empty to autodetect"), + cl::init("")); + + static ExitOnError ExitOnErr; #ifdef LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET @@ -321,7 +328,7 @@ void benchmarkMain() { LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET(); #endif - const LLVMState State; + const LLVMState State(CpuName); const auto Opcodes = getOpcodesOrDie(State.getInstrInfo()); std::vector<BenchmarkCode> Configurations; @@ -399,7 +406,7 @@ static void analysisMain() { llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetDisassembler(); // Read benchmarks. - const LLVMState State; + const LLVMState State(""); const std::vector<InstructionBenchmark> Points = ExitOnErr(InstructionBenchmark::readYamls(State, BenchmarkFile)); llvm::outs() << "Parsed " << Points.size() << " benchmark points\n"; |

