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