blob: 77f0524960fe98ef200908a7204305be9a30b37d [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
Clement Courbet844f22d2018-03-13 13:11:01 +000083 const Instruction &getInstruction(unsigned Index) const {
84 const auto It = Instructions.find(Index);
85 assert(It != Instructions.end() && "no running instructions with index");
86 assert(It->second);
Clement Courbet7efbea12018-03-13 13:44:18 +000087 return *It->second;
Clement Courbet844f22d2018-03-13 13:11:01 +000088 }
89 void eraseInstruction(unsigned Index) { Instructions.erase(Index); }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000090 unsigned getTotalRegisterMappingsCreated() const {
91 return DU->getTotalRegisterMappingsCreated();
92 }
93 unsigned getMaxUsedRegisterMappings() const {
94 return DU->getMaxUsedRegisterMappings();
95 }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000096 void getBuffersUsage(std::vector<BufferUsageEntry> &Usage) const {
97 return HWS->getBuffersUsage(Usage);
98 }
99
100 unsigned getNumRATStalls() const { return DU->getNumRATStalls(); }
101 unsigned getNumRCUStalls() const { return DU->getNumRCUStalls(); }
102 unsigned getNumSQStalls() const { return DU->getNumSQStalls(); }
103 unsigned getNumLDQStalls() const { return DU->getNumLDQStalls(); }
104 unsigned getNumSTQStalls() const { return DU->getNumSTQStalls(); }
105 unsigned getNumDispatchGroupStalls() const {
106 return DU->getNumDispatchGroupStalls();
107 }
108
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000109 void addEventListener(HWEventListener *Listener);
110 void notifyCycleBegin(unsigned Cycle);
Clement Courbet844f22d2018-03-13 13:11:01 +0000111 void notifyInstructionEvent(const HWInstructionEvent &Event);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000112 void notifyResourceAvailable(const ResourceRef &RR);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +0000113 void notifyCycleEnd(unsigned Cycle);
114};
115
116} // namespace mca
117
118#endif