-
Notifications
You must be signed in to change notification settings - Fork 15k
[llvm] Move data layout string computation to TargetParser #157612
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
Conversation
Clang and other frontends generally need the LLVM data layout string in order to generate LLVM IR modules for LLVM. MLIR clients often need it as well, since MLIR users often lower to LLVM IR. Before this change, the LLVM datalayout string was computed in the LLVM${TGT}CodeGen library in the relevant TargetMachine subclass. However, none of the logic for computing the data layout string requires any details of code generation. Clients who want to avoid duplicating this information were forced to link in LLVMCodeGen and all registered targets, leading to bloated binaries. By moving this information to the DataLayout class in the IR file, we can delete the duplicate datalayout strings in Clang, and retain the ability to generate IR for unregistered targets.
@llvm/pr-subscribers-backend-systemz @llvm/pr-subscribers-backend-arm Author: Reid Kleckner (rnk) ChangesClang and other frontends generally need the LLVM data layout string in Before this change, the LLVM datalayout string was computed in the By moving this information to the DataLayout class in the IR file, we This is intended to be a very mechanical LLVM-only change, but there is an immediately obvious follow-up to clang, which will be prepared separately. The vast majority of data layouts are computable with two inputs: the triple and the "ABI name". There is only one exception, NVPTX, which has a cl::opt to enable short device pointers. I invented a "shortptr" ABI name to pass this option through the target independent interface. Everything else fits. Mips is a bit awkward because it uses a special MipsABIInfo abstraction, which includes members with codegen-like concepts like ABI physical registers that can't live in TargetParser. I think the string logic of looking for "n32" "n64" etc is reasonable to duplicate. We have plenty of other minor duplication to preserve layering. Patch is 77.42 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/157612.diff 38 Files Affected:
diff --git a/llvm/benchmarks/RuntimeLibcalls.cpp b/llvm/benchmarks/RuntimeLibcalls.cpp
index 9ac77bb74a3df..707bdca7ceab7 100644
--- a/llvm/benchmarks/RuntimeLibcalls.cpp
+++ b/llvm/benchmarks/RuntimeLibcalls.cpp
@@ -54,10 +54,7 @@ static std::vector<std::string> readSymbolsFromFile(StringRef InputFile) {
// Hackily figure out if there's a prefix on the symbol names - llvm-nm
// appears to not have a flag to skip this.
llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
- std::string DummyDatalayout = "e";
- DummyDatalayout += DataLayout::getManglingComponent(HostTriple);
-
- DataLayout DL(DummyDatalayout);
+ DataLayout DL(HostTriple.computeDataLayout());
char GlobalPrefix = DL.getGlobalPrefix();
std::vector<std::string> Lines;
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 2acae246c0b1e..5653ee7b6837d 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -303,8 +303,6 @@ class DataLayout {
llvm_unreachable("invalid mangling mode");
}
- LLVM_ABI static const char *getManglingComponent(const Triple &T);
-
/// Returns true if the specified type fits in a native integer type
/// supported by the CPU.
///
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 8e12c6852075d..5a462ceafb639 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -1327,6 +1327,10 @@ class Triple {
const VersionTuple &Version);
LLVM_ABI ExceptionHandling getDefaultExceptionHandling() const;
+
+ /// Compute the LLVM IR data layout string based on the triple. Some targets
+ /// customize the layout based on the ABIName string.
+ LLVM_ABI std::string computeDataLayout(StringRef ABIName = "") const;
};
} // End llvm namespace
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index ed629d4e5ea22..77f9b997a2ebf 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -172,18 +172,6 @@ struct LessPointerAddrSpace {
};
} // namespace
-const char *DataLayout::getManglingComponent(const Triple &T) {
- if (T.isOSBinFormatGOFF())
- return "-m:l";
- if (T.isOSBinFormatMachO())
- return "-m:o";
- if ((T.isOSWindows() || T.isUEFI()) && T.isOSBinFormatCOFF())
- return T.getArch() == Triple::x86 ? "-m:x" : "-m:w";
- if (T.isOSBinFormatXCOFF())
- return "-m:a";
- return "-m:e";
-}
-
// Default primitive type specifications.
// NOTE: These arrays must be sorted by type bit width.
constexpr DataLayout::PrimitiveSpec DefaultIntSpecs[] = {
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index 4650b2d0c8151..dde1d88403bfe 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -295,27 +295,6 @@ static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
return std::make_unique<AArch64_ELFTargetObjectFile>();
}
-// Helper function to build a DataLayout string
-static std::string computeDataLayout(const Triple &TT,
- const MCTargetOptions &Options,
- bool LittleEndian) {
- if (TT.isOSBinFormatMachO()) {
- if (TT.getArch() == Triple::aarch64_32)
- return "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
- "n32:64-S128-Fn32";
- return "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-"
- "Fn32";
- }
- if (TT.isOSBinFormatCOFF())
- return "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:"
- "128-n32:64-S128-Fn32";
- std::string Endian = LittleEndian ? "e" : "E";
- std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
- return Endian + "-m:e" + Ptr32 +
- "-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-"
- "n32:64-S128-Fn32";
-}
-
static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU) {
if (CPU.empty() && TT.isArm64e())
return "apple-a12";
@@ -368,11 +347,10 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT,
bool LittleEndian)
- : CodeGenTargetMachineImpl(
- T, computeDataLayout(TT, Options.MCOptions, LittleEndian), TT,
- computeDefaultCPU(TT, CPU), FS, Options,
- getEffectiveRelocModel(TT, RM),
- getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
+ : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT,
+ computeDefaultCPU(TT, CPU), FS, Options,
+ getEffectiveRelocModel(TT, RM),
+ getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian),
UseNewSMEABILowering(EnableNewSMEABILowering) {
initAsmInfo();
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 9afe7590fe4ef..92a587b5771b6 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -720,25 +720,6 @@ static MachineSchedRegistry GCNILPSchedRegistry(
"Run GCN iterative scheduler for ILP scheduling (experimental)",
createIterativeILPMachineScheduler);
-static StringRef computeDataLayout(const Triple &TT) {
- if (TT.getArch() == Triple::r600) {
- // 32-bit pointers.
- return "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
- "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1";
- }
-
- // 32-bit private, local, and region pointers. 64-bit global, constant and
- // flat. 160-bit non-integral fat buffer pointers that include a 128-bit
- // buffer descriptor and a 32-bit offset, which are indexed by 32-bit values
- // (address space 7), and 128-bit non-integral buffer resourcees (address
- // space 8) which cannot be non-trivilally accessed by LLVM memory operations
- // like getelementptr.
- return "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
- "-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-"
- "v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-"
- "v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9";
-}
-
LLVM_READNONE
static StringRef getGPUOrDefault(const Triple &TT, StringRef GPU) {
if (!GPU.empty())
@@ -764,7 +745,7 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, const Triple &TT,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OptLevel)
: CodeGenTargetMachineImpl(
- T, computeDataLayout(TT), TT, getGPUOrDefault(TT, CPU), FS, Options,
+ T, TT.computeDataLayout(), TT, getGPUOrDefault(TT, CPU), FS, Options,
getEffectiveRelocModel(RM),
getEffectiveCodeModel(CM, CodeModel::Small), OptLevel),
TLOF(createTLOF(getTargetTriple())) {
diff --git a/llvm/lib/Target/ARC/ARCTargetMachine.cpp b/llvm/lib/Target/ARC/ARCTargetMachine.cpp
index 370336394ba7f..8e1944062a2c3 100644
--- a/llvm/lib/Target/ARC/ARCTargetMachine.cpp
+++ b/llvm/lib/Target/ARC/ARCTargetMachine.cpp
@@ -33,12 +33,9 @@ ARCTargetMachine::ARCTargetMachine(const Target &T, const Triple &TT,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
- : CodeGenTargetMachineImpl(
- T,
- "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
- "f32:32:32-i64:32-f64:32-a:0:32-n32",
- TT, CPU, FS, Options, getRelocModel(RM),
- getEffectiveCodeModel(CM, CodeModel::Small), OL),
+ : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
+ getRelocModel(RM),
+ getEffectiveCodeModel(CM, CodeModel::Small), OL),
TLOF(std::make_unique<TargetLoweringObjectFileELF>()),
Subtarget(TT, std::string(CPU), std::string(FS), *this) {
initAsmInfo();
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index fedf9e2cf34b1..346776e0c4b25 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -121,62 +121,6 @@ static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
return std::make_unique<ARMElfTargetObjectFile>();
}
-static std::string computeDataLayout(const Triple &TT,
- const TargetOptions &Options,
- bool isLittle) {
- auto ABI = ARM::computeTargetABI(TT, Options.MCOptions.ABIName);
- std::string Ret;
-
- if (isLittle)
- // Little endian.
- Ret += "e";
- else
- // Big endian.
- Ret += "E";
-
- Ret += DataLayout::getManglingComponent(TT);
-
- // Pointers are 32 bits and aligned to 32 bits.
- Ret += "-p:32:32";
-
- // Function pointers are aligned to 8 bits (because the LSB stores the
- // ARM/Thumb state).
- Ret += "-Fi8";
-
- // ABIs other than APCS have 64 bit integers with natural alignment.
- if (ABI != ARM::ARM_ABI_APCS)
- Ret += "-i64:64";
-
- // We have 64 bits floats. The APCS ABI requires them to be aligned to 32
- // bits, others to 64 bits. We always try to align to 64 bits.
- if (ABI == ARM::ARM_ABI_APCS)
- Ret += "-f64:32:64";
-
- // We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others
- // to 64. We always ty to give them natural alignment.
- if (ABI == ARM::ARM_ABI_APCS)
- Ret += "-v64:32:64-v128:32:128";
- else if (ABI != ARM::ARM_ABI_AAPCS16)
- Ret += "-v128:64:128";
-
- // Try to align aggregates to 32 bits (the default is 64 bits, which has no
- // particular hardware support on 32-bit ARM).
- Ret += "-a:0:32";
-
- // Integer registers are 32 bits.
- Ret += "-n32";
-
- // The stack is 64 bit aligned on AAPCS and 32 bit aligned everywhere else.
- if (ABI == ARM::ARM_ABI_AAPCS16)
- Ret += "-S128";
- else if (ABI == ARM::ARM_ABI_AAPCS)
- Ret += "-S64";
- else
- Ret += "-S32";
-
- return Ret;
-}
-
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
std::optional<Reloc::Model> RM) {
if (!RM)
@@ -201,12 +145,13 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
const TargetOptions &Options,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
- CodeGenOptLevel OL, bool isLittle)
- : CodeGenTargetMachineImpl(T, computeDataLayout(TT, Options, isLittle), TT,
- CPU, FS, Options, getEffectiveRelocModel(TT, RM),
- getEffectiveCodeModel(CM, CodeModel::Small), OL),
+ CodeGenOptLevel OL)
+ : CodeGenTargetMachineImpl(
+ T, TT.computeDataLayout(Options.MCOptions.ABIName), TT, CPU, FS,
+ Options, getEffectiveRelocModel(TT, RM),
+ getEffectiveCodeModel(CM, CodeModel::Small), OL),
TargetABI(ARM::computeTargetABI(TT, Options.MCOptions.ABIName)),
- TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {
+ TLOF(createTLOF(getTargetTriple())), isLittle(TT.isLittleEndian()) {
// Default to triple-appropriate float ABI
if (Options.FloatABIType == FloatABI::Default) {
@@ -334,7 +279,7 @@ ARMLETargetMachine::ARMLETargetMachine(const Target &T, const Triple &TT,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
- : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
+ : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
@@ -342,7 +287,7 @@ ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
- : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
+ : ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
namespace {
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.h b/llvm/lib/Target/ARM/ARMTargetMachine.h
index 1d73af1da6d02..c417c4c8bae65 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.h
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.h
@@ -42,8 +42,7 @@ class ARMBaseTargetMachine : public CodeGenTargetMachineImpl {
ARMBaseTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
std::optional<Reloc::Model> RM,
- std::optional<CodeModel::Model> CM, CodeGenOptLevel OL,
- bool isLittle);
+ std::optional<CodeModel::Model> CM, CodeGenOptLevel OL);
~ARMBaseTargetMachine() override;
const ARMSubtarget *getSubtargetImpl(const Function &F) const override;
diff --git a/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
index fbd148478c894..f001d7974669a 100644
--- a/llvm/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/llvm/lib/Target/AVR/AVRTargetMachine.cpp
@@ -28,9 +28,6 @@
namespace llvm {
-static const char *AVRDataLayout =
- "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8";
-
/// Processes a CPU name.
static StringRef getCPU(StringRef CPU) {
if (CPU.empty() || CPU == "generic") {
@@ -50,8 +47,8 @@ AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
- : CodeGenTargetMachineImpl(T, AVRDataLayout, TT, getCPU(CPU), FS, Options,
- getEffectiveRelocModel(RM),
+ : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, getCPU(CPU), FS,
+ Options, getEffectiveRelocModel(RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
SubTarget(TT, std::string(getCPU(CPU)), std::string(FS), *this) {
this->TLOF = std::make_unique<AVRTargetObjectFile>();
diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
index 527a480354571..10b758647c735 100644
--- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp
+++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
@@ -59,14 +59,6 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFTarget() {
initializeBPFMIPreEmitCheckingPass(PR);
}
-// DataLayout: little or big endian
-static std::string computeDataLayout(const Triple &TT) {
- if (TT.getArch() == Triple::bpfeb)
- return "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
- else
- return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
-}
-
static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
return RM.value_or(Reloc::PIC_);
}
@@ -77,7 +69,7 @@ BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
- : CodeGenTargetMachineImpl(T, computeDataLayout(TT), TT, CPU, FS, Options,
+ : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
getEffectiveRelocModel(RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
TLOF(std::make_unique<TargetLoweringObjectFileELF>()),
diff --git a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp
index ae6ef89fdcd07..d0058b9af14be 100644
--- a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp
+++ b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp
@@ -33,28 +33,13 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTarget() {
initializeCSKYDAGToDAGISelLegacyPass(*Registry);
}
-static std::string computeDataLayout(const Triple &TT) {
- std::string Ret;
-
- // Only support little endian for now.
- // TODO: Add support for big endian.
- Ret += "e";
-
- // CSKY is always 32-bit target with the CSKYv2 ABI as prefer now.
- // It's a 4-byte aligned stack with ELF mangling only.
- Ret += "-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32"
- "-v128:32:32-a:0:32-Fi32-n32";
-
- return Ret;
-}
-
CSKYTargetMachine::CSKYTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
- : CodeGenTargetMachineImpl(T, computeDataLayout(TT), TT, CPU, FS, Options,
+ : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
RM.value_or(Reloc::Static),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
TLOF(std::make_unique<CSKYELFTargetObjectFile>()) {
diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index f5d5a73c926e9..bcf84403b2c0d 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -134,11 +134,8 @@ DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
std::optional<Reloc::Model> RM,
std::optional<CodeModel::Model> CM,
CodeGenOptLevel OL, bool JIT)
- : CodeGenTargetMachineImpl(
- T,
- "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
- "f32:32-f64:64-n8:16:32:64",
- TT, CPU, FS, Options, Reloc::Static, CodeModel::Small, OL),
+ : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
+ Reloc::Static, CodeModel::Small, OL),
TLOF(std::make_unique<DXILTargetObjectFile>()),
Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
initAsmInfo();
diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
index 66508fd767793..0afa04ab57e81 100644
--- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -231,14 +231,10 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT,
// Specify the vector alignment explicitly. For v512x1, the calculated
// alignment would be 512*alignment(i1), which is 512 bytes, instead of
// the required minimum of 64 bytes.
- : CodeGenTargetMachineImpl(
- T,
- "e-m:e-p:32:32:32-a:0-n16:32-"
- "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-"
- "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048",
- TT, CPU, FS, Options, getEffectiveRelocModel(RM),
- getEffectiveCodeModel(CM, CodeModel::Small),
- (HexagonNoOpt ? CodeGenOptLevel::None : OL)),
+ : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
+ getEffectiveRelocModel(RM),
+ getEffectiveCodeModel(CM, CodeModel::Small),
+ ...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
@@ -59,6 +59,12 @@ static cl::opt<bool> DisableRequireStructuredCFG( | |||
"unexpected regressions happen."), | |||
cl::init(false), cl::Hidden); | |||
|
|||
static cl::opt<bool> UseShortPointersOpt( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This definitely should not be configurable by cl::opt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but is that a blocking concern? I assume this is load bearing. It has tons of tests. As covered in the commit message, I modeled this as an ABI name string (which wasn't used for anything before) and moved on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this an ABI name string now, it should be passed via the dedicated --target-abi option. Not a blocker to me (not saying for @arsenm), but a FIXME would be nice.
// Only support little endian for now. | ||
// TODO: Add support for big endian. | ||
Ret += "e"; | ||
|
||
// CSKY is always 32-bit target with the CSKYv2 ABI as prefer now. | ||
// It's a 4-byte aligned stack with ELF mangling only. | ||
Ret += "-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32" | ||
"-v128:32:32-a:0:32-Fi32-n32"; | ||
|
||
return Ret; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directly return the full string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, done.
enum class MipsABI { Unknown, O32, N32, N64 }; | ||
} | ||
|
||
// FIXME: This duplicates MipsABIInfo::computeTargetABI, but duplicating this is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just ran into issues from this. MipsABIInfo is irredeemably broken. You should not be able to change the pointer size with a side flag. It should not be possible for Triple's getArchPointerBitWidth to be wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not be possible for Triple's getArchPointerBitWidth to be wrong
Or we should delete this method. Pointers in different address spaces can have different sizes, and should be queried via DataLayout. There are only two uses of this method in the codebase (not counting transitive uses and uses in tests). One in Flang/tools/TargetSetup.h, the other in JITLink.h.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's transitively used in a lot more places. The platform pointer size is still a relevant property disconnected from any type. i.e., checking a type sized pointer is not always an option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe those can be replaced with Triple.isArch64Bit() etc (I managed to do this locally).
Speaking of JITLink, it should really use the "pointer" size from parsed DWARF CIE in most places.
In any case, this is not related to this PR, but is an idea for a future change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without looking at the specifics of these use cases, this would risk being incompatible with architectures that use more interesting pointer encodings than "machine word", such as CHERI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this Mips N32/N64 stuff is just old. If someone was adding this today, we'd model these things as "environments" in the triple, but at the time, it was inflexible and less extensible. The whole "triple" (how many components does it have now?) concept is not very principled.
To me, this is a lesser design flaw than --nvptx-use-short-ptrs
, that's pretty crazy.
Co-authored-by: Matt Arsenault <[email protected]> Co-authored-by: Sergei Barannikov <[email protected]>
return Ret; | ||
} | ||
|
||
// Helper function to build a DataLayout string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Helper function to build a DataLayout string |
std::string Triple::computeDataLayout(StringRef ABIName) const { | ||
switch (getArch()) { | ||
case Triple::arm: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may create extra friction for downstream custom backends, which now have another file to patch (to add their triple here). It's probably fine -- the patch would be tiny, and this would be worth the benefit it brings -- but I feel like it's still worth calling out. Is there any way to decouple it?
This is already the status quo (e.g. Triple.cpp has several cases like this), so it's not anything that needs to be solved in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does, it makes that use case slightly worse. I think @jyknight advocated for us leaning into target registration, and having a lighter weight ${TGT}TargetInfo library with these details. That would make things more pluggable. I'm compromising that goal for now to recover some short term MLIR client binary size savings and eliminate duplication with Clang.
It occurs to me that any downstream target will today need a clang local patch to add their data layout there, so this is net-zero for local modifications, even if it creates friction now.
Adding @rolfmorel as this may change our usage for the data layout construction in MLIR from target machine. |
Ret += getManglingComponent(TT); | ||
|
||
// Special features for z/OS. | ||
if (TT.isOSzOS()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to remove the isArch64Bit
check? It's currently always true, but I guess this was added as preparation for when we may add support for 32-bit z/OS in the future ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arsenm asked me to remove all uses of isArch64Bit
and replace them with direct architecture checks. I've done the same thing in all other functions (see the x86 one), but there was no analogue for systemz, since we don't have 32-bit z/OS support. I think we can remove this dead code for now. This will be the first and most obvious thing that needs to be addressed in any future 32-bit z/OS port. Also, this talk about 32-bit Linux support (yes, a different OS) comes to mind:
https://www.webpronews.com/linux-kernel-eyes-phasing-out-32-bit-support-for-security-gains/
Are folks really planning to add 32-bit z/OS support in the near future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in the near future, but potentially at some point. (As opposed to Linux, 32-bit z/OS is unlikely to go away any time soon.) I guess it's OK to remove this for now then. @redstar FYI ...
Great! Though to check: this enables us to obtain the right data layout string (and in turn the DataLayout struct) from a triple. So w.r.t. #145899, this means that on the MLIR side we do not have to go through TargetMachine. It doesn't help with regard to the triples needing to be registered by the backends, right? If so, on the MLIR side, I don't think this enables us to get rid of all the llvm-project/mlir/lib/Target/LLVMIR/Transforms/CMakeLists.txt Lines 13 to 16 in 9334ef9
and the request for backends to register their triples: llvm-project/mlir/lib/Target/LLVMIR/Transforms/TargetUtils.cpp Lines 25 to 34 in 94d5c54
Also on the MLIR side, we now have https://github.com/llvm/llvm-project/pull/154938/files#diff-14efa88fcf2e1013f43154bb29e5f9e75d1b0e544ecebadaf2806a04729ec23aR47-R64, i.e. obtaining the right / default feature flags from a target triple & CPU string. It seems unavoidable that this goes through TargetMachine. Though here too, this information can/should be independent of codegen. It is probably harder to break this information out of the backends. Does anybody have any suggestions for minimizing the dependencies for
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I think that moving DataLayout computation to TargetParser is a big improvement, and am willing to take it even with some rough edges.
@rolfmorel The information about cpus and target features for a triple is also part of TargetParser -- but the interface to access that information is pretty terrible right now (basically each target has its own bespoke APIs, there is no common way to query this across targets). |
I suppose I have to take the point that this isn't going to serve MLIR's needs entirely. In order to that, I think we need to move the information MLIR needs from My change is actually not really a step in that direction. The main benefit of having the data layout always available in TargetParser for all known LLVM targets is that it reduces code duplication with frontends like clang (I can't remember if Rust also duplicates the data layouts) without complicating their test suites by requiring target registration. It's hard for me to say how much of the information that MLIR needs should be hidden behind target registration or simply always available. There's a tradeoff between simplicity, abstraction, and extensibility to make on that question. |
SPIRV tests appear to be broken at head based on my local testing results, so I will push through the failed github checks. |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/76/builds/12834 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/15937 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/145/builds/9706 Here is the relevant piece of the build log for the reference
|
This is probably caused by the fact that |
Yep, that should be fixed by 4ae520b |
Clang and other frontends generally need the LLVM data layout string in
order to generate LLVM IR modules for LLVM. MLIR clients often need it
as well, since MLIR users often lower to LLVM IR.
Before this change, the LLVM datalayout string was computed in the
LLVM${TGT}CodeGen library in the relevant TargetMachine subclass.
However, none of the logic for computing the data layout string requires
any details of code generation. Clients who want to avoid duplicating
this information were forced to link in LLVMCodeGen and all registered
targets, leading to bloated binaries. This happened in PR #145899,
which measurably increased binary size for some of our users.
By moving this information to the TargetParser library, we
can delete the duplicate datalayout strings in Clang, and retain the
ability to generate IR for unregistered targets.
This is intended to be a very mechanical LLVM-only change, but there is an immediately obvious follow-up to clang, which will be prepared separately.
The vast majority of data layouts are computable with two inputs: the triple and the "ABI name". There is only one exception, NVPTX, which has a cl::opt to enable short device pointers. I invented a "shortptr" ABI name to pass this option through the target independent interface. Everything else fits. Mips is a bit awkward because it uses a special MipsABIInfo abstraction, which includes members with codegen-like concepts like ABI physical registers that can't live in TargetParser. I think the string logic of looking for "n32" "n64" etc is reasonable to duplicate. We have plenty of other minor duplication to preserve layering.