Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:34

0001 //=- llvm/CodeGen/ScheduleHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file implements the ScheduleHazardRecognizer class, which implements
0010 // hazard-avoidance heuristics for scheduling.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
0015 #define LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
0016 
0017 namespace llvm {
0018 
0019 class MachineInstr;
0020 class SUnit;
0021 
0022 /// HazardRecognizer - This determines whether or not an instruction can be
0023 /// issued this cycle, and whether or not a noop needs to be inserted to handle
0024 /// the hazard.
0025 class ScheduleHazardRecognizer {
0026 protected:
0027   /// MaxLookAhead - Indicate the number of cycles in the scoreboard
0028   /// state. Important to restore the state after backtracking. Additionally,
0029   /// MaxLookAhead=0 identifies a fake recognizer, allowing the client to
0030   /// bypass virtual calls. Currently the PostRA scheduler ignores it.
0031   unsigned MaxLookAhead = 0;
0032 
0033 public:
0034   ScheduleHazardRecognizer() = default;
0035   virtual ~ScheduleHazardRecognizer();
0036 
0037   enum HazardType {
0038     NoHazard,      // This instruction can be emitted at this cycle.
0039     Hazard,        // This instruction can't be emitted at this cycle.
0040     NoopHazard     // This instruction can't be emitted, and needs noops.
0041   };
0042 
0043   unsigned getMaxLookAhead() const { return MaxLookAhead; }
0044 
0045   bool isEnabled() const { return MaxLookAhead != 0; }
0046 
0047   /// atIssueLimit - Return true if no more instructions may be issued in this
0048   /// cycle.
0049   ///
0050   /// FIXME: remove this once MachineScheduler is the only client.
0051   virtual bool atIssueLimit() const { return false; }
0052 
0053   /// getHazardType - Return the hazard type of emitting this node.  There are
0054   /// three possible results.  Either:
0055   ///  * NoHazard: it is legal to issue this instruction on this cycle.
0056   ///  * Hazard: issuing this instruction would stall the machine.  If some
0057   ///     other instruction is available, issue it first.
0058   ///  * NoopHazard: issuing this instruction would break the program.  If
0059   ///     some other instruction can be issued, do so, otherwise issue a noop.
0060   virtual HazardType getHazardType(SUnit *, int Stalls = 0) {
0061     return NoHazard;
0062   }
0063 
0064   /// Reset - This callback is invoked when a new block of
0065   /// instructions is about to be schedule. The hazard state should be
0066   /// set to an initialized state.
0067   virtual void Reset() {}
0068 
0069   /// EmitInstruction - This callback is invoked when an instruction is
0070   /// emitted, to advance the hazard state.
0071   virtual void EmitInstruction(SUnit *) {}
0072 
0073   /// This overload will be used when the hazard recognizer is being used
0074   /// by a non-scheduling pass, which does not use SUnits.
0075   virtual void EmitInstruction(MachineInstr *) {}
0076 
0077   /// PreEmitNoops - This callback is invoked prior to emitting an instruction.
0078   /// It should return the number of noops to emit prior to the provided
0079   /// instruction.
0080   /// Note: This is only used during PostRA scheduling. EmitNoop is not called
0081   /// for these noops.
0082   virtual unsigned PreEmitNoops(SUnit *) {
0083     return 0;
0084   }
0085 
0086   /// This overload will be used when the hazard recognizer is being used
0087   /// by a non-scheduling pass, which does not use SUnits.
0088   virtual unsigned PreEmitNoops(MachineInstr *) {
0089     return 0;
0090   }
0091 
0092   /// ShouldPreferAnother - This callback may be invoked if getHazardType
0093   /// returns NoHazard. If, even though there is no hazard, it would be better to
0094   /// schedule another available instruction, this callback should return true.
0095   virtual bool ShouldPreferAnother(SUnit *) {
0096     return false;
0097   }
0098 
0099   /// AdvanceCycle - This callback is invoked whenever the next top-down
0100   /// instruction to be scheduled cannot issue in the current cycle, either
0101   /// because of latency or resource conflicts.  This should increment the
0102   /// internal state of the hazard recognizer so that previously "Hazard"
0103   /// instructions will now not be hazards.
0104   virtual void AdvanceCycle() {}
0105 
0106   /// RecedeCycle - This callback is invoked whenever the next bottom-up
0107   /// instruction to be scheduled cannot issue in the current cycle, either
0108   /// because of latency or resource conflicts.
0109   virtual void RecedeCycle() {}
0110 
0111   /// EmitNoop - This callback is invoked when a noop was added to the
0112   /// instruction stream.
0113   virtual void EmitNoop() {
0114     // Default implementation: count it as a cycle.
0115     AdvanceCycle();
0116   }
0117 
0118   /// EmitNoops - This callback is invoked when noops were added to the
0119   /// instruction stream.
0120   virtual void EmitNoops(unsigned Quantity) {
0121     // Default implementation: count it as a cycle.
0122     for (unsigned i = 0; i < Quantity; ++i)
0123       EmitNoop();
0124   }
0125 };
0126 
0127 } // end namespace llvm
0128 
0129 #endif // LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H