1 //===---------------------- RetireControlUnit.h -----------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file simulates the hardware responsible for retiring instructions.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_MCA_RETIRE_CONTROL_UNIT_H
16 #define LLVM_MCA_RETIRE_CONTROL_UNIT_H
18 #include "llvm/MC/MCSchedule.h"
19 #include "llvm/MCA/HardwareUnits/HardwareUnit.h"
20 #include "llvm/MCA/Instruction.h"
26 /// This class tracks which instructions are in-flight (i.e., dispatched but not
27 /// retired) in the OoO backend.
29 /// This class checks on every cycle if/which instructions can be retired.
30 /// Instructions are retired in program order.
31 /// In the event of an instruction being retired, the pipeline that owns
32 /// this RetireControlUnit (RCU) gets notified.
34 /// On instruction retired, register updates are all architecturally
35 /// committed, and any physicall registers previously allocated for the
36 /// retired instruction are freed.
37 struct RetireControlUnit : public HardwareUnit {
38 // A RUToken is created by the RCU for every instruction dispatched to the
39 // schedulers. These "tokens" are managed by the RCU in its token Queue.
41 // On every cycle ('cycleEvent'), the RCU iterates through the token queue
42 // looking for any token with its 'Executed' flag set. If a token has that
43 // flag set, then the instruction has reached the write-back stage and will
44 // be retired by the RCU.
46 // 'NumSlots' represents the number of entries consumed by the instruction in
47 // the reorder buffer. Those entries will become available again once the
48 // instruction is retired.
50 // Note that the size of the reorder buffer is defined by the scheduling
51 // model via field 'NumMicroOpBufferSize'.
54 unsigned NumSlots; // Slots reserved to this instruction.
55 bool Executed; // True if the instruction is past the WB stage.
59 unsigned NextAvailableSlotIdx;
60 unsigned CurrentInstructionSlotIdx;
61 unsigned AvailableSlots;
62 unsigned MaxRetirePerCycle; // 0 means no limit.
63 std::vector<RUToken> Queue;
66 RetireControlUnit(const MCSchedModel &SM);
68 bool isEmpty() const { return AvailableSlots == Queue.size(); }
69 bool isAvailable(unsigned Quantity = 1) const {
70 // Some instructions may declare a number of uOps which exceeds the size
71 // of the reorder buffer. To avoid problems, cap the amount of slots to
72 // the size of the reorder buffer.
73 Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size()));
75 // Further normalize the number of micro opcodes for instructions that
76 // declare zero opcodes. This should match the behavior of method
78 Quantity = std::max(Quantity, 1U);
79 return AvailableSlots >= Quantity;
82 unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; }
84 // Reserves a number of slots, and returns a new token.
85 unsigned reserveSlot(const InstRef &IS, unsigned NumMicroOps);
87 // Return the current token from the RCU's circular token queue.
88 const RUToken &peekCurrentToken() const;
90 // Advance the pointer to the next token in the circular token queue.
91 void consumeCurrentToken();
93 // Update the RCU token to represent the executed state.
94 void onInstructionExecuted(unsigned TokenID);
104 #endif // LLVM_MCA_RETIRE_CONTROL_UNIT_H