aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorJF Bastien <jfb@chromium.org>2013-08-01 15:06:01 -0700
committerJF Bastien <jfb@chromium.org>2013-08-01 15:06:01 -0700
commita7665e96f34c4a981d59c78b0b872b8f0b100cb9 (patch)
treeaa05a7a1f915980654ae61c5a2f5952abfc7e561 /lib/Analysis
parentb9657234ee8b1951db5977a8ffb55a2e5df6d76c (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.cpp32
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyModule.cpp2
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);