Skip to content

Commit f58aa07

Browse files
authored
Merge pull request #68536 from Azoy/maxAtomicInlineWidth
[AST] Add #if _atomicBitWidth as a valid compilation conditional
2 parents 581b9d8 + a3f4361 commit f58aa07

26 files changed

+152
-29
lines changed

include/swift/AST/PlatformConditionKinds.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,8 @@ PLATFORM_CONDITION(TargetEnvironment, "targetEnvironment")
4646
/// Pointer authentication enabled
4747
PLATFORM_CONDITION_(PtrAuth, "ptrauth")
4848

49+
/// The active arch target's max atomic bit width.
50+
PLATFORM_CONDITION_(AtomicBitWidth, "atomicBitWidth")
51+
4952
#undef PLATFORM_CONDITION
5053
#undef PLATFORM_CONDITION_

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,9 @@ namespace swift {
683683
/// by name.
684684
bool hasFeature(llvm::StringRef featureName) const;
685685

686+
/// Sets the "_atomicBitWidth" conditional.
687+
void setAtomicBitWidth(llvm::Triple triple);
688+
686689
/// Returns true if the given platform condition argument represents
687690
/// a supported target operating system.
688691
///
@@ -720,7 +723,7 @@ namespace swift {
720723
}
721724

722725
private:
723-
llvm::SmallVector<std::pair<PlatformConditionKind, std::string>, 6>
726+
llvm::SmallVector<std::pair<PlatformConditionKind, std::string>, 10>
724727
PlatformConditionValues;
725728
llvm::SmallVector<std::string, 2> CustomConditionalCompilationFlags;
726729
};

lib/Basic/LangOptions.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ static const SupportedConditionalValue SupportedConditionalCompilationPtrAuthSch
107107
"_arm64e",
108108
};
109109

110+
static const SupportedConditionalValue SupportedConditionalCompilationAtomicBitWidths[] = {
111+
"_32",
112+
"_64",
113+
"_128"
114+
};
115+
110116
static const PlatformConditionKind AllPublicPlatformConditionKinds[] = {
111117
#define PLATFORM_CONDITION(LABEL, IDENTIFIER) PlatformConditionKind::LABEL,
112118
#define PLATFORM_CONDITION_(LABEL, IDENTIFIER)
@@ -131,6 +137,8 @@ ArrayRef<SupportedConditionalValue> getSupportedConditionalCompilationValues(con
131137
return SupportedConditionalCompilationTargetEnvironments;
132138
case PlatformConditionKind::PtrAuth:
133139
return SupportedConditionalCompilationPtrAuthSchemes;
140+
case PlatformConditionKind::AtomicBitWidth:
141+
return SupportedConditionalCompilationAtomicBitWidths;
134142
}
135143
llvm_unreachable("Unhandled PlatformConditionKind in switch");
136144
}
@@ -194,6 +202,7 @@ checkPlatformConditionSupported(PlatformConditionKind Kind, StringRef Value,
194202
case PlatformConditionKind::Runtime:
195203
case PlatformConditionKind::TargetEnvironment:
196204
case PlatformConditionKind::PtrAuth:
205+
case PlatformConditionKind::AtomicBitWidth:
197206
return isMatching(Kind, Value, suggestedKind, suggestedValues);
198207
case PlatformConditionKind::CanImport:
199208
// All importable names are valid.
@@ -268,6 +277,104 @@ bool LangOptions::hasFeature(llvm::StringRef featureName) const {
268277
return false;
269278
}
270279

280+
void LangOptions::setAtomicBitWidth(llvm::Triple triple) {
281+
// We really want to use Clang's getMaxAtomicInlineWidth(), but that requires
282+
// a Clang::TargetInfo and we're setting up lang opts very early in the
283+
// pipeline before any ASTContext or any ClangImporter instance where we can
284+
// access the target's info.
285+
286+
switch (triple.getArch()) {
287+
// ARM is only a 32 bit arch and all archs besides the microcontroller profile
288+
// ones have double word atomics.
289+
case llvm::Triple::ArchType::arm:
290+
case llvm::Triple::ArchType::thumb:
291+
switch (triple.getSubArch()) {
292+
case llvm::Triple::SubArchType::ARMSubArch_v6m:
293+
case llvm::Triple::SubArchType::ARMSubArch_v7m:
294+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_32");
295+
break;
296+
297+
default:
298+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
299+
break;
300+
}
301+
break;
302+
303+
// AArch64 (arm64) supports double word atomics on all archs besides the
304+
// microcontroller profiles.
305+
case llvm::Triple::ArchType::aarch64:
306+
switch (triple.getSubArch()) {
307+
case llvm::Triple::SubArchType::ARMSubArch_v8m_baseline:
308+
case llvm::Triple::SubArchType::ARMSubArch_v8m_mainline:
309+
case llvm::Triple::SubArchType::ARMSubArch_v8_1m_mainline:
310+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
311+
break;
312+
313+
default:
314+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_128");
315+
break;
316+
}
317+
break;
318+
319+
// arm64_32 has 32 bit pointer words, but it has the same architecture as
320+
// arm64 and supports 128 bit atomics.
321+
case llvm::Triple::ArchType::aarch64_32:
322+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_128");
323+
break;
324+
325+
// PowerPC does not support double word atomics.
326+
case llvm::Triple::ArchType::ppc:
327+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_32");
328+
break;
329+
330+
// All of the 64 bit PowerPC flavors do not support double word atomics.
331+
case llvm::Triple::ArchType::ppc64:
332+
case llvm::Triple::ArchType::ppc64le:
333+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
334+
break;
335+
336+
// SystemZ (s390x) does not support double word atomics.
337+
case llvm::Triple::ArchType::systemz:
338+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
339+
break;
340+
341+
// Wasm32 supports double word atomics.
342+
case llvm::Triple::ArchType::wasm32:
343+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
344+
break;
345+
346+
// x86 supports double word atomics.
347+
//
348+
// Technically, this is incorrect. However, on all x86 platforms where Swift
349+
// is deployed this is true.
350+
case llvm::Triple::ArchType::x86:
351+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
352+
break;
353+
354+
// x86_64 supports double word atomics.
355+
//
356+
// Technically, this is incorrect. However, on all x86_64 platforms where Swift
357+
// is deployed this is true. If the ClangImporter ever stops unconditionally
358+
// adding '-mcx16' to its Clang instance, then be sure to update this below.
359+
case llvm::Triple::ArchType::x86_64:
360+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_128");
361+
break;
362+
363+
default:
364+
// Some exotic architectures may not support atomics at all. If that's the
365+
// case please update the switch with your flavor of arch. Otherwise assume
366+
// every arch supports at least word atomics.
367+
368+
if (triple.isArch32Bit()) {
369+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_32");
370+
}
371+
372+
if (triple.isArch64Bit()) {
373+
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
374+
}
375+
}
376+
}
377+
271378
std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
272379
clearAllPlatformConditionValues();
273380

@@ -439,6 +546,9 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
439546
addPlatformConditionValue(PlatformConditionKind::TargetEnvironment,
440547
"macabi");
441548

549+
// Set the "_atomicBitWidth" platform condition.
550+
setAtomicBitWidth(triple);
551+
442552
// If you add anything to this list, change the default size of
443553
// PlatformConditionValues to not require an extra allocation
444554
// in the common case.

lib/Parse/ParseIfConfig.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ class ValidateIfConfigCondition :
380380
return E;
381381
}
382382

383-
// ( 'os' | 'arch' | '_endian' | '_pointerBitWidth' | '_runtime' ) '(' identifier ')''
383+
// ( 'os' | 'arch' | '_endian' | '_pointerBitWidth' | '_runtime' | '_atomicBitWidth' ) '(' identifier ')''
384384
auto Kind = getPlatformConditionKind(*KindName);
385385
if (!Kind.has_value()) {
386386
D.diagnose(E->getLoc(), diag::unsupported_platform_condition_expression);
@@ -422,6 +422,8 @@ class ValidateIfConfigCondition :
422422
DiagName = "target environment"; break;
423423
case PlatformConditionKind::PtrAuth:
424424
DiagName = "pointer authentication scheme"; break;
425+
case PlatformConditionKind::AtomicBitWidth:
426+
DiagName = "atomic bit width"; break;
425427
case PlatformConditionKind::Runtime:
426428
llvm_unreachable("handled above");
427429
}

test/Parse/ConditionalCompilation/aarch64AndroidTarget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let i: Int = "Hello"
88
#endif
99

10-
#if arch(arm64) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64)
10+
#if arch(arm64) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
1111
class C {}
1212
var x = C()
1313
#endif

test/Parse/ConditionalCompilation/arm64AppleTVOSTarget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let i: Int = "Hello"
88
#endif
99

10-
#if arch(arm64) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64)
10+
#if arch(arm64) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
1111
class C {}
1212
var x = C()
1313
#endif

test/Parse/ConditionalCompilation/arm64IOSTarget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let i: Int = "Hello"
88
#endif
99

10-
#if arch(arm64) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64)
10+
#if arch(arm64) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
1111
class C {}
1212
var x = C()
1313
#endif

test/Parse/ConditionalCompilation/armAndroidTarget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let i: Int = "Hello"
88
#endif
99

10-
#if arch(arm) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_32)
10+
#if arch(arm) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
1111
class C {}
1212
var x = C()
1313
#endif

test/Parse/ConditionalCompilation/armIOSTarget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let i: Int = "Hello"
88
#endif
99

10-
#if arch(arm) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32)
10+
#if arch(arm) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
1111
class C {}
1212
var x = C()
1313
#endif

test/Parse/ConditionalCompilation/armWatchOSTarget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
let i: Int = "Hello"
88
#endif
99

10-
#if arch(arm) && os(watchOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32)
10+
#if arch(arm) && os(watchOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
1111
class C {}
1212
var x = C()
1313
#endif

0 commit comments

Comments
 (0)