1 | //=- llvm/CodeGen/ScoreboardHazardRecognizer.h - Schedule 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 defines the ScoreboardHazardRecognizer class, which |
10 | // encapsulates hazard-avoidance heuristics for scheduling, based on the |
11 | // scheduling itineraries specified for the target. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H |
16 | #define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H |
17 | |
18 | #include "llvm/CodeGen/ScheduleHazardRecognizer.h" |
19 | #include "llvm/MC/MCInstrItineraries.h" |
20 | #include <cassert> |
21 | #include <cstddef> |
22 | #include <cstring> |
23 | |
24 | namespace llvm { |
25 | |
26 | class ScheduleDAG; |
27 | class SUnit; |
28 | |
29 | class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer { |
30 | // Scoreboard to track function unit usage. Scoreboard[0] is a |
31 | // mask of the FUs in use in the cycle currently being |
32 | // schedule. Scoreboard[1] is a mask for the next cycle. The |
33 | // Scoreboard is used as a circular buffer with the current cycle |
34 | // indicated by Head. |
35 | // |
36 | // Scoreboard always counts cycles in forward execution order. If used by a |
37 | // bottom-up scheduler, then the scoreboard cycles are the inverse of the |
38 | // scheduler's cycles. |
39 | class Scoreboard { |
40 | InstrStage::FuncUnits *Data = nullptr; |
41 | |
42 | // The maximum number of cycles monitored by the Scoreboard. This |
43 | // value is determined based on the target itineraries to ensure |
44 | // that all hazards can be tracked. |
45 | size_t Depth = 0; |
46 | |
47 | // Indices into the Scoreboard that represent the current cycle. |
48 | size_t Head = 0; |
49 | |
50 | public: |
51 | Scoreboard() = default; |
52 | Scoreboard &operator=(const Scoreboard &other) = delete; |
53 | Scoreboard(const Scoreboard &other) = delete; |
54 | ~Scoreboard() { |
55 | delete[] Data; |
56 | } |
57 | |
58 | size_t getDepth() const { return Depth; } |
59 | |
60 | InstrStage::FuncUnits& operator[](size_t idx) const { |
61 | // Depth is expected to be a power-of-2. |
62 | assert(Depth && !(Depth & (Depth - 1)) && |
63 | "Scoreboard was not initialized properly!" ); |
64 | |
65 | return Data[(Head + idx) & (Depth-1)]; |
66 | } |
67 | |
68 | void reset(size_t d = 1) { |
69 | if (!Data) { |
70 | Depth = d; |
71 | Data = new InstrStage::FuncUnits[Depth]; |
72 | } |
73 | |
74 | memset(s: Data, c: 0, n: Depth * sizeof(Data[0])); |
75 | Head = 0; |
76 | } |
77 | |
78 | void advance() { |
79 | Head = (Head + 1) & (Depth-1); |
80 | } |
81 | |
82 | void recede() { |
83 | Head = (Head - 1) & (Depth-1); |
84 | } |
85 | |
86 | // Print the scoreboard. |
87 | void dump() const; |
88 | }; |
89 | |
90 | // Support for tracing ScoreboardHazardRecognizer as a component within |
91 | // another module. |
92 | const char *DebugType; |
93 | |
94 | // Itinerary data for the target. |
95 | const InstrItineraryData *ItinData; |
96 | |
97 | const ScheduleDAG *DAG; |
98 | |
99 | /// IssueWidth - Max issue per cycle. 0=Unknown. |
100 | unsigned IssueWidth = 0; |
101 | |
102 | /// IssueCount - Count instructions issued in this cycle. |
103 | unsigned IssueCount = 0; |
104 | |
105 | Scoreboard ReservedScoreboard; |
106 | Scoreboard RequiredScoreboard; |
107 | |
108 | public: |
109 | ScoreboardHazardRecognizer(const InstrItineraryData *II, |
110 | const ScheduleDAG *DAG, |
111 | const char *ParentDebugType = "" ); |
112 | |
113 | /// atIssueLimit - Return true if no more instructions may be issued in this |
114 | /// cycle. |
115 | bool atIssueLimit() const override; |
116 | |
117 | // Stalls provides an cycle offset at which SU will be scheduled. It will be |
118 | // negative for bottom-up scheduling. |
119 | HazardType getHazardType(SUnit *SU, int Stalls) override; |
120 | void Reset() override; |
121 | void EmitInstruction(SUnit *SU) override; |
122 | void AdvanceCycle() override; |
123 | void RecedeCycle() override; |
124 | }; |
125 | |
126 | } // end namespace llvm |
127 | |
128 | #endif // LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H |
129 | |