LLVM: lib/MCA/Stages/DispatchStage.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
21
22#define DEBUG_TYPE "llvm-mca"
23
24namespace llvm {
25namespace mca {
26
31 : DispatchWidth(MaxDispatchWidth), AvailableEntries(MaxDispatchWidth),
32 CarryOver(0U), STI(Subtarget), RCU(R), PRF(F) {
33 if (!DispatchWidth)
35}
36
37void DispatchStage::notifyInstructionDispatched(const InstRef &IR,
39 unsigned UOps) const {
40 LLVM_DEBUG(dbgs() << "[E] Instruction Dispatched: #" << IR << '\n');
43}
44
45bool DispatchStage::checkPRF(const InstRef &IR) const {
47 for (const WriteState &RegDef : IR.getInstruction()->getDefs())
49
50 const unsigned RegisterMask = PRF.isAvailable(RegDefs);
51
52 if (RegisterMask) {
55 return false;
56 }
57
58 return true;
59}
60
61bool DispatchStage::checkRCU(const InstRef &IR) const {
62 const unsigned NumMicroOps = IR.getInstruction()->getNumMicroOps();
63 if (RCU.isAvailable(NumMicroOps))
64 return true;
67 return false;
68}
69
70bool DispatchStage::canDispatch(const InstRef &IR) const {
71 bool CanDispatch = checkRCU(IR);
72 CanDispatch &= checkPRF(IR);
74 return CanDispatch;
75}
76
78 assert(!CarryOver && "Cannot dispatch another instruction!");
80 const unsigned NumMicroOps = IS.getNumMicroOps();
81 if (NumMicroOps > DispatchWidth) {
82 assert(AvailableEntries == DispatchWidth);
83 AvailableEntries = 0;
84 CarryOver = NumMicroOps - DispatchWidth;
85 CarriedOver = IR;
86 } else {
87 assert(AvailableEntries >= NumMicroOps);
88 AvailableEntries -= NumMicroOps;
89 }
90
91
92 if (IS.getEndGroup())
93 AvailableEntries = 0;
94
95
96 if (IS.isOptimizableMove())
97 if (PRF.tryEliminateMoveOrSwap(IS.getDefs(), IS.getUses()))
98 IS.setEliminated();
99
100
101
102
103
104
105
106
107
108
109 if (!IS.isEliminated()) {
110 for (ReadState &RS : IS.getUses())
111 PRF.addRegisterRead(RS, STI);
112 }
113
114
115
116
117 SmallVector<unsigned, 4> RegisterFiles(PRF.getNumRegisterFiles());
118 for (WriteState &WS : IS.getDefs())
119 PRF.addRegisterWrite(WriteRef(IR.getSourceIndex(), &WS), RegisterFiles);
120
121
122 unsigned RCUTokenID = RCU.dispatch(IR);
123
124 IS.dispatch(RCUTokenID);
125
126
127
128 notifyInstructionDispatched(IR, RegisterFiles,
129 std::min(DispatchWidth, NumMicroOps));
131}
132
134
135
136 if (!CarryOver) {
137 AvailableEntries = DispatchWidth;
139 }
140
141 AvailableEntries = CarryOver >= DispatchWidth ? 0 : DispatchWidth - CarryOver;
142 unsigned DispatchedOpcodes = DispatchWidth - AvailableEntries;
143 CarryOver -= DispatchedOpcodes;
144 assert(CarriedOver && "Invalid dispatched instruction");
145
147 notifyInstructionDispatched(CarriedOver, RegisterFiles, DispatchedOpcodes);
148 if (!CarryOver)
151}
152
154
155 if (!AvailableEntries)
156 return false;
157
160 unsigned Required = std::min(NumMicroOps, DispatchWidth);
161 if (Required > AvailableEntries)
162 return false;
163
164 if (Inst.getBeginGroup() && AvailableEntries != DispatchWidth)
165 return false;
166
167
168
169
170 return canDispatch(IR);
171}
172
174 assert(canDispatch(IR) && "Cannot dispatch another instruction!");
175 return dispatch(IR);
176}
177
178#ifndef NDEBUG
180 PRF.dump();
181 RCU.dump();
182}
183#endif
184}
185}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file models the dispatch component of an instruction pipeline.
This file defines the main interface for hardware event listeners.
Legalize the Machine IR a function s Machine IR
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Subclass of Error for the sole purpose of identifying the success path in the type system.
Lightweight error class with error context and mandatory checking.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Generic base class for all target subtargets.
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Error cycleStart() override
Called once at the start of each cycle.
Definition DispatchStage.cpp:133
void dump() const
Definition DispatchStage.cpp:179
bool isAvailable(const InstRef &IR) const override
Returns true if it can execute IR during this cycle.
Definition DispatchStage.cpp:153
Error execute(InstRef &IR) override
The primary action that this stage performs on instruction IR.
Definition DispatchStage.cpp:173
DispatchStage(const MCSubtargetInfo &Subtarget, const MCRegisterInfo &MRI, unsigned MaxDispatchWidth, RetireControlUnit &R, RegisterFile &F)
Definition DispatchStage.cpp:27
An InstRef contains both a SourceMgr index and Instruction pair.
unsigned getNumMicroOps() const
bool getBeginGroup() const
An instruction propagated through the simulated instruction pipeline.
Manages hardware register files, and tracks register definitions for register renaming purposes.
unsigned isAvailable(ArrayRef< MCPhysReg > Regs) const
Error moveToTheNextStage(InstRef &IR)
Called when an instruction is ready to move the next pipeline stage.
void notifyEvent(const EventT &Event) const
Notify listeners of a particular hardware event.
bool checkNextStage(const InstRef &IR) const
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
This class tracks which instructions are in-flight (i.e., dispatched but not retired) in the OoO back...