Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 1 | //===--------------------- Backend.h ----------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | /// \file |
| 10 | /// |
| 11 | /// This file implements an OoO backend for the llvm-mca tool. |
| 12 | /// |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #ifndef LLVM_TOOLS_LLVM_MCA_BACKEND_H |
| 16 | #define LLVM_TOOLS_LLVM_MCA_BACKEND_H |
| 17 | |
| 18 | #include "Dispatch.h" |
| 19 | #include "InstrBuilder.h" |
| 20 | #include "Scheduler.h" |
| 21 | #include "SourceMgr.h" |
| 22 | |
| 23 | namespace mca { |
| 24 | |
| 25 | struct HWEventListener; |
| 26 | |
| 27 | /// \brief An out of order backend for a specific subtarget. |
| 28 | /// |
| 29 | /// It emulates an out-of-order execution of instructions. Instructions are |
| 30 | /// fetched from a MCInst sequence managed by an object of class SourceMgr. |
| 31 | /// Instructions are firstly dispatched to the schedulers and then executed. |
| 32 | /// This class tracks the lifetime of an instruction from the moment where |
| 33 | /// it gets dispatched to the schedulers, to the moment where it finishes |
| 34 | /// executing and register writes are architecturally committed. |
| 35 | /// In particular, it monitors changes in the state of every instruction |
| 36 | /// in flight. |
| 37 | /// Instructions are executed in a loop of iterations. The number of iterations |
| 38 | /// is defined by the SourceMgr object. |
| 39 | /// The Backend entrypoint is method 'Run()' which execute cycles in a loop |
| 40 | /// until there are new instructions to dispatch, and not every instruction |
| 41 | /// has been retired. |
| 42 | /// Internally, the Backend collects statistical information in the form of |
| 43 | /// histograms. For example, it tracks how the dispatch group size changes |
| 44 | /// over time. |
| 45 | class Backend { |
| 46 | const llvm::MCSubtargetInfo &STI; |
| 47 | |
| 48 | std::unique_ptr<InstrBuilder> IB; |
| 49 | std::unique_ptr<Scheduler> HWS; |
| 50 | std::unique_ptr<DispatchUnit> DU; |
| 51 | std::unique_ptr<SourceMgr> SM; |
| 52 | unsigned Cycles; |
| 53 | |
| 54 | llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> Instructions; |
| 55 | std::set<HWEventListener *> Listeners; |
| 56 | |
| 57 | void runCycle(unsigned Cycle); |
| 58 | |
| 59 | public: |
| 60 | Backend(const llvm::MCSubtargetInfo &Subtarget, const llvm::MCInstrInfo &MCII, |
| 61 | const llvm::MCRegisterInfo &MRI, std::unique_ptr<SourceMgr> Source, |
| 62 | unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0, |
| 63 | unsigned MaxRetirePerCycle = 0, unsigned LoadQueueSize = 0, |
| 64 | unsigned StoreQueueSize = 0, bool AssumeNoAlias = false) |
| 65 | : STI(Subtarget), |
| 66 | HWS(llvm::make_unique<Scheduler>(this, Subtarget.getSchedModel(), |
| 67 | LoadQueueSize, StoreQueueSize, |
| 68 | AssumeNoAlias)), |
| 69 | DU(llvm::make_unique<DispatchUnit>( |
| 70 | this, MRI, Subtarget.getSchedModel().MicroOpBufferSize, |
| 71 | RegisterFileSize, MaxRetirePerCycle, DispatchWidth, HWS.get())), |
| 72 | SM(std::move(Source)), Cycles(0) { |
| 73 | IB = llvm::make_unique<InstrBuilder>(MCII, getProcResourceMasks()); |
| 74 | } |
| 75 | |
| 76 | void run() { |
| 77 | while (SM->hasNext() || !DU->isRCUEmpty()) |
| 78 | runCycle(Cycles++); |
| 79 | } |
| 80 | |
| 81 | unsigned getNumIterations() const { return SM->getNumIterations(); } |
| 82 | unsigned getNumInstructions() const { return SM->size(); } |
| 83 | unsigned getNumCycles() const { return Cycles; } |
| 84 | unsigned getTotalRegisterMappingsCreated() const { |
| 85 | return DU->getTotalRegisterMappingsCreated(); |
| 86 | } |
| 87 | unsigned getMaxUsedRegisterMappings() const { |
| 88 | return DU->getMaxUsedRegisterMappings(); |
| 89 | } |
| 90 | unsigned getDispatchWidth() const { return DU->getDispatchWidth(); } |
| 91 | |
| 92 | const llvm::MCSubtargetInfo &getSTI() const { return STI; } |
| 93 | const llvm::MCSchedModel &getSchedModel() const { |
| 94 | return STI.getSchedModel(); |
| 95 | } |
| 96 | const llvm::ArrayRef<uint64_t> getProcResourceMasks() const { |
| 97 | return HWS->getProcResourceMasks(); |
| 98 | } |
| 99 | |
| 100 | double getRThroughput(const InstrDesc &ID) const { |
| 101 | return HWS->getRThroughput(ID); |
| 102 | } |
| 103 | void getBuffersUsage(std::vector<BufferUsageEntry> &Usage) const { |
| 104 | return HWS->getBuffersUsage(Usage); |
| 105 | } |
| 106 | |
| 107 | unsigned getNumRATStalls() const { return DU->getNumRATStalls(); } |
| 108 | unsigned getNumRCUStalls() const { return DU->getNumRCUStalls(); } |
| 109 | unsigned getNumSQStalls() const { return DU->getNumSQStalls(); } |
| 110 | unsigned getNumLDQStalls() const { return DU->getNumLDQStalls(); } |
| 111 | unsigned getNumSTQStalls() const { return DU->getNumSTQStalls(); } |
| 112 | unsigned getNumDispatchGroupStalls() const { |
| 113 | return DU->getNumDispatchGroupStalls(); |
| 114 | } |
| 115 | |
| 116 | const llvm::MCInst &getMCInstFromIndex(unsigned Index) const { |
| 117 | return SM->getMCInstFromIndex(Index); |
| 118 | } |
| 119 | |
| 120 | const InstrDesc &getInstrDesc(const llvm::MCInst &Inst) const { |
| 121 | return IB->getOrCreateInstrDesc(STI, Inst); |
| 122 | } |
| 123 | |
| 124 | const SourceMgr &getSourceMgr() const { return *SM; } |
| 125 | |
| 126 | void addEventListener(HWEventListener *Listener); |
| 127 | void notifyCycleBegin(unsigned Cycle); |
| 128 | void notifyInstructionDispatched(unsigned Index); |
| 129 | void notifyInstructionReady(unsigned Index); |
| 130 | void notifyInstructionIssued( |
| 131 | unsigned Index, |
| 132 | const llvm::ArrayRef<std::pair<ResourceRef, unsigned>> &Used); |
| 133 | void notifyInstructionExecuted(unsigned Index); |
| 134 | void notifyResourceAvailable(const ResourceRef &RR); |
| 135 | void notifyInstructionRetired(unsigned Index); |
| 136 | void notifyCycleEnd(unsigned Cycle); |
| 137 | }; |
| 138 | |
| 139 | } // namespace mca |
| 140 | |
| 141 | #endif |