diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-10-14 20:59:01 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-10-14 20:59:01 +0000 |
commit | 2be460723940f8184ec36529b6f6ddf59c04e411 (patch) | |
tree | bba05a4c3fc787de766a2a7fd35ac36cadc0167f /lib/AST/ASTContext.cpp | |
parent | 41be673e93ed225b45479557b20ff19b3082bae8 (diff) |
Misc fixes for atomics. Biggest fix is doing alignment correctly for _Atomic types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b625655e45..ae96dfd148 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1064,13 +1064,25 @@ ASTContext::getTypeInfo(const Type *T) const { } case Type::Atomic: { - // FIXME: The alignment needs to be "fixed". - return getTypeInfo(cast<AtomicType>(T)->getValueType()); + 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.) + Align = static_cast<unsigned>(Width); + } } } - assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2"); + assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2"); return std::make_pair(Width, Align); } |