[llvm] r343766 - [llvm-mca] Check for inconsistencies when constructing instruction descriptors.

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 4 03:36:49 PDT 2018


Author: adibiagio
Date: Thu Oct  4 03:36:49 2018
New Revision: 343766

URL: http://llvm.org/viewvc/llvm-project?rev=343766&view=rev
Log:
[llvm-mca] Check for inconsistencies when constructing instruction descriptors.

This should help with catching inconsistent definitions of instructions with
zero opcodes, which also declare to consume scheduler/pipeline resources.

Modified:
    llvm/trunk/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h
    llvm/trunk/tools/llvm-mca/include/InstrBuilder.h
    llvm/trunk/tools/llvm-mca/lib/HardwareUnits/RetireControlUnit.cpp
    llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp

Modified: llvm/trunk/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h?rev=343766&r1=343765&r2=343766&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h (original)
+++ llvm/trunk/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h Thu Oct  4 03:36:49 2018
@@ -70,6 +70,11 @@ public:
     // of the reorder buffer. To avoid problems, cap the amount of slots to
     // the size of the reorder buffer.
     Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size()));
+
+    // Further normalize the number of micro opcodes for instructions that
+    // declare zero opcodes. This should match the behavior of method
+    // reserveSlot().
+    Quantity = std::max(Quantity, 1U);
     return AvailableSlots >= Quantity;
   }
 

Modified: llvm/trunk/tools/llvm-mca/include/InstrBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/include/InstrBuilder.h?rev=343766&r1=343765&r2=343766&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/include/InstrBuilder.h (original)
+++ llvm/trunk/tools/llvm-mca/include/InstrBuilder.h Thu Oct  4 03:36:49 2018
@@ -62,6 +62,8 @@ class InstrBuilder {
                              unsigned SchedClassID);
   llvm::Error populateReads(InstrDesc &ID, const llvm::MCInst &MCI,
                             unsigned SchedClassID);
+  llvm::Error verifyInstrDesc(const InstrDesc &ID,
+                              const llvm::MCInst &MCI) const;
 
 public:
   InstrBuilder(const llvm::MCSubtargetInfo &sti, const llvm::MCInstrInfo &mcii,

Modified: llvm/trunk/tools/llvm-mca/lib/HardwareUnits/RetireControlUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/lib/HardwareUnits/RetireControlUnit.cpp?rev=343766&r1=343765&r2=343766&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/lib/HardwareUnits/RetireControlUnit.cpp (original)
+++ llvm/trunk/tools/llvm-mca/lib/HardwareUnits/RetireControlUnit.cpp Thu Oct  4 03:36:49 2018
@@ -41,10 +41,10 @@ RetireControlUnit::RetireControlUnit(con
 // Reserves a number of slots, and returns a new token.
 unsigned RetireControlUnit::reserveSlot(const InstRef &IR,
                                         unsigned NumMicroOps) {
-  assert(isAvailable(NumMicroOps));
+  assert(isAvailable(NumMicroOps) && "Reorder Buffer unavailable!");
   unsigned NormalizedQuantity =
       std::min(NumMicroOps, static_cast<unsigned>(Queue.size()));
-  // Zero latency instructions may have zero mOps. Artificially bump this
+  // Zero latency instructions may have zero uOps. Artificially bump this
   // value to 1. Although zero latency instructions don't consume scheduler
   // resources, they still consume one slot in the retire queue.
   NormalizedQuantity = std::max(NormalizedQuantity, 1U);

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=343766&r1=343765&r2=343766&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp (original)
+++ llvm/trunk/tools/llvm-mca/lib/InstrBuilder.cpp Thu Oct  4 03:36:49 2018
@@ -321,6 +321,36 @@ Error InstrBuilder::populateReads(InstrD
   return ErrorSuccess();
 }
 
+Error InstrBuilder::verifyInstrDesc(const InstrDesc &ID,
+                                    const MCInst &MCI) const {
+  if (ID.NumMicroOps != 0)
+    return ErrorSuccess();
+
+  bool UsesMemory = ID.MayLoad || ID.MayStore;
+  bool UsesBuffers = !ID.Buffers.empty();
+  bool UsesResources = !ID.Resources.empty();
+  if (!UsesMemory && !UsesBuffers && !UsesResources)
+    return ErrorSuccess();
+
+  std::string ToString;
+  raw_string_ostream OS(ToString);
+  if (UsesMemory) {
+    WithColor::error() << "found an inconsistent instruction that decodes "
+                       << "into zero opcodes and that consumes load/store "
+                       << "unit resources.\n";
+  } else {
+    WithColor::error() << "found an inconsistent instruction that decodes"
+                       << " to zero opcodes and that consumes scheduler "
+                       << "resources.\n";
+  }
+
+  MCIP.printInst(&MCI, OS, "", STI);
+  OS.flush();
+  WithColor::note() << "instruction: " << ToString << '\n';
+  return make_error<StringError>("Invalid instruction definition found",
+                                 inconvertibleErrorCode());
+}
+
 Expected<const InstrDesc &>
 InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
   assert(STI.getSchedModel().hasInstrSchedModel() &&
@@ -392,6 +422,10 @@ InstrBuilder::createInstrDescImpl(const
   LLVM_DEBUG(dbgs() << "\t\tMaxLatency=" << ID->MaxLatency << '\n');
   LLVM_DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n');
 
+  // Sanity check on the instruction descriptor.
+  if (Error Err = verifyInstrDesc(*ID, MCI))
+    return std::move(Err);
+
   // Now add the new descriptor.
   SchedClassID = MCDesc.getSchedClass();
   if (!SM.getSchedClassDesc(SchedClassID)->isVariant()) {




More information about the llvm-commits mailing list