Skip to content

[ARM][AArch64] autogenerate header file for TargetParser from Target tablegen files #88378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 24, 2024

Conversation

tmatheson-arm
Copy link
Contributor

This patch introduces the generation of two files as part of TargetParser. The idea is to introduce a mechanism to share data between the backend and TargetParser, to reduce duplication of code. It works the same way as the current RISC-V implementation. The target tablegen file (in this case ARM.td or AArch64.td) is processed during building of TargetParser to generate the following files in the build tree:

  • build/include/llvm/TargetParser/ARMTargetParserDef.inc
  • build/include/llvm/TargetParser/AArch64TargetParserDef.inc

For now, the use of these generated files is limited to files outside of TargetParser. The main reason for this is that the modifications to TargetParser will require additional data added to the tablegen files, which I want to split into separate PRs. I can push those for review if people want to see them as motivation for this change.

This header is generated in TargetParser. These changes do not make use
of it in TargetParser itself, but future changes will.

The end goal is to share information between TargetParser and the
backend.
@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2024

@llvm/pr-subscribers-backend-aarch64

Author: Tomas Matheson (tmatheson-arm)

Changes

This patch introduces the generation of two files as part of TargetParser. The idea is to introduce a mechanism to share data between the backend and TargetParser, to reduce duplication of code. It works the same way as the current RISC-V implementation. The target tablegen file (in this case ARM.td or AArch64.td) is processed during building of TargetParser to generate the following files in the build tree:

  • build/include/llvm/TargetParser/ARMTargetParserDef.inc
  • build/include/llvm/TargetParser/AArch64TargetParserDef.inc

For now, the use of these generated files is limited to files outside of TargetParser. The main reason for this is that the modifications to TargetParser will require additional data added to the tablegen files, which I want to split into separate PRs. I can push those for review if people want to see them as motivation for this change.


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

7 Files Affected:

  • (modified) llvm/include/llvm/TargetParser/CMakeLists.txt (+9)
  • (modified) llvm/lib/Target/AArch64/AArch64Subtarget.h (+3-55)
  • (modified) llvm/lib/Target/ARM/ARMSubtarget.cpp (-1)
  • (modified) llvm/lib/Target/ARM/ARMSubtarget.h (+6-76)
  • (modified) llvm/lib/TargetParser/CMakeLists.txt (+2)
  • (added) llvm/utils/TableGen/ARMTargetDefEmitter.cpp (+67)
  • (modified) llvm/utils/TableGen/CMakeLists.txt (+1)
diff --git a/llvm/include/llvm/TargetParser/CMakeLists.txt b/llvm/include/llvm/TargetParser/CMakeLists.txt
index 7f080e01548c7c..f89d4eb5ea1638 100644
--- a/llvm/include/llvm/TargetParser/CMakeLists.txt
+++ b/llvm/include/llvm/TargetParser/CMakeLists.txt
@@ -1,3 +1,12 @@
+set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/ARM/ARM.td)
+tablegen(LLVM ARMTargetParserDef.inc -gen-arm-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/ARM/)
+add_public_tablegen_target(ARMTargetParserTableGen)
+
+set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/AArch64/AArch64.td)
+tablegen(LLVM AArch64TargetParserDef.inc -gen-arm-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/AArch64/)
+add_public_tablegen_target(AArch64TargetParserTableGen)
+
 set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/RISCV.td)
 tablegen(LLVM RISCVTargetParserDef.inc -gen-riscv-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/)
 add_public_tablegen_target(RISCVTargetParserTableGen)
+
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 95bef7a76bcab7..8ff5f9076f53b9 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -39,61 +39,9 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
 public:
   enum ARMProcFamilyEnum : uint8_t {
     Others,
-    A64FX,
-    Ampere1,
-    Ampere1A,
-    Ampere1B,
-    AppleA7,
-    AppleA10,
-    AppleA11,
-    AppleA12,
-    AppleA13,
-    AppleA14,
-    AppleA15,
-    AppleA16,
-    AppleA17,
-    Carmel,
-    CortexA35,
-    CortexA53,
-    CortexA55,
-    CortexA510,
-    CortexA520,
-    CortexA57,
-    CortexA65,
-    CortexA72,
-    CortexA73,
-    CortexA75,
-    CortexA76,
-    CortexA77,
-    CortexA78,
-    CortexA78AE,
-    CortexA78C,
-    CortexA710,
-    CortexA715,
-    CortexA720,
-    CortexR82,
-    CortexX1,
-    CortexX1C,
-    CortexX2,
-    CortexX3,
-    CortexX4,
-    ExynosM3,
-    Falkor,
-    Kryo,
-    NeoverseE1,
-    NeoverseN1,
-    NeoverseN2,
-    Neoverse512TVB,
-    NeoverseV1,
-    NeoverseV2,
-    Saphira,
-    ThunderX2T99,
-    ThunderX,
-    ThunderXT81,
-    ThunderXT83,
-    ThunderXT88,
-    ThunderX3T110,
-    TSV110
+    #define ARM_PROCESSOR_FAMILY(ENUM) ENUM,
+    #include "llvm/TargetParser/AArch64TargetParserDef.inc"
+    #undef ARM_PROCESSOR_FAMILY
   };
 
 protected:
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp
index 04ba20a17187b4..20543f63e496f1 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.cpp
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -293,7 +293,6 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
   case CortexA78C:
   case CortexA710:
   case CortexR4:
-  case CortexR4F:
   case CortexR5:
   case CortexR7:
   case CortexM3:
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 497ae160fde281..3c07c91b9baad0 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -49,45 +49,9 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
 protected:
   enum ARMProcFamilyEnum {
     Others,
-
-    CortexA12,
-    CortexA15,
-    CortexA17,
-    CortexA32,
-    CortexA35,
-    CortexA5,
-    CortexA53,
-    CortexA55,
-    CortexA57,
-    CortexA7,
-    CortexA72,
-    CortexA73,
-    CortexA75,
-    CortexA76,
-    CortexA77,
-    CortexA78,
-    CortexA78AE,
-    CortexA78C,
-    CortexA710,
-    CortexA8,
-    CortexA9,
-    CortexM3,
-    CortexM7,
-    CortexM52,
-    CortexR4,
-    CortexR4F,
-    CortexR5,
-    CortexR52,
-    CortexR7,
-    CortexX1,
-    CortexX1C,
-    Exynos,
-    Krait,
-    Kryo,
-    NeoverseN1,
-    NeoverseN2,
-    NeoverseV1,
-    Swift
+    #define ARM_PROCESSOR_FAMILY(ENUM) ENUM,
+    #include "llvm/TargetParser/ARMTargetParserDef.inc"
+    #undef ARM_PROCESSOR_FAMILY
   };
   enum ARMProcClassEnum {
     None,
@@ -97,43 +61,9 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
     RClass
   };
   enum ARMArchEnum {
-    ARMv4,
-    ARMv4t,
-    ARMv5,
-    ARMv5t,
-    ARMv5te,
-    ARMv5tej,
-    ARMv6,
-    ARMv6k,
-    ARMv6kz,
-    ARMv6m,
-    ARMv6sm,
-    ARMv6t2,
-    ARMv7a,
-    ARMv7em,
-    ARMv7m,
-    ARMv7r,
-    ARMv7ve,
-    ARMv81a,
-    ARMv82a,
-    ARMv83a,
-    ARMv84a,
-    ARMv85a,
-    ARMv86a,
-    ARMv87a,
-    ARMv88a,
-    ARMv89a,
-    ARMv8a,
-    ARMv8mBaseline,
-    ARMv8mMainline,
-    ARMv8r,
-    ARMv81mMainline,
-    ARMv9a,
-    ARMv91a,
-    ARMv92a,
-    ARMv93a,
-    ARMv94a,
-    ARMv95a,
+    #define ARM_ARCHITECTURE(ENUM) ENUM,
+    #include "llvm/TargetParser/ARMTargetParserDef.inc"
+    #undef ARM_ARCHITECTURE
   };
 
 public:
diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt
index da1e352b037338..00f01a127ab316 100644
--- a/llvm/lib/TargetParser/CMakeLists.txt
+++ b/llvm/lib/TargetParser/CMakeLists.txt
@@ -37,5 +37,7 @@ add_llvm_component_library(LLVMTargetParser
   Support
 
   DEPENDS
+  ARMTargetParserTableGen
+  AArch64TargetParserTableGen
   RISCVTargetParserTableGen
   )
diff --git a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp
new file mode 100644
index 00000000000000..5253d7225d5183
--- /dev/null
+++ b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp
@@ -0,0 +1,67 @@
+//===- ARMTargetDefEmitter.cpp - Generate data about ARM Architectures ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend exports information about CPUs, FPUs, architectures,
+// and features into a common format that can be used by both TargetParser and
+// the ARM backend.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+using namespace llvm;
+
+static void EmitARMTargetDef(RecordKeeper &RK, raw_ostream &OS) {
+  OS << "// Autogenerated by ARMTargetDefEmitter.cpp\n\n";
+
+  // Look through all SubtargetFeature defs with the given FieldName, and
+  // collect the set of all Values that that FieldName is set to.
+  auto gatherSubtargetFeatureFieldValues = [&RK](StringRef FieldName) {
+    llvm::StringSet<> Set;
+    for (const Record *Rec : RK.getAllDerivedDefinitions("SubtargetFeature")) {
+      if (Rec->getValueAsString("FieldName") == FieldName) {
+        Set.insert(Rec->getValueAsString("Value"));
+      }
+    }
+    return Set;
+  };
+
+  // The ARMProcFamilyEnum values are initialised by SubtargetFeature defs
+  // which set the ARMProcFamily field. We can generate the enum from these defs
+  // which look like this:
+  //
+  // def ProcA5      : SubtargetFeature<"a5", "ARMProcFamily", "CortexA5",
+  //                                    "Cortex-A5 ARM processors", []>;
+  OS << "#ifndef ARM_PROCESSOR_FAMILY\n"
+     << "#define ARM_PROCESSOR_FAMILY(ENUM)\n"
+     << "#endif\n\n";
+  const StringSet<> ARMProcFamilyVals =
+      gatherSubtargetFeatureFieldValues("ARMProcFamily");
+  for (const StringRef &Family : ARMProcFamilyVals.keys()) {
+    OS << "ARM_PROCESSOR_FAMILY(" << Family << ")\n";
+  }
+  OS << "\n#undef ARM_PROCESSOR_FAMILY\n";
+  OS << "\n";
+
+  OS << "#ifndef ARM_ARCHITECTURE\n"
+     << "#define ARM_ARCHITECTURE(ENUM)\n"
+     << "#endif\n\n";
+  // This should correspond to instances of the Architecture tablegen class.
+  const StringSet<> ARMArchVals = gatherSubtargetFeatureFieldValues("ARMArch");
+  for (const StringRef &Arch : ARMArchVals.keys()) {
+    OS << "ARM_ARCHITECTURE(" << Arch << ")\n";
+  }
+  OS << "\n#undef ARM_ARCHITECTURE\n";
+  OS << "\n";
+}
+
+static TableGen::Emitter::Opt
+    X("gen-arm-target-def", EmitARMTargetDef,
+      "Generate the ARM Architecture information header.");
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index 577aeded4be72c..5285232e587a81 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -13,6 +13,7 @@ set(LLVM_LINK_COMPONENTS Support)
 # ValueType definitions.
 add_tablegen(llvm-min-tblgen LLVM_HEADERS
   TableGen.cpp
+  ARMTargetDefEmitter.cpp
   Attributes.cpp
   DirectiveEmitter.cpp
   IntrinsicEmitter.cpp

@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2024

@llvm/pr-subscribers-backend-arm

Author: Tomas Matheson (tmatheson-arm)

Changes

This patch introduces the generation of two files as part of TargetParser. The idea is to introduce a mechanism to share data between the backend and TargetParser, to reduce duplication of code. It works the same way as the current RISC-V implementation. The target tablegen file (in this case ARM.td or AArch64.td) is processed during building of TargetParser to generate the following files in the build tree:

  • build/include/llvm/TargetParser/ARMTargetParserDef.inc
  • build/include/llvm/TargetParser/AArch64TargetParserDef.inc

For now, the use of these generated files is limited to files outside of TargetParser. The main reason for this is that the modifications to TargetParser will require additional data added to the tablegen files, which I want to split into separate PRs. I can push those for review if people want to see them as motivation for this change.


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

7 Files Affected:

  • (modified) llvm/include/llvm/TargetParser/CMakeLists.txt (+9)
  • (modified) llvm/lib/Target/AArch64/AArch64Subtarget.h (+3-55)
  • (modified) llvm/lib/Target/ARM/ARMSubtarget.cpp (-1)
  • (modified) llvm/lib/Target/ARM/ARMSubtarget.h (+6-76)
  • (modified) llvm/lib/TargetParser/CMakeLists.txt (+2)
  • (added) llvm/utils/TableGen/ARMTargetDefEmitter.cpp (+67)
  • (modified) llvm/utils/TableGen/CMakeLists.txt (+1)
diff --git a/llvm/include/llvm/TargetParser/CMakeLists.txt b/llvm/include/llvm/TargetParser/CMakeLists.txt
index 7f080e01548c7c..f89d4eb5ea1638 100644
--- a/llvm/include/llvm/TargetParser/CMakeLists.txt
+++ b/llvm/include/llvm/TargetParser/CMakeLists.txt
@@ -1,3 +1,12 @@
+set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/ARM/ARM.td)
+tablegen(LLVM ARMTargetParserDef.inc -gen-arm-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/ARM/)
+add_public_tablegen_target(ARMTargetParserTableGen)
+
+set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/AArch64/AArch64.td)
+tablegen(LLVM AArch64TargetParserDef.inc -gen-arm-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/AArch64/)
+add_public_tablegen_target(AArch64TargetParserTableGen)
+
 set(LLVM_TARGET_DEFINITIONS ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/RISCV.td)
 tablegen(LLVM RISCVTargetParserDef.inc -gen-riscv-target-def -I ${PROJECT_SOURCE_DIR}/lib/Target/RISCV/)
 add_public_tablegen_target(RISCVTargetParserTableGen)
+
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 95bef7a76bcab7..8ff5f9076f53b9 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -39,61 +39,9 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
 public:
   enum ARMProcFamilyEnum : uint8_t {
     Others,
-    A64FX,
-    Ampere1,
-    Ampere1A,
-    Ampere1B,
-    AppleA7,
-    AppleA10,
-    AppleA11,
-    AppleA12,
-    AppleA13,
-    AppleA14,
-    AppleA15,
-    AppleA16,
-    AppleA17,
-    Carmel,
-    CortexA35,
-    CortexA53,
-    CortexA55,
-    CortexA510,
-    CortexA520,
-    CortexA57,
-    CortexA65,
-    CortexA72,
-    CortexA73,
-    CortexA75,
-    CortexA76,
-    CortexA77,
-    CortexA78,
-    CortexA78AE,
-    CortexA78C,
-    CortexA710,
-    CortexA715,
-    CortexA720,
-    CortexR82,
-    CortexX1,
-    CortexX1C,
-    CortexX2,
-    CortexX3,
-    CortexX4,
-    ExynosM3,
-    Falkor,
-    Kryo,
-    NeoverseE1,
-    NeoverseN1,
-    NeoverseN2,
-    Neoverse512TVB,
-    NeoverseV1,
-    NeoverseV2,
-    Saphira,
-    ThunderX2T99,
-    ThunderX,
-    ThunderXT81,
-    ThunderXT83,
-    ThunderXT88,
-    ThunderX3T110,
-    TSV110
+    #define ARM_PROCESSOR_FAMILY(ENUM) ENUM,
+    #include "llvm/TargetParser/AArch64TargetParserDef.inc"
+    #undef ARM_PROCESSOR_FAMILY
   };
 
 protected:
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp
index 04ba20a17187b4..20543f63e496f1 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.cpp
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -293,7 +293,6 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
   case CortexA78C:
   case CortexA710:
   case CortexR4:
-  case CortexR4F:
   case CortexR5:
   case CortexR7:
   case CortexM3:
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 497ae160fde281..3c07c91b9baad0 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -49,45 +49,9 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
 protected:
   enum ARMProcFamilyEnum {
     Others,
-
-    CortexA12,
-    CortexA15,
-    CortexA17,
-    CortexA32,
-    CortexA35,
-    CortexA5,
-    CortexA53,
-    CortexA55,
-    CortexA57,
-    CortexA7,
-    CortexA72,
-    CortexA73,
-    CortexA75,
-    CortexA76,
-    CortexA77,
-    CortexA78,
-    CortexA78AE,
-    CortexA78C,
-    CortexA710,
-    CortexA8,
-    CortexA9,
-    CortexM3,
-    CortexM7,
-    CortexM52,
-    CortexR4,
-    CortexR4F,
-    CortexR5,
-    CortexR52,
-    CortexR7,
-    CortexX1,
-    CortexX1C,
-    Exynos,
-    Krait,
-    Kryo,
-    NeoverseN1,
-    NeoverseN2,
-    NeoverseV1,
-    Swift
+    #define ARM_PROCESSOR_FAMILY(ENUM) ENUM,
+    #include "llvm/TargetParser/ARMTargetParserDef.inc"
+    #undef ARM_PROCESSOR_FAMILY
   };
   enum ARMProcClassEnum {
     None,
@@ -97,43 +61,9 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
     RClass
   };
   enum ARMArchEnum {
-    ARMv4,
-    ARMv4t,
-    ARMv5,
-    ARMv5t,
-    ARMv5te,
-    ARMv5tej,
-    ARMv6,
-    ARMv6k,
-    ARMv6kz,
-    ARMv6m,
-    ARMv6sm,
-    ARMv6t2,
-    ARMv7a,
-    ARMv7em,
-    ARMv7m,
-    ARMv7r,
-    ARMv7ve,
-    ARMv81a,
-    ARMv82a,
-    ARMv83a,
-    ARMv84a,
-    ARMv85a,
-    ARMv86a,
-    ARMv87a,
-    ARMv88a,
-    ARMv89a,
-    ARMv8a,
-    ARMv8mBaseline,
-    ARMv8mMainline,
-    ARMv8r,
-    ARMv81mMainline,
-    ARMv9a,
-    ARMv91a,
-    ARMv92a,
-    ARMv93a,
-    ARMv94a,
-    ARMv95a,
+    #define ARM_ARCHITECTURE(ENUM) ENUM,
+    #include "llvm/TargetParser/ARMTargetParserDef.inc"
+    #undef ARM_ARCHITECTURE
   };
 
 public:
diff --git a/llvm/lib/TargetParser/CMakeLists.txt b/llvm/lib/TargetParser/CMakeLists.txt
index da1e352b037338..00f01a127ab316 100644
--- a/llvm/lib/TargetParser/CMakeLists.txt
+++ b/llvm/lib/TargetParser/CMakeLists.txt
@@ -37,5 +37,7 @@ add_llvm_component_library(LLVMTargetParser
   Support
 
   DEPENDS
+  ARMTargetParserTableGen
+  AArch64TargetParserTableGen
   RISCVTargetParserTableGen
   )
diff --git a/llvm/utils/TableGen/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp
new file mode 100644
index 00000000000000..5253d7225d5183
--- /dev/null
+++ b/llvm/utils/TableGen/ARMTargetDefEmitter.cpp
@@ -0,0 +1,67 @@
+//===- ARMTargetDefEmitter.cpp - Generate data about ARM Architectures ----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend exports information about CPUs, FPUs, architectures,
+// and features into a common format that can be used by both TargetParser and
+// the ARM backend.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringSet.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+using namespace llvm;
+
+static void EmitARMTargetDef(RecordKeeper &RK, raw_ostream &OS) {
+  OS << "// Autogenerated by ARMTargetDefEmitter.cpp\n\n";
+
+  // Look through all SubtargetFeature defs with the given FieldName, and
+  // collect the set of all Values that that FieldName is set to.
+  auto gatherSubtargetFeatureFieldValues = [&RK](StringRef FieldName) {
+    llvm::StringSet<> Set;
+    for (const Record *Rec : RK.getAllDerivedDefinitions("SubtargetFeature")) {
+      if (Rec->getValueAsString("FieldName") == FieldName) {
+        Set.insert(Rec->getValueAsString("Value"));
+      }
+    }
+    return Set;
+  };
+
+  // The ARMProcFamilyEnum values are initialised by SubtargetFeature defs
+  // which set the ARMProcFamily field. We can generate the enum from these defs
+  // which look like this:
+  //
+  // def ProcA5      : SubtargetFeature<"a5", "ARMProcFamily", "CortexA5",
+  //                                    "Cortex-A5 ARM processors", []>;
+  OS << "#ifndef ARM_PROCESSOR_FAMILY\n"
+     << "#define ARM_PROCESSOR_FAMILY(ENUM)\n"
+     << "#endif\n\n";
+  const StringSet<> ARMProcFamilyVals =
+      gatherSubtargetFeatureFieldValues("ARMProcFamily");
+  for (const StringRef &Family : ARMProcFamilyVals.keys()) {
+    OS << "ARM_PROCESSOR_FAMILY(" << Family << ")\n";
+  }
+  OS << "\n#undef ARM_PROCESSOR_FAMILY\n";
+  OS << "\n";
+
+  OS << "#ifndef ARM_ARCHITECTURE\n"
+     << "#define ARM_ARCHITECTURE(ENUM)\n"
+     << "#endif\n\n";
+  // This should correspond to instances of the Architecture tablegen class.
+  const StringSet<> ARMArchVals = gatherSubtargetFeatureFieldValues("ARMArch");
+  for (const StringRef &Arch : ARMArchVals.keys()) {
+    OS << "ARM_ARCHITECTURE(" << Arch << ")\n";
+  }
+  OS << "\n#undef ARM_ARCHITECTURE\n";
+  OS << "\n";
+}
+
+static TableGen::Emitter::Opt
+    X("gen-arm-target-def", EmitARMTargetDef,
+      "Generate the ARM Architecture information header.");
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index 577aeded4be72c..5285232e587a81 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -13,6 +13,7 @@ set(LLVM_LINK_COMPONENTS Support)
 # ValueType definitions.
 add_tablegen(llvm-min-tblgen LLVM_HEADERS
   TableGen.cpp
+  ARMTargetDefEmitter.cpp
   Attributes.cpp
   DirectiveEmitter.cpp
   IntrinsicEmitter.cpp

Copy link

github-actions bot commented Apr 11, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

    ARM: CortexM52, NeoverseN1, NeoverseN2, CortexR4F
    AArch64: CortexX1C (still present in Target/ARM)

Since these have no corresponding Processor SubtargetFeature,
ARMProcFamily can never be set to these enum values.
Copy link
Contributor

@pratlucas pratlucas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Collaborator

@DavidSpickett DavidSpickett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tmatheson-arm tmatheson-arm merged commit 71c5964 into llvm:main Apr 24, 2024
@tmatheson-arm tmatheson-arm deleted the tablegen_for_targetparser branch April 24, 2024 08:18
@DavidSpickett
Copy link
Collaborator

Thanks for continuing to do this work, it's something we've wanted for a long time now!

@lateautumn233
Copy link

llvm-tblgen: Unknown command line argument '-gen-arm-target-def'.  Try: '/home/quqiu/dev/tc-build/build/llvm/bootstrap/bin/llvm-tblgen --help'                                                          llvm-tblgen: Did you mean '--gen-riscv-target-def'?

It should also be added for llvm-tblgen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants