• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===---------------------- RetireControlUnit.h -----------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This file simulates the hardware responsible for retiring instructions.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
16 #define LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
17 
18 #include "HardwareUnit.h"
19 #include "Instruction.h"
20 #include "llvm/MC/MCSchedule.h"
21 #include <vector>
22 
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 AvailableSlots;
61   unsigned MaxRetirePerCycle; // 0 means no limit.
62   std::vector<RUToken> Queue;
63 
64 public:
65   RetireControlUnit(const llvm::MCSchedModel &SM);
66 
isFullRetireControlUnit67   bool isFull() const { return !AvailableSlots; }
isEmptyRetireControlUnit68   bool isEmpty() const { return AvailableSlots == Queue.size(); }
69   bool isAvailable(unsigned Quantity = 1) const {
70     // Some instructions may declare a number of uOps which exceeds the size
71     // of the reorder buffer. To avoid problems, cap the amount of slots to
72     // the size of the reorder buffer.
73     Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size()));
74     return AvailableSlots >= Quantity;
75   }
76 
getMaxRetirePerCycleRetireControlUnit77   unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; }
78 
79   // Reserves a number of slots, and returns a new token.
80   unsigned reserveSlot(const InstRef &IS, unsigned NumMicroOps);
81 
82   // Return the current token from the RCU's circular token queue.
83   const RUToken &peekCurrentToken() const;
84 
85   // Advance the pointer to the next token in the circular token queue.
86   void consumeCurrentToken();
87 
88   // Update the RCU token to represent the executed state.
89   void onInstructionExecuted(unsigned TokenID);
90 
91 #ifndef NDEBUG
92   void dump() const;
93 #endif
94 };
95 
96 } // namespace mca
97 
98 #endif // LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
99