summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/tools/llvm-mca/Backend.cpp28
-rw-r--r--llvm/tools/llvm-mca/Dispatch.cpp43
-rw-r--r--llvm/tools/llvm-mca/Dispatch.h5
-rw-r--r--llvm/tools/llvm-mca/InstrBuilder.cpp36
-rw-r--r--llvm/tools/llvm-mca/InstrBuilder.h3
-rw-r--r--llvm/tools/llvm-mca/Instruction.h8
6 files changed, 65 insertions, 58 deletions
diff --git a/llvm/tools/llvm-mca/Backend.cpp b/llvm/tools/llvm-mca/Backend.cpp
index c17d48ca150..96668294498 100644
--- a/llvm/tools/llvm-mca/Backend.cpp
+++ b/llvm/tools/llvm-mca/Backend.cpp
@@ -31,26 +31,18 @@ void Backend::addEventListener(HWEventListener *Listener) {
void Backend::runCycle(unsigned Cycle) {
notifyCycleBegin(Cycle);
- if (!SM.hasNext()) {
- notifyCycleEnd(Cycle);
- return;
- }
-
- InstRef IR = SM.peekNext();
- const InstrDesc *Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
- while (DU->isAvailable(Desc->NumMicroOps) && DU->canDispatch(*Desc)) {
- Instruction *NewIS = IB->createInstruction(STI, *DU, IR.first, *IR.second);
- Instructions[IR.first] = std::unique_ptr<Instruction>(NewIS);
- NewIS->setRCUTokenID(DU->dispatch(IR.first, NewIS));
-
- // Check if we have dispatched all the instructions.
- SM.updateNext();
- if (!SM.hasNext())
+ while (SM.hasNext()) {
+ InstRef IR = SM.peekNext();
+ std::unique_ptr<Instruction> NewIS(
+ IB->createInstruction(STI, IR.first, *IR.second));
+ const InstrDesc &Desc = NewIS->getDesc();
+ if (!DU->isAvailable(Desc.NumMicroOps) || !DU->canDispatch(Desc))
break;
- // Prepare for the next round.
- IR = SM.peekNext();
- Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
+ Instruction *IS = NewIS.get();
+ Instructions[IR.first] = std::move(NewIS);
+ IS->setRCUTokenID(DU->dispatch(IR.first, IS, STI));
+ SM.updateNext();
}
notifyCycleEnd(Cycle);
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);
diff --git a/llvm/tools/llvm-mca/Dispatch.h b/llvm/tools/llvm-mca/Dispatch.h
index e810ddaf77b..66ac2f7e64a 100644
--- a/llvm/tools/llvm-mca/Dispatch.h
+++ b/llvm/tools/llvm-mca/Dispatch.h
@@ -18,6 +18,7 @@
#include "Instruction.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include <map>
namespace mca {
@@ -236,6 +237,7 @@ class DispatchUnit {
bool checkRCU(const InstrDesc &Desc);
bool checkScheduler(const InstrDesc &Desc);
+ void updateRAWDependencies(ReadState &RS, const llvm::MCSubtargetInfo &STI);
void notifyInstructionDispatched(unsigned IID);
public:
@@ -263,7 +265,8 @@ public:
return checkRCU(Desc) && checkRAT(Desc) && checkScheduler(Desc);
}
- unsigned dispatch(unsigned IID, Instruction *NewInst);
+ unsigned dispatch(unsigned IID, Instruction *NewInst,
+ const llvm::MCSubtargetInfo &STI);
void collectWrites(llvm::SmallVectorImpl<WriteState *> &Vec,
unsigned RegID) const {
diff --git a/llvm/tools/llvm-mca/InstrBuilder.cpp b/llvm/tools/llvm-mca/InstrBuilder.cpp
index 35b3a3592fe..7c9ffdc7ed7 100644
--- a/llvm/tools/llvm-mca/InstrBuilder.cpp
+++ b/llvm/tools/llvm-mca/InstrBuilder.cpp
@@ -419,14 +419,12 @@ const InstrDesc &InstrBuilder::getOrCreateInstrDesc(const MCSubtargetInfo &STI,
}
Instruction *InstrBuilder::createInstruction(const MCSubtargetInfo &STI,
- DispatchUnit &DU, unsigned Idx,
- const MCInst &MCI) {
+ unsigned Idx, const MCInst &MCI) {
const InstrDesc &D = getOrCreateInstrDesc(STI, MCI);
Instruction *NewIS = new Instruction(D);
// Populate Reads first.
const MCSchedModel &SM = STI.getSchedModel();
- SmallVector<WriteState *, 4> DependentWrites;
for (const ReadDescriptor &RD : D.Reads) {
int RegID = -1;
if (RD.OpIndex != -1) {
@@ -447,34 +445,9 @@ Instruction *InstrBuilder::createInstruction(const MCSubtargetInfo &STI,
// Okay, this is a register operand. Create a ReadState for it.
assert(RegID > 0 && "Invalid register ID found!");
- ReadState *NewRDS = new ReadState(RD);
+ ReadState *NewRDS = new ReadState(RD, RegID);
NewIS->getUses().emplace_back(std::unique_ptr<ReadState>(NewRDS));
- DU.collectWrites(DependentWrites, RegID);
- NewRDS->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 after how many cycles this read becomes available.
- if (!RD.HasReadAdvanceEntries) {
- for (WriteState *WS : DependentWrites)
- WS->addUser(NewRDS, /* ReadAdvance */ 0);
- // Prepare the set for another round.
- DependentWrites.clear();
- continue;
- }
-
- 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(NewRDS, ReadAdvance);
- }
-
- // Prepare the set for another round.
- DependentWrites.clear();
- }
+ }
// Now populate writes.
for (const WriteDescriptor &WD : D.Writes) {
@@ -489,11 +462,8 @@ Instruction *InstrBuilder::createInstruction(const MCSubtargetInfo &STI,
WriteState *NewWS = new WriteState(WD);
NewIS->getDefs().emplace_back(std::unique_ptr<WriteState>(NewWS));
NewWS->setRegisterID(RegID);
- DU.addNewRegisterMapping(*NewWS);
}
- // Update Latency.
- NewIS->setCyclesLeft(D.MaxLatency);
return NewIS;
}
diff --git a/llvm/tools/llvm-mca/InstrBuilder.h b/llvm/tools/llvm-mca/InstrBuilder.h
index ddbd2835b9d..252b68ca5b0 100644
--- a/llvm/tools/llvm-mca/InstrBuilder.h
+++ b/llvm/tools/llvm-mca/InstrBuilder.h
@@ -15,7 +15,6 @@
#ifndef LLVM_TOOLS_LLVM_MCA_INSTRBUILDER_H
#define LLVM_TOOLS_LLVM_MCA_INSTRBUILDER_H
-#include "Dispatch.h"
#include "Instruction.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -53,7 +52,7 @@ public:
const llvm::MCInst &MCI);
Instruction *createInstruction(const llvm::MCSubtargetInfo &STI,
- DispatchUnit &DU, unsigned Idx,
+ unsigned Idx,
const llvm::MCInst &MCI);
};
diff --git a/llvm/tools/llvm-mca/Instruction.h b/llvm/tools/llvm-mca/Instruction.h
index 8d0bb0f529d..a7601931c61 100644
--- a/llvm/tools/llvm-mca/Instruction.h
+++ b/llvm/tools/llvm-mca/Instruction.h
@@ -131,6 +131,7 @@ public:
/// writes only partially update the register associated to this read.
class ReadState {
const ReadDescriptor &RD;
+ unsigned RegisterID;
unsigned DependentWrites;
int CyclesLeft;
unsigned TotalCycles;
@@ -142,14 +143,15 @@ public:
return (CyclesLeft == UNKNOWN_CYCLES || CyclesLeft == 0);
}
- ReadState(const ReadDescriptor &Desc)
- : RD(Desc), DependentWrites(0), CyclesLeft(UNKNOWN_CYCLES),
- TotalCycles(0) {}
+ ReadState(const ReadDescriptor &Desc, unsigned RegID)
+ : RD(Desc), RegisterID(RegID), DependentWrites(0),
+ CyclesLeft(UNKNOWN_CYCLES), TotalCycles(0) {}
ReadState(const ReadState &Other) = delete;
ReadState &operator=(const ReadState &Other) = delete;
const ReadDescriptor &getDescriptor() const { return RD; }
unsigned getSchedClass() const { return RD.SchedClassID; }
+ unsigned getRegisterID() const { return RegisterID; }
void cycleEvent();
void writeStartEvent(unsigned Cycles);
void setDependentWrites(unsigned Writes) { DependentWrites = Writes; }
OpenPOWER on IntegriCloud