Target.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //===-- Target.cpp ----------------------------------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "Target.h"
  10. #include "Latency.h"
  11. #include "ROBSize.h"
  12. #include "Uops.h"
  13. namespace llvm {
  14. namespace exegesis {
  15. ExegesisTarget::~ExegesisTarget() {} // anchor.
  16. static ExegesisTarget *FirstTarget = nullptr;
  17. const ExegesisTarget *ExegesisTarget::lookup(llvm::Triple TT) {
  18. for (const ExegesisTarget *T = FirstTarget; T != nullptr; T = T->Next) {
  19. if (T->matchesArch(TT.getArch()))
  20. return T;
  21. }
  22. return nullptr;
  23. }
  24. void ExegesisTarget::registerTarget(ExegesisTarget *Target) {
  25. if (FirstTarget == nullptr) {
  26. FirstTarget = Target;
  27. return;
  28. }
  29. if (Target->Next != nullptr)
  30. return; // Already registered.
  31. Target->Next = FirstTarget;
  32. FirstTarget = Target;
  33. }
  34. std::unique_ptr<SnippetGenerator>
  35. ExegesisTarget::createLatencySnippetGenerator(const LLVMState &State) const {
  36. return llvm::make_unique<LatencySnippetGenerator>(State);
  37. }
  38. std::unique_ptr<SnippetGenerator>
  39. ExegesisTarget::createUopsSnippetGenerator(const LLVMState &State) const {
  40. return llvm::make_unique<UopsSnippetGenerator>(State);
  41. }
  42. std::unique_ptr<SnippetGenerator>
  43. static createROBSizeSnippetGenerator(const LLVMState &State) {
  44. return llvm::make_unique<ROBSizeSnippetGenerator>(State);
  45. }
  46. std::unique_ptr<BenchmarkRunner>
  47. ExegesisTarget::createLatencyBenchmarkRunner(const LLVMState &State) const {
  48. return llvm::make_unique<LatencyBenchmarkRunner>(State);
  49. }
  50. std::unique_ptr<BenchmarkRunner>
  51. ExegesisTarget::createUopsBenchmarkRunner(const LLVMState &State) const {
  52. return llvm::make_unique<UopsBenchmarkRunner>(State);
  53. }
  54. std::unique_ptr<SnippetGenerator>
  55. ExegesisTarget::createSnippetGenerator(InstructionBenchmark::ModeE Mode,
  56. const LLVMState &State) const {
  57. switch (Mode) {
  58. case InstructionBenchmark::Unknown:
  59. return nullptr;
  60. case InstructionBenchmark::Latency:
  61. return createLatencySnippetGenerator(State);
  62. case InstructionBenchmark::Uops:
  63. return createUopsSnippetGenerator(State);
  64. case InstructionBenchmark::ROBSize:
  65. return createROBSizeSnippetGenerator(State);
  66. }
  67. return nullptr;
  68. }
  69. std::unique_ptr<BenchmarkRunner>
  70. ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
  71. const LLVMState &State) const {
  72. switch (Mode) {
  73. case InstructionBenchmark::Unknown:
  74. return nullptr;
  75. case InstructionBenchmark::Latency:
  76. case InstructionBenchmark::ROBSize:
  77. return createLatencyBenchmarkRunner(State);
  78. case InstructionBenchmark::Uops:
  79. return createUopsBenchmarkRunner(State);
  80. }
  81. return nullptr;
  82. }
  83. static_assert(std::is_pod<PfmCountersInfo>::value,
  84. "We shouldn't have dynamic initialization here");
  85. const PfmCountersInfo PfmCountersInfo::Default = {nullptr, nullptr, nullptr, 0u};
  86. const PfmCountersInfo &
  87. ExegesisTarget::getPfmCounters(llvm::StringRef CpuName) const {
  88. assert(std::is_sorted(
  89. CpuPfmCounters.begin(), CpuPfmCounters.end(),
  90. [](const CpuAndPfmCounters &LHS, const CpuAndPfmCounters &RHS) {
  91. return strcmp(LHS.CpuName, RHS.CpuName) < 0;
  92. }) &&
  93. "CpuPfmCounters table is not sorted");
  94. // Find entry
  95. auto Found =
  96. std::lower_bound(CpuPfmCounters.begin(), CpuPfmCounters.end(), CpuName);
  97. if (Found == CpuPfmCounters.end() ||
  98. llvm::StringRef(Found->CpuName) != CpuName) {
  99. return PfmCountersInfo::Default;
  100. }
  101. assert(Found->PCI && "Missing counters");
  102. return *Found->PCI;
  103. }
  104. namespace {
  105. // Default implementation.
  106. class ExegesisDefaultTarget : public ExegesisTarget {
  107. public:
  108. ExegesisDefaultTarget() : ExegesisTarget({}) {}
  109. private:
  110. std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
  111. unsigned Reg,
  112. const llvm::APInt &Value) const override {
  113. llvm_unreachable("Not yet implemented");
  114. }
  115. std::vector<llvm::MCInst> copyReg(const llvm::MCSubtargetInfo &STI,
  116. unsigned ToReg, unsigned FromReg) const override {
  117. llvm_unreachable("Not yet implemented");
  118. }
  119. bool matchesArch(llvm::Triple::ArchType Arch) const override {
  120. llvm_unreachable("never called");
  121. return false;
  122. }
  123. };
  124. } // namespace
  125. const ExegesisTarget &ExegesisTarget::getDefault() {
  126. static ExegesisDefaultTarget Target;
  127. return Target;
  128. }
  129. } // namespace exegesis
  130. } // namespace llvm