Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/AST/PlatformConditionKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ PLATFORM_CONDITION(TargetEnvironment, "targetEnvironment")
/// Pointer authentication enabled
PLATFORM_CONDITION_(PtrAuth, "ptrauth")

/// The active arch target's max atomic bit width.
PLATFORM_CONDITION_(AtomicBitWidth, "atomicBitWidth")

#undef PLATFORM_CONDITION
#undef PLATFORM_CONDITION_
5 changes: 4 additions & 1 deletion include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,9 @@ namespace swift {
/// by name.
bool hasFeature(llvm::StringRef featureName) const;

/// Sets the "_atomicBitWidth" conditional.
void setAtomicBitWidth(llvm::Triple triple);

/// Returns true if the given platform condition argument represents
/// a supported target operating system.
///
Expand Down Expand Up @@ -714,7 +717,7 @@ namespace swift {
}

private:
llvm::SmallVector<std::pair<PlatformConditionKind, std::string>, 6>
llvm::SmallVector<std::pair<PlatformConditionKind, std::string>, 10>
PlatformConditionValues;
llvm::SmallVector<std::string, 2> CustomConditionalCompilationFlags;
};
Expand Down
110 changes: 110 additions & 0 deletions lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ static const SupportedConditionalValue SupportedConditionalCompilationPtrAuthSch
"_arm64e",
};

static const SupportedConditionalValue SupportedConditionalCompilationAtomicBitWidths[] = {
"_32",
"_64",
"_128"
};

static const PlatformConditionKind AllPublicPlatformConditionKinds[] = {
#define PLATFORM_CONDITION(LABEL, IDENTIFIER) PlatformConditionKind::LABEL,
#define PLATFORM_CONDITION_(LABEL, IDENTIFIER)
Expand All @@ -131,6 +137,8 @@ ArrayRef<SupportedConditionalValue> getSupportedConditionalCompilationValues(con
return SupportedConditionalCompilationTargetEnvironments;
case PlatformConditionKind::PtrAuth:
return SupportedConditionalCompilationPtrAuthSchemes;
case PlatformConditionKind::AtomicBitWidth:
return SupportedConditionalCompilationAtomicBitWidths;
}
llvm_unreachable("Unhandled PlatformConditionKind in switch");
}
Expand Down Expand Up @@ -194,6 +202,7 @@ checkPlatformConditionSupported(PlatformConditionKind Kind, StringRef Value,
case PlatformConditionKind::Runtime:
case PlatformConditionKind::TargetEnvironment:
case PlatformConditionKind::PtrAuth:
case PlatformConditionKind::AtomicBitWidth:
return isMatching(Kind, Value, suggestedKind, suggestedValues);
case PlatformConditionKind::CanImport:
// All importable names are valid.
Expand Down Expand Up @@ -268,6 +277,104 @@ bool LangOptions::hasFeature(llvm::StringRef featureName) const {
return false;
}

void LangOptions::setAtomicBitWidth(llvm::Triple triple) {
// We really want to use Clang's getMaxAtomicInlineWidth(), but that requires
// a Clang::TargetInfo and we're setting up lang opts very early in the
// pipeline before any ASTContext or any ClangImporter instance where we can
// access the target's info.

switch (triple.getArch()) {
// ARM is only a 32 bit arch and all archs besides the microcontroller profile
// ones have double word atomics.
case llvm::Triple::ArchType::arm:
case llvm::Triple::ArchType::thumb:
switch (triple.getSubArch()) {
case llvm::Triple::SubArchType::ARMSubArch_v6m:
case llvm::Triple::SubArchType::ARMSubArch_v7m:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_32");
break;

default:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
break;
}
break;

// AArch64 (arm64) supports double word atomics on all archs besides the
// microcontroller profiles.
case llvm::Triple::ArchType::aarch64:
switch (triple.getSubArch()) {
case llvm::Triple::SubArchType::ARMSubArch_v8m_baseline:
case llvm::Triple::SubArchType::ARMSubArch_v8m_mainline:
case llvm::Triple::SubArchType::ARMSubArch_v8_1m_mainline:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
break;

default:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_128");
break;
}
break;

// arm64_32 has 32 bit pointer words, but it has the same architecture as
// arm64 and supports 128 bit atomics.
case llvm::Triple::ArchType::aarch64_32:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_128");
break;

// PowerPC does not support double word atomics.
case llvm::Triple::ArchType::ppc:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_32");
break;

// All of the 64 bit PowerPC flavors do not support double word atomics.
case llvm::Triple::ArchType::ppc64:
case llvm::Triple::ArchType::ppc64le:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
break;

// SystemZ (s390x) does not support double word atomics.
case llvm::Triple::ArchType::systemz:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
break;

// Wasm32 supports double word atomics.
case llvm::Triple::ArchType::wasm32:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
break;

// x86 supports double word atomics.
//
// Technically, this is incorrect. However, on all x86 platforms where Swift
// is deployed this is true.
case llvm::Triple::ArchType::x86:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
break;

// x86_64 supports double word atomics.
//
// Technically, this is incorrect. However, on all x86_64 platforms where Swift
// is deployed this is true. If the ClangImporter ever stops unconditionally
// adding '-mcx16' to its Clang instance, then be sure to update this below.
case llvm::Triple::ArchType::x86_64:
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_128");
break;

default:
// Some exotic architectures may not support atomics at all. If that's the
// case please update the switch with your flavor of arch. Otherwise assume
// every arch supports at least word atomics.

if (triple.isArch32Bit()) {
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_32");
}

if (triple.isArch64Bit()) {
addPlatformConditionValue(PlatformConditionKind::AtomicBitWidth, "_64");
}
}
}

std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
clearAllPlatformConditionValues();

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

// Set the "_atomicBitWidth" platform condition.
setAtomicBitWidth(triple);

// If you add anything to this list, change the default size of
// PlatformConditionValues to not require an extra allocation
// in the common case.
Expand Down
4 changes: 3 additions & 1 deletion lib/Parse/ParseIfConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ class ValidateIfConfigCondition :
return E;
}

// ( 'os' | 'arch' | '_endian' | '_pointerBitWidth' | '_runtime' ) '(' identifier ')''
// ( 'os' | 'arch' | '_endian' | '_pointerBitWidth' | '_runtime' | '_atomicBitWidth' ) '(' identifier ')''
auto Kind = getPlatformConditionKind(*KindName);
if (!Kind.has_value()) {
D.diagnose(E->getLoc(), diag::unsupported_platform_condition_expression);
Expand Down Expand Up @@ -422,6 +422,8 @@ class ValidateIfConfigCondition :
DiagName = "target environment"; break;
case PlatformConditionKind::PtrAuth:
DiagName = "pointer authentication scheme"; break;
case PlatformConditionKind::AtomicBitWidth:
DiagName = "atomic bit width"; break;
case PlatformConditionKind::Runtime:
llvm_unreachable("handled above");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(arm64) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64)
#if arch(arm64) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
class C {}
var x = C()
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(arm64) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64)
#if arch(arm64) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/arm64IOSTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(arm64) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64)
#if arch(arm64) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/armAndroidTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(arm) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_32)
#if arch(arm) && os(Android) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/armIOSTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(arm) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32)
#if arch(arm) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/armWatchOSTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(arm) && os(watchOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32)
#if arch(arm) && os(watchOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(i386) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32)
#if arch(i386) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/i386IOSTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(i386) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32)
#if arch(i386) && os(iOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(i386) && os(watchOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32)
#if arch(i386) && os(watchOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
15 changes: 10 additions & 5 deletions test/Parse/ConditionalCompilation/identifierName.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ func f2(
FOO: Int,
swift: Int, _compiler_version: Int,
os: Int, arch: Int, _endian: Int, _pointerBitWidth: Int, _runtime: Int,
targetEnvironment: Int,
targetEnvironment: Int, _atomicBitWidth: Int,
arm: Int, i386: Int, macOS: Int, OSX: Int, Linux: Int,
big: Int, little: Int,
_32: Int, _64: Int,
_32: Int, _64: Int, _128: Int,
_ObjC: Int, _Native: Int,
simulator: Int
) {
Expand All @@ -28,6 +28,8 @@ func f2(
_ = _runtime + _ObjC + _Native
#elseif targetEnvironment(simulator)
_ = targetEnvironment + simulator
#elseif _atomicBitWidth(_32) && _atomicBitWidth(_64) && _atomicBitWidth(_128)
_ = _atomicBitWidth + _32 + _64 + _128
#elseif swift(>=1.0) && _compiler_version("4.*.0")
_ = swift + _compiler_version
#endif
Expand All @@ -38,10 +40,10 @@ func f2() {
let
FOO = 1, swift = 1, _compiler_version = 1,
os = 1, arch = 1, _endian = 1, _pointerBitWidth = 1, _runtime = 1,
targetEnvironment = 1,
targetEnvironment = 1, _atomicBitWidth = 1,
arm = 1, i386 = 1, macOS = 1, OSX = 1, Linux = 1,
big = 1, little = 1,
_32 = 1, _64 = 1,
_32 = 1, _64 = 1, _128 = 1,
_ObjC = 1, _Native = 1,
simulator = 1

Expand All @@ -59,6 +61,8 @@ func f2() {
_ = _runtime + _ObjC + _Native
#elseif targetEnvironment(simulator)
_ = targetEnvironment + simulator
#elseif _atomicBitWidth(_32) && _atomicBitWidth(_64) && _atomicBitWidth(_128)
_ = _atomicBitWidth + _32 + _64 + _128
#elseif swift(>=1.0) && _compiler_version("4.*.0")
_ = swift + _compiler_version
#endif
Expand All @@ -69,7 +73,7 @@ struct S {
let
FOO = 1, swift = 1, _compiler_version = 1,
os = 1, arch = 1, _endian = 1, _pointerBitWidth = 1, _runtime = 1,
targetEnvironment = 1,
targetEnvironment = 1, _atomicBitWidth = 1,
arm = 1, i386 = 1, macOS = 1, OSX = 1, Linux = 1,
big = 1, little = 1,
_32 = 1, _64 = 1,
Expand All @@ -83,6 +87,7 @@ struct S {
#elseif _pointerBitWidth(_32) && _pointerBitWidth(_64)
#elseif _runtime(_ObjC) && _runtime(_Native)
#elseif targetEnvironment(simulator)
#elseif _atomicBitWidth(_32) && _atomicBitWidth(_64) && _atomicBitWidth(_128)
#elseif swift(>=1.0) && _compiler_version("4.*.0")
#endif

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %swift -typecheck %s -verify -target powerpc64-unknown-linux-gnu -disable-objc-interop -parse-stdlib
// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target powerpc64-unknown-linux-gnu

#if arch(powerpc64) && os(Linux) && _runtime(_Native) && _endian(big) && _pointerBitWidth(_64)
#if arch(powerpc64) && os(Linux) && _runtime(_Native) && _endian(big) && _pointerBitWidth(_64) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %swift -typecheck %s -verify -target powerpc64le-unknown-linux-gnu -disable-objc-interop -parse-stdlib
// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target powerpc64le-unknown-linux-gnu

#if arch(powerpc64le) && os(Linux) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64)
#if arch(powerpc64le) && os(Linux) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/s390xLinuxTarget.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %swift -typecheck %s -verify -target s390x-unknown-linux-gnu -disable-objc-interop -parse-stdlib
// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target s390x-unknown-linux-gnu

#if arch(s390x) && os(Linux) && _runtime(_Native) && _endian(big) && _pointerBitWidth(_64)
#if arch(s390x) && os(Linux) && _runtime(_Native) && _endian(big) && _pointerBitWidth(_64) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/wasm32Target.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %swift -typecheck %s -verify -target wasm32-unknown-wasi -disable-objc-interop -parse-stdlib
// RUN: %swift-ide-test -test-input-complete -source-filename %s -target wasm32-unknown-wasi

#if arch(wasm32) && os(WASI) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_32)
#if arch(wasm32) && os(WASI) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_32) && _atomicBitWidth(_64)
class C {}
var x = C()
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let i: Int = "Hello"
#endif

#if arch(x86_64) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64)
#if arch(x86_64) && os(tvOS) && _runtime(_ObjC) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/x64CygwinTarget.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %swift -typecheck %s -verify -target x86_64-unknown-windows-cygnus -disable-objc-interop -parse-stdlib
// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target x86_64-unknown-windows-cygnus
#if arch(x86_64) && os(Cygwin) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64)
#if arch(x86_64) && os(Cygwin) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
class C {}
var x = C()
#endif
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/ConditionalCompilation/x64FreeBSDTarget.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %swift -typecheck %s -verify -target x86_64-unknown-freebsd10 -disable-objc-interop -parse-stdlib
// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target x86_64-unknown-freebsd10

#if arch(x86_64) && os(FreeBSD) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64)
#if arch(x86_64) && os(FreeBSD) && _runtime(_Native) && _endian(little) && _pointerBitWidth(_64) && _atomicBitWidth(_128)
class C {}
var x = C()
#endif
Expand Down
Loading