1 //===---------------------- RetireControlUnit.h -----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file simulates the hardware responsible for retiring instructions.
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"
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.
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'.
53 unsigned NumSlots
; // Slots reserved to this instruction.
54 bool Executed
; // True if the instruction is past the WB stage.
58 unsigned NextAvailableSlotIdx
;
59 unsigned CurrentInstructionSlotIdx
;
60 unsigned NumROBEntries
;
61 unsigned AvailableEntries
;
62 unsigned MaxRetirePerCycle
; // 0 means no limit.
63 std::vector
<RUToken
> Queue
;
65 unsigned normalizeQuantity(unsigned Quantity
) const {
66 // Some instructions may declare a number of uOps which exceeds the size
67 // of the reorder buffer. To avoid problems, cap the amount of slots to
68 // the size of the reorder buffer.
69 Quantity
= std::min(Quantity
, NumROBEntries
);
71 // Further normalize the number of micro opcodes for instructions that
72 // declare zero opcodes. This should match the behavior of method
74 return std::max(Quantity
, 1U);
77 unsigned computeNextSlotIdx() const;
80 RetireControlUnit(const MCSchedModel
&SM
);
82 bool isEmpty() const { return AvailableEntries
== NumROBEntries
; }
84 bool isAvailable(unsigned Quantity
= 1) const {
85 return AvailableEntries
>= normalizeQuantity(Quantity
);
88 unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle
; }
90 // Reserves a number of slots, and returns a new token reference.
91 unsigned dispatch(const InstRef
&IS
);
93 // Return the current token from the RCU's circular token queue.
94 const RUToken
&getCurrentToken() const;
96 const RUToken
&peekNextToken() const;
98 // Advance the pointer to the next token in the circular token queue.
99 void consumeCurrentToken();
101 // Update the RCU token to represent the executed state.
102 void onInstructionExecuted(unsigned TokenID
);
112 #endif // LLVM_MCA_RETIRE_CONTROL_UNIT_H