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
22#include <cassert>
23#include <cstring>
24
25namespace llvm {
26
27class InstrItineraryData;
28class ScheduleDAG;
29class SUnit;
30
31class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
32  // Scoreboard to track function unit usage. Scoreboard[0] is a
33  // mask of the FUs in use in the cycle currently being
34  // schedule. Scoreboard[1] is a mask for the next cycle. The
35  // Scoreboard is used as a circular buffer with the current cycle
36  // indicated by Head.
37  //
38  // Scoreboard always counts cycles in forward execution order. If used by a
39  // bottom-up scheduler, then the scoreboard cycles are the inverse of the
40  // scheduler's cycles.
41  class Scoreboard {
42    unsigned *Data;
43
44    // The maximum number of cycles monitored by the Scoreboard. This
45    // value is determined based on the target itineraries to ensure
46    // that all hazards can be tracked.
47    size_t Depth;
48    // Indices into the Scoreboard that represent the current cycle.
49    size_t Head;
50  public:
51    Scoreboard():Data(NULL), Depth(0), Head(0) { }
52    ~Scoreboard() {
53      delete[] Data;
54    }
55
56    size_t getDepth() const { return Depth; }
57    unsigned& operator[](size_t idx) const {
58      // Depth is expected to be a power-of-2.
59      assert(Depth && !(Depth & (Depth - 1)) &&
60             "Scoreboard was not initialized properly!");
61
62      return Data[(Head + idx) & (Depth-1)];
63    }
64
65    void reset(size_t d = 1) {
66      if (Data == NULL) {
67        Depth = d;
68        Data = new unsigned[Depth];
69      }
70
71      memset(Data, 0, Depth * sizeof(Data[0]));
72      Head = 0;
73    }
74
75    void advance() {
76      Head = (Head + 1) & (Depth-1);
77    }
78
79    void recede() {
80      Head = (Head - 1) & (Depth-1);
81    }
82
83    // Print the scoreboard.
84    void dump() const;
85  };
86
87#ifndef NDEBUG
88  // Support for tracing ScoreboardHazardRecognizer as a component within
89  // another module. Follows the current thread-unsafe model of tracing.
90  static const char *DebugType;
91#endif
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;
100
101  /// IssueCount - Count instructions issued in this cycle.
102  unsigned IssueCount;
103
104  Scoreboard ReservedScoreboard;
105  Scoreboard RequiredScoreboard;
106
107public:
108  ScoreboardHazardRecognizer(const InstrItineraryData *ItinData,
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  virtual bool atIssueLimit() const;
115
116  // Stalls provides an cycle offset at which SU will be scheduled. It will be
117  // negative for bottom-up scheduling.
118  virtual HazardType getHazardType(SUnit *SU, int Stalls);
119  virtual void Reset();
120  virtual void EmitInstruction(SUnit *SU);
121  virtual void AdvanceCycle();
122  virtual void RecedeCycle();
123};
124
125}
126
127#endif //!LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
128