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 | 4b72fddd9914d76370704c79f5fdedfbc6c6dedc (patch) | |
tree | a7fdd04f544b898111e60d696d30d8b5f6953571 /clang/lib/AST/ASTContext.cpp | |
parent | 8b478360efd56c1b150647f794b2e13e6fef8400 (diff) | |
download | bcm5719-llvm-4b72fddd9914d76370704c79f5fdedfbc6c6dedc.tar.gz bcm5719-llvm-4b72fddd9914d76370704c79f5fdedfbc6c6dedc.zip |
Misc fixes for atomics. Biggest fix is doing alignment correctly for _Atomic types.
llvm-svn: 142002
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b625655e45f..ae96dfd1481 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/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); } |