summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca/Dispatch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-mca/Dispatch.cpp')
-rw-r--r--llvm/tools/llvm-mca/Dispatch.cpp43
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);
OpenPOWER on IntegriCloud