20#define DEBUG_TYPE "llvm-mca"
49 float ReservationStationScaleFactor)
51 RM(STI.getSchedModel(), ReservationStationScaleFactor), CB(CB), LSU(LSU),
52 NumIssued(), CarryOver(), Bandwidth(), LastWriteBackCycle() {}
55 return STI.getSchedModel().IssueWidth;
59 return !IssuedInst.empty() || SI.isValid() || CarriedOver;
63 if (SI.isValid() || CarriedOver)
70 if (Bandwidth < NumMicroOps && !ShouldCarryOver)
82 if (RM.checkAvailability(
IR.getInstruction()->getDesc())) {
91 unsigned FirstWBCycle =
IR.getInstruction()->getLatency();
92 for (
const WriteState &WS :
IR.getInstruction()->getDefs()) {
93 int CyclesLeft = WS.getCyclesLeft();
95 CyclesLeft = WS.getLatency();
98 FirstWBCycle = std::min(FirstWBCycle, (
unsigned)CyclesLeft);
108 for (
const ReadState &RS :
IR.getInstruction()->getUses()) {
117bool InOrderIssueStage::canExecute(
const InstRef &
IR) {
118 assert(!
SI.getCyclesLeft() &&
"Should not have reached this code!");
119 assert(!
SI.isValid() &&
"Should not have reached this code!");
131 if (
IR.getInstruction()->isMemOp() && !LSU.isReady(
IR)) {
138 if (
unsigned CustomStallCycles = CB.checkCustomHazard(IssuedInst,
IR)) {
143 if (LastWriteBackCycle) {
144 if (!
IR.getInstruction()->getRetireOOO()) {
147 if (NextWriteBackCycle < LastWriteBackCycle) {
148 SI.update(
IR, LastWriteBackCycle - NextWriteBackCycle,
159 unsigned SourceIndex,
162 assert(!IS.isEliminated());
171void InOrderIssueStage::notifyInstructionIssued(
const InstRef &
IR,
180void InOrderIssueStage::notifyInstructionDispatched(
181 const InstRef &
IR,
unsigned Ops, ArrayRef<unsigned> UsedRegs) {
183 HWInstructionDispatchedEvent(
IR, UsedRegs,
Ops));
188void InOrderIssueStage::notifyInstructionExecuted(
const InstRef &
IR) {
194void InOrderIssueStage::notifyInstructionRetired(
const InstRef &
IR,
195 ArrayRef<unsigned> FreedRegs) {
203 IS.setLSUTokenID(LSU.dispatch(
IR));
216 unsigned SourceIndex =
IR.getSourceIndex();
219 if (!canExecute(
IR)) {
221 <<
SI.getCyclesLeft() <<
" cycles\n");
227 IS.dispatch(RCUTokenID);
232 unsigned NumMicroOps = IS.getNumMicroOps();
233 notifyInstructionDispatched(
IR, NumMicroOps, UsedRegs);
236 RM.issueInstruction(
Desc, UsedResources);
237 IS.execute(SourceIndex);
245 Use.first.first = RM.resolveResourceMask(Mask);
247 notifyInstructionIssued(
IR, UsedResources);
249 bool ShouldCarryOver = NumMicroOps > Bandwidth;
250 if (ShouldCarryOver) {
251 CarryOver = NumMicroOps - Bandwidth;
254 NumIssued += Bandwidth;
257 NumIssued += NumMicroOps;
258 Bandwidth =
IS.getEndGroup() ? 0 : Bandwidth - NumMicroOps;
265 if (
IS.isExecuted() && !ShouldCarryOver) {
266 PRF.onInstructionExecuted(&IS);
267 LSU.onInstructionExecuted(
IR);
268 notifyInstructionExecuted(
IR);
270 retireInstruction(
IR);
271 return llvm::ErrorSuccess();
274 IssuedInst.push_back(
IR);
276 if (!
IR.getInstruction()->getRetireOOO())
277 LastWriteBackCycle =
IS.getCyclesLeft();
279 return llvm::ErrorSuccess();
282void InOrderIssueStage::updateIssuedInst() {
285 unsigned NumExecuted = 0;
286 for (
auto I = IssuedInst.begin(),
E = IssuedInst.end();
287 I != (
E - NumExecuted);) {
292 if (!
IS.isExecuted()) {
294 <<
" is still executing\n");
302 if (CarriedOver.getInstruction() !=
IR.getInstruction()) {
303 PRF.onInstructionExecuted(&IS);
304 LSU.onInstructionExecuted(
IR);
305 notifyInstructionExecuted(
IR);
307 retireInstruction(*
I);
312 std::iter_swap(
I,
E - NumExecuted);
316 IssuedInst.resize(IssuedInst.size() - NumExecuted);
319void InOrderIssueStage::updateCarriedOver() {
323 assert(!SI.isValid() &&
"A stalled instruction cannot be carried over.");
325 if (CarryOver > Bandwidth) {
326 CarryOver -= Bandwidth;
328 LLVM_DEBUG(
dbgs() <<
"[N] Carry over (" << CarryOver <<
"uops left) #"
329 << CarriedOver <<
" \n");
333 LLVM_DEBUG(
dbgs() <<
"[N] Carry over (complete) #" << CarriedOver <<
" \n");
335 if (CarriedOver.getInstruction()->getEndGroup())
338 Bandwidth -= CarryOver;
342 if (CarriedOver.getInstruction()->isExecuted()) {
343 PRF.onInstructionExecuted(CarriedOver.getInstruction());
344 LSU.onInstructionExecuted(CarriedOver);
345 notifyInstructionExecuted(CarriedOver);
347 retireInstruction(CarriedOver);
350 CarriedOver = InstRef();
354void InOrderIssueStage::retireInstruction(
InstRef &
IR) {
358 llvm::SmallVector<unsigned, 4> FreedRegs(PRF.getNumRegisterFiles());
359 for (
const WriteState &WS :
IS.getDefs())
360 PRF.removeRegisterWrite(WS, FreedRegs);
363 LSU.onInstructionRetired(
IR);
365 notifyInstructionRetired(
IR, FreedRegs);
368void InOrderIssueStage::notifyStallEvent() {
369 assert(SI.getCyclesLeft() &&
"A zero cycles stall?");
370 assert(SI.isValid() &&
"Invalid stall information found!");
372 const InstRef &
IR = SI.getInstruction();
374 switch (SI.getStallKind()) {
408 RM.cycleEvent(Freed);
417 if (!SI.getCyclesLeft()) {
428 if (SI.getCyclesLeft()) {
445 if (LastWriteBackCycle > 0)
446 --LastWriteBackCycle;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
InOrderIssueStage implements an in-order execution pipeline.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
A Load/Store unit class that models load/store queues and that implements a simple weak memory consis...
Legalize the Machine IR a function s Machine IR
This file defines abstractions used by the Pipeline to model register reads, register writes and inst...
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
This file defines a register mapping file class.
This file simulates the hardware responsible for retiring instructions.
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.
Generic base class for all target subtargets.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A Use represents the edge between a Value definition and its users.
Class which can be overriden by targets to enforce instruction dependencies and behaviours that aren'...
bool hasWorkToComplete() const override
Returns true if some instructions are still executing this stage.
Error cycleEnd() override
Called once at the end of each cycle.
Error execute(InstRef &IR) override
The primary action that this stage performs on instruction IR.
bool isAvailable(const InstRef &) const override
Returns true if it can execute IR during this cycle.
unsigned getIssueWidth() const
Error cycleStart() override
Called once at the start of each cycle.
An InstRef contains both a SourceMgr index and Instruction pair.
unsigned getNumMicroOps() const
bool getBeginGroup() const
An instruction propagated through the simulated instruction pipeline.
Abstract base interface for LS (load/store) units in llvm-mca.
virtual void onInstructionIssued(const InstRef &IR)=0
Tracks register operand latency in cycles.
Manages hardware register files, and tracks register definitions for register renaming purposes.
LLVM_ABI void addRegisterWrite(WriteRef Write, MutableArrayRef< unsigned > UsedPhysRegs)
unsigned getNumRegisterFiles() const
LLVM_ABI RAWHazard checkRAWHazards(const MCSubtargetInfo &STI, const ReadState &RS) const
LLVM_ABI void addRegisterRead(ReadState &RS, const MCSubtargetInfo &STI) const
void notifyEvent(const EventT &Event) const
Notify listeners of a particular hardware event.
A reference to a register write.
Tracks uses of a register definition (e.g.
static void addRegisterReadWrite(RegisterFile &PRF, Instruction &IS, unsigned SourceIndex, const MCSubtargetInfo &STI, SmallVectorImpl< unsigned > &UsedRegs)
static bool hasResourceHazard(const ResourceManager &RM, const InstRef &IR)
static unsigned findFirstWriteBackCycle(const InstRef &IR)
std::pair< ResourceRef, ReleaseAtCycles > ResourceUse
static unsigned checkRegisterHazard(const RegisterFile &PRF, const MCSubtargetInfo &STI, const InstRef &IR)
Return a number of cycles left until register requirements of the instructions are met.
constexpr int UNKNOWN_CYCLES
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.
An instruction descriptor.
bool hasUnknownCycles() const
static const unsigned UnhandledTokenID
LLVM_ABI void update(const InstRef &Inst, unsigned Cycles, StallKind SK)