MCSchedule.cpp 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. //===- MCSchedule.cpp - Scheduling ------------------------------*- 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. //
  10. // This file defines the default scheduling model.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/MC/MCSchedule.h"
  14. #include "llvm/MC/MCInstrDesc.h"
  15. #include "llvm/MC/MCInstrInfo.h"
  16. #include "llvm/MC/MCSubtargetInfo.h"
  17. #include <type_traits>
  18. using namespace llvm;
  19. static_assert(std::is_pod<MCSchedModel>::value,
  20. "We shouldn't have a static constructor here");
  21. const MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
  22. DefaultMicroOpBufferSize,
  23. DefaultLoopMicroOpBufferSize,
  24. DefaultLoadLatency,
  25. DefaultHighLatency,
  26. DefaultMispredictPenalty,
  27. false,
  28. true,
  29. 0,
  30. nullptr,
  31. nullptr,
  32. 0,
  33. 0,
  34. nullptr,
  35. nullptr};
  36. int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
  37. const MCSchedClassDesc &SCDesc) {
  38. int Latency = 0;
  39. for (unsigned DefIdx = 0, DefEnd = SCDesc.NumWriteLatencyEntries;
  40. DefIdx != DefEnd; ++DefIdx) {
  41. // Lookup the definition's write latency in SubtargetInfo.
  42. const MCWriteLatencyEntry *WLEntry =
  43. STI.getWriteLatencyEntry(&SCDesc, DefIdx);
  44. // Early exit if we found an invalid latency.
  45. if (WLEntry->Cycles < 0)
  46. return WLEntry->Cycles;
  47. Latency = std::max(Latency, static_cast<int>(WLEntry->Cycles));
  48. }
  49. return Latency;
  50. }
  51. int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
  52. unsigned SchedClass) const {
  53. const MCSchedClassDesc &SCDesc = *getSchedClassDesc(SchedClass);
  54. if (!SCDesc.isValid())
  55. return 0;
  56. if (!SCDesc.isVariant())
  57. return MCSchedModel::computeInstrLatency(STI, SCDesc);
  58. llvm_unreachable("unsupported variant scheduling class");
  59. }
  60. Optional<double>
  61. MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
  62. const MCSchedClassDesc &SCDesc) {
  63. Optional<double> Throughput;
  64. const MCSchedModel &SM = STI.getSchedModel();
  65. const MCWriteProcResEntry *I = STI.getWriteProcResBegin(&SCDesc);
  66. const MCWriteProcResEntry *E = STI.getWriteProcResEnd(&SCDesc);
  67. for (; I != E; ++I) {
  68. if (!I->Cycles)
  69. continue;
  70. unsigned NumUnits = SM.getProcResource(I->ProcResourceIdx)->NumUnits;
  71. double Temp = NumUnits * 1.0 / I->Cycles;
  72. Throughput = Throughput ? std::min(Throughput.getValue(), Temp) : Temp;
  73. }
  74. return Throughput ? 1 / Throughput.getValue() : Throughput;
  75. }
  76. Optional<double>
  77. MCSchedModel::getReciprocalThroughput(unsigned SchedClass,
  78. const InstrItineraryData &IID) {
  79. Optional<double> Throughput;
  80. const InstrStage *I = IID.beginStage(SchedClass);
  81. const InstrStage *E = IID.endStage(SchedClass);
  82. for (; I != E; ++I) {
  83. if (!I->getCycles())
  84. continue;
  85. double Temp = countPopulation(I->getUnits()) * 1.0 / I->getCycles();
  86. Throughput = Throughput ? std::min(Throughput.getValue(), Temp) : Temp;
  87. }
  88. return Throughput ? 1 / Throughput.getValue() : Throughput;
  89. }