20#define DEBUG_TYPE "llvm-mca"
49 : STI(STI), PRF(PRF), RM(STI.getSchedModel()), CB(CB), LSU(LSU),
50 NumIssued(), CarryOver(), Bandwidth(), LastWriteBackCycle() {}
53 return STI.getSchedModel().IssueWidth;
57 return !IssuedInst.empty() || SI.isValid() || CarriedOver;
61 if (SI.isValid() || CarriedOver)
68 if (Bandwidth < NumMicroOps && !ShouldCarryOver)
80 if (RM.checkAvailability(
IR.getInstruction()->getDesc())) {
89 unsigned FirstWBCycle =
IR.getInstruction()->getLatency();
90 for (
const WriteState &WS :
IR.getInstruction()->getDefs()) {
91 int CyclesLeft = WS.getCyclesLeft();
93 CyclesLeft = WS.getLatency();
96 FirstWBCycle = std::min(FirstWBCycle, (
unsigned)CyclesLeft);
106 for (
const ReadState &RS :
IR.getInstruction()->getUses()) {
115bool InOrderIssueStage::canExecute(
const InstRef &
IR) {
116 assert(!
SI.getCyclesLeft() &&
"Should not have reached this code!");
117 assert(!
SI.isValid() &&
"Should not have reached this code!");
129 if (
IR.getInstruction()->isMemOp() && !LSU.isReady(
IR)) {
136 if (
unsigned CustomStallCycles = CB.checkCustomHazard(IssuedInst,
IR)) {
141 if (LastWriteBackCycle) {
142 if (!
IR.getInstruction()->getRetireOOO()) {
145 if (NextWriteBackCycle < LastWriteBackCycle) {
146 SI.update(
IR, LastWriteBackCycle - NextWriteBackCycle,
157 unsigned SourceIndex,
169void InOrderIssueStage::notifyInstructionIssued(
const InstRef &
IR,
178void InOrderIssueStage::notifyInstructionDispatched(
179 const InstRef &
IR,
unsigned Ops, ArrayRef<unsigned> UsedRegs) {
181 HWInstructionDispatchedEvent(
IR, UsedRegs,
Ops));
186void InOrderIssueStage::notifyInstructionExecuted(
const InstRef &
IR) {
192void InOrderIssueStage::notifyInstructionRetired(
const InstRef &
IR,
193 ArrayRef<unsigned> FreedRegs) {
214 unsigned SourceIndex =
IR.getSourceIndex();
217 if (!canExecute(
IR)) {
219 <<
SI.getCyclesLeft() <<
" cycles\n");
231 notifyInstructionDispatched(
IR, NumMicroOps, UsedRegs);
234 RM.issueInstruction(
Desc, UsedResources);
243 Use.first.first = RM.resolveResourceMask(Mask);
245 notifyInstructionIssued(
IR, UsedResources);
247 bool ShouldCarryOver = NumMicroOps > Bandwidth;
248 if (ShouldCarryOver) {
249 CarryOver = NumMicroOps - Bandwidth;
252 NumIssued += Bandwidth;
255 NumIssued += NumMicroOps;
256 Bandwidth = IS.
getEndGroup() ? 0 : Bandwidth - NumMicroOps;
264 PRF.onInstructionExecuted(&IS);
265 LSU.onInstructionExecuted(
IR);
266 notifyInstructionExecuted(
IR);
268 retireInstruction(
IR);
269 return llvm::ErrorSuccess();
272 IssuedInst.push_back(
IR);
274 if (!
IR.getInstruction()->getRetireOOO())
277 return llvm::ErrorSuccess();
280void InOrderIssueStage::updateIssuedInst() {
283 unsigned NumExecuted = 0;
284 for (
auto I = IssuedInst.begin(),
E = IssuedInst.end();
285 I != (
E - NumExecuted);) {
290 if (!IS.isExecuted()) {
292 <<
" is still executing\n");
301 PRF.onInstructionExecuted(&IS);
302 LSU.onInstructionExecuted(
IR);
303 notifyInstructionExecuted(
IR);
305 retireInstruction(*
I);
310 std::iter_swap(
I,
E - NumExecuted);
314 IssuedInst.resize(IssuedInst.size() - NumExecuted);
317void InOrderIssueStage::updateCarriedOver() {
321 assert(!SI.isValid() &&
"A stalled instruction cannot be carried over.");
323 if (CarryOver > Bandwidth) {
324 CarryOver -= Bandwidth;
326 LLVM_DEBUG(
dbgs() <<
"[N] Carry over (" << CarryOver <<
"uops left) #"
327 << CarriedOver <<
" \n");
331 LLVM_DEBUG(
dbgs() <<
"[N] Carry over (complete) #" << CarriedOver <<
" \n");
333 if (CarriedOver.getInstruction()->getEndGroup())
336 Bandwidth -= CarryOver;
340 if (CarriedOver.getInstruction()->isExecuted()) {
341 PRF.onInstructionExecuted(CarriedOver.getInstruction());
342 LSU.onInstructionExecuted(CarriedOver);
343 notifyInstructionExecuted(CarriedOver);
345 retireInstruction(CarriedOver);
348 CarriedOver = InstRef();
352void InOrderIssueStage::retireInstruction(
InstRef &
IR) {
356 llvm::SmallVector<unsigned, 4> FreedRegs(PRF.getNumRegisterFiles());
357 for (
const WriteState &WS : IS.getDefs())
358 PRF.removeRegisterWrite(WS, FreedRegs);
361 LSU.onInstructionRetired(
IR);
363 notifyInstructionRetired(
IR, FreedRegs);
366void InOrderIssueStage::notifyStallEvent() {
367 assert(SI.getCyclesLeft() &&
"A zero cycles stall?");
368 assert(SI.isValid() &&
"Invalid stall information found!");
370 const InstRef &
IR = SI.getInstruction();
372 switch (SI.getStallKind()) {
406 RM.cycleEvent(Freed);
415 if (!SI.getCyclesLeft()) {
426 if (SI.getCyclesLeft()) {
443 if (LastWriteBackCycle > 0)
444 --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.
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.
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
const InstrDesc & getDesc() const
SmallVectorImpl< WriteState > & getDefs()
SmallVectorImpl< ReadState > & getUses()
bool getBeginGroup() const
An instruction propagated through the simulated instruction pipeline.
LLVM_ABI void cycleEvent()
bool isEliminated() const
int getCyclesLeft() const
LLVM_ABI void execute(unsigned IID)
void setLSUTokenID(unsigned LSUTok)
LLVM_ABI void dispatch(unsigned RCUTokenID)
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.
void addRegisterWrite(WriteRef Write, MutableArrayRef< unsigned > UsedPhysRegs)
unsigned getNumRegisterFiles() const
RAWHazard checkRAWHazards(const MCSubtargetInfo &STI, const ReadState &RS) const
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
void update(const InstRef &Inst, unsigned Cycles, StallKind SK)