diff options
author | Clement Courbet <courbet@google.com> | 2019-10-08 14:30:24 +0000 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2019-10-08 14:30:24 +0000 |
commit | 2cd0f2895946de546d066f67c88ff365d3210017 (patch) | |
tree | 1dde8cff5615fac6906b453afef96f2fb7fbc685 | |
parent | cf3ab6d96c3e9477b05bbbe8b525151320e96d71 (diff) | |
download | bcm5719-llvm-2cd0f2895946de546d066f67c88ff365d3210017.tar.gz bcm5719-llvm-2cd0f2895946de546d066f67c88ff365d3210017.zip |
[llvm-exegesis] Add options to SnippetGenerator.
Summary:
This adds a `-max-configs-per-opcode` option to limit the number of
configs per opcode.
Reviewers: gchatelet
Subscribers: tschuett, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D68642
llvm-svn: 374054
-rw-r--r-- | llvm/docs/CommandGuide/llvm-exegesis.rst | 14 | ||||
-rw-r--r-- | llvm/test/tools/llvm-exegesis/X86/max-configs.test | 24 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/Latency.h | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/SnippetGenerator.h | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/Target.cpp | 22 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/Target.h | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/Uops.h | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 14 | ||||
-rw-r--r-- | llvm/tools/llvm-exegesis/llvm-exegesis.cpp | 11 | ||||
-rw-r--r-- | llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp | 5 |
11 files changed, 86 insertions, 28 deletions
diff --git a/llvm/docs/CommandGuide/llvm-exegesis.rst b/llvm/docs/CommandGuide/llvm-exegesis.rst index 4ac1c766354..81e92e7736d 100644 --- a/llvm/docs/CommandGuide/llvm-exegesis.rst +++ b/llvm/docs/CommandGuide/llvm-exegesis.rst @@ -195,11 +195,23 @@ OPTIONS to specify at least one of the `-analysis-clusters-output-file=` and `-analysis-inconsistencies-output-file=`. -.. option:: -num-repetitions=<Number of repetition> +.. option:: -num-repetitions=<Number of repetitions> Specify the number of repetitions of the asm snippet. Higher values lead to more accurate measurements but lengthen the benchmark. +.. option:: -max-configs-per-opcode=<value> + + Specify the maximum configurations that can be generated for each opcode. + By default this is `1`, meaning that we assume that a single measurement is + enough to characterize an opcode. This might not be true of all instructions: + for example, the performance characteristics of the LEA instruction on X86 + depends on the value of assigned registers and immediates. Setting a value of + `-max-configs-per-opcode` larger than `1` allows `llvm-exegesis` to explore + more configurations to discover if some register or immediate assignments + lead to different performance characteristics. + + .. option:: -benchmarks-file=</path/to/file> File to read (`analysis` mode) or write (`latency`/`uops`/`inverse_throughput` diff --git a/llvm/test/tools/llvm-exegesis/X86/max-configs.test b/llvm/test/tools/llvm-exegesis/X86/max-configs.test new file mode 100644 index 00000000000..a980e85d4b5 --- /dev/null +++ b/llvm/test/tools/llvm-exegesis/X86/max-configs.test @@ -0,0 +1,24 @@ +# RUN: llvm-exegesis -mode=latency -opcode-name=SBB8rr -max-configs-per-opcode=1 | FileCheck -check-prefixes=CHECK,CHECK1 %s +# RUN: llvm-exegesis -mode=latency -opcode-name=SBB8rr -max-configs-per-opcode=2 | FileCheck -check-prefixes=CHECK,CHECK2 %s + +CHECK: --- +CHECK-NEXT: mode: latency +CHECK-NEXT: key: +CHECK-NEXT: instructions: +CHECK-NEXT: SBB8rr +CHECK-NEXT: config: '' +CHECK-NEXT: register_initial_values: +CHECK-DAG: - '[[REG1:[A-Z0-9]+]]=0x0' +CHECK-LAST: ... + +CHECK1-NOT: SBB8rr + +CHECK2: --- +CHECK2-NEXT: mode: latency +CHECK2-NEXT: key: +CHECK2-NEXT: instructions: +CHECK2-NEXT: SBB8rr +CHECK2-NEXT: config: '' +CHECK2-NEXT: register_initial_values: +CHECK2-DAG: - '[[REG1:[A-Z0-9]+]]=0x0' +CHECK2-LAST: ... diff --git a/llvm/tools/llvm-exegesis/lib/Latency.h b/llvm/tools/llvm-exegesis/lib/Latency.h index 503f91daf89..0ad0c2cea9b 100644 --- a/llvm/tools/llvm-exegesis/lib/Latency.h +++ b/llvm/tools/llvm-exegesis/lib/Latency.h @@ -24,7 +24,7 @@ namespace exegesis { class LatencySnippetGenerator : public SnippetGenerator { public: - LatencySnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {} + using SnippetGenerator::SnippetGenerator; ~LatencySnippetGenerator() override; llvm::Expected<std::vector<CodeTemplate>> diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp index 879962001e6..1b16259b8e6 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.cpp @@ -33,7 +33,8 @@ std::vector<CodeTemplate> getSingleton(CodeTemplate &&CT) { SnippetGeneratorFailure::SnippetGeneratorFailure(const llvm::Twine &S) : llvm::StringError(S, llvm::inconvertibleErrorCode()) {} -SnippetGenerator::SnippetGenerator(const LLVMState &State) : State(State) {} +SnippetGenerator::SnippetGenerator(const LLVMState &State, const Options &Opts) + : State(State), Opts(Opts) {} SnippetGenerator::~SnippetGenerator() = default; @@ -81,6 +82,9 @@ SnippetGenerator::generateConfigurations( computeRegisterInitialValues(CT.Instructions); BC.Key.Config = CT.Config; Output.push_back(std::move(BC)); + if (Output.size() >= Opts.MaxConfigsPerOpcode) + return Output; // Early exit if we exceeded the number of allowed + // configs. } } return Output; diff --git a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h index c2ea1c12473..8e8cd6fcb99 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h +++ b/llvm/tools/llvm-exegesis/lib/SnippetGenerator.h @@ -51,7 +51,11 @@ public: // Common code for all benchmark modes. class SnippetGenerator { public: - explicit SnippetGenerator(const LLVMState &State); + struct Options { + unsigned MaxConfigsPerOpcode = 1; + }; + + explicit SnippetGenerator(const LLVMState &State, const Options &Opts); virtual ~SnippetGenerator(); @@ -66,6 +70,7 @@ public: protected: const LLVMState &State; + const Options Opts; private: // API to be implemented by subclasses. diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index a5ba24c20f2..7e27627c98c 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -36,17 +36,17 @@ void ExegesisTarget::registerTarget(ExegesisTarget *Target) { FirstTarget = Target; } -std::unique_ptr<SnippetGenerator> -ExegesisTarget::createSnippetGenerator(InstructionBenchmark::ModeE Mode, - const LLVMState &State) const { +std::unique_ptr<SnippetGenerator> ExegesisTarget::createSnippetGenerator( + InstructionBenchmark::ModeE Mode, const LLVMState &State, + const SnippetGenerator::Options &Opts) const { switch (Mode) { case InstructionBenchmark::Unknown: return nullptr; case InstructionBenchmark::Latency: - return createLatencySnippetGenerator(State); + return createLatencySnippetGenerator(State, Opts); case InstructionBenchmark::Uops: case InstructionBenchmark::InverseThroughput: - return createUopsSnippetGenerator(State); + return createUopsSnippetGenerator(State, Opts); } return nullptr; } @@ -66,14 +66,14 @@ ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode, return nullptr; } -std::unique_ptr<SnippetGenerator> -ExegesisTarget::createLatencySnippetGenerator(const LLVMState &State) const { - return std::make_unique<LatencySnippetGenerator>(State); +std::unique_ptr<SnippetGenerator> ExegesisTarget::createLatencySnippetGenerator( + const LLVMState &State, const SnippetGenerator::Options &Opts) const { + return std::make_unique<LatencySnippetGenerator>(State, Opts); } -std::unique_ptr<SnippetGenerator> -ExegesisTarget::createUopsSnippetGenerator(const LLVMState &State) const { - return std::make_unique<UopsSnippetGenerator>(State); +std::unique_ptr<SnippetGenerator> ExegesisTarget::createUopsSnippetGenerator( + const LLVMState &State, const SnippetGenerator::Options &Opts) const { + return std::make_unique<UopsSnippetGenerator>(State, Opts); } std::unique_ptr<BenchmarkRunner> ExegesisTarget::createLatencyBenchmarkRunner( diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 70313a7a2f7..511104d5947 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -125,7 +125,8 @@ public: // Creates a snippet generator for the given mode. std::unique_ptr<SnippetGenerator> createSnippetGenerator(InstructionBenchmark::ModeE Mode, - const LLVMState &State) const; + const LLVMState &State, + const SnippetGenerator::Options &Opts) const; // Creates a benchmark runner for the given mode. std::unique_ptr<BenchmarkRunner> createBenchmarkRunner(InstructionBenchmark::ModeE Mode, @@ -151,9 +152,9 @@ private: // Targets can implement their own snippet generators/benchmarks runners by // implementing these. std::unique_ptr<SnippetGenerator> virtual createLatencySnippetGenerator( - const LLVMState &State) const; + const LLVMState &State, const SnippetGenerator::Options &Opts) const; std::unique_ptr<SnippetGenerator> virtual createUopsSnippetGenerator( - const LLVMState &State) const; + const LLVMState &State, const SnippetGenerator::Options &Opts) const; std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner( const LLVMState &State, InstructionBenchmark::ModeE Mode) const; std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner( diff --git a/llvm/tools/llvm-exegesis/lib/Uops.h b/llvm/tools/llvm-exegesis/lib/Uops.h index 23caff26658..fcfeabe99ee 100644 --- a/llvm/tools/llvm-exegesis/lib/Uops.h +++ b/llvm/tools/llvm-exegesis/lib/Uops.h @@ -22,7 +22,7 @@ namespace exegesis { class UopsSnippetGenerator : public SnippetGenerator { public: - UopsSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {} + using SnippetGenerator::SnippetGenerator; ~UopsSnippetGenerator() override; llvm::Expected<std::vector<CodeTemplate>> diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index ce66610891d..1532af8ddec 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -462,14 +462,16 @@ private: sizeof(kUnavailableRegisters[0])); } - std::unique_ptr<SnippetGenerator> - createLatencySnippetGenerator(const LLVMState &State) const override { - return std::make_unique<X86LatencySnippetGenerator>(State); + std::unique_ptr<SnippetGenerator> createLatencySnippetGenerator( + const LLVMState &State, + const SnippetGenerator::Options &Opts) const override { + return std::make_unique<X86LatencySnippetGenerator>(State, Opts); } - std::unique_ptr<SnippetGenerator> - createUopsSnippetGenerator(const LLVMState &State) const override { - return std::make_unique<X86UopsSnippetGenerator>(State); + std::unique_ptr<SnippetGenerator> createUopsSnippetGenerator( + const LLVMState &State, + const SnippetGenerator::Options &Opts) const override { + return std::make_unique<X86UopsSnippetGenerator>(State, Opts); } bool matchesArch(llvm::Triple::ArchType Arch) const override { diff --git a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp index 616b7c96232..e86dc817cb2 100644 --- a/llvm/tools/llvm-exegesis/llvm-exegesis.cpp +++ b/llvm/tools/llvm-exegesis/llvm-exegesis.cpp @@ -95,6 +95,12 @@ static cl::opt<unsigned> cl::desc("number of time to repeat the asm snippet"), cl::cat(BenchmarkOptions), cl::init(10000)); +static cl::opt<unsigned> MaxConfigsPerOpcode( + "max-configs-per-opcode", + cl::desc( + "allow to snippet generator to generate at most that many configs"), + cl::cat(BenchmarkOptions), cl::init(1)); + static cl::opt<bool> IgnoreInvalidSchedClass( "ignore-invalid-sched-class", cl::desc("ignore instructions that do not define a sched class"), @@ -214,8 +220,11 @@ generateSnippets(const LLVMState &State, unsigned Opcode, if (InstrDesc.isCall() || InstrDesc.isReturn()) return make_error<Failure>("Unsupported opcode: isCall/isReturn"); + SnippetGenerator::Options Options; + Options.MaxConfigsPerOpcode = MaxConfigsPerOpcode; const std::unique_ptr<SnippetGenerator> Generator = - State.getExegesisTarget().createSnippetGenerator(BenchmarkMode, State); + State.getExegesisTarget().createSnippetGenerator(BenchmarkMode, State, + Options); if (!Generator) llvm::report_fatal_error("cannot create snippet generator"); return Generator->generateConfigurations(Instr, ForbiddenRegs); diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp index c5a69250999..9eac269ed6d 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp @@ -45,7 +45,7 @@ protected: template <typename SnippetGeneratorT> class SnippetGeneratorTest : public X86SnippetGeneratorTest { protected: - SnippetGeneratorTest() : Generator(State) {} + SnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()) {} std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) { randomGenerator().seed(0); // Initialize seed. @@ -335,7 +335,8 @@ TEST_F(UopsSnippetGeneratorTest, MemoryUse) { class FakeSnippetGenerator : public SnippetGenerator { public: - FakeSnippetGenerator(const LLVMState &State) : SnippetGenerator(State) {} + FakeSnippetGenerator(const LLVMState &State, const Options &Opts) + : SnippetGenerator(State, Opts) {} Instruction createInstruction(unsigned Opcode) { return State.getIC().getInstr(Opcode); |