blob: eb2593d721503865e15d2e09822888d91fc72d3b [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///
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000011/// This file simulates the hardware responsible for retiring instructions.
Matt Davis6aa5dcd2018-05-01 23:04:01 +000012///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
16#define LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
17
David Blaikie1ca61f62018-05-09 17:28:10 +000018#include "Instruction.h"
Matt Davis6aa5dcd2018-05-01 23:04:01 +000019#include "llvm/MC/MCSchedule.h"
20
David Blaikiec30365c2018-05-11 19:21:40 +000021#include <algorithm>
22#include <vector>
23
Matt Davis6aa5dcd2018-05-01 23:04:01 +000024namespace mca {
25
Matt Davis679083e2018-05-17 19:22:29 +000026class DispatchStage;
Matt Davis6aa5dcd2018-05-01 23:04:01 +000027
28/// This class tracks which instructions are in-flight (i.e., dispatched but not
29/// retired) in the OoO backend.
30//
31/// This class checks on every cycle if/which instructions can be retired.
32/// Instructions are retired in program order.
Matt Davis679083e2018-05-17 19:22:29 +000033/// In the event of instruction retired, the DispatchStage object that owns
Matt Davis6aa5dcd2018-05-01 23:04:01 +000034/// this RetireControlUnit (RCU) gets notified.
35/// On instruction retired, register updates are all architecturally
36/// committed, and any temporary registers originally allocated for the
37/// retired instruction are freed.
38struct RetireControlUnit {
39 // A RUToken is created by the RCU for every instruction dispatched to the
40 // schedulers. These "tokens" are managed by the RCU in its token Queue.
41 //
42 // On evey cycle ('cycleEvent'), the RCU iterates through the token queue
43 // looking for any token with its 'Executed' flag set. If a token has that
44 // flag set, then the instruction has reached the write-back stage and will
45 // be retired by the RCU.
46 //
47 // 'NumSlots' represents the number of entries consumed by the instruction in
48 // the reorder buffer. Those entries will become available again once the
49 // instruction is retired.
50 //
51 // Note that the size of the reorder buffer is defined by the scheduling
52 // model via field 'NumMicroOpBufferSize'.
53 struct RUToken {
Matt Davis21a8d322018-05-07 18:29:15 +000054 InstRef IR;
Matt Davis6aa5dcd2018-05-01 23:04:01 +000055 unsigned NumSlots; // Slots reserved to this instruction.
56 bool Executed; // True if the instruction is past the WB stage.
57 };
58
59private:
60 unsigned NextAvailableSlotIdx;
61 unsigned CurrentInstructionSlotIdx;
62 unsigned AvailableSlots;
63 unsigned MaxRetirePerCycle; // 0 means no limit.
64 std::vector<RUToken> Queue;
Matt Davis6aa5dcd2018-05-01 23:04:01 +000065
66public:
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000067 RetireControlUnit(const llvm::MCSchedModel &SM);
Matt Davis6aa5dcd2018-05-01 23:04:01 +000068
69 bool isFull() const { return !AvailableSlots; }
70 bool isEmpty() const { return AvailableSlots == Queue.size(); }
71 bool isAvailable(unsigned Quantity = 1) const {
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000072 // Some instructions may declare a number of uOps which exceeds the size
Matt Davis6aa5dcd2018-05-01 23:04:01 +000073 // of the reorder buffer. To avoid problems, cap the amount of slots to
74 // the size of the reorder buffer.
75 Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size()));
76 return AvailableSlots >= Quantity;
77 }
78
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000079 unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; }
80
Matt Davis6aa5dcd2018-05-01 23:04:01 +000081 // Reserves a number of slots, and returns a new token.
Matt Davis21a8d322018-05-07 18:29:15 +000082 unsigned reserveSlot(const InstRef &IS, unsigned NumMicroOps);
Matt Davis6aa5dcd2018-05-01 23:04:01 +000083
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000084 // Return the current token from the RCU's circular token queue.
85 const RUToken &peekCurrentToken() const;
Matt Davis6aa5dcd2018-05-01 23:04:01 +000086
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000087 // Advance the pointer to the next token in the circular token queue.
88 void consumeCurrentToken();
89
90 // Update the RCU token to represent the executed state.
Matt Davis6aa5dcd2018-05-01 23:04:01 +000091 void onInstructionExecuted(unsigned TokenID);
92
93#ifndef NDEBUG
94 void dump() const;
95#endif
96};
97
98} // namespace mca
99
100#endif // LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H