]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/RetireControlUnit.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / MCA / HardwareUnits / RetireControlUnit.h
1 //===---------------------- RetireControlUnit.h -----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file simulates the hardware responsible for retiring instructions.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_MCA_RETIRE_CONTROL_UNIT_H
15 #define LLVM_MCA_RETIRE_CONTROL_UNIT_H
16
17 #include "llvm/MC/MCSchedule.h"
18 #include "llvm/MCA/HardwareUnits/HardwareUnit.h"
19 #include "llvm/MCA/Instruction.h"
20 #include <vector>
21
22 namespace llvm {
23 namespace mca {
24
25 /// This class tracks which instructions are in-flight (i.e., dispatched but not
26 /// retired) in the OoO backend.
27 //
28 /// This class checks on every cycle if/which instructions can be retired.
29 /// Instructions are retired in program order.
30 /// In the event of an instruction being retired, the pipeline that owns
31 /// this RetireControlUnit (RCU) gets notified.
32 ///
33 /// On instruction retired, register updates are all architecturally
34 /// committed, and any physicall registers previously allocated for the
35 /// retired instruction are freed.
36 struct RetireControlUnit : public HardwareUnit {
37   // A RUToken is created by the RCU for every instruction dispatched to the
38   // schedulers.  These "tokens" are managed by the RCU in its token Queue.
39   //
40   // On every cycle ('cycleEvent'), the RCU iterates through the token queue
41   // looking for any token with its 'Executed' flag set.  If a token has that
42   // flag set, then the instruction has reached the write-back stage and will
43   // be retired by the RCU.
44   //
45   // 'NumSlots' represents the number of entries consumed by the instruction in
46   // the reorder buffer. Those entries will become available again once the
47   // instruction is retired.
48   //
49   // Note that the size of the reorder buffer is defined by the scheduling
50   // model via field 'NumMicroOpBufferSize'.
51   struct RUToken {
52     InstRef IR;
53     unsigned NumSlots; // Slots reserved to this instruction.
54     bool Executed;     // True if the instruction is past the WB stage.
55   };
56
57 private:
58   unsigned NextAvailableSlotIdx;
59   unsigned CurrentInstructionSlotIdx;
60   unsigned AvailableSlots;
61   unsigned MaxRetirePerCycle; // 0 means no limit.
62   std::vector<RUToken> Queue;
63
64 public:
65   RetireControlUnit(const MCSchedModel &SM);
66
67   bool isEmpty() const { return AvailableSlots == Queue.size(); }
68   bool isAvailable(unsigned Quantity = 1) const {
69     // Some instructions may declare a number of uOps which exceeds the size
70     // of the reorder buffer. To avoid problems, cap the amount of slots to
71     // the size of the reorder buffer.
72     Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size()));
73
74     // Further normalize the number of micro opcodes for instructions that
75     // declare zero opcodes. This should match the behavior of method
76     // reserveSlot().
77     Quantity = std::max(Quantity, 1U);
78     return AvailableSlots >= Quantity;
79   }
80
81   unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; }
82
83   // Reserves a number of slots, and returns a new token.
84   unsigned reserveSlot(const InstRef &IS, unsigned NumMicroOps);
85
86   // Return the current token from the RCU's circular token queue.
87   const RUToken &peekCurrentToken() const;
88
89   // Advance the pointer to the next token in the circular token queue.
90   void consumeCurrentToken();
91
92   // Update the RCU token to represent the executed state.
93   void onInstructionExecuted(unsigned TokenID);
94
95 #ifndef NDEBUG
96   void dump() const;
97 #endif
98 };
99
100 } // namespace mca
101 } // namespace llvm
102
103 #endif // LLVM_MCA_RETIRE_CONTROL_UNIT_H