Home | History | Annotate | Line # | Download | only in CodeGen
      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 
     53     ~Scoreboard() {
     54       delete[] Data;
     55     }
     56 
     57     size_t getDepth() const { return Depth; }
     58 
     59     InstrStage::FuncUnits& operator[](size_t idx) const {
     60       // Depth is expected to be a power-of-2.
     61       assert(Depth && !(Depth & (Depth - 1)) &&
     62              "Scoreboard was not initialized properly!");
     63 
     64       return Data[(Head + idx) & (Depth-1)];
     65     }
     66 
     67     void reset(size_t d = 1) {
     68       if (!Data) {
     69         Depth = d;
     70         Data = new InstrStage::FuncUnits[Depth];
     71       }
     72 
     73       memset(Data, 0, Depth * sizeof(Data[0]));
     74       Head = 0;
     75     }
     76 
     77     void advance() {
     78       Head = (Head + 1) & (Depth-1);
     79     }
     80 
     81     void recede() {
     82       Head = (Head - 1) & (Depth-1);
     83     }
     84 
     85     // Print the scoreboard.
     86     void dump() const;
     87   };
     88 
     89   // Support for tracing ScoreboardHazardRecognizer as a component within
     90   // another module.
     91   const char *DebugType;
     92 
     93   // Itinerary data for the target.
     94   const InstrItineraryData *ItinData;
     95 
     96   const ScheduleDAG *DAG;
     97 
     98   /// IssueWidth - Max issue per cycle. 0=Unknown.
     99   unsigned IssueWidth = 0;
    100 
    101   /// IssueCount - Count instructions issued in this cycle.
    102   unsigned IssueCount = 0;
    103 
    104   Scoreboard ReservedScoreboard;
    105   Scoreboard RequiredScoreboard;
    106 
    107 public:
    108   ScoreboardHazardRecognizer(const InstrItineraryData *II,
    109                              const ScheduleDAG *DAG,
    110                              const char *ParentDebugType = "");
    111 
    112   /// atIssueLimit - Return true if no more instructions may be issued in this
    113   /// cycle.
    114   bool atIssueLimit() const override;
    115 
    116   // Stalls provides an cycle offset at which SU will be scheduled. It will be
    117   // negative for bottom-up scheduling.
    118   HazardType getHazardType(SUnit *SU, int Stalls) override;
    119   void Reset() override;
    120   void EmitInstruction(SUnit *SU) override;
    121   void AdvanceCycle() override;
    122   void RecedeCycle() override;
    123 };
    124 
    125 } // end namespace llvm
    126 
    127 #endif // LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
    128