forked from OSchip/llvm-project
Initial implementation of __atomic_is_lock_free. The input is the size of an atomic type rather than an atomic type itself just to save some implementation pain; I can change that if it seems worthwhile.
I think this is the last hook needed for <atomic> besides defines for ATOMIC_CHAR_LOCK_FREE and friends. llvm-svn: 142281
This commit is contained in:
parent
6bf79084c3
commit
a4c2602b71
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)));
|
||||
}
|
Loading…
Reference in New Issue