[llvm] [TableGen][SubtargetEmitter] Refactor hasReadOfWrite to take ProcModel argument (PR #92032)

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Tue May 14 06:27:30 PDT 2024


https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/92032

>From 453db2ec5d6e636fb68895e63e36baa03fafdb6c Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 13 May 2024 14:01:25 -0700
Subject: [PATCH 1/2] [TableGen][SubtargetEmitter] Refactor hasReadOfWrite to
 take ProcModel argument

SubtargetEmitter::GenSchedClassTables takes a CodeGenProcModel, but
calls hasReadOfWrite which loops over all ProcModels. We overload hasReadOfWrite
to have a version that return true if the given write record is referenced by a
ReadAdvance for the specified ProcModel. This leads to a 144% speedup on
the RISC-V backend of our downstream.

This patch is purley performance related has no impact on the final generated
code.
---
 .../utils/TableGen/Common/CodeGenSchedule.cpp | 22 ++++++++++++-------
 llvm/utils/TableGen/Common/CodeGenSchedule.h  |  8 ++++++-
 llvm/utils/TableGen/SubtargetEmitter.cpp      |  4 ++--
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
index 0e81623a6aa38..da5038d947b09 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
@@ -746,18 +746,24 @@ unsigned CodeGenSchedModels::getSchedRWIdx(const Record *Def,
   return I == RWVec.end() ? 0 : std::distance(RWVec.begin(), I);
 }
 
-bool CodeGenSchedModels::hasReadOfWrite(Record *WriteDef) const {
-  for (auto &ProcModel : ProcModels) {
-    const RecVec &RADefs = ProcModel.ReadAdvanceDefs;
-    for (auto &RADef : RADefs) {
-      RecVec ValidWrites = RADef->getValueAsListOfDefs("ValidWrites");
-      if (is_contained(ValidWrites, WriteDef))
-        return true;
-    }
+bool CodeGenSchedModels::hasReadOfWrite(
+    Record *WriteDef, const CodeGenProcModel &ProcModel) const {
+  const RecVec &RADefs = ProcModel.ReadAdvanceDefs;
+  for (auto &RADef : RADefs) {
+    RecVec ValidWrites = RADef->getValueAsListOfDefs("ValidWrites");
+    if (is_contained(ValidWrites, WriteDef))
+      return true;
   }
   return false;
 }
 
+bool CodeGenSchedModels::hasReadOfWrite(Record *WriteDef) const {
+  for (auto &ProcModel : ProcModels)
+    if (hasReadOfWrite(WriteDef, ProcModel))
+      return true;
+  return false;
+}
+
 static void splitSchedReadWrites(const RecVec &RWDefs, RecVec &WriteDefs,
                                  RecVec &ReadDefs) {
   for (Record *RWDef : RWDefs) {
diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.h b/llvm/utils/TableGen/Common/CodeGenSchedule.h
index 61980e7e196e5..f73b691421a08 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.h
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.h
@@ -536,7 +536,13 @@ class CodeGenSchedModels {
 
   unsigned getSchedRWIdx(const Record *Def, bool IsRead) const;
 
-  // Return true if the given write record is referenced by a ReadAdvance.
+  // Return true if the given write record is referenced by a ReadAdvance for
+  // the specified ProcModel.
+  bool hasReadOfWrite(Record *WriteDef,
+                      const CodeGenProcModel &ProcModel) const;
+
+  // Return true if the given write record is referenced by a ReadAdvance by any
+  // ProcModel.
   bool hasReadOfWrite(Record *WriteDef) const;
 
   // Get a SchedClass from its index.
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index b6b7641cfb929..5b2a196a3ad74 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -1122,8 +1122,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
       WriterNames.push_back(SchedModels.getSchedWrite(WriteID).Name);
       // If this Write is not referenced by a ReadAdvance, don't distinguish it
       // from other WriteLatency entries.
-      if (!SchedModels.hasReadOfWrite(
-              SchedModels.getSchedWrite(WriteID).TheDef)) {
+      if (!SchedModels.hasReadOfWrite(SchedModels.getSchedWrite(WriteID).TheDef,
+                                      ProcModel)) {
         WriteID = 0;
       }
       WLEntry.WriteResourceID = WriteID;

>From a183d4ef581c1c6d2528232283a37f9da07b6761 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Tue, 14 May 2024 06:27:02 -0700
Subject: [PATCH 2/2] fixup! move to CodeGenProcModel

---
 .../utils/TableGen/Common/CodeGenSchedule.cpp | 27 +++++++------------
 llvm/utils/TableGen/Common/CodeGenSchedule.h  | 12 +++------
 llvm/utils/TableGen/SubtargetEmitter.cpp      |  4 +--
 3 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
index da5038d947b09..2ec0812320d14 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
@@ -746,24 +746,6 @@ unsigned CodeGenSchedModels::getSchedRWIdx(const Record *Def,
   return I == RWVec.end() ? 0 : std::distance(RWVec.begin(), I);
 }
 
-bool CodeGenSchedModels::hasReadOfWrite(
-    Record *WriteDef, const CodeGenProcModel &ProcModel) const {
-  const RecVec &RADefs = ProcModel.ReadAdvanceDefs;
-  for (auto &RADef : RADefs) {
-    RecVec ValidWrites = RADef->getValueAsListOfDefs("ValidWrites");
-    if (is_contained(ValidWrites, WriteDef))
-      return true;
-  }
-  return false;
-}
-
-bool CodeGenSchedModels::hasReadOfWrite(Record *WriteDef) const {
-  for (auto &ProcModel : ProcModels)
-    if (hasReadOfWrite(WriteDef, ProcModel))
-      return true;
-  return false;
-}
-
 static void splitSchedReadWrites(const RecVec &RWDefs, RecVec &WriteDefs,
                                  RecVec &ReadDefs) {
   for (Record *RWDef : RWDefs) {
@@ -2232,6 +2214,15 @@ bool CodeGenProcModel::isUnsupported(const CodeGenInstruction &Inst) const {
   return false;
 }
 
+bool CodeGenProcModel::hasReadOfWrite(Record *WriteDef) const {
+  for (auto &RADef : ReadAdvanceDefs) {
+    RecVec ValidWrites = RADef->getValueAsListOfDefs("ValidWrites");
+    if (is_contained(ValidWrites, WriteDef))
+      return true;
+  }
+  return false;
+}
+
 #ifndef NDEBUG
 void CodeGenProcModel::dump() const {
   dbgs() << Index << ": " << ModelName << " "
diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.h b/llvm/utils/TableGen/Common/CodeGenSchedule.h
index f73b691421a08..10ec7f41f56ff 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.h
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.h
@@ -277,6 +277,9 @@ struct CodeGenProcModel {
 
   bool isUnsupported(const CodeGenInstruction &Inst) const;
 
+  // Return true if the given write record is referenced by a ReadAdvance.
+  bool hasReadOfWrite(Record *WriteDef) const;
+
 #ifndef NDEBUG
   void dump() const;
 #endif
@@ -536,15 +539,6 @@ class CodeGenSchedModels {
 
   unsigned getSchedRWIdx(const Record *Def, bool IsRead) const;
 
-  // Return true if the given write record is referenced by a ReadAdvance for
-  // the specified ProcModel.
-  bool hasReadOfWrite(Record *WriteDef,
-                      const CodeGenProcModel &ProcModel) const;
-
-  // Return true if the given write record is referenced by a ReadAdvance by any
-  // ProcModel.
-  bool hasReadOfWrite(Record *WriteDef) const;
-
   // Get a SchedClass from its index.
   CodeGenSchedClass &getSchedClass(unsigned Idx) {
     assert(Idx < SchedClasses.size() && "bad SchedClass index");
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 5b2a196a3ad74..489b8844fc8ba 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -1122,10 +1122,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
       WriterNames.push_back(SchedModels.getSchedWrite(WriteID).Name);
       // If this Write is not referenced by a ReadAdvance, don't distinguish it
       // from other WriteLatency entries.
-      if (!SchedModels.hasReadOfWrite(SchedModels.getSchedWrite(WriteID).TheDef,
-                                      ProcModel)) {
+      if(!ProcModel.hasReadOfWrite(SchedModels.getSchedWrite(WriteID).TheDef))
         WriteID = 0;
-      }
       WLEntry.WriteResourceID = WriteID;
 
       for (unsigned WS : WriteSeq) {



More information about the llvm-commits mailing list