@@ -107,6 +107,12 @@ static const SupportedConditionalValue SupportedConditionalCompilationPtrAuthSch
107
107
" _arm64e" ,
108
108
};
109
109
110
+ static const SupportedConditionalValue SupportedConditionalCompilationAtomicBitWidths[] = {
111
+ " _32" ,
112
+ " _64" ,
113
+ " _128"
114
+ };
115
+
110
116
static const PlatformConditionKind AllPublicPlatformConditionKinds[] = {
111
117
#define PLATFORM_CONDITION (LABEL, IDENTIFIER ) PlatformConditionKind::LABEL,
112
118
#define PLATFORM_CONDITION_ (LABEL, IDENTIFIER )
@@ -131,6 +137,8 @@ ArrayRef<SupportedConditionalValue> getSupportedConditionalCompilationValues(con
131
137
return SupportedConditionalCompilationTargetEnvironments;
132
138
case PlatformConditionKind::PtrAuth:
133
139
return SupportedConditionalCompilationPtrAuthSchemes;
140
+ case PlatformConditionKind::AtomicBitWidth:
141
+ return SupportedConditionalCompilationAtomicBitWidths;
134
142
}
135
143
llvm_unreachable (" Unhandled PlatformConditionKind in switch" );
136
144
}
@@ -194,6 +202,7 @@ checkPlatformConditionSupported(PlatformConditionKind Kind, StringRef Value,
194
202
case PlatformConditionKind::Runtime:
195
203
case PlatformConditionKind::TargetEnvironment:
196
204
case PlatformConditionKind::PtrAuth:
205
+ case PlatformConditionKind::AtomicBitWidth:
197
206
return isMatching (Kind, Value, suggestedKind, suggestedValues);
198
207
case PlatformConditionKind::CanImport:
199
208
// All importable names are valid.
@@ -268,6 +277,104 @@ bool LangOptions::hasFeature(llvm::StringRef featureName) const {
268
277
return false ;
269
278
}
270
279
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
+
271
378
std::pair<bool , bool > LangOptions::setTarget (llvm::Triple triple) {
272
379
clearAllPlatformConditionValues ();
273
380
@@ -439,6 +546,9 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
439
546
addPlatformConditionValue (PlatformConditionKind::TargetEnvironment,
440
547
" macabi" );
441
548
549
+ // Set the "_atomicBitWidth" platform condition.
550
+ setAtomicBitWidth (triple);
551
+
442
552
// If you add anything to this list, change the default size of
443
553
// PlatformConditionValues to not require an extra allocation
444
554
// in the common case.
0 commit comments