[llvm] [TableGen] Use a struct with operator() for searchable table comparison. (PR #97784)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 20:12:43 PDT 2024


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/97784

Previously we used a lambda. #96174 is proposing to use equal_range for some cases instead of lower_bound. This requires two different comparison functions since KeyType and IndexType are different types.

CC: @quic-garvgupt 

>From 5c0f6f03a4bb0c5bb9dfba2e61b39bf4fc1dda67 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 4 Jul 2024 20:06:56 -0700
Subject: [PATCH] [TableGen] Use a struct with operator() for searchable table
 comparison.

Previously we used a lambda. #96174 is proposing to use equal_range
for some cases instead of lower_bound. This requires two different
comparison functions since KeyType and IndexType are different types.
---
 .../utils/TableGen/SearchableTableEmitter.cpp | 41 ++++++++++++++++---
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index 48ee23db957def..aae1ab929405b7 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -448,10 +448,9 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
   }
   OS << "};\n";
 
-  OS << "  auto Table = ArrayRef(" << IndexName << ");\n";
-  OS << "  auto Idx = std::lower_bound(Table.begin(), Table.end(), Key,\n";
-  OS << "    [](const " << IndexTypeName << " &LHS, const KeyType &RHS) {\n";
-
+  OS << "  struct Comp {\n";
+  OS << "    bool operator()(const " << IndexTypeName
+     << " &LHS, const KeyType &RHS) const {\n";
   for (const auto &Field : Index.Fields) {
     if (isa<StringRecTy>(Field.RecType)) {
       OS << "      int Cmp" << Field.Name << " = StringRef(LHS." << Field.Name
@@ -474,9 +473,41 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
       OS << "        return false;\n";
     }
   }
+  OS << "      return false;\n";
+  OS << "    }\n";
 
+  OS << "    bool operator()(const KeyType &LHS, const " << IndexTypeName
+     << " &RHS) const {\n";
+  for (const auto &Field : Index.Fields) {
+    if (isa<StringRecTy>(Field.RecType)) {
+      OS << "      int Cmp" << Field.Name << " = StringRef(LHS." << Field.Name
+         << ").compare(RHS." << Field.Name << ");\n";
+      OS << "      if (Cmp" << Field.Name << " < 0) return true;\n";
+      OS << "      if (Cmp" << Field.Name << " > 0) return false;\n";
+    } else if (Field.Enum) {
+      // Explicitly cast to unsigned, because the signedness of enums is
+      // compiler-dependent.
+      OS << "      if ((unsigned)LHS." << Field.Name << " < (unsigned)RHS."
+         << Field.Name << ")\n";
+      OS << "        return true;\n";
+      OS << "      if ((unsigned)LHS." << Field.Name << " > (unsigned)RHS."
+         << Field.Name << ")\n";
+      OS << "        return false;\n";
+    } else {
+      OS << "      if (LHS." << Field.Name << " < RHS." << Field.Name << ")\n";
+      OS << "        return true;\n";
+      OS << "      if (LHS." << Field.Name << " > RHS." << Field.Name << ")\n";
+      OS << "        return false;\n";
+    }
+  }
   OS << "      return false;\n";
-  OS << "    });\n\n";
+  OS << "    }\n";
+
+  OS << "  };\n";
+
+  OS << "  auto Table = ArrayRef(" << IndexName << ");\n";
+  OS << "  auto Idx = std::lower_bound(Table.begin(), Table.end(), Key, "
+        "Comp());\n";
 
   OS << "  if (Idx == Table.end()";
 



More information about the llvm-commits mailing list