[llvm] TableGen: Add first class support for processor aliases (PR #211775)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 24 06:26:24 PDT 2026


================
@@ -286,49 +287,79 @@ static void checkDuplicateCPUFeatures(StringRef CPUName,
 std::pair<unsigned, unsigned>
 SubtargetEmitter::cpuKeyValues(raw_ostream &OS,
                                const FeatureMapTy &FeatureMap) {
-  // Gather and sort processor information
   std::vector<const Record *> ProcessorList =
       Records.getAllDerivedDefinitions("Processor");
-  llvm::sort(ProcessorList, LessRecordFieldName());
 
-  // In the string table, include the aliases as well.
+  StringMap<const Record *> ProcessorMap;
+  for (const Record *Processor : ProcessorList)
+    ProcessorMap[Processor->getValueAsString("Name")] = Processor;
+
+  // Each alias is emitted as an entry pointing at its canonical processor, so
+  // generic CPU-string handling (e.g. `isCPUStringValid`) accepts alias names.
+  struct SubTypeEntry {
+    StringRef Name;
+    const Record *Proc;
+  };
+  std::vector<SubTypeEntry> SubTypeEntries;
+
   std::vector<const Record *> ProcessorAliasList =
       Records.getAllDerivedDefinitionsIfDefined("ProcessorAlias");
-  SmallVector<StringRef> Names;
-  Names.reserve(ProcessorList.size() + ProcessorAliasList.size());
+  SubTypeEntries.reserve(ProcessorList.size() + ProcessorAliasList.size());
+
   for (const Record *Processor : ProcessorList)
-    Names.push_back(Processor->getValueAsString("Name"));
-  for (const Record *Rec : ProcessorAliasList)
-    Names.push_back(Rec->getValueAsString("Name"));
-  llvm::sort(Names);
+    SubTypeEntries.push_back({Processor->getValueAsString("Name"), Processor});
+
+  StringSet<> AliasNames;
+  for (const Record *Rec : ProcessorAliasList) {
+    StringRef Name = Rec->getValueAsString("Name");
+    StringRef Alias = Rec->getValueAsString("Alias");
+    auto It = ProcessorMap.find(Alias);
+    if (It == ProcessorMap.end())
+      PrintFatalError(Rec, "Alias '" + Name +
+                               "' references a non-existent Processor '" +
+                               Alias + "'");
+    if (ProcessorMap.contains(Name))
+      PrintFatalError(Rec,
+                      "Alias '" + Name + "' duplicates an existing Processor");
+    if (!AliasNames.insert(Name).second)
+      PrintFatalError(Rec, "Alias '" + Name + "' duplicates an existing alias");
+    SubTypeEntries.push_back({Name, It->second});
+  }
+
+  // The table must stay sorted by key for the binary search in the lookups.
+  llvm::sort(SubTypeEntries,
+             [](const SubTypeEntry &LHS, const SubTypeEntry &RHS) {
+               return LHS.Name < RHS.Name;
+             });
 
   StringToOffsetTable StrTab;
-  for (StringRef Name : Names)
-    StrTab.GetOrAddStringOffset(Name);
+  for (const SubTypeEntry &Entry : SubTypeEntries)
+    StrTab.GetOrAddStringOffset(Entry.Name);
 
   // Note that unlike `FeatureKeyValues`, here we do not need to check for
   // duplicate processors, since that is already done when the SubtargetEmitter
   // constructor calls `getSchedModels` to build a `CodeGenSchedModels` object,
   // which does the duplicate processor check.
 
+  unsigned Total = SubTypeEntries.size();
+
   // Begin processor table.
   OS << "// Sorted (by key) array of values for CPU subtype.\n"
-     << "extern const llvm::SubtargetSubTypeKVStorage< " << ProcessorList.size()
-     << ", " << (StrTab.size() + 1) << "> " << Target
-     << "SubTypeKVStorage = {\n  {\n";
+     << "extern const llvm::SubtargetSubTypeKVStorage< " << Total << ", "
+     << (StrTab.size() + 1) << "> " << Target << "SubTypeKVStorage = {\n  {\n";
 
-  for (const auto &[Idx, Processor] : enumerate(ProcessorList)) {
-    StringRef Name = Processor->getValueAsString("Name");
+  for (const auto &[Idx, Entry] : enumerate(SubTypeEntries)) {
----------------
arsenm wrote:

You still need to perform the lookup by name, which requires the alphabetically sorted list (the table is ultimately searched with std::lower_bound). There's some deduplication on the business end, like the sched models 

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


More information about the llvm-commits mailing list