]> granicus.if.org Git - llvm/commitdiff
[MCA] Store a bitmask of used groups in the instruction descriptor.
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Wed, 13 Feb 2019 14:56:06 +0000 (14:56 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Wed, 13 Feb 2019 14:56:06 +0000 (14:56 +0000)
This is to speedup 'checkAvailability' queries in class ResourceManager.
No functional change intended.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353949 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MCA/HardwareUnits/ResourceManager.h
include/llvm/MCA/Instruction.h
lib/MCA/HardwareUnits/ResourceManager.cpp
lib/MCA/InstrBuilder.cpp

index 66272af8a9f08be28a2b12a9204a5828c2b30a39..3addaaf4775989d835297a789be0eef4547b7014 100644 (file)
@@ -347,6 +347,9 @@ class ResourceManager {
   // Set of processor resource units that are available during this cycle.
   uint64_t AvailableProcResUnits;
 
+  // Set of processor resource groups that are currently reserved.
+  uint64_t ReservedResourceGroups;
+
   // Returns the actual resource unit that will be used.
   ResourceRef selectPipe(uint64_t ResourceID);
 
@@ -397,7 +400,7 @@ public:
   // Returns a zero mask if resources requested by Desc are all available during
   // this cycle. It returns a non-zero mask value only if there are unavailable
   // processor resources; each bit set in the mask represents a busy processor
-  // resource unit.
+  // resource unit or a reserved processor resource group.
   uint64_t checkAvailability(const InstrDesc &Desc) const;
 
   uint64_t getProcResUnitMask() const { return ProcResUnitMask; }
index 0fba938560d70d373436decfc982b6ad934ddfc7..658b7fe4f891c6e6ad9a291b3daea1a90fa7b0c2 100644 (file)
@@ -338,6 +338,9 @@ struct InstrDesc {
   // A list of buffered resources consumed by this instruction.
   SmallVector<uint64_t, 4> Buffers;
 
+  unsigned UsedProcResUnits;
+  unsigned UsedProcResGroups;
+
   unsigned MaxLatency;
   // Number of MicroOps for this instruction.
   unsigned NumMicroOps;
index da6bfd5533916cbd4d3bc5ee9ec4126e8a6541f5..21e0271c852503825ff198968733b42a07e07e0e 100644 (file)
@@ -118,8 +118,8 @@ ResourceManager::ResourceManager(const MCSchedModel &SM)
     : Resources(SM.getNumProcResourceKinds()),
       Strategies(SM.getNumProcResourceKinds()),
       Resource2Groups(SM.getNumProcResourceKinds(), 0),
-      ProcResID2Mask(SM.getNumProcResourceKinds()),
-      ProcResUnitMask(0) {
+      ProcResID2Mask(SM.getNumProcResourceKinds()), ProcResUnitMask(0),
+      ReservedResourceGroups(0) {
   computeProcResourceMasks(SM, ProcResID2Mask);
 
   for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
@@ -278,7 +278,10 @@ uint64_t ResourceManager::checkAvailability(const InstrDesc &Desc) const {
       BusyResourceMask |= E.first;
   }
 
-  return BusyResourceMask & ProcResUnitMask;
+  BusyResourceMask &= ProcResUnitMask;
+  if (BusyResourceMask)
+    return BusyResourceMask;
+  return Desc.UsedProcResGroups & ReservedResourceGroups;
 }
 
 void ResourceManager::issueInstruction(
@@ -330,13 +333,17 @@ void ResourceManager::cycleEvent(SmallVectorImpl<ResourceRef> &ResourcesFreed) {
 
 void ResourceManager::reserveResource(uint64_t ResourceID) {
   ResourceState &Resource = *Resources[getResourceStateIndex(ResourceID)];
-  assert(!Resource.isReserved());
+  assert(Resource.isAResourceGroup() && !Resource.isReserved() &&
+         "Unexpected resource found!");
   Resource.setReserved();
+  ReservedResourceGroups ^= PowerOf2Floor(ResourceID);
 }
 
 void ResourceManager::releaseResource(uint64_t ResourceID) {
   ResourceState &Resource = *Resources[getResourceStateIndex(ResourceID)];
   Resource.clearReserved();
+  if (Resource.isAResourceGroup())
+    ReservedResourceGroups ^= PowerOf2Floor(ResourceID);
 }
 
 } // namespace mca
index 1e08f898523679849974fe63729f8725a93e62ca..e10efb28f77531e03ccb5f4c0032621cd749411d 100644 (file)
@@ -97,14 +97,14 @@ static void initializeUsedResources(InstrDesc &ID,
   });
 
   uint64_t UsedResourceUnits = 0;
+  uint64_t UsedResourceGroups = 0;
 
   // Remove cycles contributed by smaller resources.
   for (unsigned I = 0, E = Worklist.size(); I < E; ++I) {
     ResourcePlusCycles &A = Worklist[I];
     if (!A.second.size()) {
-      A.second.NumUnits = 0;
-      A.second.setReserved();
-      ID.Resources.emplace_back(A);
+      assert(countPopulation(A.first) > 1 && "Expected a group!");
+      UsedResourceGroups |= PowerOf2Floor(A.first);
       continue;
     }
 
@@ -127,6 +127,9 @@ static void initializeUsedResources(InstrDesc &ID,
     }
   }
 
+  ID.UsedProcResUnits = UsedResourceUnits;
+  ID.UsedProcResGroups = UsedResourceGroups;
+
   // A SchedWrite may specify a number of cycles in which a resource group
   // is reserved. For example (on target x86; cpu Haswell):
   //
@@ -179,10 +182,14 @@ static void initializeUsedResources(InstrDesc &ID,
 
   LLVM_DEBUG({
     for (const std::pair<uint64_t, ResourceUsage> &R : ID.Resources)
-      dbgs() << "\t\tMask=" << format_hex(R.first, 16) << ", "
+      dbgs() << "\t\tResource Mask=" << format_hex(R.first, 16) << ", "
+             << "Reserved=" << R.second.isReserved() << ", "
+             << "#Units=" << R.second.NumUnits << ", "
              << "cy=" << R.second.size() << '\n';
     for (const uint64_t R : ID.Buffers)
       dbgs() << "\t\tBuffer Mask=" << format_hex(R, 16) << '\n';
+    dbgs()   << "\t\t Used Units=" << format_hex(ID.UsedProcResUnits, 16) << '\n';
+    dbgs()   << "\t\tUsed Groups=" << format_hex(ID.UsedProcResGroups, 16) << '\n';
   });
 }