blob: 027850ecba5406e1517dab3d0c7888a31fc631f7 [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 Biagio91ab2ee2018-03-19 13:23:07 +000027class HWStallEvent;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000028
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.
47class 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 Biagio8af3fe82018-03-08 16:08:43 +000053 SourceMgr &SM;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000054 unsigned Cycles;
55
56 llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> Instructions;
57 std::set<HWEventListener *> Listeners;
58
59 void runCycle(unsigned Cycle);
60
61public:
62 Backend(const llvm::MCSubtargetInfo &Subtarget, const llvm::MCInstrInfo &MCII,
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000063 const llvm::MCRegisterInfo &MRI, SourceMgr &Source,
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000064 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 Biagio8af3fe82018-03-08 16:08:43 +000074 SM(Source), Cycles(0) {
Andrea Di Biagio4704f032018-03-20 12:25:54 +000075 IB = llvm::make_unique<InstrBuilder>(Subtarget, MCII);
Clement Courbet844f22d2018-03-13 13:11:01 +000076 HWS->setDispatchUnit(DU.get());
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000077 }
78
79 void run() {
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000080 while (SM.hasNext() || !DU->isRCUEmpty())
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000081 runCycle(Cycles++);
82 }
83
Clement Courbet844f22d2018-03-13 13:11:01 +000084 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 Courbet7efbea12018-03-13 13:44:18 +000088 return *It->second;
Clement Courbet844f22d2018-03-13 13:11:01 +000089 }
90 void eraseInstruction(unsigned Index) { Instructions.erase(Index); }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000091
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000092 void addEventListener(HWEventListener *Listener);
93 void notifyCycleBegin(unsigned Cycle);
Clement Courbet844f22d2018-03-13 13:11:01 +000094 void notifyInstructionEvent(const HWInstructionEvent &Event);
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +000095 void notifyStallEvent(const HWStallEvent &Event);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000096 void notifyResourceAvailable(const ResourceRef &RR);
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +000097 void notifyReservedBuffers(llvm::ArrayRef<unsigned> Buffers);
98 void notifyReleasedBuffers(llvm::ArrayRef<unsigned> Buffers);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000099 void notifyCycleEnd(unsigned Cycle);
100};
101
102} // namespace mca
103
104#endif