[llvm] r346545 - [llvm-mca] Account for buffered resources when analyzing "Super" resources.

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 9 11:30:21 PST 2018


Author: adibiagio
Date: Fri Nov  9 11:30:20 2018
New Revision: 346545

URL: http://llvm.org/viewvc/llvm-project?rev=346545&view=rev
Log:
[llvm-mca] Account for buffered resources when analyzing "Super" resources.

This was noticed when working on PR3946.
By construction, a group cannot be used as a "Super" resource. That constraint
is enforced by method `SubtargetEmitter::ExpandProcResource()`.

A Super resource S can be part of a group G. However, method
`SubtargetEmitter::ExpandProcResource()` would not update the number of
consumed resource cycles in G based on S.
In practice, this is perfectly fine because the resource usage is correctly
computed for processor resource units. However, llvm-mca should still check if G
is a buffered resource.
Before this patch, llvm-mca didn't correctly check if S was part of a group that
defines a buffer. So, the instruction descriptor was not correctly set.

For now, the semantic change introduced by this patch doesn't affect any of the
upstream scheduling models. However, it will allow to make some progress on PR3946.

Modified:
    llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp

Modified: llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp?rev=346545&r1=346544&r2=346545&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp (original)
+++ llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp Fri Nov  9 11:30:20 2018
@@ -55,12 +55,15 @@ static void initializeUsedResources(Inst
   // part of a "Super" resource. The key value is the "Super" resource mask ID.
   DenseMap<uint64_t, unsigned> SuperResources;
 
+  unsigned NumProcResources = SM.getNumProcResourceKinds();
+  APInt Buffers(NumProcResources, 0);
+
   for (unsigned I = 0, E = SCDesc.NumWriteProcResEntries; I < E; ++I) {
     const MCWriteProcResEntry *PRE = STI.getWriteProcResBegin(&SCDesc) + I;
     const MCProcResourceDesc &PR = *SM.getProcResource(PRE->ProcResourceIdx);
     uint64_t Mask = ProcResourceMasks[PRE->ProcResourceIdx];
     if (PR.BufferSize != -1)
-      ID.Buffers.push_back(Mask);
+      Buffers.setBit(PRE->ProcResourceIdx);
     CycleSegment RCy(0, PRE->Cycles, false);
     Worklist.emplace_back(ResourcePlusCycles(Mask, ResourceUsage(RCy)));
     if (PR.SuperIdx) {
@@ -138,6 +141,30 @@ static void initializeUsedResources(Inst
     }
   }
 
+  // Identify extra buffers that are consumed through super resources.
+  for (const std::pair<uint64_t, unsigned> &SR : SuperResources) {
+    for (unsigned I = 1, E = NumProcResources; I < E; ++I) {
+      const MCProcResourceDesc &PR = *SM.getProcResource(I);
+      if (PR.BufferSize == -1)
+        continue;
+
+      uint64_t Mask = ProcResourceMasks[I];
+      if (Mask != SR.first && ((Mask & SR.first) == SR.first))
+        Buffers.setBit(I);
+    }
+  }
+
+  // Now set the buffers.
+  if (unsigned NumBuffers = Buffers.countPopulation()) {
+    ID.Buffers.resize(NumBuffers);
+    for (unsigned I = 0, E = NumProcResources; I < E && NumBuffers; ++I) {
+      if (Buffers[I]) {
+        --NumBuffers;
+        ID.Buffers[NumBuffers] = ProcResourceMasks[I];
+      }
+    }
+  }
+
   LLVM_DEBUG({
     for (const std::pair<uint64_t, ResourceUsage> &R : ID.Resources)
       dbgs() << "\t\tMask=" << R.first << ", cy=" << R.second.size() << '\n';




More information about the llvm-commits mailing list