diff options
| author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-10-25 17:03:51 +0000 |
|---|---|---|
| committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-10-25 17:03:51 +0000 |
| commit | 1e6d0aad7e90744dcaa5d9be8644dafd5181834d (patch) | |
| tree | 05238615999949d7eeee62ec2ad4e32c15b13915 /llvm/tools/llvm-mca/include | |
| parent | b53cf99388b24f1477dc50cada7a21c083bca083 (diff) | |
| download | bcm5719-llvm-1e6d0aad7e90744dcaa5d9be8644dafd5181834d.tar.gz bcm5719-llvm-1e6d0aad7e90744dcaa5d9be8644dafd5181834d.zip | |
[llvm-mca] Introduce a new base class for mca::Instruction, and change how read/write information is stored.
This patch introduces a new base class for Instruction named InstructionBase.
Class InstructionBase is responsible for tracking data dependencies with the
help of ReadState and WriteState objects. Class Instruction now derives from
InstructionBase, and adds extra information related to the `InstrStage` as well
as the `RCUTokenID`.
ReadState and WriteState objects are no longer unique pointers. This avoids
extra heap allocation and pointer checks that weren't really needed. Now, those
objects are simply stored into SmallVectors. We use a SmallVector instead of a
std::vector because we expect most instructions to only have a very small number
of reads and writes. By using a simple SmallVector we also avoid extra heap
allocations most of the time.
In a debug build, this improves the performance of llvm-mca by roughly 10% (I
still have to verify the impact in performance on a release build).
llvm-svn: 345280
Diffstat (limited to 'llvm/tools/llvm-mca/include')
| -rw-r--r-- | llvm/tools/llvm-mca/include/Instruction.h | 106 |
1 files changed, 56 insertions, 50 deletions
diff --git a/llvm/tools/llvm-mca/include/Instruction.h b/llvm/tools/llvm-mca/include/Instruction.h index a1d1082a215..9d1c91ad441 100644 --- a/llvm/tools/llvm-mca/include/Instruction.h +++ b/llvm/tools/llvm-mca/include/Instruction.h @@ -16,7 +16,9 @@ #ifndef LLVM_TOOLS_LLVM_MCA_INSTRUCTION_H #define LLVM_TOOLS_LLVM_MCA_INSTRUCTION_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/MathExtras.h" #ifndef NDEBUG @@ -134,8 +136,6 @@ public: : WD(Desc), CyclesLeft(UNKNOWN_CYCLES), RegisterID(RegID), ClearsSuperRegs(clearsSuperRegs), WritesZero(writesZero), IsEliminated(false), DependentWrite(nullptr), NumWriteUsers(0U) {} - WriteState(const WriteState &Other) = delete; - WriteState &operator=(const WriteState &Other) = delete; int getCyclesLeft() const { return CyclesLeft; } unsigned getWriteResourceID() const { return WD.SClassOrWriteResourceID; } @@ -205,8 +205,6 @@ public: : RD(Desc), RegisterID(RegID), DependentWrites(0), CyclesLeft(UNKNOWN_CYCLES), TotalCycles(0), IsReady(true), IndependentFromDef(false) {} - ReadState(const ReadState &Other) = delete; - ReadState &operator=(const ReadState &Other) = delete; const ReadDescriptor &getDescriptor() const { return RD; } unsigned getSchedClass() const { return RD.SchedClassID; } @@ -313,13 +311,59 @@ struct InstrDesc { InstrDesc &operator=(const InstrDesc &Other) = delete; }; +/// Base class for instructions consumed by the simulation pipeline. +/// +/// This class tracks data dependencies as well as generic properties +/// of the instruction. +class InstructionBase { + const InstrDesc &Desc; + + // This field is set for instructions that are candidates for move + // elimination. For more information about move elimination, see the + // definition of RegisterMappingTracker in RegisterFile.h + bool IsOptimizableMove; + + // Output dependencies. + // One entry per each implicit and explicit register definition. + llvm::SmallVector<WriteState, 4> Defs; + + // Input dependencies. + // One entry per each implicit and explicit register use. + llvm::SmallVector<ReadState, 4> Uses; + +public: + InstructionBase(const InstrDesc &D) : Desc(D), IsOptimizableMove(false) {} + + llvm::SmallVectorImpl<WriteState> &getDefs() { return Defs; } + const llvm::ArrayRef<WriteState> getDefs() const { return Defs; } + llvm::SmallVectorImpl<ReadState> &getUses() { return Uses; } + const llvm::ArrayRef<ReadState> getUses() const { return Uses; } + const InstrDesc &getDesc() const { return Desc; } + + unsigned getLatency() const { return Desc.MaxLatency; } + + bool hasDependentUsers() const { + return llvm::any_of( + Defs, [](const WriteState &Def) { return Def.getNumUsers() > 0; }); + } + + unsigned getNumUsers() const { + unsigned NumUsers = 0; + for (const WriteState &Def : Defs) + NumUsers += Def.getNumUsers(); + return NumUsers; + } + + // Returns true if this instruction is a candidate for move elimination. + bool isOptimizableMove() const { return IsOptimizableMove; } + void setOptimizableMove() { IsOptimizableMove = true; } +}; + /// An instruction propagated through the simulated instruction pipeline. /// /// This class is used to monitor changes to the internal state of instructions /// that are sent to the various components of the simulated hardware pipeline. -class Instruction { - const InstrDesc &Desc; - +class Instruction : public InstructionBase { enum InstrStage { IS_INVALID, // Instruction in an invalid state. IS_AVAILABLE, // Instruction dispatched but operands are not ready. @@ -339,51 +383,16 @@ class Instruction { // Retire Unit token ID for this instruction. unsigned RCUTokenID; - // This field is set for instructions that are candidates for move - // elimination. For more information about move elimination, see the - // definition of RegisterMappingTracker in RegisterFile.h - bool IsOptimizableMove; - - using UniqueDef = std::unique_ptr<WriteState>; - using UniqueUse = std::unique_ptr<ReadState>; - using VecDefs = std::vector<UniqueDef>; - using VecUses = std::vector<UniqueUse>; - - // Output dependencies. - // One entry per each implicit and explicit register definition. - VecDefs Defs; - - // Input dependencies. - // One entry per each implicit and explicit register use. - VecUses Uses; - public: Instruction(const InstrDesc &D) - : Desc(D), Stage(IS_INVALID), CyclesLeft(UNKNOWN_CYCLES), RCUTokenID(0), - IsOptimizableMove(false) {} + : InstructionBase(D), Stage(IS_INVALID), CyclesLeft(UNKNOWN_CYCLES), + RCUTokenID(0) {} Instruction(const Instruction &Other) = delete; Instruction &operator=(const Instruction &Other) = delete; - VecDefs &getDefs() { return Defs; } - const VecDefs &getDefs() const { return Defs; } - VecUses &getUses() { return Uses; } - const VecUses &getUses() const { return Uses; } - const InstrDesc &getDesc() const { return Desc; } unsigned getRCUTokenID() const { return RCUTokenID; } int getCyclesLeft() const { return CyclesLeft; } - bool hasDependentUsers() const { - return llvm::any_of( - Defs, [](const UniqueDef &Def) { return Def->getNumUsers() > 0; }); - } - - unsigned getNumUsers() const { - unsigned NumUsers = 0; - for (const UniqueDef &Def : Defs) - NumUsers += Def->getNumUsers(); - return NumUsers; - } - // Transition to the dispatch stage, and assign a RCUToken to this // instruction. The RCUToken is used to track the completion of every // register write performed by this instruction. @@ -407,13 +416,10 @@ public: bool isExecuted() const { return Stage == IS_EXECUTED; } bool isRetired() const { return Stage == IS_RETIRED; } - // Returns true if this instruction is a candidate for move elimination. - bool isOptimizableMove() const { return IsOptimizableMove; } - void setOptimizableMove() { IsOptimizableMove = true; } bool isEliminated() const { - return isReady() && Defs.size() && - llvm::all_of(Defs, - [](const UniqueDef &D) { return D->isEliminated(); }); + return isReady() && getDefs().size() && + llvm::all_of(getDefs(), + [](const WriteState &W) { return W.isEliminated(); }); } // Forces a transition from state IS_AVAILABLE to state IS_EXECUTED. |

