mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-18 19:36:36 +00:00

Summary: This class maintains the same logic as the original RetireControlUnit. This is just an intermediate patch to make the RCU a Stage. Future patches will remove the dependency on the DispatchStage, and then more properly populate the pre/execute/post Stage interface. Reviewers: andreadb, RKSimon, courbet Reviewed By: andreadb, courbet Subscribers: javed.absar, mgorny, tschuett, gbedwell, llvm-commits Differential Revision: https://reviews.llvm.org/D47244 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333292 91177308-0d34-0410-b5e6-96231b3b80d8
101 lines
3.5 KiB
C++
101 lines
3.5 KiB
C++
//===---------------------- RetireControlUnit.h -----------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
/// \file
|
|
///
|
|
/// This file simulates the hardware responsible for retiring instructions.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
|
|
#define LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
|
|
|
|
#include "Instruction.h"
|
|
#include "llvm/MC/MCSchedule.h"
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
namespace mca {
|
|
|
|
class DispatchStage;
|
|
|
|
/// This class tracks which instructions are in-flight (i.e., dispatched but not
|
|
/// retired) in the OoO backend.
|
|
//
|
|
/// This class checks on every cycle if/which instructions can be retired.
|
|
/// Instructions are retired in program order.
|
|
/// In the event of instruction retired, the DispatchStage object that owns
|
|
/// this RetireControlUnit (RCU) gets notified.
|
|
/// On instruction retired, register updates are all architecturally
|
|
/// committed, and any temporary registers originally allocated for the
|
|
/// retired instruction are freed.
|
|
struct RetireControlUnit {
|
|
// A RUToken is created by the RCU for every instruction dispatched to the
|
|
// schedulers. These "tokens" are managed by the RCU in its token Queue.
|
|
//
|
|
// On evey cycle ('cycleEvent'), the RCU iterates through the token queue
|
|
// looking for any token with its 'Executed' flag set. If a token has that
|
|
// flag set, then the instruction has reached the write-back stage and will
|
|
// be retired by the RCU.
|
|
//
|
|
// 'NumSlots' represents the number of entries consumed by the instruction in
|
|
// the reorder buffer. Those entries will become available again once the
|
|
// instruction is retired.
|
|
//
|
|
// Note that the size of the reorder buffer is defined by the scheduling
|
|
// model via field 'NumMicroOpBufferSize'.
|
|
struct RUToken {
|
|
InstRef IR;
|
|
unsigned NumSlots; // Slots reserved to this instruction.
|
|
bool Executed; // True if the instruction is past the WB stage.
|
|
};
|
|
|
|
private:
|
|
unsigned NextAvailableSlotIdx;
|
|
unsigned CurrentInstructionSlotIdx;
|
|
unsigned AvailableSlots;
|
|
unsigned MaxRetirePerCycle; // 0 means no limit.
|
|
std::vector<RUToken> Queue;
|
|
|
|
public:
|
|
RetireControlUnit(const llvm::MCSchedModel &SM);
|
|
|
|
bool isFull() const { return !AvailableSlots; }
|
|
bool isEmpty() const { return AvailableSlots == Queue.size(); }
|
|
bool isAvailable(unsigned Quantity = 1) const {
|
|
// Some instructions may declare a number of uOps which exceeds the size
|
|
// of the reorder buffer. To avoid problems, cap the amount of slots to
|
|
// the size of the reorder buffer.
|
|
Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size()));
|
|
return AvailableSlots >= Quantity;
|
|
}
|
|
|
|
unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; }
|
|
|
|
// Reserves a number of slots, and returns a new token.
|
|
unsigned reserveSlot(const InstRef &IS, unsigned NumMicroOps);
|
|
|
|
// Return the current token from the RCU's circular token queue.
|
|
const RUToken &peekCurrentToken() const;
|
|
|
|
// Advance the pointer to the next token in the circular token queue.
|
|
void consumeCurrentToken();
|
|
|
|
// Update the RCU token to represent the executed state.
|
|
void onInstructionExecuted(unsigned TokenID);
|
|
|
|
#ifndef NDEBUG
|
|
void dump() const;
|
|
#endif
|
|
};
|
|
|
|
} // namespace mca
|
|
|
|
#endif // LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
|