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_HARDWAREUNITS_RETIRECONTROLUNIT_H 15 #define LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_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 NumROBEntries; 61 unsigned AvailableEntries; 62 unsigned MaxRetirePerCycle; // 0 means no limit. 63 std::vector<RUToken> Queue; 64 normalizeQuantityRetireControlUnit65 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); 70 71 // Further normalize the number of micro opcodes for instructions that 72 // declare zero opcodes. This should match the behavior of method 73 // reserveSlot(). 74 return std::max(Quantity, 1U); 75 } 76 77 unsigned computeNextSlotIdx() const; 78 79 public: 80 RetireControlUnit(const MCSchedModel &SM); 81 isEmptyRetireControlUnit82 bool isEmpty() const { return AvailableEntries == NumROBEntries; } 83 84 bool isAvailable(unsigned Quantity = 1) const { 85 return AvailableEntries >= normalizeQuantity(Quantity); 86 } 87 getMaxRetirePerCycleRetireControlUnit88 unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; } 89 90 // Reserves a number of slots, and returns a new token reference. 91 unsigned dispatch(const InstRef &IS); 92 93 // Return the current token from the RCU's circular token queue. 94 const RUToken &getCurrentToken() const; 95 96 const RUToken &peekNextToken() const; 97 98 // Advance the pointer to the next token in the circular token queue. 99 void consumeCurrentToken(); 100 101 // Update the RCU token to represent the executed state. 102 void onInstructionExecuted(unsigned TokenID); 103 104 #ifndef NDEBUG 105 void dump() const; 106 #endif 107 108 // Assigned to instructions that are not handled by the RCU. 109 static const unsigned UnhandledTokenID = ~0U; 110 }; 111 112 } // namespace mca 113 } // namespace llvm 114 115 #endif // LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_H 116