mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-01 00:35:43 +00:00
[llvm-mca] Simplify (and better standardize) the Instruction interface.
llvm-svn: 328190
This commit is contained in:
parent
ee0510fa94
commit
660fc0f64f
@ -42,7 +42,7 @@ void Backend::runCycle(unsigned Cycle) {
|
||||
|
||||
Instruction *IS = NewIS.get();
|
||||
Instructions[IR.first] = std::move(NewIS);
|
||||
IS->setRCUTokenID(DU->dispatch(IR.first, IS, STI));
|
||||
DU->dispatch(IR.first, IS, STI);
|
||||
SM.updateNext();
|
||||
}
|
||||
|
||||
|
@ -348,7 +348,7 @@ void DispatchUnit::updateRAWDependencies(ReadState &RS,
|
||||
DependentWrites.clear();
|
||||
}
|
||||
|
||||
unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst,
|
||||
void DispatchUnit::dispatch(unsigned IID, Instruction *NewInst,
|
||||
const MCSubtargetInfo &STI) {
|
||||
assert(!CarryOver && "Cannot dispatch another instruction!");
|
||||
unsigned NumMicroOps = NewInst->getDesc().NumMicroOps;
|
||||
@ -370,17 +370,17 @@ unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst,
|
||||
for (std::unique_ptr<WriteState> &WS : NewInst->getDefs())
|
||||
RAT->addRegisterMapping(*WS, RegisterFiles);
|
||||
|
||||
// Set the cycles left before the write-back stage.
|
||||
const InstrDesc &D = NewInst->getDesc();
|
||||
NewInst->setCyclesLeft(D.MaxLatency);
|
||||
// Reserve slots in the RCU, and notify the instruction that it has been
|
||||
// dispatched to the schedulers for execution.
|
||||
NewInst->dispatch(RCU->reserveSlot(IID, NumMicroOps));
|
||||
|
||||
// Reserve slots in the RCU.
|
||||
unsigned RCUTokenID = RCU->reserveSlot(IID, NumMicroOps);
|
||||
NewInst->setRCUTokenID(RCUTokenID);
|
||||
// Notify listeners of the "instruction dispatched" event.
|
||||
notifyInstructionDispatched(IID, RegisterFiles);
|
||||
|
||||
// Now move the instruction into the scheduler's queue.
|
||||
// The scheduler is responsible for checking if this is a zero-latency
|
||||
// instruction that doesn't consume pipeline/scheduler resources.
|
||||
SC->scheduleInstruction(IID, *NewInst);
|
||||
return RCUTokenID;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -250,7 +250,8 @@ class DispatchUnit {
|
||||
bool checkScheduler(unsigned Index, const InstrDesc &Desc);
|
||||
|
||||
void updateRAWDependencies(ReadState &RS, const llvm::MCSubtargetInfo &STI);
|
||||
void notifyInstructionDispatched(unsigned IID, llvm::ArrayRef<unsigned> UsedPhysRegs);
|
||||
void notifyInstructionDispatched(unsigned IID,
|
||||
llvm::ArrayRef<unsigned> UsedPhysRegs);
|
||||
|
||||
public:
|
||||
DispatchUnit(Backend *B, const llvm::MCRegisterInfo &MRI,
|
||||
@ -279,8 +280,7 @@ public:
|
||||
checkScheduler(Index, Desc);
|
||||
}
|
||||
|
||||
unsigned dispatch(unsigned IID, Instruction *NewInst,
|
||||
const llvm::MCSubtargetInfo &STI);
|
||||
void dispatch(unsigned IID, Instruction *I, const llvm::MCSubtargetInfo &STI);
|
||||
|
||||
void collectWrites(llvm::SmallVectorImpl<WriteState *> &Vec,
|
||||
unsigned RegID) const {
|
||||
@ -306,7 +306,6 @@ public:
|
||||
void dump() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace mca
|
||||
|
||||
#endif
|
||||
|
@ -92,10 +92,12 @@ void WriteState::dump() const {
|
||||
}
|
||||
#endif
|
||||
|
||||
void Instruction::dispatch() {
|
||||
void Instruction::dispatch(unsigned RCUToken) {
|
||||
assert(Stage == IS_INVALID);
|
||||
Stage = IS_AVAILABLE;
|
||||
RCUTokenID = RCUToken;
|
||||
|
||||
// Check if input operands are already available.
|
||||
if (std::all_of(Uses.begin(), Uses.end(),
|
||||
[](const UniqueUse &Use) { return Use->isReady(); }))
|
||||
Stage = IS_READY;
|
||||
@ -104,8 +106,14 @@ void Instruction::dispatch() {
|
||||
void Instruction::execute() {
|
||||
assert(Stage == IS_READY);
|
||||
Stage = IS_EXECUTING;
|
||||
|
||||
// Set the cycles left before the write-back stage.
|
||||
setCyclesLeft(Desc.MaxLatency);
|
||||
|
||||
for (UniqueDef &Def : Defs)
|
||||
Def->onInstructionIssued();
|
||||
|
||||
// Transition to the "executed" stage if this is a zero-latency instruction.
|
||||
if (!CyclesLeft)
|
||||
Stage = IS_EXECUTED;
|
||||
}
|
||||
|
@ -110,11 +110,9 @@ public:
|
||||
int getCyclesLeft() const { return CyclesLeft; }
|
||||
unsigned getWriteResourceID() const { return WD.SClassOrWriteResourceID; }
|
||||
unsigned getRegisterID() const { return RegisterID; }
|
||||
void setRegisterID(unsigned ID) { RegisterID = ID; }
|
||||
|
||||
void addUser(ReadState *Use, int ReadAdvance);
|
||||
bool fullyUpdatesSuperRegs() const { return WD.FullyUpdatesSuperRegs; }
|
||||
bool isWrittenBack() const { return CyclesLeft == 0; }
|
||||
|
||||
// On every cycle, update CyclesLeft and notify dependent users.
|
||||
void cycleEvent();
|
||||
@ -291,22 +289,16 @@ public:
|
||||
unsigned getRCUTokenID() const { return RCUTokenID; }
|
||||
int getCyclesLeft() const { return CyclesLeft; }
|
||||
void setCyclesLeft(int Cycles) { CyclesLeft = Cycles; }
|
||||
void setRCUTokenID(unsigned TokenID) { RCUTokenID = TokenID; }
|
||||
|
||||
// Transition to the dispatch stage.
|
||||
// No definition is updated because the instruction is not "executing".
|
||||
void dispatch();
|
||||
// Transition to the dispatch stage, and assign a RCUToken to this
|
||||
// instruction. The RCUToken is used to track the completion of every
|
||||
// register write performed by this instruction.
|
||||
void dispatch(unsigned RCUTokenID);
|
||||
|
||||
// Instruction issued. Transition to the IS_EXECUTING state, and update
|
||||
// all the definitions.
|
||||
void execute();
|
||||
|
||||
void forceExecuted() {
|
||||
assert((Stage == IS_INVALID && isZeroLatency()) ||
|
||||
(Stage == IS_READY && Desc.MaxLatency == 0));
|
||||
Stage = IS_EXECUTED;
|
||||
}
|
||||
|
||||
bool isDispatched() const { return Stage == IS_AVAILABLE; }
|
||||
bool isReady() const { return Stage == IS_READY; }
|
||||
bool isExecuting() const { return Stage == IS_EXECUTING; }
|
||||
|
@ -241,16 +241,16 @@ void Scheduler::scheduleInstruction(unsigned Idx, Instruction &MCIS) {
|
||||
// eliminated at register renaming stage, since we know in advance that those
|
||||
// clear their output register.
|
||||
if (MCIS.isZeroLatency()) {
|
||||
assert(MCIS.isReady() && "data dependent zero-latency instruction?");
|
||||
notifyInstructionReady(Idx);
|
||||
MCIS.forceExecuted();
|
||||
MCIS.execute();
|
||||
notifyInstructionIssued(Idx, {});
|
||||
assert(MCIS.isExecuted() && "Unexpected non-zero latency!");
|
||||
notifyInstructionExecuted(Idx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Consume entries in the reservation stations.
|
||||
const InstrDesc &Desc = MCIS.getDesc();
|
||||
|
||||
if (!Desc.Buffers.empty()) {
|
||||
// Reserve a slot in each buffered resource. Also, mark units with
|
||||
// BufferSize=0 as reserved. Resources with a buffer size of zero will only
|
||||
@ -265,7 +265,6 @@ void Scheduler::scheduleInstruction(unsigned Idx, Instruction &MCIS) {
|
||||
if (MayLoad || MayStore)
|
||||
LSU->reserve(Idx, MayLoad, MayStore, Desc.HasSideEffects);
|
||||
|
||||
MCIS.dispatch();
|
||||
bool IsReady = MCIS.isReady();
|
||||
if (IsReady && (MayLoad || MayStore))
|
||||
IsReady &= LSU->isReady(Idx);
|
||||
|
Loading…
x
Reference in New Issue
Block a user