]> granicus.if.org Git - clang/commitdiff
Initial implementation of __atomic_is_lock_free. The input is the size of an atomic...
authorEli Friedman <eli.friedman@gmail.com>
Mon, 17 Oct 2011 21:44:23 +0000 (21:44 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Mon, 17 Oct 2011 21:44:23 +0000 (21:44 +0000)
I think this is the last hook needed for <atomic> besides defines for ATOMIC_CHAR_LOCK_FREE and friends.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142281 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Builtins.def
lib/AST/ExprConstant.cpp
test/CodeGen/atomic-ops.c

index e5690c123393904ff4f8840942705eac8c085074..63de4e5a75d2690582ee2f70694d217224b8d365 100644 (file)
@@ -598,6 +598,7 @@ BUILTIN(__atomic_fetch_or, "v.", "t")
 BUILTIN(__atomic_fetch_xor, "v.", "t")
 BUILTIN(__atomic_thread_fence, "vi", "n")
 BUILTIN(__atomic_signal_fence, "vi", "n")
+BUILTIN(__atomic_is_lock_free, "iz", "n")
 
 // Non-overloaded atomic builtins.
 BUILTIN(__sync_synchronize, "v.", "n")
index 3c21dc4472a035f6424caaccd6d72c8463831063..c3cc78e053ccf3227d2fc63422156390bfa1e19a 100644 (file)
@@ -1344,6 +1344,50 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
     }
       
     return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+
+  case Builtin::BI__atomic_is_lock_free: {
+    APSInt SizeVal;
+    if (!EvaluateInteger(E->getArg(0), SizeVal, Info))
+      return false;
+
+    // For __atomic_is_lock_free(sizeof(_Atomic(T))), if the size is a power
+    // of two less than the maximum inline atomic width, we know it is
+    // lock-free.  If the size isn't a power of two, or greater than the
+    // maximum alignment where we promote atomics, we know it is not lock-free
+    // (at least not in the sense of atomic_is_lock_free).  Otherwise,
+    // the answer can only be determined at runtime; for example, 16-byte
+    // atomics have lock-free implementations on some, but not all,
+    // x86-64 processors.
+
+    // Check power-of-two.
+    CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
+    if (!Size.isPowerOfTwo())
+#if 0
+      // FIXME: Suppress this folding until the ABI for the promotion width
+      // settles.
+      return Success(0, E);
+#else
+      return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+#endif
+
+#if 0
+    // Check against promotion width.
+    // FIXME: Suppress this folding until the ABI for the promotion width
+    // settles.
+    unsigned PromoteWidthBits =
+        Info.Ctx.getTargetInfo().getMaxAtomicPromoteWidth();
+    if (Size > Info.Ctx.toCharUnitsFromBits(PromoteWidthBits))
+      return Success(0, E);
+#endif
+
+    // Check against inlining width.
+    unsigned InlineWidthBits =
+        Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
+    if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits))
+      return Success(1, E);
+
+    return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
+  }
   }
 }
 
index e2904cf10e8113cb611a664295b65ac98ff08f76..0ae70b1b370118064da31683eeb838b83f11b027 100644 (file)
@@ -75,3 +75,9 @@ X fs(_Atomic(X) *c) {
   // CHECK: atomicrmw xchg i32*
   return __atomic_exchange(c, (X){2}, memory_order_seq_cst);
 }
+
+int lock_free() {
+  // CHECK: @lock_free
+  // CHECK: ret i32 1
+  return __atomic_is_lock_free(sizeof(_Atomic(int)));
+}
\ No newline at end of file