]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / SystemZ / SystemZHazardRecognizer.h
1 //=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- 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 declares a hazard recognizer for the SystemZ scheduler.
11 //
12 // This class is used by the SystemZ scheduling strategy to maintain
13 // the state during scheduling, and provide cost functions for
14 // scheduling candidates. This includes:
15 //
16 // * Decoder grouping. A decoder group can maximally hold 3 uops, and
17 // instructions that always begin a new group should be scheduled when
18 // the current decoder group is empty.
19 // * Processor resources usage. It is beneficial to balance the use of
20 // resources.
21 //
22 // A goal is to consider all instructions, also those outside of any
23 // scheduling region. Such instructions are "advanced" past and include
24 // single instructions before a scheduling region, branches etc.
25 //
26 // A block that has only one predecessor continues scheduling with the state
27 // of it (which may be updated by emitting branches).
28 //
29 // ===---------------------------------------------------------------------===//
30
31 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
32 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
33
34 #include "SystemZSubtarget.h"
35 #include "llvm/ADT/SmallVector.h"
36 #include "llvm/CodeGen/MachineFunction.h"
37 #include "llvm/CodeGen/MachineScheduler.h"
38 #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
39 #include "llvm/MC/MCInstrDesc.h"
40 #include "llvm/Support/raw_ostream.h"
41 #include <string>
42
43 namespace llvm {
44
45 /// SystemZHazardRecognizer maintains the state for one MBB during scheduling.
46 class SystemZHazardRecognizer : public ScheduleHazardRecognizer {
47
48 #ifndef NDEBUG
49   const SystemZInstrInfo *TII;
50 #endif
51   const TargetSchedModel *SchedModel;
52
53   /// Keep track of the number of decoder slots used in the current
54   /// decoder group.
55   unsigned CurrGroupSize;
56
57   /// The tracking of resources here are quite similar to the common
58   /// code use of a critical resource. However, z13 differs in the way
59   /// that it has two processor sides which may be interesting to
60   /// model in the future (a work in progress).
61
62   /// Counters for the number of uops scheduled per processor
63   /// resource.
64   SmallVector<int, 0> ProcResourceCounters;
65
66   /// This is the resource with the greatest queue, which the
67   /// scheduler tries to avoid.
68   unsigned CriticalResourceIdx;
69
70   /// Return the number of decoder slots MI requires.
71   inline unsigned getNumDecoderSlots(SUnit *SU) const;
72
73   /// Return true if MI fits into current decoder group.
74   bool fitsIntoCurrentGroup(SUnit *SU) const;
75
76   /// Two decoder groups per cycle are formed (for z13), meaning 2x3
77   /// instructions. This function returns a number between 0 and 5,
78   /// representing the current decoder slot of the current cycle.
79   unsigned getCurrCycleIdx();
80   
81   /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx()
82   /// when a stalling operation is scheduled (which uses the FPd resource).
83   unsigned LastFPdOpCycleIdx;
84
85   /// A counter of decoder groups scheduled.
86   unsigned GrpCount;
87
88   unsigned getCurrGroupSize() {return CurrGroupSize;};
89
90   /// Start next decoder group.
91   void nextGroup(bool DbgOutput = true);
92
93   /// Clear all counters for processor resources.
94   void clearProcResCounters();
95
96   /// With the goal of alternating processor sides for stalling (FPd)
97   /// ops, return true if it seems good to schedule an FPd op next.
98   bool isFPdOpPreferred_distance(const SUnit *SU);
99
100   /// Last emitted instruction or nullptr.
101   MachineInstr *LastEmittedMI;
102
103 public:
104   SystemZHazardRecognizer(const SystemZInstrInfo *tii,
105                           const TargetSchedModel *SM)
106       :
107 #ifndef NDEBUG
108         TII(tii),
109 #endif
110         SchedModel(SM) {
111     Reset();
112   }
113
114   HazardType getHazardType(SUnit *m, int Stalls = 0) override;
115   void Reset() override;
116   void EmitInstruction(SUnit *SU) override;
117
118   /// Resolves and cache a resolved scheduling class for an SUnit.
119   const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
120     if (!SU->SchedClass && SchedModel->hasInstrSchedModel())
121       SU->SchedClass = SchedModel->resolveSchedClass(SU->getInstr());
122     return SU->SchedClass;
123   }
124
125   /// Wrap a non-scheduled instruction in an SU and emit it.
126   void emitInstruction(MachineInstr *MI, bool TakenBranch = false);
127
128   // Cost functions used by SystemZPostRASchedStrategy while
129   // evaluating candidates.
130
131   /// Return the cost of decoder grouping for SU. If SU must start a
132   /// new decoder group, this is negative if this fits the schedule or
133   /// positive if it would mean ending a group prematurely. For normal
134   /// instructions this returns 0.
135   int groupingCost(SUnit *SU) const; 
136
137   /// Return the cost of SU in regards to processor resources usage.
138   /// A positive value means it would be better to wait with SU, while
139   /// a negative value means it would be good to schedule SU next.
140   int resourcesCost(SUnit *SU);
141
142 #ifndef NDEBUG
143   // Debug dumping.
144   std::string CurGroupDbg; // current group as text
145   void dumpSU(SUnit *SU, raw_ostream &OS) const;
146   void dumpCurrGroup(std::string Msg = "") const;
147   void dumpProcResourceCounters() const;
148 #endif
149
150   MachineBasicBlock::iterator getLastEmittedMI() { return LastEmittedMI; }
151
152   /// Copy counters from end of single predecessor.
153   void copyState(SystemZHazardRecognizer *Incoming);
154 };
155
156 } // namespace llvm
157
158 #endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */