diff options
author | John McCall <rjmccall@apple.com> | 2013-03-07 21:37:17 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2013-03-07 21:37:17 +0000 |
commit | 9eda3abe7e183b05834947391c0cdc291f4ee0d8 (patch) | |
tree | 423816b735698663315497d61aa2a0987752bbfb /lib/AST | |
parent | fafaaef243322b1e598a72d7dbfaf2ca0c139174 (diff) |
Promote atomic type sizes up to a power of two, capped by
MaxAtomicPromoteWidth. Fix a ton of terrible bugs with
_Atomic types and (non-intrinsic-mediated) loads and stores
thereto.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176658 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index db1aa1a944..4580424696 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1602,18 +1602,21 @@ ASTContext::getTypeInfoImpl(const Type *T) const { } case Type::Atomic: { + // Start with the base type information. std::pair<uint64_t, unsigned> Info = getTypeInfo(cast<AtomicType>(T)->getValueType()); Width = Info.first; Align = Info.second; - if (Width != 0 && Width <= Target->getMaxAtomicPromoteWidth() && - llvm::isPowerOf2_64(Width)) { - // We can potentially perform lock-free atomic operations for this - // type; promote the alignment appropriately. - // FIXME: We could potentially promote the width here as well... - // is that worthwhile? (Non-struct atomic types generally have - // power-of-two size anyway, but structs might not. Requires a bit - // of implementation work to make sure we zero out the extra bits.) + + // If the size of the type doesn't exceed the platform's max + // atomic promotion width, make the size and alignment more + // favorable to atomic operations: + if (Width != 0 && Width <= Target->getMaxAtomicPromoteWidth()) { + // Round the size up to a power of 2. + if (!llvm::isPowerOf2_64(Width)) + Width = llvm::NextPowerOf2(Width); + + // Set the alignment equal to the size. Align = static_cast<unsigned>(Width); } } |