diff options
Diffstat (limited to 'llvm/tools/llvm-mca/Dispatch.cpp')
-rw-r--r-- | llvm/tools/llvm-mca/Dispatch.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/llvm/tools/llvm-mca/Dispatch.cpp b/llvm/tools/llvm-mca/Dispatch.cpp index a3aad188945..33b5f4926c9 100644 --- a/llvm/tools/llvm-mca/Dispatch.cpp +++ b/llvm/tools/llvm-mca/Dispatch.cpp @@ -237,7 +237,36 @@ bool DispatchUnit::checkScheduler(const InstrDesc &Desc) { return false; } -unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst) { +void DispatchUnit::updateRAWDependencies(ReadState &RS, + const MCSubtargetInfo &STI) { + SmallVector<WriteState *, 4> DependentWrites; + + collectWrites(DependentWrites, RS.getRegisterID()); + RS.setDependentWrites(DependentWrites.size()); + DEBUG(dbgs() << "Found " << DependentWrites.size() << " dependent writes\n"); + // 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(); + if (!RD.HasReadAdvanceEntries) { + for (WriteState *WS : DependentWrites) + WS->addUser(&RS, /* ReadAdvance */ 0); + return; + } + + const MCSchedModel &SM = STI.getSchedModel(); + const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID); + for (WriteState *WS : DependentWrites) { + unsigned WriteResID = WS->getWriteResourceID(); + int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.OpIndex, WriteResID); + WS->addUser(&RS, ReadAdvance); + } + // Prepare the set for another round. + DependentWrites.clear(); +} + +unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst, + const MCSubtargetInfo &STI) { assert(!CarryOver && "Cannot dispatch another instruction!"); unsigned NumMicroOps = NewInst->getDesc().NumMicroOps; if (NumMicroOps > DispatchWidth) { @@ -249,6 +278,18 @@ unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst) { AvailableEntries -= NumMicroOps; } + // Update RAW dependencies. + for (std::unique_ptr<ReadState> &RS : NewInst->getUses()) + updateRAWDependencies(*RS, STI); + + // Allocate temporary registers in the register file. + for (std::unique_ptr<WriteState> &WS : NewInst->getDefs()) + addNewRegisterMapping(*WS); + + // Set the cycles left before the write-back stage. + const InstrDesc &D = NewInst->getDesc(); + NewInst->setCyclesLeft(D.MaxLatency); + // Reserve slots in the RCU. unsigned RCUTokenID = RCU->reserveSlot(IID, NumMicroOps); NewInst->setRCUTokenID(RCUTokenID); |