LCOV - code coverage report
Current view: top level - lib/IR - IRBuilder.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 201 280 71.8 %
Date: 2017-09-14 15:23:50 Functions: 25 48 52.1 %
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/IR/Function.h"
      17             : #include "llvm/IR/GlobalVariable.h"
      18             : #include "llvm/IR/Intrinsics.h"
      19             : #include "llvm/IR/LLVMContext.h"
      20             : #include "llvm/IR/Statepoint.h"
      21             : using namespace llvm;
      22             : 
      23             : /// CreateGlobalString - Make a new global variable with an initializer that
      24             : /// has array of i8 type filled in with the nul terminated string value
      25             : /// specified.  If Name is specified, it is the name of the global variable
      26             : /// created.
      27       21468 : GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
      28             :                                                   const Twine &Name,
      29             :                                                   unsigned AddressSpace) {
      30       21468 :   Constant *StrConstant = ConstantDataArray::getString(Context, Str);
      31       21468 :   Module &M = *BB->getParent()->getParent();
      32       21468 :   GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
      33             :                                           true, GlobalValue::PrivateLinkage,
      34             :                                           StrConstant, Name, nullptr,
      35             :                                           GlobalVariable::NotThreadLocal,
      36       21468 :                                           AddressSpace);
      37       42936 :   GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
      38       21468 :   return GV;
      39             : }
      40             : 
      41           0 : Type *IRBuilderBase::getCurrentFunctionReturnType() const {
      42             :   assert(BB && BB->getParent() && "No current function!");
      43           0 :   return BB->getParent()->getReturnType();
      44             : }
      45             : 
      46       75817 : Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
      47      151634 :   PointerType *PT = cast<PointerType>(Ptr->getType());
      48       75817 :   if (PT->getElementType()->isIntegerTy(8))
      49             :     return Ptr;
      50             :   
      51             :   // Otherwise, we need to insert a bitcast.
      52       50586 :   PT = getInt8PtrTy(PT->getAddressSpace());
      53       50586 :   BitCastInst *BCI = new BitCastInst(Ptr, PT, "");
      54       50586 :   BB->getInstList().insert(InsertPt, BCI);
      55       25293 :   SetInstDebugLocation(BCI);
      56       25293 :   return BCI;
      57             : }
      58             : 
      59       68605 : static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops,
      60             :                                   IRBuilderBase *Builder,
      61             :                                   const Twine& Name="") {
      62       68605 :   CallInst *CI = CallInst::Create(Callee, Ops, Name);
      63      137210 :   Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
      64       68605 :   Builder->SetInstDebugLocation(CI);
      65       68605 :   return CI;  
      66             : }
      67             : 
      68          16 : static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest,
      69             :                                       BasicBlock *UnwindDest,
      70             :                                       ArrayRef<Value *> Ops,
      71             :                                       IRBuilderBase *Builder,
      72             :                                       const Twine &Name = "") {
      73             :   InvokeInst *II =
      74          16 :       InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name);
      75          32 :   Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),
      76          16 :                                                   II);
      77          16 :   Builder->SetInstDebugLocation(II);
      78          16 :   return II;
      79             : }
      80             : 
      81       22812 : CallInst *IRBuilderBase::
      82             : CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
      83             :              bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
      84             :              MDNode *NoAliasTag) {
      85       22812 :   Ptr = getCastedInt8PtrValue(Ptr);
      86       22812 :   Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) };
      87       22812 :   Type *Tys[] = { Ptr->getType(), Size->getType() };
      88       22812 :   Module *M = BB->getParent()->getParent();
      89       22812 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
      90             :   
      91       45624 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
      92             :   
      93             :   // Set the TBAA info if present.
      94       22812 :   if (TBAATag)
      95           2 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
      96             : 
      97       22812 :   if (ScopeTag)
      98           2 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
      99             :  
     100       22812 :   if (NoAliasTag)
     101           2 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     102             :  
     103       22812 :   return CI;
     104             : }
     105             : 
     106        7861 : CallInst *IRBuilderBase::
     107             : CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
     108             :              bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag,
     109             :              MDNode *ScopeTag, MDNode *NoAliasTag) {
     110        7861 :   Dst = getCastedInt8PtrValue(Dst);
     111        7861 :   Src = getCastedInt8PtrValue(Src);
     112             : 
     113        7861 :   Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
     114        7861 :   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
     115        7861 :   Module *M = BB->getParent()->getParent();
     116        7861 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
     117             :   
     118       15722 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     119             :   
     120             :   // Set the TBAA info if present.
     121        7861 :   if (TBAATag)
     122           8 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     123             : 
     124             :   // Set the TBAA Struct info if present.
     125        7861 :   if (TBAAStructTag)
     126           1 :     CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
     127             :  
     128        7861 :   if (ScopeTag)
     129           8 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     130             :  
     131        7861 :   if (NoAliasTag)
     132           8 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     133             :  
     134        7861 :   return CI;  
     135             : }
     136             : 
     137           7 : CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
     138             :     Value *Dst, Value *Src, Value *Size, uint32_t ElementSize, MDNode *TBAATag,
     139             :     MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
     140           7 :   Dst = getCastedInt8PtrValue(Dst);
     141           7 :   Src = getCastedInt8PtrValue(Src);
     142             : 
     143           7 :   Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
     144           7 :   Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
     145           7 :   Module *M = BB->getParent()->getParent();
     146           7 :   Value *TheFn = Intrinsic::getDeclaration(
     147           7 :       M, Intrinsic::memcpy_element_unordered_atomic, Tys);
     148             : 
     149          14 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     150             : 
     151             :   // Set the TBAA info if present.
     152           7 :   if (TBAATag)
     153           0 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     154             : 
     155             :   // Set the TBAA Struct info if present.
     156           7 :   if (TBAAStructTag)
     157           0 :     CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
     158             : 
     159           7 :   if (ScopeTag)
     160           0 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     161             : 
     162           7 :   if (NoAliasTag)
     163           0 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     164             : 
     165           7 :   return CI;
     166             : }
     167             : 
     168          98 : CallInst *IRBuilderBase::
     169             : CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
     170             :               bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
     171             :               MDNode *NoAliasTag) {
     172          98 :   Dst = getCastedInt8PtrValue(Dst);
     173          98 :   Src = getCastedInt8PtrValue(Src);
     174             :   
     175          98 :   Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
     176          98 :   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
     177          98 :   Module *M = BB->getParent()->getParent();
     178          98 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
     179             :   
     180         196 :   CallInst *CI = createCallHelper(TheFn, Ops, this);
     181             :   
     182             :   // Set the TBAA info if present.
     183          98 :   if (TBAATag)
     184           1 :     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
     185             :  
     186          98 :   if (ScopeTag)
     187           1 :     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
     188             :  
     189          98 :   if (NoAliasTag)
     190           1 :     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
     191             :  
     192          98 :   return CI;  
     193             : }
     194             : 
     195          17 : static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
     196             :                                     Value *Src) {
     197          17 :   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
     198          17 :   Value *Ops[] = {Src};
     199          34 :   Type *Tys[] = { Src->getType()->getVectorElementType(), Src->getType() };
     200          17 :   auto Decl = Intrinsic::getDeclaration(M, ID, Tys);
     201          34 :   return createCallHelper(Decl, Ops, Builder);
     202             : }
     203             : 
     204           0 : CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
     205           0 :   Module *M = GetInsertBlock()->getParent()->getParent();
     206           0 :   Value *Ops[] = {Acc, Src};
     207           0 :   Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
     208           0 :                  Src->getType()};
     209           0 :   auto Decl = Intrinsic::getDeclaration(
     210           0 :       M, Intrinsic::experimental_vector_reduce_fadd, Tys);
     211           0 :   return createCallHelper(Decl, Ops, this);
     212             : }
     213             : 
     214           0 : CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
     215           0 :   Module *M = GetInsertBlock()->getParent()->getParent();
     216           0 :   Value *Ops[] = {Acc, Src};
     217           0 :   Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
     218           0 :                  Src->getType()};
     219           0 :   auto Decl = Intrinsic::getDeclaration(
     220           0 :       M, Intrinsic::experimental_vector_reduce_fmul, Tys);
     221           0 :   return createCallHelper(Decl, Ops, this);
     222             : }
     223             : 
     224          17 : CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
     225             :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_add,
     226          17 :                                Src);
     227             : }
     228             : 
     229           0 : CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
     230             :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_mul,
     231           0 :                                Src);
     232             : }
     233             : 
     234           0 : CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
     235             :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_and,
     236           0 :                                Src);
     237             : }
     238             : 
     239           0 : CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
     240             :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_or,
     241           0 :                                Src);
     242             : }
     243             : 
     244           0 : CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
     245             :   return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_xor,
     246           0 :                                Src);
     247             : }
     248             : 
     249           0 : CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
     250           0 :   auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smax
     251             :                      : Intrinsic::experimental_vector_reduce_umax;
     252           0 :   return getReductionIntrinsic(this, ID, Src);
     253             : }
     254             : 
     255           0 : CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
     256           0 :   auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smin
     257             :                      : Intrinsic::experimental_vector_reduce_umin;
     258           0 :   return getReductionIntrinsic(this, ID, Src);
     259             : }
     260             : 
     261           0 : CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src, bool NoNaN) {
     262             :   auto Rdx = getReductionIntrinsic(
     263           0 :       this, Intrinsic::experimental_vector_reduce_fmax, Src);
     264           0 :   if (NoNaN) {
     265           0 :     FastMathFlags FMF;
     266           0 :     FMF.setNoNaNs();
     267           0 :     Rdx->setFastMathFlags(FMF);
     268             :   }
     269           0 :   return Rdx;
     270             : }
     271             : 
     272           0 : CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src, bool NoNaN) {
     273             :   auto Rdx = getReductionIntrinsic(
     274           0 :       this, Intrinsic::experimental_vector_reduce_fmin, Src);
     275           0 :   if (NoNaN) {
     276           0 :     FastMathFlags FMF;
     277           0 :     FMF.setNoNaNs();
     278           0 :     Rdx->setFastMathFlags(FMF);
     279             :   }
     280           0 :   return Rdx;
     281             : }
     282             : 
     283       16726 : CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
     284             :   assert(isa<PointerType>(Ptr->getType()) &&
     285             :          "lifetime.start only applies to pointers.");
     286       16726 :   Ptr = getCastedInt8PtrValue(Ptr);
     287       16726 :   if (!Size)
     288           2 :     Size = getInt64(-1);
     289             :   else
     290             :     assert(Size->getType() == getInt64Ty() &&
     291             :            "lifetime.start requires the size to be an i64");
     292       16726 :   Value *Ops[] = { Size, Ptr };
     293       16726 :   Module *M = BB->getParent()->getParent();
     294       50178 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start,
     295       33452 :                                            { Ptr->getType() });
     296       33452 :   return createCallHelper(TheFn, Ops, this);
     297             : }
     298             : 
     299       20347 : CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
     300             :   assert(isa<PointerType>(Ptr->getType()) &&
     301             :          "lifetime.end only applies to pointers.");
     302       20347 :   Ptr = getCastedInt8PtrValue(Ptr);
     303       20347 :   if (!Size)
     304           3 :     Size = getInt64(-1);
     305             :   else
     306             :     assert(Size->getType() == getInt64Ty() &&
     307             :            "lifetime.end requires the size to be an i64");
     308       20347 :   Value *Ops[] = { Size, Ptr };
     309       20347 :   Module *M = BB->getParent()->getParent();
     310       61041 :   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end,
     311       40694 :                                            { Ptr->getType() });
     312       40694 :   return createCallHelper(TheFn, Ops, this);
     313             : }
     314             : 
     315           0 : CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
     316             : 
     317             :   assert(isa<PointerType>(Ptr->getType()) &&
     318             :          "invariant.start only applies to pointers.");
     319           0 :   Ptr = getCastedInt8PtrValue(Ptr);
     320           0 :   if (!Size)
     321           0 :     Size = getInt64(-1);
     322             :   else
     323             :     assert(Size->getType() == getInt64Ty() &&
     324             :            "invariant.start requires the size to be an i64");
     325             : 
     326           0 :   Value *Ops[] = {Size, Ptr};
     327             :   // Fill in the single overloaded type: memory object type.
     328           0 :   Type *ObjectPtr[1] = {Ptr->getType()};
     329           0 :   Module *M = BB->getParent()->getParent();
     330             :   Value *TheFn =
     331           0 :       Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr);
     332           0 :   return createCallHelper(TheFn, Ops, this);
     333             : }
     334             : 
     335         146 : CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
     336             :   assert(Cond->getType() == getInt1Ty() &&
     337             :          "an assumption condition must be of type i1");
     338             : 
     339         146 :   Value *Ops[] = { Cond };
     340         146 :   Module *M = BB->getParent()->getParent();
     341         146 :   Value *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
     342         292 :   return createCallHelper(FnAssume, Ops, this);
     343             : }
     344             : 
     345             : /// \brief Create a call to a Masked Load intrinsic.
     346             : /// \p Ptr      - base pointer for the load
     347             : /// \p Align    - alignment of the source location
     348             : /// \p Mask     - vector of booleans which indicates what vector lanes should
     349             : ///               be accessed in memory
     350             : /// \p PassThru - pass-through value that is used to fill the masked-off lanes
     351             : ///               of the result
     352             : /// \p Name     - name of the result variable
     353         242 : CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align,
     354             :                                           Value *Mask, Value *PassThru,
     355             :                                           const Twine &Name) {
     356         484 :   PointerType *PtrTy = cast<PointerType>(Ptr->getType());
     357         242 :   Type *DataTy = PtrTy->getElementType();
     358             :   assert(DataTy->isVectorTy() && "Ptr should point to a vector");
     359             :   assert(Mask && "Mask should not be all-ones (null)");
     360         242 :   if (!PassThru)
     361           0 :     PassThru = UndefValue::get(DataTy);
     362         242 :   Type *OverloadedTypes[] = { DataTy, PtrTy };
     363         242 :   Value *Ops[] = { Ptr, getInt32(Align), Mask,  PassThru};
     364         242 :   return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
     365         726 :                                OverloadedTypes, Name);
     366             : }
     367             : 
     368             : /// \brief Create a call to a Masked Store intrinsic.
     369             : /// \p Val   - data to be stored,
     370             : /// \p Ptr   - base pointer for the store
     371             : /// \p Align - alignment of the destination location
     372             : /// \p Mask  - vector of booleans which indicates what vector lanes should
     373             : ///            be accessed in memory
     374         165 : CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
     375             :                                            unsigned Align, Value *Mask) {
     376         330 :   PointerType *PtrTy = cast<PointerType>(Ptr->getType());
     377         165 :   Type *DataTy = PtrTy->getElementType();
     378             :   assert(DataTy->isVectorTy() && "Ptr should point to a vector");
     379             :   assert(Mask && "Mask should not be all-ones (null)");
     380         165 :   Type *OverloadedTypes[] = { DataTy, PtrTy };
     381         165 :   Value *Ops[] = { Val, Ptr, getInt32(Align), Mask };
     382         495 :   return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
     383             : }
     384             : 
     385             : /// Create a call to a Masked intrinsic, with given intrinsic Id,
     386             : /// an array of operands - Ops, and an array of overloaded types -
     387             : /// OverloadedTypes.
     388         434 : CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
     389             :                                                ArrayRef<Value *> Ops,
     390             :                                                ArrayRef<Type *> OverloadedTypes,
     391             :                                                const Twine &Name) {
     392         434 :   Module *M = BB->getParent()->getParent();
     393         434 :   Value *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
     394         434 :   return createCallHelper(TheFn, Ops, this, Name);
     395             : }
     396             : 
     397             : /// \brief Create a call to a Masked Gather intrinsic.
     398             : /// \p Ptrs     - vector of pointers for loading
     399             : /// \p Align    - alignment for one element
     400             : /// \p Mask     - vector of booleans which indicates what vector lanes should
     401             : ///               be accessed in memory
     402             : /// \p PassThru - pass-through value that is used to fill the masked-off lanes
     403             : ///               of the result
     404             : /// \p Name     - name of the result variable
     405          14 : CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, unsigned Align,
     406             :                                             Value *Mask,  Value *PassThru,
     407             :                                             const Twine& Name) {
     408          28 :   auto PtrsTy = cast<VectorType>(Ptrs->getType());
     409          28 :   auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
     410          28 :   unsigned NumElts = PtrsTy->getVectorNumElements();
     411          14 :   Type *DataTy = VectorType::get(PtrTy->getElementType(), NumElts);
     412             : 
     413          14 :   if (!Mask)
     414           7 :     Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
     415             :                                      NumElts));
     416             : 
     417          14 :   if (!PassThru)
     418          14 :     PassThru = UndefValue::get(DataTy);
     419             : 
     420          14 :   Type *OverloadedTypes[] = {DataTy, PtrsTy};
     421          14 :   Value * Ops[] = {Ptrs, getInt32(Align), Mask, PassThru};
     422             : 
     423             :   // We specify only one type when we create this intrinsic. Types of other
     424             :   // arguments are derived from this type.
     425          14 :   return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, OverloadedTypes,
     426          42 :                                Name);
     427             : }
     428             : 
     429             : /// \brief Create a call to a Masked Scatter intrinsic.
     430             : /// \p Data  - data to be stored,
     431             : /// \p Ptrs  - the vector of pointers, where the \p Data elements should be
     432             : ///            stored
     433             : /// \p Align - alignment for one element
     434             : /// \p Mask  - vector of booleans which indicates what vector lanes should
     435             : ///            be accessed in memory
     436          13 : CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
     437             :                                              unsigned Align, Value *Mask) {
     438          26 :   auto PtrsTy = cast<VectorType>(Ptrs->getType());
     439          26 :   auto DataTy = cast<VectorType>(Data->getType());
     440          26 :   unsigned NumElts = PtrsTy->getVectorNumElements();
     441             : 
     442             : #ifndef NDEBUG
     443             :   auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
     444             :   assert(NumElts == DataTy->getVectorNumElements() &&
     445             :          PtrTy->getElementType() == DataTy->getElementType() &&
     446             :          "Incompatible pointer and data types");
     447             : #endif
     448             : 
     449          13 :   if (!Mask)
     450           3 :     Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
     451             :                                      NumElts));
     452             : 
     453          13 :   Type *OverloadedTypes[] = {DataTy, PtrsTy};
     454          13 :   Value * Ops[] = {Data, Ptrs, getInt32(Align), Mask};
     455             : 
     456             :   // We specify only one type when we create this intrinsic. Types of other
     457             :   // arguments are derived from this type.
     458          39 :   return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
     459             : }
     460             : 
     461             : template <typename T0, typename T1, typename T2, typename T3>
     462             : static std::vector<Value *>
     463         146 : getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
     464             :                   Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
     465             :                   ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs,
     466             :                   ArrayRef<T3> GCArgs) {
     467         146 :   std::vector<Value *> Args;
     468         292 :   Args.push_back(B.getInt64(ID));
     469         292 :   Args.push_back(B.getInt32(NumPatchBytes));
     470         146 :   Args.push_back(ActualCallee);
     471         292 :   Args.push_back(B.getInt32(CallArgs.size()));
     472         292 :   Args.push_back(B.getInt32(Flags));
     473         584 :   Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
     474         292 :   Args.push_back(B.getInt32(TransitionArgs.size()));
     475         584 :   Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end());
     476         292 :   Args.push_back(B.getInt32(DeoptArgs.size()));
     477         584 :   Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
     478         584 :   Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
     479             : 
     480         146 :   return Args;
     481             : }
     482             : 
     483             : template <typename T0, typename T1, typename T2, typename T3>
     484         130 : static CallInst *CreateGCStatepointCallCommon(
     485             :     IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
     486             :     Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
     487             :     ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs,
     488             :     const Twine &Name) {
     489             :   // Extract out the type of the callee.
     490         260 :   PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
     491             :   assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
     492             :          "actual callee must be a callable value");
     493             : 
     494         130 :   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
     495             :   // Fill in the one generic type'd argument (the function is also vararg)
     496         130 :   Type *ArgTypes[] = { FuncPtrType };
     497         130 :   Function *FnStatepoint =
     498         260 :     Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
     499             :                               ArgTypes);
     500             : 
     501         260 :   std::vector<llvm::Value *> Args =
     502             :       getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
     503             :                         CallArgs, TransitionArgs, DeoptArgs, GCArgs);
     504         260 :   return createCallHelper(FnStatepoint, Args, Builder, Name);
     505             : }
     506             : 
     507           0 : CallInst *IRBuilderBase::CreateGCStatepointCall(
     508             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
     509             :     ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
     510             :     ArrayRef<Value *> GCArgs, const Twine &Name) {
     511           0 :   return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
     512             :       this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
     513           0 :       CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
     514             : }
     515             : 
     516         130 : CallInst *IRBuilderBase::CreateGCStatepointCall(
     517             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
     518             :     ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs,
     519             :     ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
     520             :   return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
     521             :       this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
     522         130 :       DeoptArgs, GCArgs, Name);
     523             : }
     524             : 
     525           0 : CallInst *IRBuilderBase::CreateGCStatepointCall(
     526             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
     527             :     ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
     528             :     ArrayRef<Value *> GCArgs, const Twine &Name) {
     529           0 :   return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
     530             :       this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
     531           0 :       CallArgs, None, DeoptArgs, GCArgs, Name);
     532             : }
     533             : 
     534             : template <typename T0, typename T1, typename T2, typename T3>
     535          16 : static InvokeInst *CreateGCStatepointInvokeCommon(
     536             :     IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
     537             :     Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
     538             :     uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs,
     539             :     ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) {
     540             :   // Extract out the type of the callee.
     541          32 :   PointerType *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
     542             :   assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
     543             :          "actual callee must be a callable value");
     544             : 
     545          16 :   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
     546             :   // Fill in the one generic type'd argument (the function is also vararg)
     547          32 :   Function *FnStatepoint = Intrinsic::getDeclaration(
     548             :       M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
     549             : 
     550          32 :   std::vector<llvm::Value *> Args =
     551             :       getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
     552             :                         InvokeArgs, TransitionArgs, DeoptArgs, GCArgs);
     553          32 :   return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder,
     554          32 :                             Name);
     555             : }
     556             : 
     557           0 : InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
     558             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
     559             :     BasicBlock *NormalDest, BasicBlock *UnwindDest,
     560             :     ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
     561             :     ArrayRef<Value *> GCArgs, const Twine &Name) {
     562           0 :   return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
     563             :       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
     564             :       uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
     565           0 :       DeoptArgs, GCArgs, Name);
     566             : }
     567             : 
     568          16 : InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
     569             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
     570             :     BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
     571             :     ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
     572             :     ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
     573             :   return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
     574             :       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
     575          16 :       InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
     576             : }
     577             : 
     578           0 : InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
     579             :     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
     580             :     BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
     581             :     ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
     582           0 :   return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
     583             :       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
     584             :       uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
     585           0 :       Name);
     586             : }
     587             : 
     588          15 : CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
     589             :                                        Type *ResultType,
     590             :                                        const Twine &Name) {
     591          15 :  Intrinsic::ID ID = Intrinsic::experimental_gc_result;
     592          15 :  Module *M = BB->getParent()->getParent();
     593          15 :  Type *Types[] = {ResultType};
     594          15 :  Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
     595             : 
     596          15 :  Value *Args[] = {Statepoint};
     597          15 :  return createCallHelper(FnGCResult, Args, this, Name);
     598             : }
     599             : 
     600           0 : CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
     601             :                                          int BaseOffset,
     602             :                                          int DerivedOffset,
     603             :                                          Type *ResultType,
     604             :                                          const Twine &Name) {
     605           0 :  Module *M = BB->getParent()->getParent();
     606           0 :  Type *Types[] = {ResultType};
     607             :  Value *FnGCRelocate =
     608           0 :    Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
     609             : 
     610             :  Value *Args[] = {Statepoint,
     611           0 :                   getInt32(BaseOffset),
     612           0 :                   getInt32(DerivedOffset)};
     613           0 :  return createCallHelper(FnGCRelocate, Args, this, Name);
     614             : }
     615             : 
     616          12 : CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID,
     617             :                                                Value *LHS, Value *RHS,
     618             :                                                const Twine &Name) {
     619          12 :   Module *M = BB->getParent()->getParent();
     620          24 :   Function *Fn =  Intrinsic::getDeclaration(M, ID, { LHS->getType() });
     621          24 :   return createCallHelper(Fn, { LHS, RHS }, this, Name);
     622             : }

Generated by: LCOV version 1.13