Target.h 8.2 KB

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