blob: fee3ca2a94892114c383e6d4cc236e32c91fa24d [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
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000029/// An out of order backend for a specific subtarget.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000030///
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
Andrea Di Biagiob5088da2018-03-23 11:50:43 +000050 InstrBuilder &IB;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000051 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:
Andrea Di Biagiob5088da2018-03-23 11:50:43 +000062 Backend(const llvm::MCSubtargetInfo &Subtarget,
63 const llvm::MCRegisterInfo &MRI, InstrBuilder &B, SourceMgr &Source,
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000064 unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0,
Andrea Di Biagio020ba252018-04-05 11:36:50 +000065 unsigned LoadQueueSize = 0, unsigned StoreQueueSize = 0,
66 bool AssumeNoAlias = false)
Andrea Di Biagiob5088da2018-03-23 11:50:43 +000067 : STI(Subtarget), IB(B),
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000068 HWS(llvm::make_unique<Scheduler>(this, Subtarget.getSchedModel(),
69 LoadQueueSize, StoreQueueSize,
70 AssumeNoAlias)),
Andrea Di Biagioc74ad502018-04-05 15:41:41 +000071 DU(llvm::make_unique<DispatchUnit>(this, Subtarget.getSchedModel(), MRI,
72 RegisterFileSize, DispatchWidth,
73 HWS.get())),
Andrea Di Biagio8af3fe82018-03-08 16:08:43 +000074 SM(Source), Cycles(0) {
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
Matt Davis21a8d322018-05-07 18:29:15 +000083 void eraseInstruction(const InstRef &IR) {
84 Instructions.erase(IR.getSourceIndex());
Clement Courbet844f22d2018-03-13 13:11:01 +000085 }
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000086
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000087 void addEventListener(HWEventListener *Listener);
88 void notifyCycleBegin(unsigned Cycle);
Clement Courbet844f22d2018-03-13 13:11:01 +000089 void notifyInstructionEvent(const HWInstructionEvent &Event);
Andrea Di Biagio91ab2ee2018-03-19 13:23:07 +000090 void notifyStallEvent(const HWStallEvent &Event);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000091 void notifyResourceAvailable(const ResourceRef &RR);
Andrea Di Biagioa3f2e482018-03-20 18:20:39 +000092 void notifyReservedBuffers(llvm::ArrayRef<unsigned> Buffers);
93 void notifyReleasedBuffers(llvm::ArrayRef<unsigned> Buffers);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000094 void notifyCycleEnd(unsigned Cycle);
95};
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000096} // namespace mca
97
98#endif