1 //=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares a hazard recognizer for the SystemZ scheduler.
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:
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
22 // ===---------------------------------------------------------------------===//
24 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
25 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
27 #include "SystemZSubtarget.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/CodeGen/MachineFunction.h"
30 #include "llvm/CodeGen/MachineScheduler.h"
31 #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
32 #include "llvm/MC/MCInstrDesc.h"
33 #include "llvm/Support/raw_ostream.h"
38 /// SystemZHazardRecognizer maintains the state during scheduling.
39 class SystemZHazardRecognizer : public ScheduleHazardRecognizer {
42 const TargetSchedModel *SchedModel;
44 /// Keep track of the number of decoder slots used in the current
46 unsigned CurrGroupSize;
48 /// The tracking of resources here are quite similar to the common
49 /// code use of a critical resource. However, z13 differs in the way
50 /// that it has two processor sides which may be interesting to
51 /// model in the future (a work in progress).
53 /// Counters for the number of uops scheduled per processor
55 SmallVector<int, 0> ProcResourceCounters;
57 /// This is the resource with the greatest queue, which the
58 /// scheduler tries to avoid.
59 unsigned CriticalResourceIdx;
61 /// Return the number of decoder slots MI requires.
62 inline unsigned getNumDecoderSlots(SUnit *SU) const;
64 /// Return true if MI fits into current decoder group.
65 bool fitsIntoCurrentGroup(SUnit *SU) const;
67 /// Two decoder groups per cycle are formed (for z13), meaning 2x3
68 /// instructions. This function returns a number between 0 and 5,
69 /// representing the current decoder slot of the current cycle.
70 unsigned getCurrCycleIdx();
72 /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx()
73 /// when a stalling operation is scheduled (which uses the FPd resource).
74 unsigned LastFPdOpCycleIdx;
76 /// A counter of decoder groups scheduled.
79 unsigned getCurrGroupSize() {return CurrGroupSize;};
81 /// Start next decoder group.
82 void nextGroup(bool DbgOutput = true);
84 /// Clear all counters for processor resources.
85 void clearProcResCounters();
87 /// With the goal of alternating processor sides for stalling (FPd)
88 /// ops, return true if it seems good to schedule an FPd op next.
89 bool isFPdOpPreferred_distance(const SUnit *SU);
92 SystemZHazardRecognizer(const MachineSchedContext *C);
94 void setDAG(ScheduleDAGMI *dag) {
96 SchedModel = dag->getSchedModel();
99 HazardType getHazardType(SUnit *m, int Stalls = 0) override;
100 void Reset() override;
101 void EmitInstruction(SUnit *SU) override;
103 // Cost functions used by SystemZPostRASchedStrategy while
104 // evaluating candidates.
106 /// Return the cost of decoder grouping for SU. If SU must start a
107 /// new decoder group, this is negative if this fits the schedule or
108 /// positive if it would mean ending a group prematurely. For normal
109 /// instructions this returns 0.
110 int groupingCost(SUnit *SU) const;
112 /// Return the cost of SU in regards to processor resources usage.
113 /// A positive value means it would be better to wait with SU, while
114 /// a negative value means it would be good to schedule SU next.
115 int resourcesCost(SUnit *SU);
119 std::string CurGroupDbg; // current group as text
120 void dumpSU(SUnit *SU, raw_ostream &OS) const;
121 void dumpCurrGroup(std::string Msg = "") const;
122 void dumpProcResourceCounters() const;
128 #endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */