RetireControlUnit.h revision 360784
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 22namespace llvm { 23namespace 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. 36struct 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 57private: 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 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); 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 79public: 80 RetireControlUnit(const MCSchedModel &SM); 81 82 bool isEmpty() const { return AvailableEntries == NumROBEntries; } 83 84 bool isAvailable(unsigned Quantity = 1) const { 85 return AvailableEntries >= normalizeQuantity(Quantity); 86 } 87 88 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 109} // namespace mca 110} // namespace llvm 111 112#endif // LLVM_MCA_RETIRE_CONTROL_UNIT_H 113