Back to home page

EIC code displayed by LXR

 
 

    


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