|
|
|||
File indexing completed on 2026-05-10 08:44:16
0001 //===---------------------- RetireControlUnit.h -----------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 /// \file 0009 /// 0010 /// This file simulates the hardware responsible for retiring instructions. 0011 /// 0012 //===----------------------------------------------------------------------===// 0013 0014 #ifndef LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_H 0015 #define LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_H 0016 0017 #include "llvm/MC/MCSchedule.h" 0018 #include "llvm/MCA/HardwareUnits/HardwareUnit.h" 0019 #include "llvm/MCA/Instruction.h" 0020 #include <vector> 0021 0022 namespace llvm { 0023 namespace mca { 0024 0025 /// This class tracks which instructions are in-flight (i.e., dispatched but not 0026 /// retired) in the OoO backend. 0027 // 0028 /// This class checks on every cycle if/which instructions can be retired. 0029 /// Instructions are retired in program order. 0030 /// In the event of an instruction being retired, the pipeline that owns 0031 /// this RetireControlUnit (RCU) gets notified. 0032 /// 0033 /// On instruction retired, register updates are all architecturally 0034 /// committed, and any physicall registers previously allocated for the 0035 /// retired instruction are freed. 0036 struct RetireControlUnit : public HardwareUnit { 0037 // A RUToken is created by the RCU for every instruction dispatched to the 0038 // schedulers. These "tokens" are managed by the RCU in its token Queue. 0039 // 0040 // On every cycle ('cycleEvent'), the RCU iterates through the token queue 0041 // looking for any token with its 'Executed' flag set. If a token has that 0042 // flag set, then the instruction has reached the write-back stage and will 0043 // be retired by the RCU. 0044 // 0045 // 'NumSlots' represents the number of entries consumed by the instruction in 0046 // the reorder buffer. Those entries will become available again once the 0047 // instruction is retired. 0048 // 0049 // Note that the size of the reorder buffer is defined by the scheduling 0050 // model via field 'NumMicroOpBufferSize'. 0051 struct RUToken { 0052 InstRef IR; 0053 unsigned NumSlots; // Slots reserved to this instruction. 0054 bool Executed; // True if the instruction is past the WB stage. 0055 }; 0056 0057 private: 0058 unsigned NextAvailableSlotIdx; 0059 unsigned CurrentInstructionSlotIdx; 0060 unsigned NumROBEntries; 0061 unsigned AvailableEntries; 0062 unsigned MaxRetirePerCycle; // 0 means no limit. 0063 std::vector<RUToken> Queue; 0064 0065 unsigned normalizeQuantity(unsigned Quantity) const { 0066 // Some instructions may declare a number of uOps which exceeds the size 0067 // of the reorder buffer. To avoid problems, cap the amount of slots to 0068 // the size of the reorder buffer. 0069 Quantity = std::min(Quantity, NumROBEntries); 0070 0071 // Further normalize the number of micro opcodes for instructions that 0072 // declare zero opcodes. This should match the behavior of method 0073 // reserveSlot(). 0074 return std::max(Quantity, 1U); 0075 } 0076 0077 unsigned computeNextSlotIdx() const; 0078 0079 public: 0080 RetireControlUnit(const MCSchedModel &SM); 0081 0082 bool isEmpty() const { return AvailableEntries == NumROBEntries; } 0083 0084 bool isAvailable(unsigned Quantity = 1) const { 0085 return AvailableEntries >= normalizeQuantity(Quantity); 0086 } 0087 0088 unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; } 0089 0090 // Reserves a number of slots, and returns a new token reference. 0091 unsigned dispatch(const InstRef &IS); 0092 0093 // Return the current token from the RCU's circular token queue. 0094 const RUToken &getCurrentToken() const; 0095 0096 const RUToken &peekNextToken() const; 0097 0098 // Advance the pointer to the next token in the circular token queue. 0099 void consumeCurrentToken(); 0100 0101 // Update the RCU token to represent the executed state. 0102 void onInstructionExecuted(unsigned TokenID); 0103 0104 #ifndef NDEBUG 0105 void dump() const; 0106 #endif 0107 0108 // Assigned to instructions that are not handled by the RCU. 0109 static const unsigned UnhandledTokenID = ~0U; 0110 }; 0111 0112 } // namespace mca 0113 } // namespace llvm 0114 0115 #endif // LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|