[llvm] r344351 - [llvm-exegesis][NFC] Simplify code at the cost of small code duplication
Guillaume Chatelet via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 12 08:12:22 PDT 2018
Author: gchatelet
Date: Fri Oct 12 08:12:22 2018
New Revision: 344351
URL: http://llvm.org/viewvc/llvm-project?rev=344351&view=rev
Log:
[llvm-exegesis][NFC] Simplify code at the cost of small code duplication
Reviewers: courbet
Subscribers: tschuett, llvm-commits
Differential Revision: https://reviews.llvm.org/D53198
Modified:
llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
Modified: llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp?rev=344351&r1=344350&r2=344351&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp Fri Oct 12 08:12:22 2018
@@ -21,81 +21,83 @@ namespace exegesis {
namespace {
-// Common code for X86 Uops and Latency runners.
-template <typename Impl> class X86SnippetGenerator : public Impl {
- using Impl::Impl;
+static llvm::Error IsInvalidOpcode(const Instruction &Instr) {
+ const auto OpcodeName = Instr.Name;
+ if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
+ OpcodeName.startswith("ADJCALLSTACK"))
+ return llvm::make_error<BenchmarkFailure>(
+ "Unsupported opcode: Push/Pop/AdjCallStack");
+ return llvm::Error::success();
+}
+
+static unsigned GetX86FPFlags(const Instruction &Instr) {
+ return Instr.Description->TSFlags & llvm::X86II::FPTypeMask;
+}
+
+class X86LatencySnippetGenerator : public LatencySnippetGenerator {
+public:
+ using LatencySnippetGenerator::LatencySnippetGenerator;
llvm::Expected<CodeTemplate>
generateCodeTemplate(const Instruction &Instr) const override {
- // Test whether we can generate a snippet for this instruction.
- const auto OpcodeName = Instr.Name;
- if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
- OpcodeName.startswith("ADJCALLSTACK")) {
- return llvm::make_error<BenchmarkFailure>(
- "Unsupported opcode: Push/Pop/AdjCallStack");
- }
+ if (auto E = IsInvalidOpcode(Instr))
+ return std::move(E);
- // Handle X87.
- const unsigned FPInstClass =
- Instr.Description->TSFlags & llvm::X86II::FPTypeMask;
- switch (FPInstClass) {
+ switch (GetX86FPFlags(Instr)) {
case llvm::X86II::NotFP:
- break;
+ return LatencySnippetGenerator::generateCodeTemplate(Instr);
case llvm::X86II::ZeroArgFP:
- return llvm::make_error<BenchmarkFailure>("Unsupported x87 ZeroArgFP");
case llvm::X86II::OneArgFP:
- return llvm::make_error<BenchmarkFailure>("Unsupported x87 OneArgFP");
+ case llvm::X86II::SpecialFP:
+ case llvm::X86II::CompareFP:
+ case llvm::X86II::CondMovFP:
+ return llvm::make_error<BenchmarkFailure>("Unsupported x87 Instruction");
case llvm::X86II::OneArgFPRW:
- case llvm::X86II::TwoArgFP: {
+ case llvm::X86II::TwoArgFP:
// These are instructions like
// - `ST(0) = fsqrt(ST(0))` (OneArgFPRW)
// - `ST(0) = ST(0) + ST(i)` (TwoArgFP)
// They are intrinsically serial and do not modify the state of the stack.
- // We generate the same code for latency and uops.
- return this->generateSelfAliasingCodeTemplate(Instr);
- }
- case llvm::X86II::CompareFP:
- return Impl::handleCompareFP(Instr);
- case llvm::X86II::CondMovFP:
- return Impl::handleCondMovFP(Instr);
- case llvm::X86II::SpecialFP:
- return llvm::make_error<BenchmarkFailure>("Unsupported x87 SpecialFP");
+ return generateSelfAliasingCodeTemplate(Instr);
default:
llvm_unreachable("Unknown FP Type!");
}
-
- // Fallback to generic implementation.
- return Impl::Base::generateCodeTemplate(Instr);
}
};
-class X86LatencyImpl : public LatencySnippetGenerator {
-protected:
- using Base = LatencySnippetGenerator;
- using Base::Base;
- llvm::Expected<CodeTemplate> handleCompareFP(const Instruction &Instr) const {
- return llvm::make_error<SnippetGeneratorFailure>(
- "Unsupported x87 CompareFP");
- }
- llvm::Expected<CodeTemplate> handleCondMovFP(const Instruction &Instr) const {
- return llvm::make_error<SnippetGeneratorFailure>(
- "Unsupported x87 CondMovFP");
- }
-};
+class X86UopsSnippetGenerator : public UopsSnippetGenerator {
+public:
+ using UopsSnippetGenerator::UopsSnippetGenerator;
+
+ llvm::Expected<CodeTemplate>
+ generateCodeTemplate(const Instruction &Instr) const override {
+ if (auto E = IsInvalidOpcode(Instr))
+ return std::move(E);
-class X86UopsImpl : public UopsSnippetGenerator {
-protected:
- using Base = UopsSnippetGenerator;
- using Base::Base;
- // We can compute uops for any FP instruction that does not grow or shrink the
- // stack (either do not touch the stack or push as much as they pop).
- llvm::Expected<CodeTemplate> handleCompareFP(const Instruction &Instr) const {
- return generateUnconstrainedCodeTemplate(
- Instr, "instruction does not grow/shrink the FP stack");
- }
- llvm::Expected<CodeTemplate> handleCondMovFP(const Instruction &Instr) const {
- return generateUnconstrainedCodeTemplate(
- Instr, "instruction does not grow/shrink the FP stack");
+ switch (GetX86FPFlags(Instr)) {
+ case llvm::X86II::NotFP:
+ return UopsSnippetGenerator::generateCodeTemplate(Instr);
+ case llvm::X86II::ZeroArgFP:
+ case llvm::X86II::OneArgFP:
+ case llvm::X86II::SpecialFP:
+ return llvm::make_error<BenchmarkFailure>("Unsupported x87 Instruction");
+ case llvm::X86II::OneArgFPRW:
+ case llvm::X86II::TwoArgFP:
+ // These are instructions like
+ // - `ST(0) = fsqrt(ST(0))` (OneArgFPRW)
+ // - `ST(0) = ST(0) + ST(i)` (TwoArgFP)
+ // They are intrinsically serial and do not modify the state of the stack.
+ // We generate the same code for latency and uops.
+ return generateSelfAliasingCodeTemplate(Instr);
+ case llvm::X86II::CompareFP:
+ case llvm::X86II::CondMovFP:
+ // We can compute uops for any FP instruction that does not grow or shrink
+ // the stack (either do not touch the stack or push as much as they pop).
+ return generateUnconstrainedCodeTemplate(
+ Instr, "instruction does not grow/shrink the FP stack");
+ default:
+ llvm_unreachable("Unknown FP Type!");
+ }
}
};
@@ -330,12 +332,12 @@ class ExegesisX86Target : public Exegesi
std::unique_ptr<SnippetGenerator>
createLatencySnippetGenerator(const LLVMState &State) const override {
- return llvm::make_unique<X86SnippetGenerator<X86LatencyImpl>>(State);
+ return llvm::make_unique<X86LatencySnippetGenerator>(State);
}
std::unique_ptr<SnippetGenerator>
createUopsSnippetGenerator(const LLVMState &State) const override {
- return llvm::make_unique<X86SnippetGenerator<X86UopsImpl>>(State);
+ return llvm::make_unique<X86UopsSnippetGenerator>(State);
}
bool matchesArch(llvm::Triple::ArchType Arch) const override {
More information about the llvm-commits
mailing list