1717#include " CIRGenOpenMPRuntime.h"
1818#include " TargetInfo.h"
1919#include " clang/AST/ASTContext.h"
20+ #include " clang/Basic/SyncScope.h"
2021#include " clang/CIR/Dialect/IR/CIRAttrs.h"
2122#include " clang/CIR/Dialect/IR/CIRDataLayout.h"
2223#include " clang/CIR/Dialect/IR/CIRDialect.h"
@@ -350,6 +351,20 @@ static cir::IntAttr extractIntAttr(mlir::Value v) {
350351 return {};
351352}
352353
354+ // Maps SyncScope::SingleScope to SyncScopeKind::SingleThread,
355+ // SyncScope::SystemScope to SyncScopeKind::System,
356+ // and asserts (llvm_unreachable) for anything else.
357+ static cir::SyncScopeKind convertSyncScopeToCIR (clang::SyncScope scope) {
358+ switch (scope) {
359+ case clang::SyncScope::SingleScope:
360+ return cir::SyncScopeKind::SingleThread;
361+ case clang::SyncScope::SystemScope:
362+ return cir::SyncScopeKind::System;
363+ default :
364+ llvm_unreachable (" NYI" );
365+ }
366+ }
367+
353368// Inspect a value that is the strong/weak flag for a compare-exchange. If it
354369// is a constant of intergral or boolean type, set `val` to the constant's
355370// boolean value and return true. Otherwise leave `val` unchanged and return
@@ -418,7 +433,7 @@ static void emitAtomicCmpXchg(CIRGenFunction &CGF, AtomicExpr *E, bool IsWeak,
418433 Address Val2, uint64_t Size,
419434 cir::MemOrder SuccessOrder,
420435 cir::MemOrder FailureOrder,
421- cir::MemScopeKind Scope) {
436+ cir::SyncScopeKind Scope) {
422437 auto &builder = CGF.getBuilder ();
423438 auto loc = CGF.getLoc (E->getSourceRange ());
424439 auto Expected = builder.createLoad (loc, Val1);
@@ -428,7 +443,7 @@ static void emitAtomicCmpXchg(CIRGenFunction &CGF, AtomicExpr *E, bool IsWeak,
428443 builder, loc, Expected.getType (), boolTy, Ptr.getPointer (), Expected,
429444 Desired, cir::MemOrderAttr::get (&CGF.getMLIRContext (), SuccessOrder),
430445 cir::MemOrderAttr::get (&CGF.getMLIRContext (), FailureOrder),
431- cir::MemScopeKindAttr ::get (&CGF.getMLIRContext (), Scope),
446+ cir::SyncScopeKindAttr ::get (&CGF.getMLIRContext (), Scope),
432447 builder.getI64IntegerAttr (Ptr.getAlignment ().getAsAlign ().value ()));
433448 cmpxchg.setIsVolatile (E->isVolatile ());
434449 cmpxchg.setWeak (IsWeak);
@@ -456,7 +471,7 @@ static void emitAtomicCmpXchg(CIRGenFunction &CGF, AtomicExpr *E, bool IsWeak,
456471static void emitAtomicCmpXchgFailureSet (
457472 CIRGenFunction &CGF, AtomicExpr *E, bool IsWeak, Address Dest, Address Ptr,
458473 Address Val1, Address Val2, mlir::Value FailureOrderVal, uint64_t Size,
459- cir::MemOrder SuccessOrder, cir::MemScopeKind Scope) {
474+ cir::MemOrder SuccessOrder, cir::SyncScopeKind Scope) {
460475
461476 cir::MemOrder FailureOrder;
462477 if (auto ordAttr = extractIntAttr (FailureOrderVal)) {
@@ -546,8 +561,7 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *E, Address Dest,
546561 Address Ptr, Address Val1, Address Val2,
547562 mlir::Value IsWeak, mlir::Value FailureOrder,
548563 uint64_t Size, cir::MemOrder Order,
549- cir::MemScopeKind Scope) {
550- assert (!cir::MissingFeatures::syncScopeID ());
564+ cir::SyncScopeKind Scope) {
551565 StringRef Op;
552566
553567 auto &builder = CGF.getBuilder ();
@@ -594,9 +608,7 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *E, Address Dest,
594608 case AtomicExpr::AO__scoped_atomic_load_n:
595609 case AtomicExpr::AO__scoped_atomic_load: {
596610 auto load = builder.createLoad (loc, Ptr);
597- // FIXME(cir): add scope information.
598- assert (!cir::MissingFeatures::syncScopeID ());
599- load.setMemOrder (Order);
611+ load.setAtomic (Order, Scope);
600612 load.setIsVolatile (E->isVolatile ());
601613
602614 // TODO(cir): this logic should be part of createStore, but doing so
@@ -619,7 +631,6 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *E, Address Dest,
619631 case AtomicExpr::AO__scoped_atomic_store_n: {
620632 auto loadVal1 = builder.createLoad (loc, Val1);
621633 // FIXME(cir): add scope information.
622- assert (!cir::MissingFeatures::syncScopeID ());
623634 builder.createStore (loc, loadVal1, Ptr, E->isVolatile (),
624635 /* isNontemporal=*/ false ,
625636 /* alignment=*/ mlir::IntegerAttr{}, orderAttr);
@@ -748,7 +759,7 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *E, Address Dest,
748759 case AtomicExpr::AO__atomic_test_and_set: {
749760 auto op = cir::AtomicTestAndSetOp::create (
750761 builder, loc, Ptr.getPointer (), Order,
751- cir::MemScopeKindAttr ::get (&CGF.getMLIRContext (), Scope),
762+ cir::SyncScopeKindAttr ::get (&CGF.getMLIRContext (), Scope),
752763 builder.getI64IntegerAttr (Ptr.getAlignment ().getQuantity ()),
753764 E->isVolatile ());
754765 builder.createStore (loc, op, Dest);
@@ -758,7 +769,7 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *E, Address Dest,
758769 case AtomicExpr::AO__atomic_clear: {
759770 cir::AtomicClearOp::create (
760771 builder, loc, Ptr.getPointer (), Order,
761- cir::MemScopeKindAttr ::get (&CGF.getMLIRContext (), Scope),
772+ cir::SyncScopeKindAttr ::get (&CGF.getMLIRContext (), Scope),
762773 builder.getI64IntegerAttr (Ptr.getAlignment ().getQuantity ()),
763774 E->isVolatile ());
764775 return ;
@@ -811,16 +822,17 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *Expr, Address Dest,
811822 // LLVM atomic instructions always have synch scope. If clang atomic
812823 // expression has no scope operand, use default LLVM synch scope.
813824 if (!ScopeModel) {
814- assert (!cir::MissingFeatures::syncScopeID ());
815825 emitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
816- Order, cir::MemScopeKind ::System);
826+ Order, cir::SyncScopeKind ::System);
817827 return ;
818828 }
819829
820830 // Handle constant scope.
821- if (extractIntAttr (Scope)) {
822- assert (!cir::MissingFeatures::syncScopeID ());
823- llvm_unreachable (" NYI" );
831+ if (auto scopeAttr = extractIntAttr (Scope)) {
832+ auto mappedScope =
833+ convertSyncScopeToCIR (ScopeModel->map (scopeAttr.getUInt ()));
834+ emitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
835+ Order, mappedScope);
824836 return ;
825837 }
826838
0 commit comments