blob: 0c755c9ad1b9ace9fe77aa889e37f8edcc06ce8a [file] [log] [blame]
Jonas Paulsson8010b632016-10-20 08:27:16 +00001//=-- 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// ===---------------------------------------------------------------------===//
23
24#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
25#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
26
27#include "SystemZSubtarget.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000028#include "llvm/ADT/SmallVector.h"
Jonas Paulsson8010b632016-10-20 08:27:16 +000029#include "llvm/CodeGen/MachineFunction.h"
30#include "llvm/CodeGen/MachineScheduler.h"
31#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
Jonas Paulsson8010b632016-10-20 08:27:16 +000032#include "llvm/MC/MCInstrDesc.h"
33#include "llvm/Support/raw_ostream.h"
34#include <string>
35
36namespace llvm {
37
38/// SystemZHazardRecognizer maintains the state during scheduling.
39class SystemZHazardRecognizer : public ScheduleHazardRecognizer {
40
41 ScheduleDAGMI *DAG;
42 const TargetSchedModel *SchedModel;
43
44 /// Keep track of the number of decoder slots used in the current
45 /// decoder group.
46 unsigned CurrGroupSize;
47
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).
52
53 /// Counters for the number of uops scheduled per processor
54 /// resource.
55 SmallVector<int, 0> ProcResourceCounters;
56
57 /// This is the resource with the greatest queue, which the
58 /// scheduler tries to avoid.
59 unsigned CriticalResourceIdx;
60
61 /// Return the number of decoder slots MI requires.
62 inline unsigned getNumDecoderSlots(SUnit *SU) const;
63
64 /// Return true if MI fits into current decoder group.
65 bool fitsIntoCurrentGroup(SUnit *SU) const;
66
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();
71
72 /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx()
73 /// when a stalling operation is scheduled (which uses the FPd resource).
74 unsigned LastFPdOpCycleIdx;
75
76 /// A counter of decoder groups scheduled.
77 unsigned GrpCount;
78
79 unsigned getCurrGroupSize() {return CurrGroupSize;};
80
81 /// Start next decoder group.
82 void nextGroup(bool DbgOutput = true);
83
84 /// Clear all counters for processor resources.
85 void clearProcResCounters();
86
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);
90
91public:
92 SystemZHazardRecognizer(const MachineSchedContext *C);
93
94 void setDAG(ScheduleDAGMI *dag) {
95 DAG = dag;
96 SchedModel = dag->getSchedModel();
97 }
98
99 HazardType getHazardType(SUnit *m, int Stalls = 0) override;
100 void Reset() override;
101 void EmitInstruction(SUnit *SU) override;
102
103 // Cost functions used by SystemZPostRASchedStrategy while
104 // evaluating candidates.
105
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;
111
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);
116
117#ifndef NDEBUG
118 // Debug dumping.
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;
123#endif
124};
125
126} // namespace llvm
127
128#endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */