aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2011-10-14 20:59:01 +0000
committerEli Friedman <eli.friedman@gmail.com>2011-10-14 20:59:01 +0000
commit2be460723940f8184ec36529b6f6ddf59c04e411 (patch)
treebba05a4c3fc787de766a2a7fd35ac36cadc0167f /lib/AST/ASTContext.cpp
parent41be673e93ed225b45479557b20ff19b3082bae8 (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.cpp18
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);
}