OSDN Git Service

[llvm-mca] Remove flag -max-retire-per-cycle, and update the docs.
[android-x86/external-llvm.git] / tools / llvm-mca / Backend.h
1 //===--------------------- 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
23 namespace mca {
24
25 class HWEventListener;
26 class HWInstructionEvent;
27 class HWStallEvent;
28
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.
47 class Backend {
48   const llvm::MCSubtargetInfo &STI;
49
50   InstrBuilder &IB;
51   std::unique_ptr<Scheduler> HWS;
52   std::unique_ptr<DispatchUnit> DU;
53   SourceMgr &SM;
54   unsigned Cycles;
55
56   llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> Instructions;
57   std::set<HWEventListener *> Listeners;
58
59   void runCycle(unsigned Cycle);
60
61 public:
62   Backend(const llvm::MCSubtargetInfo &Subtarget,
63           const llvm::MCRegisterInfo &MRI, InstrBuilder &B, SourceMgr &Source,
64           unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0,
65           unsigned LoadQueueSize = 0, unsigned StoreQueueSize = 0,
66           bool AssumeNoAlias = false)
67       : STI(Subtarget), IB(B),
68         HWS(llvm::make_unique<Scheduler>(this, Subtarget.getSchedModel(),
69                                          LoadQueueSize, StoreQueueSize,
70                                          AssumeNoAlias)),
71         DU(llvm::make_unique<DispatchUnit>(
72             this, STI, MRI, Subtarget.getSchedModel().MicroOpBufferSize,
73             RegisterFileSize, DispatchWidth, HWS.get())),
74         SM(Source), Cycles(0) {
75     HWS->setDispatchUnit(DU.get());
76   }
77
78   void run() {
79     while (SM.hasNext() || !DU->isRCUEmpty())
80       runCycle(Cycles++);
81   }
82
83   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);
87     return *It->second;
88   }
89   void eraseInstruction(unsigned Index) { Instructions.erase(Index); }
90
91   void addEventListener(HWEventListener *Listener);
92   void notifyCycleBegin(unsigned Cycle);
93   void notifyInstructionEvent(const HWInstructionEvent &Event);
94   void notifyStallEvent(const HWStallEvent &Event);
95   void notifyResourceAvailable(const ResourceRef &RR);
96   void notifyReservedBuffers(llvm::ArrayRef<unsigned> Buffers);
97   void notifyReleasedBuffers(llvm::ArrayRef<unsigned> Buffers);
98   void notifyCycleEnd(unsigned Cycle);
99 };
100 } // namespace mca
101
102 #endif