diff options
| author | Guillaume Chatelet <gchatelet@google.com> | 2018-10-12 15:12:22 +0000 |
|---|---|---|
| committer | Guillaume Chatelet <gchatelet@google.com> | 2018-10-12 15:12:22 +0000 |
| commit | 946fb0517a504e8f87ac3b21f259f7d2e0aadd56 (patch) | |
| tree | ed6de52a71a47dedac11807dd2bf51ce465fd2db /llvm/tools/llvm-exegesis/lib/X86/Target.cpp | |
| parent | 55ab86b72b4947345c4fc204f773800ef2a09b08 (diff) | |
| download | bcm5719-llvm-946fb0517a504e8f87ac3b21f259f7d2e0aadd56.tar.gz bcm5719-llvm-946fb0517a504e8f87ac3b21f259f7d2e0aadd56.zip | |
[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
llvm-svn: 344351
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/X86/Target.cpp')
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 118 |
1 files changed, 60 insertions, 58 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 440996ad555..0e9a6de95ce 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -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; -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"); + llvm::Expected<CodeTemplate> + generateCodeTemplate(const Instruction &Instr) const override { + if (auto E = IsInvalidOpcode(Instr)) + return std::move(E); + + 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 ExegesisTarget { 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 { |

