Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / include / llvm / MCA / HardwareUnits / RetireControlUnit.h
blob06290141739e5663a8e53f39e5002e0bd66fc948
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 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_MCA_RETIRE_CONTROL_UNIT_H
15 #define LLVM_MCA_RETIRE_CONTROL_UNIT_H
17 #include "llvm/MC/MCSchedule.h"
18 #include "llvm/MCA/HardwareUnits/HardwareUnit.h"
19 #include "llvm/MCA/Instruction.h"
20 #include <vector>
22 namespace llvm {
23 namespace mca {
25 /// This class tracks which instructions are in-flight (i.e., dispatched but not
26 /// retired) in the OoO backend.
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.
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.
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.
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.
57 private:
58 unsigned NextAvailableSlotIdx;
59 unsigned CurrentInstructionSlotIdx;
60 unsigned AvailableSlots;
61 unsigned MaxRetirePerCycle; // 0 means no limit.
62 std::vector<RUToken> Queue;
64 public:
65 RetireControlUnit(const MCSchedModel &SM);
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()));
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;
81 unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; }
83 // Reserves a number of slots, and returns a new token.
84 unsigned reserveSlot(const InstRef &IS, unsigned NumMicroOps);
86 // Return the current token from the RCU's circular token queue.
87 const RUToken &peekCurrentToken() const;
89 // Advance the pointer to the next token in the circular token queue.
90 void consumeCurrentToken();
92 // Update the RCU token to represent the executed state.
93 void onInstructionExecuted(unsigned TokenID);
95 #ifndef NDEBUG
96 void dump() const;
97 #endif
100 } // namespace mca
101 } // namespace llvm
103 #endif // LLVM_MCA_RETIRE_CONTROL_UNIT_H