Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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