[llvm] [TableGen] Rework `EmitIntrinsicToBuiltinMap` (PR #104681)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 19 20:46:11 PDT 2024


================
@@ -596,89 +598,178 @@ void IntrinsicEmitter::EmitIntrinsicToBuiltinMap(
     const CodeGenIntrinsicTable &Ints, bool IsClang, raw_ostream &OS) {
   StringRef CompilerName = IsClang ? "Clang" : "MS";
   StringRef UpperCompilerName = IsClang ? "CLANG" : "MS";
-  // map<TargetPrefix, map<BuiltinName, EnumName>>. Note that we iterate over
-  // both maps in the code below. For the inner map, entries need to be emitted
-  // in the sorted order of `BuiltinName` because we use std::lower_bound to
-  // search these entries. For the outer map, it doesn't need be be sorted, but
-  // we use a map to eliminate non-determinism in the emitted code.
-  typedef std::map<StringRef, std::map<StringRef, StringRef>> BIMTy;
-  BIMTy BuiltinMap;
-  StringToOffsetTable Table;
+
+  // map<TargetPrefix, pair<map<BuiltinName, EnumName>, CommonPrefix>.
+  // Note that we iterate over both the maps in the code below and both
+  // iterations need to iterate in sorted key order. For the inner map, entries
+  // need to be emitted in the sorted order of `BuiltinName - CommonPrefix`
+  // because we use std::lower_bound to search these entries. For the outer map
+  // as well, entries need to be emitted in sorter order of `TargetPrefix` as we
+  // use std::lower_bound to search these entries.
+  using BIMEntryTy = std::pair<std::map<StringRef, StringRef>, StringRef>;
+  std::map<StringRef, BIMEntryTy> BuiltinMap;
+
   for (const CodeGenIntrinsic &Int : Ints) {
     StringRef BuiltinName = IsClang ? Int.ClangBuiltinName : Int.MSBuiltinName;
     if (BuiltinName.empty())
       continue;
     // Get the map for this target prefix.
-    std::map<StringRef, StringRef> &BIM = BuiltinMap[Int.TargetPrefix];
+    auto &[Map, CommonPrefix] = BuiltinMap[Int.TargetPrefix];
 
-    if (!BIM.insert(std::pair(BuiltinName, Int.EnumName)).second)
+    if (!Map.insert({BuiltinName, Int.EnumName}).second)
       PrintFatalError(Int.TheDef->getLoc(),
                       "Intrinsic '" + Int.TheDef->getName() + "': duplicate " +
                           CompilerName + " builtin name!");
-    Table.GetOrAddStringOffset(BuiltinName);
-  }
 
-  OS << "// Get the LLVM intrinsic that corresponds to a builtin.\n";
-  OS << "// This is used by the C front-end.  The builtin name is passed\n";
-  OS << "// in as BuiltinName, and a target prefix (e.g. 'ppc') is passed\n";
-  OS << "// in as TargetPrefix. The result is assigned to 'IntrinsicID'.\n";
-  OS << "#ifdef GET_LLVM_INTRINSIC_FOR_" << UpperCompilerName << "_BUILTIN\n";
+    // Update common prefix.
+    if (!CommonPrefix.data()) {
+      // For the first builtin for this target, initialize the common prefix.
+      CommonPrefix = BuiltinName;
+      continue;
+    }
 
-  OS << "Intrinsic::ID Intrinsic::getIntrinsicFor" << CompilerName
-     << "Builtin(const char "
-     << "*TargetPrefixStr, StringRef BuiltinNameStr) {\n";
+    // Update the common prefix. Note that this assumes that `take_front` will
+    // never set the `Data` pointer in CommonPrefix to nullptr.
+    const char *Mismatch = mismatch(CommonPrefix, BuiltinName).first;
+    CommonPrefix = CommonPrefix.take_front(Mismatch - CommonPrefix.begin());
+  }
 
-  if (Table.Empty()) {
-    OS << "  return Intrinsic::not_intrinsic;\n";
-    OS << "}\n";
-    OS << "#endif\n\n";
+  // Populate the string table with the names of all the builtins after
+  // removing this common prefix.
+  StringToOffsetTable Table;
+  for (const auto &[TargetPrefix, Entry] : BuiltinMap) {
+    auto &[Map, CommonPrefix] = Entry;
+    for (auto &[BuiltinName, EnumName] : Map) {
+      StringRef Suffix = BuiltinName.substr(CommonPrefix.size());
+      if (!Suffix.empty())
----------------
jurahul wrote:

Fixed this case. Also added a const `GetStringOffset` function to the `StringToOffsetTable` to lookup the offset of a pre-existing string.  

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


More information about the llvm-commits mailing list