[MCA] Moved the logic that updates register dependencies from DispatchStage to RegisterFile. NFC

DispatchStage should always delegate to an object of class RegisterFile the task
of updating data dependencies.  ReadState and WriteState objects should not be
modified directly by DispatchStage.
This patch also renames stage IS_AVAILABLE to IS_DISPATCHED.

llvm-svn: 353170
This commit is contained in:
Andrea Di Biagio 2019-02-05 14:11:41 +00:00
parent cad6336675
commit 4bce783ee3
7 changed files with 32 additions and 39 deletions

View File

@ -20,6 +20,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MCA/HardwareUnits/HardwareUnit.h"
#include "llvm/Support/Error.h"
@ -195,7 +196,7 @@ public:
// Collect writes that are in a data dependency with RS, and update RS
// internal state.
void addRegisterRead(ReadState &RS, SmallVectorImpl<WriteRef> &Writes) const;
void addRegisterRead(ReadState &RS, const MCSubtargetInfo &STI) const;
// Removes write \param WS from the register mappings.
// Physical registers may be released to reflect this update.

View File

@ -74,7 +74,7 @@ public:
/// An instruction is moved from the WaitSet to the ReadySet when register
/// operands become available, and all memory dependencies are met.
/// Instructions that are moved from the WaitSet to the ReadySet transition
/// in state from 'IS_AVAILABLE' to 'IS_READY'.
/// in state from 'IS_DISPATCHED' to 'IS_READY'.
///
/// On every cycle, the Scheduler checks if it can promote instructions from the
/// WaitSet to the ReadySet.

View File

@ -409,12 +409,12 @@ public:
/// that are sent to the various components of the simulated hardware pipeline.
class Instruction : public InstructionBase {
enum InstrStage {
IS_INVALID, // Instruction in an invalid state.
IS_AVAILABLE, // Instruction dispatched but operands are not ready.
IS_READY, // Instruction dispatched and operands ready.
IS_EXECUTING, // Instruction issued.
IS_EXECUTED, // Instruction executed. Values are written back.
IS_RETIRED // Instruction retired.
IS_INVALID, // Instruction in an invalid state.
IS_DISPATCHED, // Instruction dispatched but operands are not ready.
IS_READY, // Instruction dispatched and operands ready.
IS_EXECUTING, // Instruction issued.
IS_EXECUTED, // Instruction executed. Values are written back.
IS_RETIRED // Instruction retired.
};
// The current instruction stage.
@ -444,7 +444,7 @@ public:
// all the definitions.
void execute();
// Force a transition from the IS_AVAILABLE state to the IS_READY state if
// Force a transition from the IS_DISPATCHED state to the IS_READY state if
// input operands are all ready. State transitions normally occur at the
// beginning of a new cycle (see method cycleEvent()). However, the scheduler
// may decide to promote instructions from the wait queue to the ready queue
@ -452,7 +452,7 @@ public:
// instruction might have changed in state.
void update();
bool isDispatched() const { return Stage == IS_AVAILABLE; }
bool isDispatched() const { return Stage == IS_DISPATCHED; }
bool isReady() const { return Stage == IS_READY; }
bool isExecuting() const { return Stage == IS_EXECUTING; }
bool isExecuted() const { return Stage == IS_EXECUTED; }
@ -464,7 +464,7 @@ public:
[](const WriteState &W) { return W.isEliminated(); });
}
// Forces a transition from state IS_AVAILABLE to state IS_EXECUTED.
// Forces a transition from state IS_DISPATCHED to state IS_EXECUTED.
void forceExecuted();
void retire() {

View File

@ -61,8 +61,6 @@ class DispatchStage final : public Stage {
bool canDispatch(const InstRef &IR) const;
Error dispatch(InstRef IR);
void updateRAWDependencies(ReadState &RS, const MCSubtargetInfo &STI);
void notifyInstructionDispatched(const InstRef &IR,
ArrayRef<unsigned> UsedPhysRegs,
unsigned uOps) const;

View File

@ -401,7 +401,7 @@ void RegisterFile::collectWrites(const ReadState &RS,
}
void RegisterFile::addRegisterRead(ReadState &RS,
SmallVectorImpl<WriteRef> &Defs) const {
const MCSubtargetInfo &STI) const {
unsigned RegID = RS.getRegisterID();
const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;
RS.setPRF(RRI.IndexPlusCost.first);
@ -410,8 +410,23 @@ void RegisterFile::addRegisterRead(ReadState &RS,
if (ZeroRegisters[RS.getRegisterID()])
RS.setReadZero();
collectWrites(RS, Defs);
RS.setDependentWrites(Defs.size());
SmallVector<WriteRef, 4> DependentWrites;
collectWrites(RS, DependentWrites);
RS.setDependentWrites(DependentWrites.size());
// We know that this read depends on all the writes in DependentWrites.
// For each write, check if we have ReadAdvance information, and use it
// to figure out in how many cycles this read becomes available.
const ReadDescriptor &RD = RS.getDescriptor();
const MCSchedModel &SM = STI.getSchedModel();
const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID);
for (WriteRef &WR : DependentWrites) {
WriteState &WS = *WR.getWriteState();
unsigned WriteResID = WS.getWriteResourceID();
int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID);
WS.addUser(&RS, ReadAdvance);
}
}
unsigned RegisterFile::isAvailable(ArrayRef<unsigned> Regs) const {

View File

@ -123,7 +123,7 @@ void WriteRef::dump() const {
void Instruction::dispatch(unsigned RCUToken) {
assert(Stage == IS_INVALID);
Stage = IS_AVAILABLE;
Stage = IS_DISPATCHED;
RCUTokenID = RCUToken;
// Check if input operands are already available.

View File

@ -62,27 +62,6 @@ bool DispatchStage::canDispatch(const InstRef &IR) const {
return checkRCU(IR) && checkPRF(IR) && checkNextStage(IR);
}
void DispatchStage::updateRAWDependencies(ReadState &RS,
const MCSubtargetInfo &STI) {
SmallVector<WriteRef, 4> DependentWrites;
// Collect all the dependent writes, and update RS internal state.
PRF.addRegisterRead(RS, DependentWrites);
// We know that this read depends on all the writes in DependentWrites.
// For each write, check if we have ReadAdvance information, and use it
// to figure out in how many cycles this read becomes available.
const ReadDescriptor &RD = RS.getDescriptor();
const MCSchedModel &SM = STI.getSchedModel();
const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID);
for (WriteRef &WR : DependentWrites) {
WriteState &WS = *WR.getWriteState();
unsigned WriteResID = WS.getWriteResourceID();
int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID);
WS.addUser(&RS, ReadAdvance);
}
}
Error DispatchStage::dispatch(InstRef IR) {
assert(!CarryOver && "Cannot dispatch another instruction!");
Instruction &IS = *IR.getInstruction();
@ -121,7 +100,7 @@ Error DispatchStage::dispatch(InstRef IR) {
// eliminated at register renaming stage.
if (!IsEliminated) {
for (ReadState &RS : IS.getUses())
updateRAWDependencies(RS, STI);
PRF.addRegisterRead(RS, STI);
}
// By default, a dependency-breaking zero-idiom is expected to be optimized