diff options
Diffstat (limited to 'llvm/tools/llvm-mca/include')
6 files changed, 57 insertions, 14 deletions
diff --git a/llvm/tools/llvm-mca/include/HWEventListener.h b/llvm/tools/llvm-mca/include/HWEventListener.h index be56c5c09a9..cef78041565 100644 --- a/llvm/tools/llvm-mca/include/HWEventListener.h +++ b/llvm/tools/llvm-mca/include/HWEventListener.h @@ -16,8 +16,8 @@ #define LLVM_TOOLS_LLVM_MCA_HWEVENTLISTENER_H #include "Instruction.h" +#include "Support.h" #include "llvm/ADT/ArrayRef.h" -#include <utility> namespace mca { @@ -61,11 +61,12 @@ public: class HWInstructionIssuedEvent : public HWInstructionEvent { public: using ResourceRef = std::pair<uint64_t, uint64_t>; - HWInstructionIssuedEvent(const InstRef &IR, - llvm::ArrayRef<std::pair<ResourceRef, double>> UR) + HWInstructionIssuedEvent( + const InstRef &IR, + llvm::ArrayRef<std::pair<ResourceRef, ResourceCycles>> UR) : HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {} - llvm::ArrayRef<std::pair<ResourceRef, double>> UsedResources; + llvm::ArrayRef<std::pair<ResourceRef, ResourceCycles>> UsedResources; }; class HWInstructionDispatchedEvent : public HWInstructionEvent { diff --git a/llvm/tools/llvm-mca/include/HardwareUnits/ResourceManager.h b/llvm/tools/llvm-mca/include/HardwareUnits/ResourceManager.h index c3f893660eb..dfac15f53fc 100644 --- a/llvm/tools/llvm-mca/include/HardwareUnits/ResourceManager.h +++ b/llvm/tools/llvm-mca/include/HardwareUnits/ResourceManager.h @@ -17,6 +17,7 @@ #define LLVM_TOOLS_LLVM_MCA_RESOURCE_MANAGER_H #include "Instruction.h" +#include "Support.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -344,7 +345,7 @@ public: void issueInstruction( const InstrDesc &Desc, - llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Pipes); + llvm::SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes); void cycleEvent(llvm::SmallVectorImpl<ResourceRef> &ResourcesFreed); diff --git a/llvm/tools/llvm-mca/include/HardwareUnits/Scheduler.h b/llvm/tools/llvm-mca/include/HardwareUnits/Scheduler.h index 61bbf3fcf36..db124958ee5 100644 --- a/llvm/tools/llvm-mca/include/HardwareUnits/Scheduler.h +++ b/llvm/tools/llvm-mca/include/HardwareUnits/Scheduler.h @@ -18,6 +18,7 @@ #include "HardwareUnits/HardwareUnit.h" #include "HardwareUnits/LSUnit.h" #include "ResourceManager.h" +#include "Support.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCSchedule.h" @@ -103,7 +104,7 @@ class Scheduler : public HardwareUnit { /// Issue an instruction without updating the ready queue. void issueInstructionImpl( InstRef &IR, - llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Pipes); + llvm::SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes); // Identify instructions that have finished executing, and remove them from // the IssuedSet. References to executed instructions are added to input @@ -164,10 +165,10 @@ public: /// Issue an instruction and populates a vector of used pipeline resources, /// and a vector of instructions that transitioned to the ready state as a /// result of this event. - void - issueInstruction(InstRef &IR, - llvm::SmallVectorImpl<std::pair<ResourceRef, double>> &Used, - llvm::SmallVectorImpl<InstRef> &Ready); + void issueInstruction( + InstRef &IR, + llvm::SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Used, + llvm::SmallVectorImpl<InstRef> &Ready); /// Returns true if IR has to be issued immediately, or if IR is a zero /// latency instruction. diff --git a/llvm/tools/llvm-mca/include/Stages/ExecuteStage.h b/llvm/tools/llvm-mca/include/Stages/ExecuteStage.h index a2753e5572f..82e5c7be3d2 100644 --- a/llvm/tools/llvm-mca/include/Stages/ExecuteStage.h +++ b/llvm/tools/llvm-mca/include/Stages/ExecuteStage.h @@ -59,9 +59,9 @@ public: llvm::Error cycleStart() override; llvm::Error execute(InstRef &IR) override; - void - notifyInstructionIssued(const InstRef &IR, - llvm::ArrayRef<std::pair<ResourceRef, double>> Used); + void notifyInstructionIssued( + const InstRef &IR, + llvm::ArrayRef<std::pair<ResourceRef, ResourceCycles>> Used); void notifyInstructionExecuted(const InstRef &IR); void notifyInstructionReady(const InstRef &IR); void notifyResourceAvailable(const ResourceRef &RR); diff --git a/llvm/tools/llvm-mca/include/Stages/InstructionTables.h b/llvm/tools/llvm-mca/include/Stages/InstructionTables.h index f8a299af269..16be004d115 100644 --- a/llvm/tools/llvm-mca/include/Stages/InstructionTables.h +++ b/llvm/tools/llvm-mca/include/Stages/InstructionTables.h @@ -28,7 +28,7 @@ namespace mca { class InstructionTables final : public Stage { const llvm::MCSchedModel &SM; InstrBuilder &IB; - llvm::SmallVector<std::pair<ResourceRef, double>, 4> UsedResources; + llvm::SmallVector<std::pair<ResourceRef, ResourceCycles>, 4> UsedResources; public: InstructionTables(const llvm::MCSchedModel &Model, InstrBuilder &Builder) diff --git a/llvm/tools/llvm-mca/include/Support.h b/llvm/tools/llvm-mca/include/Support.h index fd8d8b5a23b..91c8e1b4177 100644 --- a/llvm/tools/llvm-mca/include/Support.h +++ b/llvm/tools/llvm-mca/include/Support.h @@ -21,6 +21,46 @@ namespace mca { +/// This class represents the number of cycles per resource (fractions of +/// cycles). That quantity is managed here as a ratio, and accessed via the +/// double cast-operator below. The two quantities, number of cycles and +/// number of resources, are kept separate. This is used by the +/// ResourcePressureView to calculate the average resource cycles +/// per instruction/iteration. +class ResourceCycles { + unsigned Numerator, Denominator; + +public: + ResourceCycles() : Numerator(0), Denominator(1) {} + ResourceCycles(unsigned Cycles, unsigned ResourceUnits = 1) + : Numerator(Cycles), Denominator(ResourceUnits) {} + + operator double() const { + assert(Denominator && "Invalid denominator (must be non-zero)."); + return (Denominator == 1) ? Numerator : (double)Numerator / Denominator; + } + + // Add the components of RHS to this instance. Instead of calculating + // the final value here, we keep track of the numerator and denominator + // separately, to reduce floating point error. + ResourceCycles &operator+=(const ResourceCycles &RHS) { + if (Denominator == RHS.Denominator) + Numerator += RHS.Numerator; + else { + // Create a common denominator for LHS and RHS by calculating the least + // common multiple from the GCD. + unsigned GCD = + llvm::GreatestCommonDivisor64(Denominator, RHS.Denominator); + unsigned LCM = (Denominator * RHS.Denominator) / GCD; + unsigned LHSNumerator = Numerator * (LCM / Denominator); + unsigned RHSNumerator = RHS.Numerator * (LCM / RHS.Denominator); + Numerator = LHSNumerator + RHSNumerator; + Denominator = LCM; + } + return *this; + } +}; + /// Populates vector Masks with processor resource masks. /// /// The number of bits set in a mask depends on the processor resource type. |