diff options
author | JF Bastien <jfb@chromium.org> | 2013-08-01 15:06:01 -0700 |
---|---|---|
committer | JF Bastien <jfb@chromium.org> | 2013-08-01 15:06:01 -0700 |
commit | a7665e96f34c4a981d59c78b0b872b8f0b100cb9 (patch) | |
tree | aa05a7a1f915980654ae61c5a2f5952abfc7e561 /lib/Analysis | |
parent | b9657234ee8b1951db5977a8ffb55a2e5df6d76c (diff) |
Add Intrinsic::nacl_atomic_is_lock_free
This is part of a bigger CL to fix C++11 in PNaCl, to commit in the following order:
- https://codereview.chromium.org/20552002
- https://codereview.chromium.org/20554002
- https://codereview.chromium.org/20560002
- https://codereview.chromium.org/20561002
This should be the last PNaCl ABI change for C11/C+11 atomic support.
Note that Clang already has a builtin for lock-free, but it's partly resolved by Clang's ExprConstant.cpp and CGBuiltin.cpp, whereas what we want is a call that becomes a constant at translation-time. I made the translation part fairly general so it's easy to support architectures where ``true`` isn't always the right answer.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3475
TEST= ./scons run_synchronization_cpp11_test --verbose bitcode=1 platform=x86-64
TEST= ninja check-all
R=dschuff@chromium.org
Review URL: https://codereview.chromium.org/20554002
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp | 32 | ||||
-rw-r--r-- | lib/Analysis/NaCl/PNaClABIVerifyModule.cpp | 2 |
2 files changed, 30 insertions, 4 deletions
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp index 5318fc8af0..e55a9f0df4 100644 --- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp +++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp @@ -213,6 +213,24 @@ static bool hasAllowedAtomicMemoryOrder( return true; } +static bool hasAllowedLockFreeByteSize(const CallInst *Call) { + if (!Call->getType()->isIntegerTy()) + return false; + const Value *Operation = Call->getOperand(0); + if (!Operation) + return false; + const Constant *C = dyn_cast<Constant>(Operation); + if (!C) + return false; + const APInt &I = C->getUniqueInteger(); + // PNaCl currently only supports atomics of byte size {1,2,4,8} (which + // may or may not be lock-free). These values coincide with + // C11/C++11's supported atomic types. + if (I == 1 || I == 2 || I == 4 || I == 8) + return true; + return false; +} + // Check the instruction's opcode and its operands. The operands may // require opcode-specific checking. // @@ -392,11 +410,11 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) { } } - // Disallow NaCl atomic intrinsics which don't have valid - // constant NaCl::AtomicOperation and NaCl::MemoryOrder - // parameters. switch (Call->getIntrinsicID()) { - default: break; // Non-atomic intrinsic. + default: break; // Other intrinsics don't require checks. + // Disallow NaCl atomic intrinsics which don't have valid + // constant NaCl::AtomicOperation and NaCl::MemoryOrder + // parameters. case Intrinsic::nacl_atomic_load: case Intrinsic::nacl_atomic_store: case Intrinsic::nacl_atomic_rmw: @@ -413,6 +431,12 @@ const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) { if (!hasAllowedAtomicRMWOperation(I, Call)) return "invalid atomicRMW operation"; } break; + // Disallow NaCl atomic_is_lock_free intrinsics which don't + // have valid constant size type. + case Intrinsic::nacl_atomic_is_lock_free: + if (!hasAllowedLockFreeByteSize(Call)) + return "invalid atomic lock-free byte size"; + break; } // Allow the instruction and skip the later checks. diff --git a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp index f1359866bd..e781680f3f 100644 --- a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp +++ b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp @@ -215,6 +215,8 @@ AllowedIntrinsics::AllowedIntrinsics(LLVMContext *Context) : Context(Context) { } addIntrinsic(Intrinsic::nacl_atomic_fence); + addIntrinsic(Intrinsic::nacl_atomic_is_lock_free); + // Stack save and restore are used to support C99 VLAs. addIntrinsic(Intrinsic::stacksave); addIntrinsic(Intrinsic::stackrestore); |