[llvm] [TableGen] Add a maps from Write/ReadType to the parent WriteRes/ReadAdvance. NFC (PR #123876)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 21 20:25:32 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

<details>
<summary>Changes</summary>

Use this to improve performance of SubtargetEmitter::findWriteResources
and SubtargetEmitter::findReadAdvance. Now we can do a map lookup
instead of a linear search through all WriteRes/ReadAdvance records.
    
This reduces the build time of RISCVGenSubtargetInfo.inc on my
machine from 43 seconds to 10 seconds.

Stacked on #<!-- -->123865

---
Full diff: https://github.com/llvm/llvm-project/pull/123876.diff


4 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVSchedMIPSP8700.td (-1) 
- (modified) llvm/utils/TableGen/Common/CodeGenSchedule.cpp (+16) 
- (modified) llvm/utils/TableGen/Common/CodeGenSchedule.h (+6) 
- (modified) llvm/utils/TableGen/SubtargetEmitter.cpp (+31-32) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVSchedMIPSP8700.td b/llvm/lib/Target/RISCV/RISCVSchedMIPSP8700.td
index 550f83a59b8b0e..ab6402dc96af10 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedMIPSP8700.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedMIPSP8700.td
@@ -125,7 +125,6 @@ def : WriteRes<WriteCSR, [p8700ALQ]>;
 
 // Handle CTI Pipeline.
 def : WriteRes<WriteJmp, [p8700IssueCTI]>;
-def : WriteRes<WriteJalr, [p8700IssueCTI]>;
 let Latency = 2 in {
 def : WriteRes<WriteJal, [p8700IssueCTI]>;
 def : WriteRes<WriteJalr, [p8700IssueCTI]>;
diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
index 8eaba05e65ce92..2a42262f865cb9 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
@@ -2112,6 +2112,14 @@ void CodeGenSchedModels::addWriteRes(const Record *ProcWriteResDef,
     return;
   WRDefs.push_back(ProcWriteResDef);
 
+  if (ProcWriteResDef->isSubClassOf("WriteRes")) {
+    auto &WRMap = ProcModels[PIdx].WriteResMap;
+    const Record *WRDef = ProcWriteResDef->getValueAsDef("WriteType");
+    if (!WRMap.try_emplace(WRDef, ProcWriteResDef).second)
+      PrintFatalError(ProcWriteResDef->getLoc(),
+                      "WriteType already used in another WriteRes");
+  }
+
   // Visit ProcResourceKinds referenced by the newly discovered WriteRes.
   for (const Record *ProcResDef :
        ProcWriteResDef->getValueAsListOfDefs("ProcResources")) {
@@ -2135,6 +2143,14 @@ void CodeGenSchedModels::addReadAdvance(const Record *ProcReadAdvanceDef,
   if (is_contained(RADefs, ProcReadAdvanceDef))
     return;
   RADefs.push_back(ProcReadAdvanceDef);
+
+  if (ProcReadAdvanceDef->isSubClassOf("ReadAdvance")) {
+    auto &RAMap = ProcModels[PIdx].ReadAdvanceMap;
+    const Record *RADef = ProcReadAdvanceDef->getValueAsDef("ReadType");
+    if (!RAMap.try_emplace(RADef, ProcReadAdvanceDef).second)
+      PrintFatalError(ProcReadAdvanceDef->getLoc(),
+                      "ReadType already used in another ReadAdvance");
+  }
 }
 
 unsigned CodeGenProcModel::getProcResourceIdx(const Record *PRDef) const {
diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.h b/llvm/utils/TableGen/Common/CodeGenSchedule.h
index fed8b3e1ccb8a6..467b77e8acba31 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.h
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.h
@@ -244,6 +244,12 @@ struct CodeGenProcModel {
   ConstRecVec WriteResDefs;
   ConstRecVec ReadAdvanceDefs;
 
+  // Map from the WriteType field to the parent WriteRes record.
+  DenseMap<const Record *, const Record *> WriteResMap;
+
+  // Map from the ReadType field to the parent ReadAdvance record.
+  DenseMap<const Record *, const Record *> ReadAdvanceMap;
+
   // Per-operand machine model resources associated with this processor.
   ConstRecVec ProcResourceDefs;
 
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 1120f06875c778..3db3ae65cc5557 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -943,24 +943,23 @@ SubtargetEmitter::findWriteResources(const CodeGenSchedRW &SchedWrite,
 
   // Check this processor's list of write resources.
   const Record *ResDef = nullptr;
-  for (const Record *WR : ProcModel.WriteResDefs) {
-    if (!WR->isSubClassOf("WriteRes"))
-      continue;
-    const Record *WRDef = WR->getValueAsDef("WriteType");
-    if (AliasDef == WRDef || SchedWrite.TheDef == WRDef) {
-      if (ResDef) {
-        PrintFatalError(WR->getLoc(), "Resources are defined for both "
-                                      "SchedWrite and its alias on processor " +
-                                          ProcModel.ModelName);
-      }
-      ResDef = WR;
-      // If there is no AliasDef and we find a match, we can early exit since
-      // there is no need to verify whether there are resources defined for both
-      // SchedWrite and its alias.
-      if (!AliasDef)
-        break;
+
+  auto I = ProcModel.WriteResMap.find(SchedWrite.TheDef);
+  if (I != ProcModel.WriteResMap.end())
+    ResDef = I->second;
+
+  if (AliasDef) {
+    I = ProcModel.WriteResMap.find(AliasDef);
+    if (I != ProcModel.WriteResMap.end()) {
+      if (ResDef)
+        PrintFatalError(I->second->getLoc(),
+                        "Resources are defined for both SchedWrite and its "
+                        "alias on processor " +
+                            ProcModel.ModelName);
+      ResDef = I->second;
     }
   }
+
   // TODO: If ProcModel has a base model (previous generation processor),
   // then call FindWriteResources recursively with that model here.
   if (!ResDef) {
@@ -1003,24 +1002,24 @@ SubtargetEmitter::findReadAdvance(const CodeGenSchedRW &SchedRead,
 
   // Check this processor's ReadAdvanceList.
   const Record *ResDef = nullptr;
-  for (const Record *RA : ProcModel.ReadAdvanceDefs) {
-    if (!RA->isSubClassOf("ReadAdvance"))
-      continue;
-    const Record *RADef = RA->getValueAsDef("ReadType");
-    if (AliasDef == RADef || SchedRead.TheDef == RADef) {
-      if (ResDef) {
-        PrintFatalError(RA->getLoc(), "Resources are defined for both "
-                                      "SchedRead and its alias on processor " +
-                                          ProcModel.ModelName);
-      }
-      ResDef = RA;
-      // If there is no AliasDef and we find a match, we can early exit since
-      // there is no need to verify whether there are resources defined for both
-      // SchedRead and its alias.
-      if (!AliasDef)
-        break;
+
+  auto I = ProcModel.ReadAdvanceMap.find(SchedRead.TheDef);
+  if (I != ProcModel.ReadAdvanceMap.end())
+    ResDef = I->second;
+
+  if (AliasDef) {
+    I = ProcModel.ReadAdvanceMap.find(AliasDef);
+    if (I != ProcModel.ReadAdvanceMap.end()) {
+      if (ResDef)
+        PrintFatalError(
+            I->second->getLoc(),
+            "Resources are defined for both SchedRead and its alias on "
+            "processor " +
+                ProcModel.ModelName);
+      ResDef = I->second;
     }
   }
+
   // TODO: If ProcModel has a base model (previous generation processor),
   // then call FindReadAdvance recursively with that model here.
   if (!ResDef && SchedRead.TheDef->getName() != "ReadDefault") {

``````````

</details>


https://github.com/llvm/llvm-project/pull/123876


More information about the llvm-commits mailing list