ScheduleHazardRecognizer.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //=- llvm/CodeGen/ScheduleHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file implements the ScheduleHazardRecognizer class, which implements
  15. // hazard-avoidance heuristics for scheduling.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
  19. #define LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
  20. namespace llvm {
  21. class MachineInstr;
  22. class SUnit;
  23. /// HazardRecognizer - This determines whether or not an instruction can be
  24. /// issued this cycle, and whether or not a noop needs to be inserted to handle
  25. /// the hazard.
  26. class ScheduleHazardRecognizer {
  27. protected:
  28. /// MaxLookAhead - Indicate the number of cycles in the scoreboard
  29. /// state. Important to restore the state after backtracking. Additionally,
  30. /// MaxLookAhead=0 identifies a fake recognizer, allowing the client to
  31. /// bypass virtual calls. Currently the PostRA scheduler ignores it.
  32. unsigned MaxLookAhead = 0;
  33. public:
  34. ScheduleHazardRecognizer() = default;
  35. virtual ~ScheduleHazardRecognizer();
  36. enum HazardType {
  37. NoHazard, // This instruction can be emitted at this cycle.
  38. Hazard, // This instruction can't be emitted at this cycle.
  39. NoopHazard // This instruction can't be emitted, and needs noops.
  40. };
  41. unsigned getMaxLookAhead() const { return MaxLookAhead; }
  42. bool isEnabled() const { return MaxLookAhead != 0; }
  43. /// atIssueLimit - Return true if no more instructions may be issued in this
  44. /// cycle.
  45. ///
  46. /// FIXME: remove this once MachineScheduler is the only client.
  47. virtual bool atIssueLimit() const { return false; }
  48. /// getHazardType - Return the hazard type of emitting this node. There are
  49. /// three possible results. Either:
  50. /// * NoHazard: it is legal to issue this instruction on this cycle.
  51. /// * Hazard: issuing this instruction would stall the machine. If some
  52. /// other instruction is available, issue it first.
  53. /// * NoopHazard: issuing this instruction would break the program. If
  54. /// some other instruction can be issued, do so, otherwise issue a noop.
  55. virtual HazardType getHazardType(SUnit *, int Stalls = 0) {
  56. return NoHazard;
  57. }
  58. /// Reset - This callback is invoked when a new block of
  59. /// instructions is about to be schedule. The hazard state should be
  60. /// set to an initialized state.
  61. virtual void Reset() {}
  62. /// EmitInstruction - This callback is invoked when an instruction is
  63. /// emitted, to advance the hazard state.
  64. virtual void EmitInstruction(SUnit *) {}
  65. /// This overload will be used when the hazard recognizer is being used
  66. /// by a non-scheduling pass, which does not use SUnits.
  67. virtual void EmitInstruction(MachineInstr *) {}
  68. /// PreEmitNoops - This callback is invoked prior to emitting an instruction.
  69. /// It should return the number of noops to emit prior to the provided
  70. /// instruction.
  71. /// Note: This is only used during PostRA scheduling. EmitNoop is not called
  72. /// for these noops.
  73. virtual unsigned PreEmitNoops(SUnit *) {
  74. return 0;
  75. }
  76. /// This overload will be used when the hazard recognizer is being used
  77. /// by a non-scheduling pass, which does not use SUnits.
  78. virtual unsigned PreEmitNoops(MachineInstr *) {
  79. return 0;
  80. }
  81. /// ShouldPreferAnother - This callback may be invoked if getHazardType
  82. /// returns NoHazard. If, even though there is no hazard, it would be better to
  83. /// schedule another available instruction, this callback should return true.
  84. virtual bool ShouldPreferAnother(SUnit *) {
  85. return false;
  86. }
  87. /// AdvanceCycle - This callback is invoked whenever the next top-down
  88. /// instruction to be scheduled cannot issue in the current cycle, either
  89. /// because of latency or resource conflicts. This should increment the
  90. /// internal state of the hazard recognizer so that previously "Hazard"
  91. /// instructions will now not be hazards.
  92. virtual void AdvanceCycle() {}
  93. /// RecedeCycle - This callback is invoked whenever the next bottom-up
  94. /// instruction to be scheduled cannot issue in the current cycle, either
  95. /// because of latency or resource conflicts.
  96. virtual void RecedeCycle() {}
  97. /// EmitNoop - This callback is invoked when a noop was added to the
  98. /// instruction stream.
  99. virtual void EmitNoop() {
  100. // Default implementation: count it as a cycle.
  101. AdvanceCycle();
  102. }
  103. /// EmitNoops - This callback is invoked when noops were added to the
  104. /// instruction stream.
  105. virtual void EmitNoops(unsigned Quantity) {
  106. // Default implementation: count it as a cycle.
  107. for (unsigned i = 0; i < Quantity; ++i)
  108. EmitNoop();
  109. }
  110. };
  111. } // end namespace llvm
  112. #endif // LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
  113. #ifdef __GNUC__
  114. #pragma GCC diagnostic pop
  115. #endif