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