Target.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //===-- Target.h ------------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. ///
  11. /// Classes that handle the creation of target-specific objects. This is
  12. /// similar to Target/TargetRegistry.
  13. ///
  14. //===----------------------------------------------------------------------===//
  15. #ifndef LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H
  16. #define LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H
  17. #include "BenchmarkResult.h"
  18. #include "BenchmarkRunner.h"
  19. #include "Error.h"
  20. #include "LlvmState.h"
  21. #include "PerfHelper.h"
  22. #include "SnippetGenerator.h"
  23. #include "llvm/ADT/Triple.h"
  24. #include "llvm/CodeGen/TargetPassConfig.h"
  25. #include "llvm/IR/CallingConv.h"
  26. #include "llvm/IR/LegacyPassManager.h"
  27. #include "llvm/MC/MCInst.h"
  28. #include "llvm/MC/MCRegisterInfo.h"
  29. #include "llvm/Support/CommandLine.h"
  30. #include "llvm/Support/Error.h"
  31. namespace llvm {
  32. namespace exegesis {
  33. extern cl::OptionCategory Options;
  34. extern cl::OptionCategory BenchmarkOptions;
  35. extern cl::OptionCategory AnalysisOptions;
  36. struct PfmCountersInfo {
  37. // An optional name of a performance counter that can be used to measure
  38. // cycles.
  39. const char *CycleCounter;
  40. // An optional name of a performance counter that can be used to measure
  41. // uops.
  42. const char *UopsCounter;
  43. // An IssueCounter specifies how to measure uops issued to specific proc
  44. // resources.
  45. struct IssueCounter {
  46. const char *Counter;
  47. // The name of the ProcResource that this counter measures.
  48. const char *ProcResName;
  49. };
  50. // An optional list of IssueCounters.
  51. const IssueCounter *IssueCounters;
  52. unsigned NumIssueCounters;
  53. static const PfmCountersInfo Default;
  54. };
  55. struct CpuAndPfmCounters {
  56. const char *CpuName;
  57. const PfmCountersInfo *PCI;
  58. bool operator<(StringRef S) const { return StringRef(CpuName) < S; }
  59. };
  60. class ExegesisTarget {
  61. public:
  62. explicit ExegesisTarget(ArrayRef<CpuAndPfmCounters> CpuPfmCounters)
  63. : CpuPfmCounters(CpuPfmCounters) {}
  64. // Targets can use this to create target-specific perf counters.
  65. virtual Expected<std::unique_ptr<pfm::Counter>>
  66. createCounter(StringRef CounterName, const LLVMState &State) const;
  67. // Targets can use this to add target-specific passes in assembleToStream();
  68. virtual void addTargetSpecificPasses(PassManagerBase &PM) const {}
  69. // Generates code to move a constant into a the given register.
  70. // Precondition: Value must fit into Reg.
  71. virtual std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
  72. const APInt &Value) const = 0;
  73. // Returns the register pointing to scratch memory, or 0 if this target
  74. // does not support memory operands. The benchmark function uses the
  75. // default calling convention.
  76. virtual unsigned getScratchMemoryRegister(const Triple &) const { return 0; }
  77. // Fills memory operands with references to the address at [Reg] + Offset.
  78. virtual void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
  79. unsigned Offset) const {
  80. llvm_unreachable(
  81. "fillMemoryOperands() requires getScratchMemoryRegister() > 0");
  82. }
  83. // Returns a counter usable as a loop counter.
  84. virtual unsigned getLoopCounterRegister(const Triple &) const { return 0; }
  85. // Adds the code to decrement the loop counter and
  86. virtual void decrementLoopCounterAndJump(MachineBasicBlock &MBB,
  87. MachineBasicBlock &TargetMBB,
  88. const MCInstrInfo &MII) const {
  89. llvm_unreachable("decrementLoopCounterAndBranch() requires "
  90. "getLoopCounterRegister() > 0");
  91. }
  92. // Returns a list of unavailable registers.
  93. // Targets can use this to prevent some registers to be automatically selected
  94. // for use in snippets.
  95. virtual ArrayRef<unsigned> getUnavailableRegisters() const { return {}; }
  96. // Returns the maximum number of bytes a load/store instruction can access at
  97. // once. This is typically the size of the largest register available on the
  98. // processor. Note that this only used as a hint to generate independant
  99. // load/stores to/from memory, so the exact returned value does not really
  100. // matter as long as it's large enough.
  101. virtual unsigned getMaxMemoryAccessSize() const { return 0; }
  102. // Assigns a random operand of the right type to variable Var.
  103. // The target is responsible for handling any operand starting from
  104. // OPERAND_FIRST_TARGET.
  105. virtual Error randomizeTargetMCOperand(const Instruction &Instr,
  106. const Variable &Var,
  107. MCOperand &AssignedValue,
  108. const BitVector &ForbiddenRegs) const {
  109. return make_error<Failure>(
  110. "targets with target-specific operands should implement this");
  111. }
  112. // Returns true if this instruction is supported as a back-to-back
  113. // instructions.
  114. // FIXME: Eventually we should discover this dynamically.
  115. virtual bool allowAsBackToBack(const Instruction &Instr) const {
  116. return true;
  117. }
  118. // For some instructions, it is interesting to measure how it's performance
  119. // characteristics differ depending on it's operands.
  120. // This allows us to produce all the interesting variants.
  121. virtual std::vector<InstructionTemplate>
  122. generateInstructionVariants(const Instruction &Instr,
  123. unsigned MaxConfigsPerOpcode) const {
  124. // By default, we're happy with whatever randomizer will give us.
  125. return {&Instr};
  126. }
  127. // Checks hardware and software support for current benchmark mode.
  128. // Returns an error if the target host does not have support to run the
  129. // benchmark.
  130. virtual Error checkFeatureSupport() const { return Error::success(); }
  131. // Creates a snippet generator for the given mode.
  132. std::unique_ptr<SnippetGenerator>
  133. createSnippetGenerator(InstructionBenchmark::ModeE Mode,
  134. const LLVMState &State,
  135. const SnippetGenerator::Options &Opts) const;
  136. // Creates a benchmark runner for the given mode.
  137. Expected<std::unique_ptr<BenchmarkRunner>> createBenchmarkRunner(
  138. InstructionBenchmark::ModeE Mode, const LLVMState &State,
  139. BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
  140. InstructionBenchmark::ResultAggregationModeE ResultAggMode =
  141. InstructionBenchmark::Min) const;
  142. // Returns the ExegesisTarget for the given triple or nullptr if the target
  143. // does not exist.
  144. static const ExegesisTarget *lookup(Triple TT);
  145. // Returns the default (unspecialized) ExegesisTarget.
  146. static const ExegesisTarget &getDefault();
  147. // Registers a target. Not thread safe.
  148. static void registerTarget(ExegesisTarget *T);
  149. virtual ~ExegesisTarget();
  150. // Returns the Pfm counters for the given CPU (or the default if no pfm
  151. // counters are defined for this CPU).
  152. const PfmCountersInfo &getPfmCounters(StringRef CpuName) const;
  153. // Saves the CPU state that needs to be preserved when running a benchmark,
  154. // and returns and RAII object that restores the state on destruction.
  155. // By default no state is preserved.
  156. struct SavedState {
  157. virtual ~SavedState();
  158. };
  159. virtual std::unique_ptr<SavedState> withSavedState() const {
  160. return std::make_unique<SavedState>();
  161. }
  162. private:
  163. virtual bool matchesArch(Triple::ArchType Arch) const = 0;
  164. // Targets can implement their own snippet generators/benchmarks runners by
  165. // implementing these.
  166. std::unique_ptr<SnippetGenerator> virtual createSerialSnippetGenerator(
  167. const LLVMState &State, const SnippetGenerator::Options &Opts) const;
  168. std::unique_ptr<SnippetGenerator> virtual createParallelSnippetGenerator(
  169. const LLVMState &State, const SnippetGenerator::Options &Opts) const;
  170. std::unique_ptr<BenchmarkRunner> virtual createLatencyBenchmarkRunner(
  171. const LLVMState &State, InstructionBenchmark::ModeE Mode,
  172. BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
  173. InstructionBenchmark::ResultAggregationModeE ResultAggMode) const;
  174. std::unique_ptr<BenchmarkRunner> virtual createUopsBenchmarkRunner(
  175. const LLVMState &State, BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
  176. InstructionBenchmark::ResultAggregationModeE ResultAggMode) const;
  177. const ExegesisTarget *Next = nullptr;
  178. const ArrayRef<CpuAndPfmCounters> CpuPfmCounters;
  179. };
  180. } // namespace exegesis
  181. } // namespace llvm
  182. #endif // LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H