diff --git a/include/llvm/MCA/HardwareUnits/Scheduler.h b/include/llvm/MCA/HardwareUnits/Scheduler.h index 53e416b1643..6e1d68020fe 100644 --- a/include/llvm/MCA/HardwareUnits/Scheduler.h +++ b/include/llvm/MCA/HardwareUnits/Scheduler.h @@ -96,6 +96,13 @@ class Scheduler : public HardwareUnit { std::vector ReadySet; std::vector IssuedSet; + // A mask of busy resource units. It defaults to the empty set (i.e. a zero + // mask), and it is cleared at the beginning of every cycle. + // It is updated every time the scheduler fails to issue an instruction from + // the ready set due to unavailable pipeline resources. + // Each bit of the mask represents an unavailable resource. + uint64_t BusyResourceUnits; + /// Verify the given selection strategy and set the Strategy member /// accordingly. If no strategy is provided, the DefaultSchedulerStrategy is /// used. @@ -126,7 +133,7 @@ public: Scheduler(std::unique_ptr RM, LSUnit &Lsu, std::unique_ptr SelectStrategy) - : LSU(Lsu), Resources(std::move(RM)) { + : LSU(Lsu), Resources(std::move(RM)), BusyResourceUnits(0) { initializeStrategy(std::move(SelectStrategy)); } @@ -194,6 +201,10 @@ public: /// resources are not available. InstRef select(); + /// Returns a mask of busy resources. Each bit of the mask identifies a unique + /// processor resource unit. In the absence of bottlenecks caused by resource + /// pressure, the mask value returned by this method is always zero. + uint64_t getBusyResourceUnits() const { return BusyResourceUnits; } bool arePipelinesFullyUsed() const { return !Resources->getAvailableProcResUnits(); } diff --git a/lib/MCA/HardwareUnits/Scheduler.cpp b/lib/MCA/HardwareUnits/Scheduler.cpp index fb1080dc02c..b8cd62f8bd4 100644 --- a/lib/MCA/HardwareUnits/Scheduler.cpp +++ b/lib/MCA/HardwareUnits/Scheduler.cpp @@ -140,6 +140,7 @@ InstRef Scheduler::select() { Strategy->compare(IR, ReadySet[QueueIndex])) { const InstrDesc &D = IR.getInstruction()->getDesc(); uint64_t BusyResourceMask = Resources->checkAvailability(D); + BusyResourceUnits |= BusyResourceMask; if (!BusyResourceMask) QueueIndex = I; } @@ -196,6 +197,8 @@ void Scheduler::cycleEvent(SmallVectorImpl &Freed, IR.getInstruction()->cycleEvent(); promoteToReadySet(Ready); + + BusyResourceUnits = 0; } bool Scheduler::mustIssueImmediately(const InstRef &IR) const {