1 //===--------------------- Backend.h ----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file implements an OoO backend for the llvm-mca tool.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_TOOLS_LLVM_MCA_BACKEND_H
16 #define LLVM_TOOLS_LLVM_MCA_BACKEND_H
19 #include "InstrBuilder.h"
20 #include "Scheduler.h"
21 #include "SourceMgr.h"
25 class HWEventListener;
26 class HWInstructionEvent;
29 /// \brief An out of order backend for a specific subtarget.
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
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
44 /// Internally, the Backend collects statistical information in the form of
45 /// histograms. For example, it tracks how the dispatch group size changes
48 const llvm::MCSubtargetInfo &STI;
51 std::unique_ptr<Scheduler> HWS;
52 std::unique_ptr<DispatchUnit> DU;
56 llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> Instructions;
57 std::set<HWEventListener *> Listeners;
59 void runCycle(unsigned Cycle);
62 Backend(const llvm::MCSubtargetInfo &Subtarget,
63 const llvm::MCRegisterInfo &MRI, InstrBuilder &B, SourceMgr &Source,
64 unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0,
65 unsigned LoadQueueSize = 0, unsigned StoreQueueSize = 0,
66 bool AssumeNoAlias = false)
67 : STI(Subtarget), IB(B),
68 HWS(llvm::make_unique<Scheduler>(this, Subtarget.getSchedModel(),
69 LoadQueueSize, StoreQueueSize,
71 DU(llvm::make_unique<DispatchUnit>(
72 this, STI, MRI, Subtarget.getSchedModel().MicroOpBufferSize,
73 RegisterFileSize, DispatchWidth, HWS.get())),
74 SM(Source), Cycles(0) {
75 HWS->setDispatchUnit(DU.get());
79 while (SM.hasNext() || !DU->isRCUEmpty())
83 const Instruction &getInstruction(unsigned Index) const {
84 const auto It = Instructions.find(Index);
85 assert(It != Instructions.end() && "no running instructions with index");
89 void eraseInstruction(unsigned Index) { Instructions.erase(Index); }
91 void addEventListener(HWEventListener *Listener);
92 void notifyCycleBegin(unsigned Cycle);
93 void notifyInstructionEvent(const HWInstructionEvent &Event);
94 void notifyStallEvent(const HWStallEvent &Event);
95 void notifyResourceAvailable(const ResourceRef &RR);
96 void notifyReservedBuffers(llvm::ArrayRef<unsigned> Buffers);
97 void notifyReleasedBuffers(llvm::ArrayRef<unsigned> Buffers);
98 void notifyCycleEnd(unsigned Cycle);