LCOV - code coverage report
Current view: top level - lib/IR - IRBuilder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 241 400 60.2 %
Date: 2018-10-20 13:21:21 Functions: 27 52 51.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- IRBuilder.cpp - Builder for LLVM Instrs ----------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file implements the IRBuilder class, which is used as a convenient way
      11             : // to create LLVM instructions with a consistent and simplified interface.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "llvm/IR/IRBuilder.h"
      16             : #include "llvm/ADT/ArrayRef.h"
      17             : #include "llvm/ADT/None.h"
      18             : #include "llvm/IR/Constant.h"
      19             : #include "llvm/IR/Constants.h"
      20             : #include "llvm/IR/DerivedTypes.h"
      21             : #include "llvm/IR/Function.h"
      22             : #include "llvm/IR/GlobalValue.h"
      23             : #include "llvm/IR/GlobalVariable.h"
      24             : #include "llvm/IR/IntrinsicInst.h"
      25             : #include "llvm/IR/Intrinsics.h"
      26             : #include "llvm/IR/LLVMContext.h"
      27             : #include "llvm/IR/Operator.h"
      28             : #include "llvm/IR/Statepoint.h"
      29             : #include "llvm/IR/Type.h"
      30             : #include "llvm/IR/Value.h"
      31             : #include "llvm/Support/Casting.h"
      32             : #include "llvm/Support/MathExtras.h"
      33             : #include <cassert>
      34             : #include <cstdint>
      35             : #include <vector>
      36             : 
      37             : using namespace llvm;
      38             : 
      39             : /// CreateGlobalString - Make a new global variable with an initializer that
      40             : /// has array of i8 type filled in with the nul terminated string value
      41             : /// specified.  If Name is specified, it is the name of the global variable
      42             : /// created.
      43       25359 : GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
      44             :                                                   const Twine &Name,
      45             :                                                   unsigned AddressSpace) {
      46       25359 :   Constant *StrConstant = ConstantDataArray::getString(Context, Str);
      47       25359 :   Module &M = *BB->getParent()->getParent();
      48       25359 :   auto *GV = new GlobalVariable(M, StrConstant->getType(), true,
      49             :                                 GlobalValue::PrivateLinkage, StrConstant, Name,
      50             :                                 nullptr, GlobalVariable::NotThreadLocal,
      51       25359 :                                 AddressSpace);
      52             :   GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
      53       25359 :   GV->setAlignment(1);
      54       25359 :   return GV;
      55             : }
      56             : 
      57           0 : Type *IRBuilderBase::getCurrentFunctionReturnType() const {
      58             :   assert(BB && BB->getParent() && "No current function!");
      59           0 :   return BB->getParent()->getReturnType();
      60             : }
      61             : 
      62      410399 : Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
      63      410399 :   auto *PT = cast<PointerType>(Ptr->getType());
      64      410399 :   if (PT->getElementType()->isIntegerTy(8))
      65             :     return Ptr;
      66             : 
      67             :   // Otherwise, we need to insert a bitcast.
      68       31047 :   PT = getInt8PtrTy(PT->getAddressSpace());
      69       31047 :   BitCastInst *BCI = new BitCastInst(Ptr, PT, "");
      70       31047 :   BB->getInstList().insert(InsertPt, BCI);
      71       31047 :   SetInstDebugLocation(BCI);
      72       31047 :   return BCI;
      73             : }
      74             : 
      75      265807 : static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops,
      76             :                                   IRBuilderBase *Builder,
      77             :                                   const Twine &Name = "",
      78             :                                   Instruction *FMFSource = nullptr) {
      79      265807 :   CallInst *CI = CallInst::Create(Callee, Ops, Name);
      80      265807 :   if (FMFSource)
      81         530 :     CI->copyFastMathFlags(FMFSource);
      82      265807 :   Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
      83      265807 :   Builder->SetInstDebugLocation(CI);
      84      265807 :   return CI;
      85             : }
      86             : 
      87          34 : static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest,
      88             :                                       BasicBlock *UnwindDest,
      89             :                                       ArrayRef<Value *> Ops,
      90             :                                       IRBuilderBase *Builder,
      91             :                                       const Twine &Name = "") {
      92             :   InvokeInst *II =
      93          34 :       InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name);
      94          34 :   Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),
      95          34 :                                                   II);
      96          34 :   Builder->SetInstDebugLocation(II);
      97          34 :   return II;
      98             : }
      99             : 
     100       32830 : CallInst *IRBuilderBase::
     101             : CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
     102             :              bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
     103             :              MDNode *NoAliasTag) {
     104       32830 :   Ptr = getCastedInt8PtrValue(Ptr);
     105       32830 :   Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
     106       32830 :   Type *Tys[] = { Ptr->getType(), Size->getType() };
     107       32830 :   Module *M = BB->getParent()->getParent();
     108       32830 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
     109             : 
     110       32830 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     111             : 
     112       32830 :   if (Align > 0)
     113       32821 :     cast<MemSetInst>(CI)->setDestAlignment(Align);
     114             : 
     115             :   // Set the TBAA info if present.
     116       32830 :   if (TBAATag)
     117           2 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     118             : 
     119       32830 :   if (ScopeTag)
     120           2 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     121             : 
     122       32830 :   if (NoAliasTag)
     123           2 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     124             : 
     125       32830 :   return CI;
     126             : }
     127             : 
     128           0 : CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet(
     129             :     Value *Ptr, Value *Val, Value *Size, unsigned Align, uint32_t ElementSize,
     130             :     MDNode *TBAATag, MDNode *ScopeTag, MDNode *NoAliasTag) {
     131             :   assert(Align >= ElementSize &&
     132             :          "Pointer alignment must be at least element size.");
     133             : 
     134           0 :   Ptr = getCastedInt8PtrValue(Ptr);
     135           0 :   Value *Ops[] = {Ptr, Val, Size, getInt32(ElementSize)};
     136           0 :   Type *Tys[] = {Ptr->getType(), Size->getType()};
     137           0 :   Module *M = BB->getParent()->getParent();
     138           0 :   Value *TheFn = Intrinsic::getDeclaration(
     139             :       M, Intrinsic::memset_element_unordered_atomic, Tys);
     140             : 
     141           0 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     142             : 
     143           0 :   cast<AtomicMemSetInst>(CI)->setDestAlignment(Align);
     144             : 
     145             :   // Set the TBAA info if present.
     146           0 :   if (TBAATag)
     147           0 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     148             : 
     149           0 :   if (ScopeTag)
     150           0 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     151             : 
     152           0 :   if (NoAliasTag)
     153           0 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     154             : 
     155           0 :   return CI;
     156             : }
     157             : 
     158      161241 : CallInst *IRBuilderBase::
     159             : CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
     160             :              Value *Size, bool isVolatile, MDNode *TBAATag,
     161             :              MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
     162             :   assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2");
     163             :   assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2");
     164      161241 :   Dst = getCastedInt8PtrValue(Dst);
     165      161241 :   Src = getCastedInt8PtrValue(Src);
     166             : 
     167      161241 :   Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
     168      161241 :   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
     169      161241 :   Module *M = BB->getParent()->getParent();
     170      161241 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
     171             : 
     172      161241 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     173             : 
     174             :   auto* MCI = cast<MemCpyInst>(CI);
     175      161241 :   if (DstAlign > 0)
     176      161240 :     MCI->setDestAlignment(DstAlign);
     177      161241 :   if (SrcAlign > 0)
     178      161238 :     MCI->setSourceAlignment(SrcAlign);
     179             : 
     180             :   // Set the TBAA info if present.
     181      161241 :   if (TBAATag)
     182           8 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     183             : 
     184             :   // Set the TBAA Struct info if present.
     185      161241 :   if (TBAAStructTag)
     186           1 :     CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
     187             : 
     188      161241 :   if (ScopeTag)
     189           8 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     190             : 
     191      161241 :   if (NoAliasTag)
     192           8 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     193             : 
     194      161241 :   return CI;
     195             : }
     196             : 
     197           7 : CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
     198             :     Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size,
     199             :     uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
     200             :     MDNode *ScopeTag, MDNode *NoAliasTag) {
     201             :   assert(DstAlign >= ElementSize &&
     202             :          "Pointer alignment must be at least element size");
     203             :   assert(SrcAlign >= ElementSize &&
     204             :          "Pointer alignment must be at least element size");
     205           7 :   Dst = getCastedInt8PtrValue(Dst);
     206           7 :   Src = getCastedInt8PtrValue(Src);
     207             : 
     208           7 :   Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
     209           7 :   Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
     210           7 :   Module *M = BB->getParent()->getParent();
     211           7 :   Value *TheFn = Intrinsic::getDeclaration(
     212             :       M, Intrinsic::memcpy_element_unordered_atomic, Tys);
     213             : 
     214           7 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     215             : 
     216             :   // Set the alignment of the pointer args.
     217             :   auto *AMCI = cast<AtomicMemCpyInst>(CI);
     218           7 :   AMCI->setDestAlignment(DstAlign);
     219           7 :   AMCI->setSourceAlignment(SrcAlign);
     220             : 
     221             :   // Set the TBAA info if present.
     222           7 :   if (TBAATag)
     223           0 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     224             : 
     225             :   // Set the TBAA Struct info if present.
     226           7 :   if (TBAAStructTag)
     227           0 :     CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
     228             : 
     229           7 :   if (ScopeTag)
     230           0 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     231             : 
     232           7 :   if (NoAliasTag)
     233           0 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     234             : 
     235           7 :   return CI;
     236             : }
     237             : 
     238        1128 : CallInst *IRBuilderBase::
     239             : CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
     240             :               Value *Size, bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
     241             :               MDNode *NoAliasTag) {
     242             :   assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2");
     243             :   assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2");
     244        1128 :   Dst = getCastedInt8PtrValue(Dst);
     245        1128 :   Src = getCastedInt8PtrValue(Src);
     246             : 
     247        1128 :   Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
     248        1128 :   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
     249        1128 :   Module *M = BB->getParent()->getParent();
     250        1128 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
     251             : 
     252        1128 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     253             : 
     254             :   auto *MMI = cast<MemMoveInst>(CI);
     255        1128 :   if (DstAlign > 0)
     256        1127 :     MMI->setDestAlignment(DstAlign);
     257        1128 :   if (SrcAlign > 0)
     258        1127 :     MMI->setSourceAlignment(SrcAlign);
     259             : 
     260             :   // Set the TBAA info if present.
     261        1128 :   if (TBAATag)
     262           1 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     263             : 
     264        1128 :   if (ScopeTag)
     265           1 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     266             : 
     267        1128 :   if (NoAliasTag)
     268           1 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     269             : 
     270        1128 :   return CI;
     271             : }
     272             : 
     273           0 : CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove(
     274             :     Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size,
     275             :     uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
     276             :     MDNode *ScopeTag, MDNode *NoAliasTag) {
     277             :   assert(DstAlign >= ElementSize &&
     278             :          "Pointer alignment must be at least element size");
     279             :   assert(SrcAlign >= ElementSize &&
     280             :          "Pointer alignment must be at least element size");
     281           0 :   Dst = getCastedInt8PtrValue(Dst);
     282           0 :   Src = getCastedInt8PtrValue(Src);
     283             : 
     284           0 :   Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
     285           0 :   Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
     286           0 :   Module *M = BB->getParent()->getParent();
     287           0 :   Value *TheFn = Intrinsic::getDeclaration(
     288             :       M, Intrinsic::memmove_element_unordered_atomic, Tys);
     289             : 
     290           0 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     291             : 
     292             :   // Set the alignment of the pointer args.
     293           0 :   CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), DstAlign));
     294           0 :   CI->addParamAttr(1, Attribute::getWithAlignment(CI->getContext(), SrcAlign));
     295             : 
     296             :   // Set the TBAA info if present.
     297           0 :   if (TBAATag)
     298           0 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     299             : 
     300             :   // Set the TBAA Struct info if present.
     301           0 :   if (TBAAStructTag)
     302           0 :     CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
     303             : 
     304           0 :   if (ScopeTag)
     305           0 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     306             : 
     307           0 :   if (NoAliasTag)
     308           0 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     309             : 
     310           0 :   return CI;
     311             : }
     312             : 
     313          20 : static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
     314             :                                     Value *Src) {
     315          20 :   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
     316          20 :   Value *Ops[] = {Src};
     317          40 :   Type *Tys[] = { Src->getType()->getVectorElementType(), Src->getType() };
     318          20 :   auto Decl = Intrinsic::getDeclaration(M, ID, Tys);
     319          20 :   return createCallHelper(Decl, Ops, Builder);
     320             : }
     321             : 
     322           0 : CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
     323           0 :   Module *M = GetInsertBlock()->getParent()->getParent();
     324           0 :   Value *Ops[] = {Acc, Src};
     325           0 :   Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
     326           0 :                  Src->getType()};
     327           0 :   auto Decl = Intrinsic::getDeclaration(
     328             :       M, Intrinsic::experimental_vector_reduce_fadd, Tys);
     329           0 :   return createCallHelper(Decl, Ops, this);
     330             : }
     331             : 
     332           0 : CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
     333           0 :   Module *M = GetInsertBlock()->getParent()->getParent();
     334           0 :   Value *Ops[] = {Acc, Src};
     335           0 :   Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
     336           0 :                  Src->getType()};
     337           0 :   auto Decl = Intrinsic::getDeclaration(
     338             :       M, Intrinsic::experimental_vector_reduce_fmul, Tys);
     339           0 :   return createCallHelper(Decl, Ops, this);
     340             : }
     341             : 
     342          20 : CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
     343          20 :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_add,
     344          20 :                                Src);
     345             : }
     346             : 
     347           0 : CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
     348           0 :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_mul,
     349           0 :                                Src);
     350             : }
     351             : 
     352           0 : CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
     353           0 :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_and,
     354           0 :                                Src);
     355             : }
     356             : 
     357           0 : CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
     358           0 :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_or,
     359           0 :                                Src);
     360             : }
     361             : 
     362           0 : CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
     363           0 :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_xor,
     364           0 :                                Src);
     365             : }
     366             : 
     367           0 : CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
     368           0 :   auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smax
     369             :                      : Intrinsic::experimental_vector_reduce_umax;
     370           0 :   return getReductionIntrinsic(this, ID, Src);
     371             : }
     372             : 
     373           0 : CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
     374           0 :   auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smin
     375             :                      : Intrinsic::experimental_vector_reduce_umin;
     376           0 :   return getReductionIntrinsic(this, ID, Src);
     377             : }
     378             : 
     379           0 : CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src, bool NoNaN) {
     380           0 :   auto Rdx = getReductionIntrinsic(
     381             :       this, Intrinsic::experimental_vector_reduce_fmax, Src);
     382           0 :   if (NoNaN) {
     383             :     FastMathFlags FMF;
     384             :     FMF.setNoNaNs();
     385           0 :     Rdx->setFastMathFlags(FMF);
     386             :   }
     387           0 :   return Rdx;
     388             : }
     389             : 
     390           0 : CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src, bool NoNaN) {
     391           0 :   auto Rdx = getReductionIntrinsic(
     392             :       this, Intrinsic::experimental_vector_reduce_fmin, Src);
     393           0 :   if (NoNaN) {
     394             :     FastMathFlags FMF;
     395             :     FMF.setNoNaNs();
     396           0 :     Rdx->setFastMathFlags(FMF);
     397             :   }
     398           0 :   return Rdx;
     399             : }
     400             : 
     401       23524 : CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
     402             :   assert(isa<PointerType>(Ptr->getType()) &&
     403             :          "lifetime.start only applies to pointers.");
     404       23524 :   Ptr = getCastedInt8PtrValue(Ptr);
     405       23524 :   if (!Size)
     406           2 :     Size = getInt64(-1);
     407             :   else
     408             :     assert(Size->getType() == getInt64Ty() &&
     409             :            "lifetime.start requires the size to be an i64");
     410       23524 :   Value *Ops[] = { Size, Ptr };
     411       23524 :   Module *M = BB->getParent()->getParent();
     412       23524 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start,
     413       23524 :                                            { Ptr->getType() });
     414       23524 :   return createCallHelper(TheFn, Ops, this);
     415             : }
     416             : 
     417       29293 : CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
     418             :   assert(isa<PointerType>(Ptr->getType()) &&
     419             :          "lifetime.end only applies to pointers.");
     420       29293 :   Ptr = getCastedInt8PtrValue(Ptr);
     421       29293 :   if (!Size)
     422           3 :     Size = getInt64(-1);
     423             :   else
     424             :     assert(Size->getType() == getInt64Ty() &&
     425             :            "lifetime.end requires the size to be an i64");
     426       29293 :   Value *Ops[] = { Size, Ptr };
     427       29293 :   Module *M = BB->getParent()->getParent();
     428       29293 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end,
     429       29293 :                                            { Ptr->getType() });
     430       29293 :   return createCallHelper(TheFn, Ops, this);
     431             : }
     432             : 
     433           0 : CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
     434             : 
     435             :   assert(isa<PointerType>(Ptr->getType()) &&
     436             :          "invariant.start only applies to pointers.");
     437           0 :   Ptr = getCastedInt8PtrValue(Ptr);
     438           0 :   if (!Size)
     439           0 :     Size = getInt64(-1);
     440             :   else
     441             :     assert(Size->getType() == getInt64Ty() &&
     442             :            "invariant.start requires the size to be an i64");
     443             : 
     444           0 :   Value *Ops[] = {Size, Ptr};
     445             :   // Fill in the single overloaded type: memory object type.
     446           0 :   Type *ObjectPtr[1] = {Ptr->getType()};
     447           0 :   Module *M = BB->getParent()->getParent();
     448             :   Value *TheFn =
     449           0 :       Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr);
     450           0 :   return createCallHelper(TheFn, Ops, this);
     451             : }
     452             : 
     453         391 : CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
     454             :   assert(Cond->getType() == getInt1Ty() &&
     455             :          "an assumption condition must be of type i1");
     456             : 
     457         391 :   Value *Ops[] = { Cond };
     458         391 :   Module *M = BB->getParent()->getParent();
     459         391 :   Value *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
     460         391 :   return createCallHelper(FnAssume, Ops, this);
     461             : }
     462             : 
     463             : /// Create a call to a Masked Load intrinsic.
     464             : /// \p Ptr      - base pointer for the load
     465             : /// \p Align    - alignment of the source location
     466             : /// \p Mask     - vector of booleans which indicates what vector lanes should
     467             : ///               be accessed in memory
     468             : /// \p PassThru - pass-through value that is used to fill the masked-off lanes
     469             : ///               of the result
     470             : /// \p Name     - name of the result variable
     471         295 : CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align,
     472             :                                           Value *Mask, Value *PassThru,
     473             :                                           const Twine &Name) {
     474         295 :   auto *PtrTy = cast<PointerType>(Ptr->getType());
     475         295 :   Type *DataTy = PtrTy->getElementType();
     476             :   assert(DataTy->isVectorTy() && "Ptr should point to a vector");
     477             :   assert(Mask && "Mask should not be all-ones (null)");
     478         295 :   if (!PassThru)
     479           0 :     PassThru = UndefValue::get(DataTy);
     480         295 :   Type *OverloadedTypes[] = { DataTy, PtrTy };
     481         295 :   Value *Ops[] = { Ptr, getInt32(Align), Mask,  PassThru};
     482         295 :   return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
     483         295 :                                OverloadedTypes, Name);
     484             : }
     485             : 
     486             : /// Create a call to a Masked Store intrinsic.
     487             : /// \p Val   - data to be stored,
     488             : /// \p Ptr   - base pointer for the store
     489             : /// \p Align - alignment of the destination location
     490             : /// \p Mask  - vector of booleans which indicates what vector lanes should
     491             : ///            be accessed in memory
     492         201 : CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
     493             :                                            unsigned Align, Value *Mask) {
     494         201 :   auto *PtrTy = cast<PointerType>(Ptr->getType());
     495         201 :   Type *DataTy = PtrTy->getElementType();
     496             :   assert(DataTy->isVectorTy() && "Ptr should point to a vector");
     497             :   assert(Mask && "Mask should not be all-ones (null)");
     498         201 :   Type *OverloadedTypes[] = { DataTy, PtrTy };
     499         201 :   Value *Ops[] = { Val, Ptr, getInt32(Align), Mask };
     500         201 :   return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
     501             : }
     502             : 
     503             : /// Create a call to a Masked intrinsic, with given intrinsic Id,
     504             : /// an array of operands - Ops, and an array of overloaded types -
     505             : /// OverloadedTypes.
     506         576 : CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
     507             :                                                ArrayRef<Value *> Ops,
     508             :                                                ArrayRef<Type *> OverloadedTypes,
     509             :                                                const Twine &Name) {
     510         576 :   Module *M = BB->getParent()->getParent();
     511         576 :   Value *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
     512         576 :   return createCallHelper(TheFn, Ops, this, Name);
     513             : }
     514             : 
     515             : /// Create a call to a Masked Gather intrinsic.
     516             : /// \p Ptrs     - vector of pointers for loading
     517             : /// \p Align    - alignment for one element
     518             : /// \p Mask     - vector of booleans which indicates what vector lanes should
     519             : ///               be accessed in memory
     520             : /// \p PassThru - pass-through value that is used to fill the masked-off lanes
     521             : ///               of the result
     522             : /// \p Name     - name of the result variable
     523          61 : CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, unsigned Align,
     524             :                                             Value *Mask,  Value *PassThru,
     525             :                                             const Twine& Name) {
     526          61 :   auto PtrsTy = cast<VectorType>(Ptrs->getType());
     527          61 :   auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
     528             :   unsigned NumElts = PtrsTy->getVectorNumElements();
     529          61 :   Type *DataTy = VectorType::get(PtrTy->getElementType(), NumElts);
     530             : 
     531          61 :   if (!Mask)
     532          29 :     Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
     533             :                                      NumElts));
     534             : 
     535          61 :   if (!PassThru)
     536          61 :     PassThru = UndefValue::get(DataTy);
     537             : 
     538          61 :   Type *OverloadedTypes[] = {DataTy, PtrsTy};
     539          61 :   Value * Ops[] = {Ptrs, getInt32(Align), Mask, PassThru};
     540             : 
     541             :   // We specify only one type when we create this intrinsic. Types of other
     542             :   // arguments are derived from this type.
     543          61 :   return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, OverloadedTypes,
     544          61 :                                Name);
     545             : }
     546             : 
     547             : /// Create a call to a Masked Scatter intrinsic.
     548             : /// \p Data  - data to be stored,
     549             : /// \p Ptrs  - the vector of pointers, where the \p Data elements should be
     550             : ///            stored
     551             : /// \p Align - alignment for one element
     552             : /// \p Mask  - vector of booleans which indicates what vector lanes should
     553             : ///            be accessed in memory
     554          19 : CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
     555             :                                              unsigned Align, Value *Mask) {
     556          19 :   auto PtrsTy = cast<VectorType>(Ptrs->getType());
     557          19 :   auto DataTy = cast<VectorType>(Data->getType());
     558             :   unsigned NumElts = PtrsTy->getVectorNumElements();
     559             : 
     560             : #ifndef NDEBUG
     561             :   auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
     562             :   assert(NumElts == DataTy->getVectorNumElements() &&
     563             :          PtrTy->getElementType() == DataTy->getElementType() &&
     564             :          "Incompatible pointer and data types");
     565             : #endif
     566             : 
     567          19 :   if (!Mask)
     568           7 :     Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
     569             :                                      NumElts));
     570             : 
     571          19 :   Type *OverloadedTypes[] = {DataTy, PtrsTy};
     572          19 :   Value * Ops[] = {Data, Ptrs, getInt32(Align), Mask};
     573             : 
     574             :   // We specify only one type when we create this intrinsic. Types of other
     575             :   // arguments are derived from this type.
     576          19 :   return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
     577             : }
     578             : 
     579             : template <typename T0, typename T1, typename T2, typename T3>
     580             : static std::vector<Value *>
     581         312 : getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
     582             :                   Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
     583             :                   ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs,
     584             :                   ArrayRef<T3> GCArgs) {
     585             :   std::vector<Value *> Args;
     586         312 :   Args.push_back(B.getInt64(ID));
     587         312 :   Args.push_back(B.getInt32(NumPatchBytes));
     588         312 :   Args.push_back(ActualCallee);
     589         312 :   Args.push_back(B.getInt32(CallArgs.size()));
     590         312 :   Args.push_back(B.getInt32(Flags));
     591             :   Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
     592         312 :   Args.push_back(B.getInt32(TransitionArgs.size()));
     593             :   Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end());
     594         312 :   Args.push_back(B.getInt32(DeoptArgs.size()));
     595             :   Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
     596         312 :   Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
     597             : 
     598         312 :   return Args;
     599             : }
     600           0 : 
     601             : template <typename T0, typename T1, typename T2, typename T3>
     602             : static CallInst *CreateGCStatepointCallCommon(
     603             :     IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
     604             :     Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
     605           0 :     ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs,
     606           0 :     const Twine &Name) {
     607           0 :   // Extract out the type of the callee.
     608           0 :   auto *FuncPtrType = cast<PointerType>(ActualCallee->getType());
     609           0 :   assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
     610             :          "actual callee must be a callable value");
     611           0 : 
     612             :   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
     613           0 :   // Fill in the one generic type'd argument (the function is also vararg)
     614             :   Type *ArgTypes[] = { FuncPtrType };
     615           0 :   Function *FnStatepoint =
     616             :     Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
     617           0 :                               ArgTypes);
     618             : 
     619         312 :   std::vector<Value *> Args =
     620             :       getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
     621             :                         CallArgs, TransitionArgs, DeoptArgs, GCArgs);
     622             :   return createCallHelper(FnStatepoint, Args, Builder, Name);
     623             : }
     624         312 : 
     625         312 : CallInst *IRBuilderBase::CreateGCStatepointCall(
     626         312 :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
     627         312 :     ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
     628         312 :     ArrayRef<Value *> GCArgs, const Twine &Name) {
     629             :   return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
     630         312 :       this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
     631             :       CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
     632         312 : }
     633             : 
     634         312 : CallInst *IRBuilderBase::CreateGCStatepointCall(
     635             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
     636         312 :     ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs,
     637             :     ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
     638           0 :   return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
     639             :       this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
     640             :       DeoptArgs, GCArgs, Name);
     641             : }
     642             : 
     643           0 : CallInst *IRBuilderBase::CreateGCStatepointCall(
     644           0 :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
     645           0 :     ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
     646           0 :     ArrayRef<Value *> GCArgs, const Twine &Name) {
     647           0 :   return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
     648             :       this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
     649           0 :       CallArgs, None, DeoptArgs, GCArgs, Name);
     650             : }
     651           0 : 
     652             : template <typename T0, typename T1, typename T2, typename T3>
     653           0 : static InvokeInst *CreateGCStatepointInvokeCommon(
     654             :     IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
     655           0 :     Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
     656             :     uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs,
     657             :     ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) {
     658             :   // Extract out the type of the callee.
     659         278 :   auto *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
     660             :   assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
     661             :          "actual callee must be a callable value");
     662             : 
     663             :   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
     664             :   // Fill in the one generic type'd argument (the function is also vararg)
     665         278 :   Function *FnStatepoint = Intrinsic::getDeclaration(
     666             :       M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
     667             : 
     668             :   std::vector<Value *> Args =
     669         278 :       getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
     670             :                         InvokeArgs, TransitionArgs, DeoptArgs, GCArgs);
     671         278 :   return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder,
     672             :                             Name);
     673         278 : }
     674             : 
     675             : InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
     676         278 :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
     677             :     BasicBlock *NormalDest, BasicBlock *UnwindDest,
     678             :     ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
     679         278 :     ArrayRef<Value *> GCArgs, const Twine &Name) {
     680             :   return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
     681           0 :       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
     682             :       uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
     683             :       DeoptArgs, GCArgs, Name);
     684             : }
     685             : 
     686             : InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
     687           0 :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
     688             :     BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
     689             :     ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
     690             :     ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
     691           0 :   return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
     692             :       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
     693           0 :       InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
     694             : }
     695           0 : 
     696             : InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
     697             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
     698           0 :     BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
     699             :     ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
     700             :   return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
     701           0 :       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
     702             :       uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
     703         278 :       Name);
     704             : }
     705             : 
     706             : CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
     707             :                                        Type *ResultType,
     708             :                                        const Twine &Name) {
     709         278 :  Intrinsic::ID ID = Intrinsic::experimental_gc_result;
     710             :  Module *M = BB->getParent()->getParent();
     711             :  Type *Types[] = {ResultType};
     712             :  Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
     713         278 : 
     714             :  Value *Args[] = {Statepoint};
     715         278 :  return createCallHelper(FnGCResult, Args, this, Name);
     716             : }
     717         278 : 
     718             : CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
     719             :                                          int BaseOffset,
     720         278 :                                          int DerivedOffset,
     721             :                                          Type *ResultType,
     722             :                                          const Twine &Name) {
     723         278 :  Module *M = BB->getParent()->getParent();
     724             :  Type *Types[] = {ResultType};
     725           0 :  Value *FnGCRelocate =
     726             :    Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
     727             : 
     728             :  Value *Args[] = {Statepoint,
     729             :                   getInt32(BaseOffset),
     730             :                   getInt32(DerivedOffset)};
     731           0 :  return createCallHelper(FnGCRelocate, Args, this, Name);
     732             : }
     733             : 
     734             : CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
     735           0 :                                               Instruction *FMFSource,
     736             :                                               const Twine &Name) {
     737           0 :   Module *M = BB->getModule();
     738             :   Function *Fn = Intrinsic::getDeclaration(M, ID, {V->getType()});
     739           0 :   return createCallHelper(Fn, {V}, this, Name, FMFSource);
     740             : }
     741             : 
     742           0 : CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
     743             :                                                Value *RHS,
     744             :                                                Instruction *FMFSource,
     745           0 :                                                const Twine &Name) {
     746             :   Module *M = BB->getModule();
     747             :   Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
     748           0 :   return createCallHelper(Fn, {LHS, RHS}, this, Name, FMFSource);
     749             : }
     750             : 
     751             : CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
     752           0 :                                          ArrayRef<Type *> Types,
     753             :                                          ArrayRef<Value *> Args,
     754           0 :                                          Instruction *FMFSource,
     755             :                                          const Twine &Name) {
     756             :   Module *M = BB->getModule();
     757         278 :   Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
     758             :   return createCallHelper(Fn, Args, this, Name, FMFSource);
     759             : }

Generated by: LCOV version 1.13