xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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 
getMaxLookAhead()43   unsigned getMaxLookAhead() const { return MaxLookAhead; }
44 
isEnabled()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.
atIssueLimit()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.
Reset()67   virtual void Reset() {}
68 
69   /// EmitInstruction - This callback is invoked when an instruction is
70   /// emitted, to advance the hazard state.
EmitInstruction(SUnit *)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.
EmitInstruction(MachineInstr *)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.
PreEmitNoops(SUnit *)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.
PreEmitNoops(MachineInstr *)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.
ShouldPreferAnother(SUnit *)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.
AdvanceCycle()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.
RecedeCycle()109   virtual void RecedeCycle() {}
110 
111   /// EmitNoop - This callback is invoked when a noop was added to the
112   /// instruction stream.
EmitNoop()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.
EmitNoops(unsigned Quantity)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