diff options
author | Daniel Neilson <dneilson@azul.com> | 2018-05-30 20:02:56 +0000 |
---|---|---|
committer | Daniel Neilson <dneilson@azul.com> | 2018-05-30 20:02:56 +0000 |
commit | e33ce2953b9fb9e55c379dc64b88af2626d77292 (patch) | |
tree | 39a57112c94a85f49e0c1233b5755465ce768a80 | |
parent | 9c6a07cc6f531e5f5b2ba7522b558ba904c6ebe7 (diff) |
[IRBuilder] Add APIs for creating calls to atomic memmove and memset intrinsics. (NFC)linaro-local/sanitizer
Summary:
Creating the IRBuilder methods:
CreateElementUnorderedAtomicMemSet
CreateElementUnorderedAtomicMemMove
These mirror the methods that create calls to the regular (non-atomic) memmove and
memset intrinsics.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333588 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/IR/IRBuilder.h | 49 | ||||
-rw-r--r-- | lib/IR/IRBuilder.cpp | 70 |
2 files changed, 119 insertions, 0 deletions
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index f9bb3a983be..056b8625fa5 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -414,6 +414,30 @@ public: MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); + /// Create and insert an element unordered-atomic memset of the region of + /// memory starting at the given pointer to the given value. + /// + /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is + /// specified, it will be added to the instruction. Likewise with alias.scope + /// and noalias tags. + CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, + uint64_t Size, unsigned Align, + uint32_t ElementSize, + MDNode *TBAATag = nullptr, + MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr) { + return CreateElementUnorderedAtomicMemSet(Ptr, Val, getInt64(Size), Align, + ElementSize, TBAATag, ScopeTag, + NoAliasTag); + } + + CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val, + Value *Size, unsigned Align, + uint32_t ElementSize, + MDNode *TBAATag = nullptr, + MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr); + /// Create and insert a memcpy between the specified pointers. /// /// If the pointers aren't i8*, they will be converted. If a TBAA tag is @@ -480,6 +504,31 @@ public: MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr); + /// \brief Create and insert an element unordered-atomic memmove between the + /// specified pointers. + /// + /// DstAlign/SrcAlign are the alignments of the Dst/Src pointers, + /// respectively. + /// + /// If the pointers aren't i8*, they will be converted. If a TBAA tag is + /// specified, it will be added to the instruction. Likewise with alias.scope + /// and noalias tags. + CallInst *CreateElementUnorderedAtomicMemMove( + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, + uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr, + MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr) { + return CreateElementUnorderedAtomicMemMove( + Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag, + TBAAStructTag, ScopeTag, NoAliasTag); + } + + CallInst *CreateElementUnorderedAtomicMemMove( + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, + uint32_t ElementSize, MDNode *TBAATag = nullptr, + MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr, + MDNode *NoAliasTag = nullptr); + /// Create a vector fadd reduction intrinsic of the source vector. /// The first parameter is a scalar accumulator value for ordered reductions. CallInst *CreateFAddReduce(Value *Acc, Value *Src); diff --git a/lib/IR/IRBuilder.cpp b/lib/IR/IRBuilder.cpp index f80be2d1b72..b6df7b530a9 100644 --- a/lib/IR/IRBuilder.cpp +++ b/lib/IR/IRBuilder.cpp @@ -124,6 +124,36 @@ CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, return CI; } +CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet( + Value *Ptr, Value *Val, Value *Size, unsigned Align, uint32_t ElementSize, + MDNode *TBAATag, MDNode *ScopeTag, MDNode *NoAliasTag) { + assert(Align >= ElementSize && + "Pointer alignment must be at least element size."); + + Ptr = getCastedInt8PtrValue(Ptr); + Value *Ops[] = {Ptr, Val, Size, getInt32(ElementSize)}; + Type *Tys[] = {Ptr->getType(), Size->getType()}; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration( + M, Intrinsic::memset_element_unordered_atomic, Tys); + + CallInst *CI = createCallHelper(TheFn, Ops, this); + + cast<AtomicMemSetInst>(CI)->setDestAlignment(Align); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + if (ScopeTag) + CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag); + + if (NoAliasTag) + CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag); + + return CI; +} + CallInst *IRBuilderBase:: CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, bool isVolatile, MDNode *TBAATag, @@ -239,6 +269,46 @@ CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, return CI; } +CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove( + Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size, + uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag, + MDNode *ScopeTag, MDNode *NoAliasTag) { + assert(DstAlign >= ElementSize && + "Pointer alignment must be at least element size"); + assert(SrcAlign >= ElementSize && + "Pointer alignment must be at least element size"); + Dst = getCastedInt8PtrValue(Dst); + Src = getCastedInt8PtrValue(Src); + + Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)}; + Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()}; + Module *M = BB->getParent()->getParent(); + Value *TheFn = Intrinsic::getDeclaration( + M, Intrinsic::memmove_element_unordered_atomic, Tys); + + CallInst *CI = createCallHelper(TheFn, Ops, this); + + // Set the alignment of the pointer args. + CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), DstAlign)); + CI->addParamAttr(1, Attribute::getWithAlignment(CI->getContext(), SrcAlign)); + + // Set the TBAA info if present. + if (TBAATag) + CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); + + // Set the TBAA Struct info if present. + if (TBAAStructTag) + CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag); + + if (ScopeTag) + CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag); + + if (NoAliasTag) + CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag); + + return CI; +} + static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID, Value *Src) { Module *M = Builder->GetInsertBlock()->getParent()->getParent(); |