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 | |
Andrea Di Biagio | 3db1fd9 | 2018-03-08 16:34:19 +0000 | [diff] [blame] | 25 | class HWEventListener; |
Clement Courbet | 844f22d | 2018-03-13 13:11:01 +0000 | [diff] [blame] | 26 | class HWInstructionEvent; |
Andrea Di Biagio | 91ab2ee | 2018-03-19 13:23:07 +0000 | [diff] [blame] | 27 | class HWStallEvent; |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 28 | |
| 29 | /// \brief An out of order backend for a specific subtarget. |
| 30 | /// |
| 31 | /// It emulates an out-of-order execution of instructions. Instructions are |
| 32 | /// fetched from a MCInst sequence managed by an object of class SourceMgr. |
| 33 | /// Instructions are firstly dispatched to the schedulers and then executed. |
| 34 | /// This class tracks the lifetime of an instruction from the moment where |
| 35 | /// it gets dispatched to the schedulers, to the moment where it finishes |
| 36 | /// executing and register writes are architecturally committed. |
| 37 | /// In particular, it monitors changes in the state of every instruction |
| 38 | /// in flight. |
| 39 | /// Instructions are executed in a loop of iterations. The number of iterations |
| 40 | /// is defined by the SourceMgr object. |
| 41 | /// The Backend entrypoint is method 'Run()' which execute cycles in a loop |
| 42 | /// until there are new instructions to dispatch, and not every instruction |
| 43 | /// has been retired. |
| 44 | /// Internally, the Backend collects statistical information in the form of |
| 45 | /// histograms. For example, it tracks how the dispatch group size changes |
| 46 | /// over time. |
| 47 | class Backend { |
| 48 | const llvm::MCSubtargetInfo &STI; |
| 49 | |
| 50 | std::unique_ptr<InstrBuilder> IB; |
| 51 | std::unique_ptr<Scheduler> HWS; |
| 52 | std::unique_ptr<DispatchUnit> DU; |
Andrea Di Biagio | 8af3fe8 | 2018-03-08 16:08:43 +0000 | [diff] [blame] | 53 | SourceMgr &SM; |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 54 | unsigned Cycles; |
| 55 | |
| 56 | llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> Instructions; |
| 57 | std::set<HWEventListener *> Listeners; |
| 58 | |
| 59 | void runCycle(unsigned Cycle); |
| 60 | |
| 61 | public: |
| 62 | Backend(const llvm::MCSubtargetInfo &Subtarget, const llvm::MCInstrInfo &MCII, |
Andrea Di Biagio | 8af3fe8 | 2018-03-08 16:08:43 +0000 | [diff] [blame] | 63 | const llvm::MCRegisterInfo &MRI, SourceMgr &Source, |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 64 | unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0, |
| 65 | unsigned MaxRetirePerCycle = 0, unsigned LoadQueueSize = 0, |
| 66 | unsigned StoreQueueSize = 0, bool AssumeNoAlias = false) |
| 67 | : STI(Subtarget), |
| 68 | HWS(llvm::make_unique<Scheduler>(this, Subtarget.getSchedModel(), |
| 69 | LoadQueueSize, StoreQueueSize, |
| 70 | AssumeNoAlias)), |
| 71 | DU(llvm::make_unique<DispatchUnit>( |
| 72 | this, MRI, Subtarget.getSchedModel().MicroOpBufferSize, |
| 73 | RegisterFileSize, MaxRetirePerCycle, DispatchWidth, HWS.get())), |
Andrea Di Biagio | 8af3fe8 | 2018-03-08 16:08:43 +0000 | [diff] [blame] | 74 | SM(Source), Cycles(0) { |
Andrea Di Biagio | 4704f03 | 2018-03-20 12:25:54 +0000 | [diff] [blame] | 75 | IB = llvm::make_unique<InstrBuilder>(Subtarget, MCII); |
Clement Courbet | 844f22d | 2018-03-13 13:11:01 +0000 | [diff] [blame] | 76 | HWS->setDispatchUnit(DU.get()); |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 77 | } |
| 78 | |
| 79 | void run() { |
Andrea Di Biagio | 8af3fe8 | 2018-03-08 16:08:43 +0000 | [diff] [blame] | 80 | while (SM.hasNext() || !DU->isRCUEmpty()) |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 81 | runCycle(Cycles++); |
| 82 | } |
| 83 | |
Clement Courbet | 844f22d | 2018-03-13 13:11:01 +0000 | [diff] [blame] | 84 | const Instruction &getInstruction(unsigned Index) const { |
| 85 | const auto It = Instructions.find(Index); |
| 86 | assert(It != Instructions.end() && "no running instructions with index"); |
| 87 | assert(It->second); |
Clement Courbet | 7efbea1 | 2018-03-13 13:44:18 +0000 | [diff] [blame] | 88 | return *It->second; |
Clement Courbet | 844f22d | 2018-03-13 13:11:01 +0000 | [diff] [blame] | 89 | } |
| 90 | void eraseInstruction(unsigned Index) { Instructions.erase(Index); } |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 91 | |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 92 | void addEventListener(HWEventListener *Listener); |
| 93 | void notifyCycleBegin(unsigned Cycle); |
Clement Courbet | 844f22d | 2018-03-13 13:11:01 +0000 | [diff] [blame] | 94 | void notifyInstructionEvent(const HWInstructionEvent &Event); |
Andrea Di Biagio | 91ab2ee | 2018-03-19 13:23:07 +0000 | [diff] [blame] | 95 | void notifyStallEvent(const HWStallEvent &Event); |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 96 | void notifyResourceAvailable(const ResourceRef &RR); |
Andrea Di Biagio | a3f2e48 | 2018-03-20 18:20:39 +0000 | [diff] [blame] | 97 | void notifyReservedBuffers(llvm::ArrayRef<unsigned> Buffers); |
| 98 | void notifyReleasedBuffers(llvm::ArrayRef<unsigned> Buffers); |
Andrea Di Biagio | 3a6b092 | 2018-03-08 13:05:02 +0000 | [diff] [blame] | 99 | void notifyCycleEnd(unsigned Cycle); |
| 100 | }; |
| 101 | |
| 102 | } // namespace mca |
| 103 | |
| 104 | #endif |