blob: c2532d8a1f861e3afe934d894dd3fbf7558b4100 [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
Andrea Di Biagio3db1fd92018-03-08 16:34:19 +000025class HWEventListener;
Clement Courbet844f22d2018-03-13 13:11:01 +000026class HWInstructionEvent;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000027
28/// \brief An out of order backend for a specific subtarget.
29///
30/// It emulates an out-of-order execution of instructions. Instructions are
31/// fetched from a MCInst sequence managed by an object of class SourceMgr.
32/// Instructions are firstly dispatched to the schedulers and then executed.
33/// This class tracks the lifetime of an instruction from the moment where
34/// it gets dispatched to the schedulers, to the moment where it finishes
35/// executing and register writes are architecturally committed.
36/// In particular, it monitors changes in the state of every instruction
37/// in flight.
38/// Instructions are executed in a loop of iterations. The number of iterations
39/// is defined by the SourceMgr object.
40/// The Backend entrypoint is method 'Run()' which execute cycles in a loop
41/// until there are new instructions to dispatch, and not every instruction
42/// has been retired.
43/// Internally, the Backend collects statistical information in the form of
44/// histograms. For example, it tracks how the dispatch group size changes
45/// over time.
46class Backend {
47 const llvm::MCSubtargetInfo &STI;
48
49 std::unique_ptr<InstrBuilder> IB;
50 std::unique_ptr<Scheduler> HWS;
51 std::unique_ptr<DispatchUnit> DU;
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000052 SourceMgr &SM;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000053 unsigned Cycles;
54
55 llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> Instructions;
56 std::set<HWEventListener *> Listeners;
57
58 void runCycle(unsigned Cycle);
59
60public:
61 Backend(const llvm::MCSubtargetInfo &Subtarget, const llvm::MCInstrInfo &MCII,
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000062 const llvm::MCRegisterInfo &MRI, SourceMgr &Source,
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000063 unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0,
64 unsigned MaxRetirePerCycle = 0, unsigned LoadQueueSize = 0,
65 unsigned StoreQueueSize = 0, bool AssumeNoAlias = false)
66 : STI(Subtarget),
67 HWS(llvm::make_unique<Scheduler>(this, Subtarget.getSchedModel(),
68 LoadQueueSize, StoreQueueSize,
69 AssumeNoAlias)),
70 DU(llvm::make_unique<DispatchUnit>(
71 this, MRI, Subtarget.getSchedModel().MicroOpBufferSize,
72 RegisterFileSize, MaxRetirePerCycle, DispatchWidth, HWS.get())),
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000073 SM(Source), Cycles(0) {
Andrea Di Biagio0c541292018-03-10 16:55:07 +000074 IB = llvm::make_unique<InstrBuilder>(MCII, HWS->getProcResourceMasks());
Clement Courbet844f22d2018-03-13 13:11:01 +000075 HWS->setDispatchUnit(DU.get());
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000076 }
77
78 void run() {
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000079 while (SM.hasNext() || !DU->isRCUEmpty())
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000080 runCycle(Cycles++);
81 }
82
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000083 unsigned getNumIterations() const { return SM.getNumIterations(); }
84 unsigned getNumInstructions() const { return SM.size(); }
Clement Courbet844f22d2018-03-13 13:11:01 +000085 const Instruction &getInstruction(unsigned Index) const {
86 const auto It = Instructions.find(Index);
87 assert(It != Instructions.end() && "no running instructions with index");
88 assert(It->second);
89 return *Instructions.find(Index)->second;
90 }
91 void eraseInstruction(unsigned Index) { Instructions.erase(Index); }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000092 unsigned getNumCycles() const { return Cycles; }
93 unsigned getTotalRegisterMappingsCreated() const {
94 return DU->getTotalRegisterMappingsCreated();
95 }
96 unsigned getMaxUsedRegisterMappings() const {
97 return DU->getMaxUsedRegisterMappings();
98 }
99 unsigned getDispatchWidth() const { return DU->getDispatchWidth(); }
100
101 const llvm::MCSubtargetInfo &getSTI() const { return STI; }
102 const llvm::MCSchedModel &getSchedModel() const {
103 return STI.getSchedModel();
104 }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000105
106 double getRThroughput(const InstrDesc &ID) const {
107 return HWS->getRThroughput(ID);
108 }
109 void getBuffersUsage(std::vector<BufferUsageEntry> &Usage) const {
110 return HWS->getBuffersUsage(Usage);
111 }
112
113 unsigned getNumRATStalls() const { return DU->getNumRATStalls(); }
114 unsigned getNumRCUStalls() const { return DU->getNumRCUStalls(); }
115 unsigned getNumSQStalls() const { return DU->getNumSQStalls(); }
116 unsigned getNumLDQStalls() const { return DU->getNumLDQStalls(); }
117 unsigned getNumSTQStalls() const { return DU->getNumSTQStalls(); }
118 unsigned getNumDispatchGroupStalls() const {
119 return DU->getNumDispatchGroupStalls();
120 }
121
122 const llvm::MCInst &getMCInstFromIndex(unsigned Index) const {
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000123 return SM.getMCInstFromIndex(Index);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000124 }
125
126 const InstrDesc &getInstrDesc(const llvm::MCInst &Inst) const {
127 return IB->getOrCreateInstrDesc(STI, Inst);
128 }
129
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +0000130 const SourceMgr &getSourceMgr() const { return SM; }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000131
132 void addEventListener(HWEventListener *Listener);
133 void notifyCycleBegin(unsigned Cycle);
Clement Courbet844f22d2018-03-13 13:11:01 +0000134 void notifyInstructionEvent(const HWInstructionEvent &Event);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000135 void notifyResourceAvailable(const ResourceRef &RR);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000136 void notifyCycleEnd(unsigned Cycle);
137};
138
139} // namespace mca
140
141#endif