summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2011-10-17 21:44:23 +0000
committerEli Friedman <eli.friedman@gmail.com>2011-10-17 21:44:23 +0000
commita4c2602b714e6c6edb98164550a5ae829b2de760 (patch)
tree9d616c76ca2fbf208d3f06ed9dad14711dfcedc2 /clang/lib/AST/ExprConstant.cpp
parent6bf79084c3e12596bcb9fa6589fa9af1b0d32a34 (diff)
downloadbcm5719-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.cpp44
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);
+ }
}
}
OpenPOWER on IntegriCloud