blob: 0c74442aefeef6fe227840549331050e51bfc824 [file] [log] [blame]
Matt Davis6aa5dcd2018-05-01 23:04:01 +00001//===---------------------- 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 implements the logic 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 "llvm/MC/MCSchedule.h"
19
20namespace mca {
21
22class DispatchUnit;
23
24/// This class tracks which instructions are in-flight (i.e., dispatched but not
25/// retired) in the OoO backend.
26//
27/// This class checks on every cycle if/which instructions can be retired.
28/// Instructions are retired in program order.
29/// In the event of instruction retired, the DispatchUnit object that owns
30/// this RetireControlUnit (RCU) gets notified.
31/// On instruction retired, register updates are all architecturally
32/// committed, and any temporary registers originally allocated for the
33/// retired instruction are freed.
34struct RetireControlUnit {
35 // A RUToken is created by the RCU for every instruction dispatched to the
36 // schedulers. These "tokens" are managed by the RCU in its token Queue.
37 //
38 // On evey cycle ('cycleEvent'), the RCU iterates through the token queue
39 // looking for any token with its 'Executed' flag set. If a token has that
40 // flag set, then the instruction has reached the write-back stage and will
41 // be retired by the RCU.
42 //
43 // 'NumSlots' represents the number of entries consumed by the instruction in
44 // the reorder buffer. Those entries will become available again once the
45 // instruction is retired.
46 //
47 // Note that the size of the reorder buffer is defined by the scheduling
48 // model via field 'NumMicroOpBufferSize'.
49 struct RUToken {
50 unsigned Index; // Instruction index.
51 unsigned NumSlots; // Slots reserved to this instruction.
52 bool Executed; // True if the instruction is past the WB stage.
53 };
54
55private:
56 unsigned NextAvailableSlotIdx;
57 unsigned CurrentInstructionSlotIdx;
58 unsigned AvailableSlots;
59 unsigned MaxRetirePerCycle; // 0 means no limit.
60 std::vector<RUToken> Queue;
61 DispatchUnit *Owner;
62
63public:
64 RetireControlUnit(const llvm::MCSchedModel &SM, DispatchUnit *DU);
65
66 bool isFull() const { return !AvailableSlots; }
67 bool isEmpty() const { return AvailableSlots == Queue.size(); }
68 bool isAvailable(unsigned Quantity = 1) const {
69 // Some instructions may declare a number of uOps which exceedes the size
70 // of the reorder buffer. To avoid problems, cap the amount of slots to
71 // the size of the reorder buffer.
72 Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size()));
73 return AvailableSlots >= Quantity;
74 }
75
76 // Reserves a number of slots, and returns a new token.
77 unsigned reserveSlot(unsigned Index, unsigned NumMicroOps);
78
79 /// Retires instructions in program order.
80 void cycleEvent();
81
82 void onInstructionExecuted(unsigned TokenID);
83
84#ifndef NDEBUG
85 void dump() const;
86#endif
87};
88
89} // namespace mca
90
91#endif // LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H