diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2011-10-17 21:44:23 +0000 | 
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2011-10-17 21:44:23 +0000 | 
| commit | a4c2602b714e6c6edb98164550a5ae829b2de760 (patch) | |
| tree | 9d616c76ca2fbf208d3f06ed9dad14711dfcedc2 /clang/lib/AST/ExprConstant.cpp | |
| parent | 6bf79084c3e12596bcb9fa6589fa9af1b0d32a34 (diff) | |
| download | bcm5719-llvm-a4c2602b714e6c6edb98164550a5ae829b2de760.tar.gz bcm5719-llvm-a4c2602b714e6c6edb98164550a5ae829b2de760.zip | |
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
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 44 | 
1 files changed, 44 insertions, 0 deletions
| diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 3c21dc4472a..c3cc78e053c 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -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); +  }    }  } | 

