aboutsummaryrefslogtreecommitdiff
path: root/include/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/MCA/HardwareUnits/Scheduler.h56
-rw-r--r--include/llvm/MCA/Instruction.h25
2 files changed, 57 insertions, 24 deletions
diff --git a/include/llvm/MCA/HardwareUnits/Scheduler.h b/include/llvm/MCA/HardwareUnits/Scheduler.h
index 6e1d68020fe..f1cfcbe6b2b 100644
--- a/include/llvm/MCA/HardwareUnits/Scheduler.h
+++ b/include/llvm/MCA/HardwareUnits/Scheduler.h
@@ -67,22 +67,6 @@ public:
/// resources. This class is also responsible for tracking the progress of
/// instructions from the dispatch stage, until the write-back stage.
///
-/// An instruction dispatched to the Scheduler is initially placed into either
-/// the 'WaitSet' or the 'ReadySet' depending on the availability of the input
-/// operands.
-///
-/// An instruction is moved from the WaitSet to the ReadySet when register
-/// operands become available, and all memory dependencies are met.
-/// Instructions that are moved from the WaitSet to the ReadySet transition
-/// in state from 'IS_DISPATCHED' to 'IS_READY'.
-///
-/// On every cycle, the Scheduler checks if it can promote instructions from the
-/// WaitSet to the ReadySet.
-///
-/// An Instruction is moved from the ReadySet the `IssuedSet` when it is issued
-/// to a (one or more) pipeline(s). This event also causes an instruction state
-/// transition (i.e. from state IS_READY, to state IS_EXECUTING). An Instruction
-/// leaves the IssuedSet when it reaches the write-back stage.
class Scheduler : public HardwareUnit {
LSUnit &LSU;
@@ -92,7 +76,38 @@ class Scheduler : public HardwareUnit {
// Hardware resources that are managed by this scheduler.
std::unique_ptr<ResourceManager> Resources;
+ // Instructions dispatched to the Scheduler are internally classified based on
+ // the instruction stage (see Instruction::InstrStage).
+ //
+ // An Instruction dispatched to the Scheduler is added to the WaitSet if not
+ // all its register operands are available, and at least one latency is unknown.
+ // By construction, the WaitSet only contains instructions that are in the
+ // IS_DISPATCHED stage.
+ //
+ // An Instruction transitions from the WaitSet to the PendingSet if the
+ // instruction is not ready yet, but the latency of every register read is known.
+ // Instructions in the PendingSet are expected to be in the IS_PENDING stage.
+ //
+ // Instructions in the PendingSet are immediately dominated only by
+ // instructions that have already been issued to the underlying pipelines.
+ // In the presence of bottlenecks caused by data dependencies, the PendingSet
+ // can be inspected to identify problematic data dependencies between
+ // instructions.
+ //
+ // An instruction is moved to the ReadySet when all register operands become
+ // available, and all memory dependencies are met. Instructions that are
+ // moved from the PendingSet to the ReadySet transition in state from
+ // 'IS_PENDING' to 'IS_READY'.
+ //
+ // On every cycle, the Scheduler checks if it can promote instructions from the
+ // PendingSet to the ReadySet.
+ //
+ // An Instruction is moved from the ReadySet to the `IssuedSet` when it starts
+ // exection. This event also causes an instruction state transition (i.e. from
+ // state IS_READY, to state IS_EXECUTING). An Instruction leaves the IssuedSet
+ // only when it reaches the write-back stage.
std::vector<InstRef> WaitSet;
+ std::vector<InstRef> PendingSet;
std::vector<InstRef> ReadySet;
std::vector<InstRef> IssuedSet;
@@ -118,9 +133,14 @@ class Scheduler : public HardwareUnit {
// vector 'Executed'.
void updateIssuedSet(SmallVectorImpl<InstRef> &Executed);
- // Try to promote instructions from WaitSet to ReadySet.
+ // Try to promote instructions from the PendingSet to the ReadySet.
// Add promoted instructions to the 'Ready' vector in input.
- void promoteToReadySet(SmallVectorImpl<InstRef> &Ready);
+ // Returns true if at least one instruction was promoted.
+ bool promoteToReadySet(SmallVectorImpl<InstRef> &Ready);
+
+ // Try to promote instructions from the WaitSet to the PendingSet.
+ // Returns true if at least one instruction was promoted.
+ bool promoteToPendingSet();
public:
Scheduler(const MCSchedModel &Model, LSUnit &Lsu)
diff --git a/include/llvm/MCA/Instruction.h b/include/llvm/MCA/Instruction.h
index 133cce51b44..0fba938560d 100644
--- a/include/llvm/MCA/Instruction.h
+++ b/include/llvm/MCA/Instruction.h
@@ -168,6 +168,14 @@ public:
bool clearsSuperRegisters() const { return ClearsSuperRegs; }
bool isWriteZero() const { return WritesZero; }
bool isEliminated() const { return IsEliminated; }
+
+ bool isReady() const {
+ if (getDependentWrite())
+ return false;
+ unsigned CyclesLeft = getDependentWriteCyclesLeft();
+ return !CyclesLeft || CyclesLeft < getLatency();
+ }
+
bool isExecuted() const {
return CyclesLeft != UNKNOWN_CYCLES && CyclesLeft <= 0;
}
@@ -239,6 +247,7 @@ public:
unsigned getRegisterID() const { return RegisterID; }
unsigned getRegisterFileID() const { return PRFID; }
+ bool isPending() const { return !IndependentFromDef && CyclesLeft > 0; }
bool isReady() const { return IsReady; }
bool isImplicitRead() const { return RD->isImplicitRead(); }
@@ -411,6 +420,7 @@ class Instruction : public InstructionBase {
enum InstrStage {
IS_INVALID, // Instruction in an invalid state.
IS_DISPATCHED, // Instruction dispatched but operands are not ready.
+ IS_PENDING, // Instruction is not ready, but operand latency is known.
IS_READY, // Instruction dispatched and operands ready.
IS_EXECUTING, // Instruction issued.
IS_EXECUTED, // Instruction executed. Values are written back.
@@ -444,15 +454,18 @@ public:
// all the definitions.
void execute();
- // Force a transition from the IS_DISPATCHED state to the IS_READY state if
- // input operands are all ready. State transitions normally occur at the
- // beginning of a new cycle (see method cycleEvent()). However, the scheduler
- // may decide to promote instructions from the wait queue to the ready queue
- // as the result of another issue event. This method is called every time the
- // instruction might have changed in state.
+ // Force a transition from the IS_DISPATCHED state to the IS_READY or
+ // IS_PENDING state. State transitions normally occur either at the beginning
+ // of a new cycle (see method cycleEvent()), or as a result of another issue
+ // event. This method is called every time the instruction might have changed
+ // in state. It internally delegates to method updateDispatched() and
+ // updateWaiting().
void update();
+ bool updateDispatched();
+ bool updatePending();
bool isDispatched() const { return Stage == IS_DISPATCHED; }
+ bool isPending() const { return Stage == IS_PENDING; }
bool isReady() const { return Stage == IS_READY; }
bool isExecuting() const { return Stage == IS_EXECUTING; }
bool isExecuted() const { return Stage == IS_EXECUTED; }