blob: 6e2db08227e6d3125f75ca7f71ed6e04d810800e [file] [log] [blame]
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +00001//===--------------------- 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
23namespace mca {
24
25struct 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.
45class 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
59public:
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