kzhuravl created this revision.
kzhuravl added reviewers: tstellarAMD, arsenm, rampitec.
kzhuravl added subscribers: cfe-commits, llvm-commits, resistor.

As described in this proposal: 
https://groups.google.com/forum/#!topic/llvm-dev/GtWfCc5j-4U

http://reviews.llvm.org/D21724

Files:
  lib/CodeGen/CGBuiltin.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGen/synchscopes.cpp

Index: test/CodeGen/synchscopes.cpp
===================================================================
--- test/CodeGen/synchscopes.cpp
+++ test/CodeGen/synchscopes.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang -emit-llvm -S -std=c++11 %s -o - | FileCheck %s
+
+// CHECK: !synchscopes = !{!0, !1}
+// CHECK: !0 = !{i32 0, !"System"}
+// CHECK: !1 = !{i32 -1, !"SingleThread"}
+
+#include <atomic>
+
+void synchscopes_acquire() {
+  atomic_thread_fence(std::memory_order_acquire);
+  atomic_signal_fence(std::memory_order_acquire);
+}
+
+void synchscopes_release() {
+  atomic_thread_fence(std::memory_order_release);
+  atomic_signal_fence(std::memory_order_release);
+}
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -374,6 +374,9 @@
   llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;
   llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap;
 
+  /// \brief Mapping from synchronization scope to it's string representation.
+  std::map<unsigned, std::string> SynchScopeMap;
+
   /// Map used to get unique type descriptor constants for sanitizers.
   llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap;
 
@@ -582,6 +585,8 @@
     AtomicGetterHelperFnMap[Ty] = Fn;
   }
 
+  void setSynchScopeMap(unsigned SynchScope, const std::string &SynchScopeName);
+
   llvm::Constant *getTypeDescriptorFromMap(QualType Ty) {
     return TypeDescriptorMap[Ty];
   }
@@ -1233,6 +1238,9 @@
 
   void EmitDeclMetadata();
 
+  /// \brief Emit synchronization scope metadata.
+  void EmitSynchScopeMetadata();
+
   /// \brief Emit the Clang version as llvm.ident metadata.
   void EmitVersionIdentMetadata();
 
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -495,6 +495,8 @@
   if (DebugInfo)
     DebugInfo->finalize();
 
+  EmitSynchScopeMetadata();
+
   EmitVersionIdentMetadata();
 
   EmitTargetMetadata();
@@ -4049,6 +4051,15 @@
   return true;
 }
 
+void CodeGenModule::setSynchScopeMap(unsigned SynchScope,
+                                     const std::string &SynchScopeName) {
+  auto Res = SynchScopeMap.find(SynchScope);
+  if (Res == SynchScopeMap.end())
+    SynchScopeMap.insert(std::make_pair(SynchScope, SynchScopeName));
+  else
+    assert(Res->second == SynchScopeName);
+}
+
 /// Emits metadata nodes associating all the global values in the
 /// current module with the Decls they came from.  This is useful for
 /// projects using IR gen as a subroutine.
@@ -4095,6 +4106,22 @@
   }
 }
 
+void CodeGenModule::EmitSynchScopeMetadata() {
+  if (!SynchScopeMap.size())
+    return;
+
+  llvm::LLVMContext &Ctx = TheModule.getContext();
+  llvm::NamedMDNode *SynchScopeMetadata =
+    TheModule.getOrInsertNamedMetadata("synchscopes");
+  for (auto &I : SynchScopeMap) {
+    llvm::Metadata *SynchScopeNode[2] = {
+      llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, I.first)),
+      llvm::MDString::get(Ctx, I.second)
+    };
+    SynchScopeMetadata->addOperand(llvm::MDNode::get(Ctx, SynchScopeNode));
+  }
+}
+
 void CodeGenModule::EmitVersionIdentMetadata() {
   llvm::NamedMDNode *IdentMetadata =
     TheModule.getOrInsertNamedMetadata("llvm.ident");
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -1474,12 +1474,17 @@
   case Builtin::BI__atomic_signal_fence:
   case Builtin::BI__c11_atomic_thread_fence:
   case Builtin::BI__c11_atomic_signal_fence: {
-    llvm::SynchronizationScope Scope;
+    unsigned Scope;
+    std::string ScopeName;
     if (BuiltinID == Builtin::BI__atomic_signal_fence ||
-        BuiltinID == Builtin::BI__c11_atomic_signal_fence)
-      Scope = llvm::SingleThread;
-    else
-      Scope = llvm::CrossThread;
+        BuiltinID == Builtin::BI__c11_atomic_signal_fence) {
+      Scope = llvm::SynchScopeSingleThread;
+      ScopeName = "SingleThread";
+    } else {
+      Scope = llvm::SynchScopeSystem;
+      ScopeName = "System";
+    }
+    CGM.setSynchScopeMap(Scope, ScopeName);
     Value *Order = EmitScalarExpr(E->getArg(0));
     if (isa<llvm::ConstantInt>(Order)) {
       int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to