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

Introduce a mechanism to share data between the ARM and AArch64 backends and
TargetParser, to reduce duplication of code. This is similar to 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.
This commit is contained in:
Tomas Matheson 2024-04-24 09:18:36 +01:00 committed by GitHub
parent 662ef86042
commit 71c5964f5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 84 additions and 136 deletions

View File

@ -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)

View File

@ -144,7 +144,6 @@ void AArch64Subtarget::initializeProperties(bool HasMinSize) {
case CortexA78C:
case CortexR82:
case CortexX1:
case CortexX1C:
PrefFunctionAlignment = Align(16);
PrefLoopAlignment = Align(32);
MaxBytesForLoopAlignment = 16;

View File

@ -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:

View File

@ -293,13 +293,11 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
case CortexA78C:
case CortexA710:
case CortexR4:
case CortexR4F:
case CortexR5:
case CortexR7:
case CortexM3:
case CortexM7:
case CortexR52:
case CortexM52:
case CortexX1:
case CortexX1C:
break;
@ -314,8 +312,6 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
case Krait:
PreISelOperandLatencyAdjustment = 1;
break;
case NeoverseN1:
case NeoverseN2:
case NeoverseV1:
break;
case Swift:

View File

@ -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 @@ protected:
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:

View File

@ -38,5 +38,7 @@ add_llvm_component_library(LLVMTargetParser
Support
DEPENDS
ARMTargetParserTableGen
AArch64TargetParserTableGen
RISCVTargetParserTableGen
)

View File

@ -0,0 +1,63 @@
//===- 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 and AArch64 backends.
//
//===----------------------------------------------------------------------===//
#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\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\n";
}
static TableGen::Emitter::Opt
X("gen-arm-target-def", EmitARMTargetDef,
"Generate the ARM or AArch64 Architecture information header.");

View File

@ -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