[llvm] r335582 - [llvm-exegesis] Get the BenchmarkRunner from the ExegesisTarget.

Clement Courbet via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 26 01:49:30 PDT 2018


Author: courbet
Date: Tue Jun 26 01:49:30 2018
New Revision: 335582

URL: http://llvm.org/viewvc/llvm-project?rev=335582&view=rev
Log:
[llvm-exegesis] Get the BenchmarkRunner from the ExegesisTarget.

Summary:
This allows targets to override code generation for some instructions.
As an example of override, this also moves ad-hoc instruction filtering
for X86 into the X86 ExegesisTarget.

Reviewers: gchatelet

Subscribers: mgorny, tschuett, llvm-commits

Differential Revision: https://reviews.llvm.org/D48587

Removed:
    llvm/trunk/tools/llvm-exegesis/lib/X86.cpp
    llvm/trunk/tools/llvm-exegesis/lib/X86.h
Modified:
    llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Assembler.h
    llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
    llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h
    llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt
    llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Latency.h
    llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp
    llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h
    llvm/trunk/tools/llvm-exegesis/lib/Target.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Target.h
    llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Uops.h
    llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp
    llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp
    llvm/trunk/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
    llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp

Modified: llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Assembler.cpp Tue Jun 26 01:49:30 2018
@@ -138,7 +138,7 @@ llvm::BitVector getFunctionReservedRegs(
   return MF.getSubtarget().getRegisterInfo()->getReservedRegs(MF);
 }
 
-void assembleToStream(const ExegesisTarget *ET,
+void assembleToStream(const ExegesisTarget &ET,
                       std::unique_ptr<llvm::LLVMTargetMachine> TM,
                       llvm::ArrayRef<unsigned> RegsToDef,
                       llvm::ArrayRef<llvm::MCInst> Instructions,
@@ -157,11 +157,10 @@ void assembleToStream(const ExegesisTarg
   auto &Properties = MF.getProperties();
   Properties.set(llvm::MachineFunctionProperties::Property::NoVRegs);
   Properties.reset(llvm::MachineFunctionProperties::Property::IsSSA);
-  std::vector<llvm::MCInst> SnippetWithSetup;
-  bool IsSnippetSetupComplete = RegsToDef.empty();
-  if (ET) {
-    SnippetWithSetup =
-        generateSnippetSetupCode(RegsToDef, *ET, IsSnippetSetupComplete);
+  bool IsSnippetSetupComplete = false;
+  std::vector<llvm::MCInst> SnippetWithSetup =
+      generateSnippetSetupCode(RegsToDef, ET, IsSnippetSetupComplete);
+  if (!SnippetWithSetup.empty()) {
     SnippetWithSetup.insert(SnippetWithSetup.end(), Instructions.begin(),
                             Instructions.end());
     Instructions = SnippetWithSetup;
@@ -190,10 +189,8 @@ void assembleToStream(const ExegesisTarg
   PM.add(MMI.release());
   TPC->printAndVerify("MachineFunctionGenerator::assemble");
   // Add target-specific passes.
-  if (ET) {
-    ET->addTargetSpecificPasses(PM);
-    TPC->printAndVerify("After ExegesisTarget::addTargetSpecificPasses");
-  }
+  ET.addTargetSpecificPasses(PM);
+  TPC->printAndVerify("After ExegesisTarget::addTargetSpecificPasses");
   // Adding the following passes:
   // - machineverifier: checks that the MachineFunction is well formed.
   // - prologepilog: saves and restore callee saved registers.

Modified: llvm/trunk/tools/llvm-exegesis/lib/Assembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Assembler.h?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Assembler.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Assembler.h Tue Jun 26 01:49:30 2018
@@ -43,7 +43,7 @@ llvm::BitVector getFunctionReservedRegs(
 // Instructions. Runs a set of llvm Passes to provide correct prologue and
 // epilogue. Once the MachineFunction is ready, it is assembled for TM to
 // AsmStream, the temporary function is eventually discarded.
-void assembleToStream(const ExegesisTarget *ET,
+void assembleToStream(const ExegesisTarget &ET,
                       std::unique_ptr<llvm::LLVMTargetMachine> TM,
                       llvm::ArrayRef<unsigned> RegsToDef,
                       llvm::ArrayRef<llvm::MCInst> Instructions,

Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.cpp Tue Jun 26 01:49:30 2018
@@ -26,23 +26,26 @@ namespace exegesis {
 BenchmarkFailure::BenchmarkFailure(const llvm::Twine &S)
     : llvm::StringError(S, llvm::inconvertibleErrorCode()) {}
 
-BenchmarkRunner::InstructionFilter::~InstructionFilter() = default;
-
-BenchmarkRunner::BenchmarkRunner(const LLVMState &State)
-    : State(State),
-      RATC(State.getRegInfo(), getFunctionReservedRegs(State.getTargetMachine())) {}
+BenchmarkRunner::BenchmarkRunner(const LLVMState &State,
+                                 InstructionBenchmark::ModeE Mode)
+    : State(State), RATC(State.getRegInfo(),
+                         getFunctionReservedRegs(State.getTargetMachine())),
+      Mode(Mode) {}
 
 BenchmarkRunner::~BenchmarkRunner() = default;
 
 llvm::Expected<std::vector<InstructionBenchmark>>
-BenchmarkRunner::run(unsigned Opcode, const InstructionFilter &Filter,
-                     unsigned NumRepetitions) {
+BenchmarkRunner::run(unsigned Opcode, unsigned NumRepetitions) {
+  const llvm::MCInstrDesc &InstrDesc = State.getInstrInfo().get(Opcode);
   // Ignore instructions that we cannot run.
-  if (State.getInstrInfo().get(Opcode).isPseudo())
+  if (InstrDesc.isPseudo())
     return llvm::make_error<BenchmarkFailure>("Unsupported opcode: isPseudo");
-
-  if (llvm::Error E = Filter.shouldRun(State, Opcode))
-    return std::move(E);
+  if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
+    return llvm::make_error<BenchmarkFailure>(
+        "Unsupported opcode: isBranch/isIndirectBranch");
+  if (InstrDesc.isCall() || InstrDesc.isReturn())
+    return llvm::make_error<BenchmarkFailure>(
+        "Unsupported opcode: isCall/isReturn");
 
   llvm::Expected<std::vector<BenchmarkConfiguration>> ConfigurationOrError =
       generateConfigurations(Opcode);
@@ -60,7 +63,7 @@ InstructionBenchmark
 BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration,
                         unsigned Opcode, unsigned NumRepetitions) const {
   InstructionBenchmark InstrBenchmark;
-  InstrBenchmark.Mode = getMode();
+  InstrBenchmark.Mode = Mode;
   InstrBenchmark.CpuName = State.getTargetMachine().getTargetCPU();
   InstrBenchmark.LLVMTriple =
       State.getTargetMachine().getTargetTriple().normalize();

Modified: llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/BenchmarkRunner.h Tue Jun 26 01:49:30 2018
@@ -54,25 +54,12 @@ struct BenchmarkConfiguration {
 // Common code for all benchmark modes.
 class BenchmarkRunner {
 public:
-  explicit BenchmarkRunner(const LLVMState &State);
-
-  // Subtargets can disable running benchmarks for some instructions by
-  // returning an error here.
-  class InstructionFilter {
-  public:
-    virtual ~InstructionFilter();
-
-    virtual llvm::Error shouldRun(const LLVMState &State,
-                                  unsigned Opcode) const {
-      return llvm::ErrorSuccess();
-    }
-  };
+  explicit BenchmarkRunner(const LLVMState &State, InstructionBenchmark::ModeE Mode);
 
   virtual ~BenchmarkRunner();
 
   llvm::Expected<std::vector<InstructionBenchmark>>
-  run(unsigned Opcode, const InstructionFilter &Filter,
-      unsigned NumRepetitions);
+  run(unsigned Opcode, unsigned NumRepetitions);
 
   // Given a snippet, computes which registers the setup code needs to define.
   std::vector<unsigned>
@@ -83,6 +70,15 @@ protected:
   const RegisterAliasingTrackerCache RATC;
 
 private:
+  // API to be implemented by subclasses.
+  virtual llvm::Expected<SnippetPrototype>
+    generatePrototype(unsigned Opcode) const = 0;
+
+  virtual std::vector<BenchmarkMeasure>
+    runMeasurements(const ExecutableFunction &EF,
+                    const unsigned NumRepetitions) const = 0;
+
+  // Internal helpers.
   InstructionBenchmark runOne(const BenchmarkConfiguration &Configuration,
                               unsigned Opcode, unsigned NumRepetitions) const;
 
@@ -91,18 +87,12 @@ private:
   llvm::Expected<std::vector<BenchmarkConfiguration>>
   generateConfigurations(unsigned Opcode) const;
 
-  virtual InstructionBenchmark::ModeE getMode() const = 0;
-
-  virtual llvm::Expected<SnippetPrototype>
-  generatePrototype(unsigned Opcode) const = 0;
-
-  virtual std::vector<BenchmarkMeasure>
-  runMeasurements(const ExecutableFunction &EF,
-                  const unsigned NumRepetitions) const = 0;
 
   llvm::Expected<std::string>
   writeObjectFile(const BenchmarkConfiguration::Setup &Setup,
                   llvm::ArrayRef<llvm::MCInst> Code) const;
+
+  const InstructionBenchmark::ModeE Mode;
 };
 
 } // namespace exegesis

Modified: llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/CMakeLists.txt Tue Jun 26 01:49:30 2018
@@ -16,7 +16,6 @@ add_library(LLVMExegesis
   RegisterAliasing.cpp
   Target.cpp
   Uops.cpp
-  X86.cpp
   )
 
 llvm_update_compile_flags(LLVMExegesis)

Modified: llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp Tue Jun 26 01:49:30 2018
@@ -31,14 +31,8 @@ static bool hasMemoryOperand(const llvm:
 
 LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
 
-InstructionBenchmark::ModeE LatencyBenchmarkRunner::getMode() const {
-  return InstructionBenchmark::Latency;
-}
-
 llvm::Error LatencyBenchmarkRunner::isInfeasible(
     const llvm::MCInstrDesc &MCInstrDesc) const {
-  if (MCInstrDesc.isPseudo())
-    return llvm::make_error<BenchmarkFailure>("Infeasible : is pseudo");
   if (llvm::any_of(MCInstrDesc.operands(), hasUnknownOperand))
     return llvm::make_error<BenchmarkFailure>(
         "Infeasible : has unknown operands");

Modified: llvm/trunk/tools/llvm-exegesis/lib/Latency.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Latency.h?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Latency.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Latency.h Tue Jun 26 01:49:30 2018
@@ -22,7 +22,8 @@ namespace exegesis {
 
 class LatencyBenchmarkRunner : public BenchmarkRunner {
 public:
-  using BenchmarkRunner::BenchmarkRunner;
+  LatencyBenchmarkRunner(const LLVMState &State)
+      : BenchmarkRunner(State, InstructionBenchmark::Latency) {}
   ~LatencyBenchmarkRunner() override;
 
   llvm::Expected<SnippetPrototype>
@@ -39,8 +40,6 @@ private:
       const Instruction &Instr,
       const AliasingConfigurations &SelfAliasing) const;
 
-  InstructionBenchmark::ModeE getMode() const override;
-
   std::vector<BenchmarkMeasure>
   runMeasurements(const ExecutableFunction &EF,
                   const unsigned NumRepetitions) const override;

Modified: llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp Tue Jun 26 01:49:30 2018
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "LlvmState.h"
+#include "Target.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
@@ -30,6 +31,10 @@ LLVMState::LLVMState(const std::string &
       TheTarget->createTargetMachine(Triple, CpuName, /*Features*/ "", Options,
                                      llvm::Reloc::Model::Static)));
   TheExegesisTarget = ExegesisTarget::lookup(TargetMachine->getTargetTriple());
+  if (!TheExegesisTarget) {
+    llvm::errs() << "no exegesis target for " << Triple << ", using default\n";
+    TheExegesisTarget = &ExegesisTarget::getDefault();
+  }
 }
 
 LLVMState::LLVMState()

Modified: llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h Tue Jun 26 01:49:30 2018
@@ -15,7 +15,6 @@
 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
 #define LLVM_TOOLS_LLVM_EXEGESIS_LLVMSTATE_H
 
-#include "Target.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstrInfo.h"
@@ -41,7 +40,7 @@ public:
   const llvm::TargetMachine &getTargetMachine() const { return *TargetMachine; }
   std::unique_ptr<llvm::LLVMTargetMachine> createTargetMachine() const;
 
-  const ExegesisTarget *getExegesisTarget() const { return TheExegesisTarget; }
+  const ExegesisTarget &getExegesisTarget() const { return *TheExegesisTarget; }
 
   bool canAssemble(const llvm::MCInst &mc_inst) const;
 
@@ -57,7 +56,7 @@ public:
   }
 
 private:
-  const ExegesisTarget *TheExegesisTarget = nullptr;
+  const ExegesisTarget *TheExegesisTarget;
   std::unique_ptr<const llvm::TargetMachine> TargetMachine;
 };
 

Modified: llvm/trunk/tools/llvm-exegesis/lib/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Target.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Target.cpp Tue Jun 26 01:49:30 2018
@@ -8,6 +8,9 @@
 //===----------------------------------------------------------------------===//
 #include "Target.h"
 
+#include "Latency.h"
+#include "Uops.h"
+
 namespace exegesis {
 
 ExegesisTarget::~ExegesisTarget() {} // anchor.
@@ -33,4 +36,47 @@ void ExegesisTarget::registerTarget(Exeg
   Target->Next = FirstTarget;
   FirstTarget = Target;
 }
+
+std::unique_ptr<BenchmarkRunner>
+ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
+                                      const LLVMState &State) const {
+  switch (Mode) {
+  case InstructionBenchmark::Unknown:
+    return nullptr;
+  case InstructionBenchmark::Latency:
+    return createLatencyBenchmarkRunner(State);
+  case InstructionBenchmark::Uops:
+    return createUopsBenchmarkRunner(State);
+  }
+  return nullptr;
+}
+
+std::unique_ptr<BenchmarkRunner>
+ExegesisTarget::createLatencyBenchmarkRunner(const LLVMState &State) const {
+  return llvm::make_unique<LatencyBenchmarkRunner>(State);
+}
+
+std::unique_ptr<BenchmarkRunner>
+ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const {
+  return llvm::make_unique<UopsBenchmarkRunner>(State);
+}
+
+namespace {
+
+// Default implementation.
+class ExegesisDefaultTarget : public ExegesisTarget {
+private:
+  bool matchesArch(llvm::Triple::ArchType Arch) const override {
+    llvm_unreachable("never called");
+    return false;
+  }
+};
+
+} // namespace
+
+const ExegesisTarget &ExegesisTarget::getDefault() {
+  static ExegesisDefaultTarget Target;
+  return Target;
+}
+
 } // namespace exegesis

Modified: llvm/trunk/tools/llvm-exegesis/lib/Target.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Target.h?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Target.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Target.h Tue Jun 26 01:49:30 2018
@@ -17,6 +17,9 @@
 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H
 #define LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H
 
+#include "BenchmarkResult.h"
+#include "BenchmarkRunner.h"
+#include "LlvmState.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/LegacyPassManager.h"
@@ -35,9 +38,16 @@ public:
     return {};
   }
 
+  // Creates a benchmark runner for the given mode.
+  std::unique_ptr<BenchmarkRunner>
+  createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
+                        const LLVMState &State) const;
+
   // Returns the ExegesisTarget for the given triple or nullptr if the target
   // does not exist.
   static const ExegesisTarget *lookup(llvm::Triple TT);
+  // Returns the default (unspecialized) ExegesisTarget.
+  static const ExegesisTarget &getDefault();
   // Registers a target. Not thread safe.
   static void registerTarget(ExegesisTarget *T);
 
@@ -45,6 +55,14 @@ public:
 
 private:
   virtual bool matchesArch(llvm::Triple::ArchType Arch) const = 0;
+
+  // Targets can implement their own Latency/Uops benchmarks runners by
+  // implementing these.
+  std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner(
+      const LLVMState &State) const;
+  std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
+      const LLVMState &State) const;
+
   const ExegesisTarget *Next = nullptr;
 };
 

Modified: llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp Tue Jun 26 01:49:30 2018
@@ -91,8 +91,6 @@ static bool hasMemoryOperand(const llvm:
 
 llvm::Error
 UopsBenchmarkRunner::isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const {
-  if (MCInstrDesc.isPseudo())
-    return llvm::make_error<BenchmarkFailure>("Infeasible : is pseudo");
   if (llvm::any_of(MCInstrDesc.operands(), hasUnknownOperand))
     return llvm::make_error<BenchmarkFailure>(
         "Infeasible : has unknown operands");
@@ -133,10 +131,6 @@ static void remove(llvm::BitVector &a, c
 
 UopsBenchmarkRunner::~UopsBenchmarkRunner() = default;
 
-InstructionBenchmark::ModeE UopsBenchmarkRunner::getMode() const {
-  return InstructionBenchmark::Uops;
-}
-
 llvm::Expected<SnippetPrototype>
 UopsBenchmarkRunner::generatePrototype(unsigned Opcode) const {
   const auto &InstrDesc = State.getInstrInfo().get(Opcode);

Modified: llvm/trunk/tools/llvm-exegesis/lib/Uops.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Uops.h?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Uops.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Uops.h Tue Jun 26 01:49:30 2018
@@ -21,7 +21,8 @@ namespace exegesis {
 
 class UopsBenchmarkRunner : public BenchmarkRunner {
 public:
-  using BenchmarkRunner::BenchmarkRunner;
+  UopsBenchmarkRunner(const LLVMState &State)
+      : BenchmarkRunner(State, InstructionBenchmark::Uops) {}
   ~UopsBenchmarkRunner() override;
 
   llvm::Expected<SnippetPrototype>
@@ -30,8 +31,6 @@ public:
 private:
   llvm::Error isInfeasible(const llvm::MCInstrDesc &MCInstrDesc) const;
 
-  InstructionBenchmark::ModeE getMode() const override;
-
   std::vector<BenchmarkMeasure>
   runMeasurements(const ExecutableFunction &EF,
                   const unsigned NumRepetitions) const override;

Removed: llvm/trunk/tools/llvm-exegesis/lib/X86.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/X86.cpp?rev=335581&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/X86.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/X86.cpp (removed)
@@ -1,38 +0,0 @@
-//===-- X86.cpp --------------------------------------------------*- C++-*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86.h"
-
-namespace exegesis {
-
-static llvm::Error makeError(llvm::Twine Msg) {
-  return llvm::make_error<llvm::StringError>(Msg,
-                                             llvm::inconvertibleErrorCode());
-}
-
-X86Filter::~X86Filter() = default;
-
-// Test whether we can generate a snippet for this instruction.
-llvm::Error X86Filter::shouldRun(const LLVMState &State,
-                                 const unsigned Opcode) const {
-  const auto &InstrInfo = State.getInstrInfo();
-  const llvm::MCInstrDesc &InstrDesc = InstrInfo.get(Opcode);
-  if (InstrDesc.isBranch() || InstrDesc.isIndirectBranch())
-    return makeError("Unsupported opcode: isBranch/isIndirectBranch");
-  if (InstrDesc.isCall() || InstrDesc.isReturn())
-    return makeError("Unsupported opcode: isCall/isReturn");
-  const auto OpcodeName = InstrInfo.getName(Opcode);
-  if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
-      OpcodeName.startswith("ADJCALLSTACK")) {
-    return makeError("Unsupported opcode: Push/Pop/AdjCallStack");
-  }
-  return llvm::ErrorSuccess();
-}
-
-} // namespace exegesis

Removed: llvm/trunk/tools/llvm-exegesis/lib/X86.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/X86.h?rev=335581&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/X86.h (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/X86.h (removed)
@@ -1,32 +0,0 @@
-//===-- X86.h ---------------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// X86 target-specific setup.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_LLVM_EXEGESIS_X86_H
-#define LLVM_TOOLS_LLVM_EXEGESIS_X86_H
-
-#include "BenchmarkRunner.h"
-#include "LlvmState.h"
-
-namespace exegesis {
-
-class X86Filter : public BenchmarkRunner::InstructionFilter {
-public:
-  ~X86Filter() override;
-
-  llvm::Error shouldRun(const LLVMState &State, unsigned Opcode) const override;
-};
-
-} // namespace exegesis
-
-#endif // LLVM_TOOLS_LLVM_EXEGESIS_X86_H

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=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/X86/Target.cpp Tue Jun 26 01:49:30 2018
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 #include "../Target.h"
 
+#include "../Latency.h"
+#include "../Uops.h"
 #include "MCTargetDesc/X86MCTargetDesc.h"
 #include "X86.h"
 #include "X86RegisterInfo.h"
@@ -15,8 +17,46 @@
 
 namespace exegesis {
 
+// Test whether we can generate a snippet for this instruction.
+static llvm::Error shouldRun(const LLVMState &State, const unsigned Opcode) {
+  const auto &InstrInfo = State.getInstrInfo();
+  const auto OpcodeName = InstrInfo.getName(Opcode);
+  if (OpcodeName.startswith("POPF") || OpcodeName.startswith("PUSHF") ||
+      OpcodeName.startswith("ADJCALLSTACK")) {
+    return llvm::make_error<BenchmarkFailure>(
+        "Unsupported opcode: Push/Pop/AdjCallStack");
+  }
+  return llvm::ErrorSuccess();
+}
+
 namespace {
 
+class X86LatencyBenchmarkRunner : public LatencyBenchmarkRunner {
+private:
+  using LatencyBenchmarkRunner::LatencyBenchmarkRunner;
+
+  llvm::Expected<SnippetPrototype>
+  generatePrototype(unsigned Opcode) const override {
+    if (llvm::Error E = shouldRun(State, Opcode)) {
+      return std::move(E);
+    }
+    return LatencyBenchmarkRunner::generatePrototype(Opcode);
+  }
+};
+
+class X86UopsBenchmarkRunner : public UopsBenchmarkRunner {
+private:
+  using UopsBenchmarkRunner::UopsBenchmarkRunner;
+
+  llvm::Expected<SnippetPrototype>
+  generatePrototype(unsigned Opcode) const override {
+    if (llvm::Error E = shouldRun(State, Opcode)) {
+      return std::move(E);
+    }
+    return UopsBenchmarkRunner::generatePrototype(Opcode);
+  }
+};
+
 class ExegesisX86Target : public ExegesisTarget {
   void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override {
     // Lowers FP pseudo-instructions, e.g. ABS_Fp32 -> ABS_F.
@@ -55,6 +95,16 @@ class ExegesisX86Target : public Exegesi
     return {};
   }
 
+  std::unique_ptr<BenchmarkRunner>
+  createLatencyBenchmarkRunner(const LLVMState &State) const override {
+    return llvm::make_unique<X86LatencyBenchmarkRunner>(State);
+  }
+
+  std::unique_ptr<BenchmarkRunner>
+  createUopsBenchmarkRunner(const LLVMState &State) const override {
+    return llvm::make_unique<X86UopsBenchmarkRunner>(State);
+  }
+
   bool matchesArch(llvm::Triple::ArchType Arch) const override {
     return Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86;
   }

Modified: llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp Tue Jun 26 01:49:30 2018
@@ -16,11 +16,9 @@
 #include "lib/BenchmarkResult.h"
 #include "lib/BenchmarkRunner.h"
 #include "lib/Clustering.h"
-#include "lib/Latency.h"
 #include "lib/LlvmState.h"
 #include "lib/PerfHelper.h"
-#include "lib/Uops.h"
-#include "lib/X86.h"
+#include "lib/Target.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCInstBuilder.h"
@@ -47,13 +45,16 @@ static llvm::cl::opt<std::string>
 static llvm::cl::opt<std::string>
     BenchmarkFile("benchmarks-file", llvm::cl::desc(""), llvm::cl::init(""));
 
-enum class BenchmarkModeE { Latency, Uops, Analysis };
-static llvm::cl::opt<BenchmarkModeE> BenchmarkMode(
+static llvm::cl::opt<exegesis::InstructionBenchmark::ModeE> BenchmarkMode(
     "mode", llvm::cl::desc("the mode to run"),
-    llvm::cl::values(
-        clEnumValN(BenchmarkModeE::Latency, "latency", "Instruction Latency"),
-        clEnumValN(BenchmarkModeE::Uops, "uops", "Uop Decomposition"),
-        clEnumValN(BenchmarkModeE::Analysis, "analysis", "Analysis")));
+    llvm::cl::values(clEnumValN(exegesis::InstructionBenchmark::Latency,
+                                "latency", "Instruction Latency"),
+                     clEnumValN(exegesis::InstructionBenchmark::Uops, "uops",
+                                "Uop Decomposition"),
+                     // When not asking for a specific benchmark mode, we'll
+                     // analyse the results.
+                     clEnumValN(exegesis::InstructionBenchmark::Unknown,
+                                "analysis", "Analysis")));
 
 static llvm::cl::opt<unsigned>
     NumRepetitions("num-repetitions",
@@ -128,9 +129,6 @@ void benchmarkMain() {
   LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET();
 #endif
 
-  // FIXME: Target-specific filter.
-  X86Filter Filter;
-
   const LLVMState State;
   const auto Opcode = GetOpcodeOrDie(State.getInstrInfo());
 
@@ -146,16 +144,10 @@ void benchmarkMain() {
   if (!State.getSubtargetInfo().getSchedModel().hasExtraProcessorInfo())
     llvm::report_fatal_error("sched model is missing extra processor info!");
 
-  std::unique_ptr<BenchmarkRunner> Runner;
-  switch (BenchmarkMode) {
-  case BenchmarkModeE::Latency:
-    Runner = llvm::make_unique<LatencyBenchmarkRunner>(State);
-    break;
-  case BenchmarkModeE::Uops:
-    Runner = llvm::make_unique<UopsBenchmarkRunner>(State);
-    break;
-  case BenchmarkModeE::Analysis:
-    llvm_unreachable("not a benchmark");
+  const std::unique_ptr<BenchmarkRunner> Runner =
+      State.getExegesisTarget().createBenchmarkRunner(BenchmarkMode, State);
+  if (!Runner) {
+    llvm::report_fatal_error("cannot create benchmark runner");
   }
 
   if (NumRepetitions == 0)
@@ -167,7 +159,7 @@ void benchmarkMain() {
 
   const BenchmarkResultContext Context = getBenchmarkResultContext(State);
   std::vector<InstructionBenchmark> Results =
-      ExitOnErr(Runner->run(Opcode, Filter, NumRepetitions));
+      ExitOnErr(Runner->run(Opcode, NumRepetitions));
   for (InstructionBenchmark &Result : Results)
     ExitOnErr(Result.writeYaml(Context, BenchmarkFile));
 
@@ -245,7 +237,7 @@ int main(int Argc, char **Argv) {
     return EXIT_FAILURE;
   });
 
-  if (BenchmarkMode == BenchmarkModeE::Analysis) {
+  if (BenchmarkMode == exegesis::InstructionBenchmark::Unknown) {
     exegesis::analysisMain();
   } else {
     exegesis::benchmarkMain();

Modified: llvm/trunk/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h (original)
+++ llvm/trunk/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h Tue Jun 26 01:49:30 2018
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Assembler.h"
+#include "Target.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
@@ -36,11 +37,11 @@ protected:
   }
 
   template <class... Bs> inline void Check(llvm::MCInst MCInst, Bs... Bytes) {
-    CheckWithSetup(nullptr, {}, MCInst, Bytes...);
+    CheckWithSetup(ExegesisTarget::getDefault(), {}, MCInst, Bytes...);
   }
 
   template <class... Bs>
-  inline void CheckWithSetup(const ExegesisTarget *ET,
+  inline void CheckWithSetup(const ExegesisTarget &ET,
                              llvm::ArrayRef<unsigned> RegsToDef,
                              llvm::MCInst MCInst, Bs... Bytes) {
     ExecutableFunction Function =
@@ -67,7 +68,7 @@ private:
   }
 
   ExecutableFunction
-  assembleToFunction(const ExegesisTarget *ET,
+  assembleToFunction(const ExegesisTarget &ET,
                      llvm::ArrayRef<unsigned> RegsToDef,
                      llvm::ArrayRef<llvm::MCInst> Instructions) {
     llvm::SmallString<256> Buffer;

Modified: llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp?rev=335582&r1=335581&r2=335582&view=diff
==============================================================================
--- llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp (original)
+++ llvm/trunk/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp Tue Jun 26 01:49:30 2018
@@ -217,17 +217,14 @@ TEST_F(UopsSnippetGeneratorTest, NoTiedV
 
 class FakeBenchmarkRunner : public BenchmarkRunner {
 public:
-  using BenchmarkRunner::BenchmarkRunner;
+  FakeBenchmarkRunner(const LLVMState &State)
+      : BenchmarkRunner(State, InstructionBenchmark::Unknown) {}
 
   Instruction createInstruction(unsigned Opcode) {
     return Instruction(State.getInstrInfo().get(Opcode), RATC);
   }
 
 private:
-  InstructionBenchmark::ModeE getMode() const override {
-    return InstructionBenchmark::Unknown;
-  }
-
   llvm::Expected<SnippetPrototype>
   generatePrototype(unsigned Opcode) const override {
     return llvm::make_error<llvm::StringError>("not implemented",




More information about the llvm-commits mailing list