[IRBuilder] Add APIs for creating calls to atomic memmove and memset intrinsics. (NFC)

Summary:
Creating the IRBuilder methods:
 CreateElementUnorderedAtomicMemSet
 CreateElementUnorderedAtomicMemMove

These mirror the methods that create calls to the regular (non-atomic) memmove and
memset intrinsics.

llvm-svn: 333588
This commit is contained in:
Daniel Neilson 2018-05-30 20:02:56 +00:00
parent 5105573041
commit 936d50aeea
2 changed files with 119 additions and 0 deletions

View File

@ -414,6 +414,30 @@ public:
MDNode *ScopeTag = nullptr, MDNode *ScopeTag = nullptr,
MDNode *NoAliasTag = 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. /// Create and insert a memcpy between the specified pointers.
/// ///
/// If the pointers aren't i8*, they will be converted. If a TBAA tag is /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
@ -480,6 +504,31 @@ public:
MDNode *ScopeTag = nullptr, MDNode *ScopeTag = nullptr,
MDNode *NoAliasTag = 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. /// Create a vector fadd reduction intrinsic of the source vector.
/// The first parameter is a scalar accumulator value for ordered reductions. /// The first parameter is a scalar accumulator value for ordered reductions.
CallInst *CreateFAddReduce(Value *Acc, Value *Src); CallInst *CreateFAddReduce(Value *Acc, Value *Src);

View File

@ -124,6 +124,36 @@ CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
return CI; 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:: CallInst *IRBuilderBase::
CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
Value *Size, bool isVolatile, MDNode *TBAATag, Value *Size, bool isVolatile, MDNode *TBAATag,
@ -239,6 +269,46 @@ CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
return CI; 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, static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
Value *Src) { Value *Src) {
Module *M = Builder->GetInsertBlock()->getParent()->getParent(); Module *M = Builder->GetInsertBlock()->getParent()->getParent();