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

Generated by: LCOV version 1.13