mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-21 03:53:04 +02:00
e75426e0b8
llvm-svn: 338513
99 lines
3.5 KiB
C++
99 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 "HardwareUnit.h"
|
|
#include "Instruction.h"
|
|
#include "llvm/MC/MCSchedule.h"
|
|
#include <vector>
|
|
|
|
namespace mca {
|
|
|
|
/// 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 an instruction being retired, the pipeline that owns
|
|
/// this RetireControlUnit (RCU) gets notified.
|
|
///
|
|
/// On instruction retired, register updates are all architecturally
|
|
/// committed, and any physicall registers previously allocated for the
|
|
/// retired instruction are freed.
|
|
struct RetireControlUnit : public HardwareUnit {
|
|
// 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 every 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
|