OLD | NEW |
1 //===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// | 1 //===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This contains code to emit Builtin calls as LLVM code. | 10 // This contains code to emit Builtin calls as LLVM code. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "CodeGenFunction.h" | 14 #include "CodeGenFunction.h" |
15 #include "CGObjCRuntime.h" | 15 #include "CGObjCRuntime.h" |
16 #include "CodeGenModule.h" | 16 #include "CodeGenModule.h" |
17 #include "TargetInfo.h" | 17 #include "TargetInfo.h" |
18 #include "clang/AST/ASTContext.h" | 18 #include "clang/AST/ASTContext.h" |
19 #include "clang/AST/Decl.h" | 19 #include "clang/AST/Decl.h" |
20 #include "clang/Basic/TargetBuiltins.h" | 20 #include "clang/Basic/TargetBuiltins.h" |
21 #include "clang/Basic/TargetInfo.h" | 21 #include "clang/Basic/TargetInfo.h" |
22 #include "clang/CodeGen/CGFunctionInfo.h" | 22 #include "clang/CodeGen/CGFunctionInfo.h" |
23 #include "llvm/IR/DataLayout.h" | 23 #include "llvm/IR/DataLayout.h" |
| 24 #include "llvm/IR/InlineAsm.h" // @LOCALMOD |
24 #include "llvm/IR/Intrinsics.h" | 25 #include "llvm/IR/Intrinsics.h" |
25 | 26 |
26 using namespace clang; | 27 using namespace clang; |
27 using namespace CodeGen; | 28 using namespace CodeGen; |
28 using namespace llvm; | 29 using namespace llvm; |
29 | 30 |
30 /// getBuiltinLibFunction - Given a builtin id for a function like | 31 /// getBuiltinLibFunction - Given a builtin id for a function like |
31 /// "__builtin_fabsf", return a Function* for "fabsf". | 32 /// "__builtin_fabsf", return a Function* for "fabsf". |
32 llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, | 33 llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, |
33 unsigned BuiltinID) { | 34 unsigned BuiltinID) { |
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 } | 1085 } |
1085 | 1086 |
1086 case Builtin::BI__sync_synchronize: { | 1087 case Builtin::BI__sync_synchronize: { |
1087 // We assume this is supposed to correspond to a C++0x-style | 1088 // We assume this is supposed to correspond to a C++0x-style |
1088 // sequentially-consistent fence (i.e. this is only usable for | 1089 // sequentially-consistent fence (i.e. this is only usable for |
1089 // synchonization, not device I/O or anything like that). This intrinsic | 1090 // synchonization, not device I/O or anything like that). This intrinsic |
1090 // is really badly designed in the sense that in theory, there isn't | 1091 // is really badly designed in the sense that in theory, there isn't |
1091 // any way to safely use it... but in practice, it mostly works | 1092 // any way to safely use it... but in practice, it mostly works |
1092 // to use it with non-atomic loads and stores to get acquire/release | 1093 // to use it with non-atomic loads and stores to get acquire/release |
1093 // semantics. | 1094 // semantics. |
1094 Builder.CreateFence(llvm::SequentiallyConsistent); | 1095 // @LOCALMOD-START |
| 1096 // Targets can ask that ``__sync_synchronize()`` be surrounded with |
| 1097 // compiler fences. This should enforce ordering of more than just |
| 1098 // atomic memory accesses, though it won't guarantee that all |
| 1099 // accesses (e.g. those to non-escaping objects) won't be reordered. |
| 1100 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); |
| 1101 std::string AsmString; // Empty. |
| 1102 std::string Constraints("~{memory}"); |
| 1103 bool HasSideEffect = true; |
| 1104 if (getTargetHooks().addAsmMemoryAroundSyncSynchronize()) { |
| 1105 Builder.CreateCall( |
| 1106 llvm::InlineAsm::get(FTy, AsmString, Constraints, HasSideEffect))-> |
| 1107 addAttribute(llvm::AttributeSet::FunctionIndex, |
| 1108 llvm::Attribute::NoUnwind); |
| 1109 Builder.CreateFence(llvm::SequentiallyConsistent); |
| 1110 Builder.CreateCall( |
| 1111 llvm::InlineAsm::get(FTy, AsmString, Constraints, HasSideEffect))-> |
| 1112 addAttribute(llvm::AttributeSet::FunctionIndex, |
| 1113 llvm::Attribute::NoUnwind); |
| 1114 } else { |
| 1115 Builder.CreateFence(llvm::SequentiallyConsistent); |
| 1116 } |
| 1117 // @LOCALMOD-END |
1095 return RValue::get(nullptr); | 1118 return RValue::get(nullptr); |
1096 } | 1119 } |
1097 | 1120 |
1098 case Builtin::BI__c11_atomic_is_lock_free: | 1121 case Builtin::BI__c11_atomic_is_lock_free: |
1099 case Builtin::BI__atomic_is_lock_free: { | 1122 case Builtin::BI__atomic_is_lock_free: { |
1100 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the | 1123 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the |
1101 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since | 1124 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since |
1102 // _Atomic(T) is always properly-aligned. | 1125 // _Atomic(T) is always properly-aligned. |
1103 const char *LibCallName = "__atomic_is_lock_free"; | 1126 const char *LibCallName = "__atomic_is_lock_free"; |
1104 CallArgList Args; | 1127 CallArgList Args; |
(...skipping 5106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6211 case R600::BI__builtin_amdgpu_rsq_clamped: | 6234 case R600::BI__builtin_amdgpu_rsq_clamped: |
6212 case R600::BI__builtin_amdgpu_rsq_clampedf: | 6235 case R600::BI__builtin_amdgpu_rsq_clampedf: |
6213 return emitUnaryFPBuiltin(*this, E, Intrinsic::AMDGPU_rsq_clamped); | 6236 return emitUnaryFPBuiltin(*this, E, Intrinsic::AMDGPU_rsq_clamped); |
6214 case R600::BI__builtin_amdgpu_ldexp: | 6237 case R600::BI__builtin_amdgpu_ldexp: |
6215 case R600::BI__builtin_amdgpu_ldexpf: | 6238 case R600::BI__builtin_amdgpu_ldexpf: |
6216 return emitFPIntBuiltin(*this, E, Intrinsic::AMDGPU_ldexp); | 6239 return emitFPIntBuiltin(*this, E, Intrinsic::AMDGPU_ldexp); |
6217 default: | 6240 default: |
6218 return nullptr; | 6241 return nullptr; |
6219 } | 6242 } |
6220 } | 6243 } |
OLD | NEW |