Skip to content

Commit f3efbce

Browse files
rnkarsenms-barannikov
authored
[llvm] Move data layout string computation to TargetParser (#157612)
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. --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com> Co-authored-by: Sergei Barannikov <barannikov88@gmail.com>
1 parent b812e3d commit f3efbce

38 files changed

+712
-613
lines changed

llvm/benchmarks/RuntimeLibcalls.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ static std::vector<std::string> readSymbolsFromFile(StringRef InputFile) {
5454
// Hackily figure out if there's a prefix on the symbol names - llvm-nm
5555
// appears to not have a flag to skip this.
5656
llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
57-
std::string DummyDatalayout = "e";
58-
DummyDatalayout += DataLayout::getManglingComponent(HostTriple);
59-
60-
DataLayout DL(DummyDatalayout);
57+
DataLayout DL(HostTriple.computeDataLayout());
6158
char GlobalPrefix = DL.getGlobalPrefix();
6259

6360
std::vector<std::string> Lines;

llvm/include/llvm/IR/DataLayout.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,6 @@ class DataLayout {
303303
llvm_unreachable("invalid mangling mode");
304304
}
305305

306-
LLVM_ABI static const char *getManglingComponent(const Triple &T);
307-
308306
/// Returns true if the specified type fits in a native integer type
309307
/// supported by the CPU.
310308
///

llvm/include/llvm/TargetParser/Triple.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,10 @@ class Triple {
13281328
const VersionTuple &Version);
13291329

13301330
LLVM_ABI ExceptionHandling getDefaultExceptionHandling() const;
1331+
1332+
/// Compute the LLVM IR data layout string based on the triple. Some targets
1333+
/// customize the layout based on the ABIName string.
1334+
LLVM_ABI std::string computeDataLayout(StringRef ABIName = "") const;
13311335
};
13321336

13331337
} // End llvm namespace

llvm/lib/IR/DataLayout.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,6 @@ struct LessPointerAddrSpace {
172172
};
173173
} // namespace
174174

175-
const char *DataLayout::getManglingComponent(const Triple &T) {
176-
if (T.isOSBinFormatGOFF())
177-
return "-m:l";
178-
if (T.isOSBinFormatMachO())
179-
return "-m:o";
180-
if ((T.isOSWindows() || T.isUEFI()) && T.isOSBinFormatCOFF())
181-
return T.getArch() == Triple::x86 ? "-m:x" : "-m:w";
182-
if (T.isOSBinFormatXCOFF())
183-
return "-m:a";
184-
return "-m:e";
185-
}
186-
187175
// Default primitive type specifications.
188176
// NOTE: These arrays must be sorted by type bit width.
189177
constexpr DataLayout::PrimitiveSpec DefaultIntSpecs[] = {

llvm/lib/Target/AArch64/AArch64TargetMachine.cpp

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -295,27 +295,6 @@ static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
295295
return std::make_unique<AArch64_ELFTargetObjectFile>();
296296
}
297297

298-
// Helper function to build a DataLayout string
299-
static std::string computeDataLayout(const Triple &TT,
300-
const MCTargetOptions &Options,
301-
bool LittleEndian) {
302-
if (TT.isOSBinFormatMachO()) {
303-
if (TT.getArch() == Triple::aarch64_32)
304-
return "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
305-
"n32:64-S128-Fn32";
306-
return "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-"
307-
"Fn32";
308-
}
309-
if (TT.isOSBinFormatCOFF())
310-
return "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:"
311-
"128-n32:64-S128-Fn32";
312-
std::string Endian = LittleEndian ? "e" : "E";
313-
std::string Ptr32 = TT.getEnvironment() == Triple::GNUILP32 ? "-p:32:32" : "";
314-
return Endian + "-m:e" + Ptr32 +
315-
"-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-"
316-
"n32:64-S128-Fn32";
317-
}
318-
319298
static StringRef computeDefaultCPU(const Triple &TT, StringRef CPU) {
320299
if (CPU.empty() && TT.isArm64e())
321300
return "apple-a12";
@@ -368,11 +347,10 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
368347
std::optional<CodeModel::Model> CM,
369348
CodeGenOptLevel OL, bool JIT,
370349
bool LittleEndian)
371-
: CodeGenTargetMachineImpl(
372-
T, computeDataLayout(TT, Options.MCOptions, LittleEndian), TT,
373-
computeDefaultCPU(TT, CPU), FS, Options,
374-
getEffectiveRelocModel(TT, RM),
375-
getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
350+
: CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT,
351+
computeDefaultCPU(TT, CPU), FS, Options,
352+
getEffectiveRelocModel(TT, RM),
353+
getEffectiveAArch64CodeModel(TT, CM, JIT), OL),
376354
TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian),
377355
UseNewSMEABILowering(EnableNewSMEABILowering) {
378356
initAsmInfo();

llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -720,25 +720,6 @@ static MachineSchedRegistry GCNILPSchedRegistry(
720720
"Run GCN iterative scheduler for ILP scheduling (experimental)",
721721
createIterativeILPMachineScheduler);
722722

723-
static StringRef computeDataLayout(const Triple &TT) {
724-
if (TT.getArch() == Triple::r600) {
725-
// 32-bit pointers.
726-
return "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
727-
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1";
728-
}
729-
730-
// 32-bit private, local, and region pointers. 64-bit global, constant and
731-
// flat. 160-bit non-integral fat buffer pointers that include a 128-bit
732-
// buffer descriptor and a 32-bit offset, which are indexed by 32-bit values
733-
// (address space 7), and 128-bit non-integral buffer resourcees (address
734-
// space 8) which cannot be non-trivilally accessed by LLVM memory operations
735-
// like getelementptr.
736-
return "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
737-
"-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-"
738-
"v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-"
739-
"v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9";
740-
}
741-
742723
LLVM_READNONE
743724
static StringRef getGPUOrDefault(const Triple &TT, StringRef GPU) {
744725
if (!GPU.empty())
@@ -764,7 +745,7 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, const Triple &TT,
764745
std::optional<CodeModel::Model> CM,
765746
CodeGenOptLevel OptLevel)
766747
: CodeGenTargetMachineImpl(
767-
T, computeDataLayout(TT), TT, getGPUOrDefault(TT, CPU), FS, Options,
748+
T, TT.computeDataLayout(), TT, getGPUOrDefault(TT, CPU), FS, Options,
768749
getEffectiveRelocModel(RM),
769750
getEffectiveCodeModel(CM, CodeModel::Small), OptLevel),
770751
TLOF(createTLOF(getTargetTriple())) {

llvm/lib/Target/ARC/ARCTargetMachine.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,9 @@ ARCTargetMachine::ARCTargetMachine(const Target &T, const Triple &TT,
3333
std::optional<Reloc::Model> RM,
3434
std::optional<CodeModel::Model> CM,
3535
CodeGenOptLevel OL, bool JIT)
36-
: CodeGenTargetMachineImpl(
37-
T,
38-
"e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
39-
"f32:32:32-i64:32-f64:32-a:0:32-n32",
40-
TT, CPU, FS, Options, getRelocModel(RM),
41-
getEffectiveCodeModel(CM, CodeModel::Small), OL),
36+
: CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
37+
getRelocModel(RM),
38+
getEffectiveCodeModel(CM, CodeModel::Small), OL),
4239
TLOF(std::make_unique<TargetLoweringObjectFileELF>()),
4340
Subtarget(TT, std::string(CPU), std::string(FS), *this) {
4441
initAsmInfo();

llvm/lib/Target/ARM/ARMTargetMachine.cpp

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -121,62 +121,6 @@ static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
121121
return std::make_unique<ARMElfTargetObjectFile>();
122122
}
123123

124-
static std::string computeDataLayout(const Triple &TT,
125-
const TargetOptions &Options,
126-
bool isLittle) {
127-
auto ABI = ARM::computeTargetABI(TT, Options.MCOptions.ABIName);
128-
std::string Ret;
129-
130-
if (isLittle)
131-
// Little endian.
132-
Ret += "e";
133-
else
134-
// Big endian.
135-
Ret += "E";
136-
137-
Ret += DataLayout::getManglingComponent(TT);
138-
139-
// Pointers are 32 bits and aligned to 32 bits.
140-
Ret += "-p:32:32";
141-
142-
// Function pointers are aligned to 8 bits (because the LSB stores the
143-
// ARM/Thumb state).
144-
Ret += "-Fi8";
145-
146-
// ABIs other than APCS have 64 bit integers with natural alignment.
147-
if (ABI != ARM::ARM_ABI_APCS)
148-
Ret += "-i64:64";
149-
150-
// We have 64 bits floats. The APCS ABI requires them to be aligned to 32
151-
// bits, others to 64 bits. We always try to align to 64 bits.
152-
if (ABI == ARM::ARM_ABI_APCS)
153-
Ret += "-f64:32:64";
154-
155-
// We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others
156-
// to 64. We always ty to give them natural alignment.
157-
if (ABI == ARM::ARM_ABI_APCS)
158-
Ret += "-v64:32:64-v128:32:128";
159-
else if (ABI != ARM::ARM_ABI_AAPCS16)
160-
Ret += "-v128:64:128";
161-
162-
// Try to align aggregates to 32 bits (the default is 64 bits, which has no
163-
// particular hardware support on 32-bit ARM).
164-
Ret += "-a:0:32";
165-
166-
// Integer registers are 32 bits.
167-
Ret += "-n32";
168-
169-
// The stack is 64 bit aligned on AAPCS and 32 bit aligned everywhere else.
170-
if (ABI == ARM::ARM_ABI_AAPCS16)
171-
Ret += "-S128";
172-
else if (ABI == ARM::ARM_ABI_AAPCS)
173-
Ret += "-S64";
174-
else
175-
Ret += "-S32";
176-
177-
return Ret;
178-
}
179-
180124
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
181125
std::optional<Reloc::Model> RM) {
182126
if (!RM)
@@ -201,12 +145,13 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
201145
const TargetOptions &Options,
202146
std::optional<Reloc::Model> RM,
203147
std::optional<CodeModel::Model> CM,
204-
CodeGenOptLevel OL, bool isLittle)
205-
: CodeGenTargetMachineImpl(T, computeDataLayout(TT, Options, isLittle), TT,
206-
CPU, FS, Options, getEffectiveRelocModel(TT, RM),
207-
getEffectiveCodeModel(CM, CodeModel::Small), OL),
148+
CodeGenOptLevel OL)
149+
: CodeGenTargetMachineImpl(
150+
T, TT.computeDataLayout(Options.MCOptions.ABIName), TT, CPU, FS,
151+
Options, getEffectiveRelocModel(TT, RM),
152+
getEffectiveCodeModel(CM, CodeModel::Small), OL),
208153
TargetABI(ARM::computeTargetABI(TT, Options.MCOptions.ABIName)),
209-
TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {
154+
TLOF(createTLOF(getTargetTriple())), isLittle(TT.isLittleEndian()) {
210155

211156
// Default to triple-appropriate float ABI
212157
if (Options.FloatABIType == FloatABI::Default) {
@@ -334,15 +279,15 @@ ARMLETargetMachine::ARMLETargetMachine(const Target &T, const Triple &TT,
334279
std::optional<Reloc::Model> RM,
335280
std::optional<CodeModel::Model> CM,
336281
CodeGenOptLevel OL, bool JIT)
337-
: ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
282+
: ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
338283

339284
ARMBETargetMachine::ARMBETargetMachine(const Target &T, const Triple &TT,
340285
StringRef CPU, StringRef FS,
341286
const TargetOptions &Options,
342287
std::optional<Reloc::Model> RM,
343288
std::optional<CodeModel::Model> CM,
344289
CodeGenOptLevel OL, bool JIT)
345-
: ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
290+
: ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {}
346291

347292
namespace {
348293

llvm/lib/Target/ARM/ARMTargetMachine.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ class ARMBaseTargetMachine : public CodeGenTargetMachineImpl {
4242
ARMBaseTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
4343
StringRef FS, const TargetOptions &Options,
4444
std::optional<Reloc::Model> RM,
45-
std::optional<CodeModel::Model> CM, CodeGenOptLevel OL,
46-
bool isLittle);
45+
std::optional<CodeModel::Model> CM, CodeGenOptLevel OL);
4746
~ARMBaseTargetMachine() override;
4847

4948
const ARMSubtarget *getSubtargetImpl(const Function &F) const override;

llvm/lib/Target/AVR/AVRTargetMachine.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828

2929
namespace llvm {
3030

31-
static const char *AVRDataLayout =
32-
"e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8";
33-
3431
/// Processes a CPU name.
3532
static StringRef getCPU(StringRef CPU) {
3633
if (CPU.empty() || CPU == "generic") {
@@ -50,8 +47,8 @@ AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT,
5047
std::optional<Reloc::Model> RM,
5148
std::optional<CodeModel::Model> CM,
5249
CodeGenOptLevel OL, bool JIT)
53-
: CodeGenTargetMachineImpl(T, AVRDataLayout, TT, getCPU(CPU), FS, Options,
54-
getEffectiveRelocModel(RM),
50+
: CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, getCPU(CPU), FS,
51+
Options, getEffectiveRelocModel(RM),
5552
getEffectiveCodeModel(CM, CodeModel::Small), OL),
5653
SubTarget(TT, std::string(getCPU(CPU)), std::string(FS), *this) {
5754
this->TLOF = std::make_unique<AVRTargetObjectFile>();

0 commit comments

Comments
 (0)