summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca/Scheduler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-mca/Scheduler.cpp')
-rw-r--r--llvm/tools/llvm-mca/Scheduler.cpp54
1 files changed, 39 insertions, 15 deletions
diff --git a/llvm/tools/llvm-mca/Scheduler.cpp b/llvm/tools/llvm-mca/Scheduler.cpp
index 4d7f1a222ca..8a42cd0877a 100644
--- a/llvm/tools/llvm-mca/Scheduler.cpp
+++ b/llvm/tools/llvm-mca/Scheduler.cpp
@@ -181,7 +181,6 @@ bool ResourceManager::mustIssueImmediately(const InstrDesc &Desc) {
void ResourceManager::issueInstruction(
unsigned Index, const InstrDesc &Desc,
SmallVectorImpl<std::pair<ResourceRef, unsigned>> &Pipes) {
- releaseBuffers(Desc.Buffers);
for (const std::pair<uint64_t, ResourceUsage> &R : Desc.Resources) {
const CycleSegment &CS = R.second.CS;
if (!CS.size()) {
@@ -252,11 +251,14 @@ void Scheduler::scheduleInstruction(unsigned Idx, Instruction &MCIS) {
// Consume entries in the reservation stations.
const InstrDesc &Desc = MCIS.getDesc();
- // Reserve a slot in each buffered resource. Also, mark units with
- // BufferSize=0 as reserved. Resources with a buffer size of zero will only be
- // released after MCIS is issued, and all the ResourceCycles for those units
- // have been consumed.
- Resources->reserveBuffers(Desc.Buffers);
+ 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
+ // be released after MCIS is issued, and all the ResourceCycles for those
+ // units have been consumed.
+ Resources->reserveBuffers(Desc.Buffers);
+ notifyReservedBuffers(Desc.Buffers);
+ }
bool MayLoad = Desc.MayLoad;
bool MayStore = Desc.MayStore;
@@ -331,6 +333,13 @@ Scheduler::Event Scheduler::canBeDispatched(const InstrDesc &Desc) const {
}
void Scheduler::issueInstruction(Instruction &IS, unsigned InstrIndex) {
+ const InstrDesc &D = IS.getDesc();
+
+ if (!D.Buffers.empty()) {
+ Resources->releaseBuffers(D.Buffers);
+ notifyReleasedBuffers(D.Buffers);
+ }
+
// Issue the instruction and collect all the consumed resources
// into a vector. That vector is then used to notify the listener.
// Most instructions consume very few resurces (typically one or
@@ -338,8 +347,6 @@ void Scheduler::issueInstruction(Instruction &IS, unsigned InstrIndex) {
// initialize its capacity to 4. This should address the majority of
// the cases.
SmallVector<std::pair<ResourceRef, unsigned>, 4> UsedResources;
-
- const InstrDesc &D = IS.getDesc();
Resources->issueInstruction(InstrIndex, D, UsedResources);
// Notify the instruction that it started executing.
// This updates the internal state of each write.
@@ -417,13 +424,14 @@ void Scheduler::updateIssuedQueue() {
void Scheduler::notifyInstructionIssued(
unsigned Index, const ArrayRef<std::pair<ResourceRef, unsigned>> &Used) {
- DEBUG(dbgs() << "[E] Instruction Issued: " << Index << '\n';
- for (const std::pair<ResourceRef, unsigned> &Resource
- : Used) {
- dbgs() << "[E] Resource Used: [" << Resource.first.first << '.'
- << Resource.first.second << "]\n";
- dbgs() << " cycles: " << Resource.second << '\n';
- });
+ DEBUG({
+ dbgs() << "[E] Instruction Issued: " << Index << '\n';
+ for (const std::pair<ResourceRef, unsigned> &Resource : Used) {
+ dbgs() << "[E] Resource Used: [" << Resource.first.first << '.'
+ << Resource.first.second << "]\n";
+ dbgs() << " cycles: " << Resource.second << '\n';
+ }
+ });
Owner->notifyInstructionEvent(HWInstructionIssuedEvent(Index, Used));
}
@@ -446,4 +454,20 @@ void Scheduler::notifyInstructionReady(unsigned Index) {
void Scheduler::notifyResourceAvailable(const ResourceRef &RR) {
Owner->notifyResourceAvailable(RR);
}
+
+void Scheduler::notifyReservedBuffers(ArrayRef<uint64_t> Buffers) {
+ SmallVector<unsigned, 4> BufferIDs(Buffers.begin(), Buffers.end());
+ std::transform(
+ Buffers.begin(), Buffers.end(), BufferIDs.begin(),
+ [&](uint64_t Op) { return Resources->resolveResourceMask(Op); });
+ Owner->notifyReservedBuffers(BufferIDs);
+}
+
+void Scheduler::notifyReleasedBuffers(ArrayRef<uint64_t> Buffers) {
+ SmallVector<unsigned, 4> BufferIDs(Buffers.begin(), Buffers.end());
+ std::transform(
+ Buffers.begin(), Buffers.end(), BufferIDs.begin(),
+ [&](uint64_t Op) { return Resources->resolveResourceMask(Op); });
+ Owner->notifyReleasedBuffers(BufferIDs);
+}
} // namespace mca
OpenPOWER on IntegriCloud