xref: /aosp_15_r20/external/llvm/lib/IR/IRBuilder.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===---- IRBuilder.cpp - Builder for LLVM Instrs -------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the IRBuilder class, which is used as a convenient way
11*9880d681SAndroid Build Coastguard Worker // to create LLVM instructions with a consistent and simplified interface.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Statepoint.h"
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker /// CreateGlobalString - Make a new global variable with an initializer that
24*9880d681SAndroid Build Coastguard Worker /// has array of i8 type filled in with the nul terminated string value
25*9880d681SAndroid Build Coastguard Worker /// specified.  If Name is specified, it is the name of the global variable
26*9880d681SAndroid Build Coastguard Worker /// created.
CreateGlobalString(StringRef Str,const Twine & Name,unsigned AddressSpace)27*9880d681SAndroid Build Coastguard Worker GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
28*9880d681SAndroid Build Coastguard Worker                                                   const Twine &Name,
29*9880d681SAndroid Build Coastguard Worker                                                   unsigned AddressSpace) {
30*9880d681SAndroid Build Coastguard Worker   Constant *StrConstant = ConstantDataArray::getString(Context, Str);
31*9880d681SAndroid Build Coastguard Worker   Module &M = *BB->getParent()->getParent();
32*9880d681SAndroid Build Coastguard Worker   GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
33*9880d681SAndroid Build Coastguard Worker                                           true, GlobalValue::PrivateLinkage,
34*9880d681SAndroid Build Coastguard Worker                                           StrConstant, Name, nullptr,
35*9880d681SAndroid Build Coastguard Worker                                           GlobalVariable::NotThreadLocal,
36*9880d681SAndroid Build Coastguard Worker                                           AddressSpace);
37*9880d681SAndroid Build Coastguard Worker   GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
38*9880d681SAndroid Build Coastguard Worker   return GV;
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker 
getCurrentFunctionReturnType() const41*9880d681SAndroid Build Coastguard Worker Type *IRBuilderBase::getCurrentFunctionReturnType() const {
42*9880d681SAndroid Build Coastguard Worker   assert(BB && BB->getParent() && "No current function!");
43*9880d681SAndroid Build Coastguard Worker   return BB->getParent()->getReturnType();
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker 
getCastedInt8PtrValue(Value * Ptr)46*9880d681SAndroid Build Coastguard Worker Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
47*9880d681SAndroid Build Coastguard Worker   PointerType *PT = cast<PointerType>(Ptr->getType());
48*9880d681SAndroid Build Coastguard Worker   if (PT->getElementType()->isIntegerTy(8))
49*9880d681SAndroid Build Coastguard Worker     return Ptr;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   // Otherwise, we need to insert a bitcast.
52*9880d681SAndroid Build Coastguard Worker   PT = getInt8PtrTy(PT->getAddressSpace());
53*9880d681SAndroid Build Coastguard Worker   BitCastInst *BCI = new BitCastInst(Ptr, PT, "");
54*9880d681SAndroid Build Coastguard Worker   BB->getInstList().insert(InsertPt, BCI);
55*9880d681SAndroid Build Coastguard Worker   SetInstDebugLocation(BCI);
56*9880d681SAndroid Build Coastguard Worker   return BCI;
57*9880d681SAndroid Build Coastguard Worker }
58*9880d681SAndroid Build Coastguard Worker 
createCallHelper(Value * Callee,ArrayRef<Value * > Ops,IRBuilderBase * Builder,const Twine & Name="")59*9880d681SAndroid Build Coastguard Worker static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops,
60*9880d681SAndroid Build Coastguard Worker                                   IRBuilderBase *Builder,
61*9880d681SAndroid Build Coastguard Worker                                   const Twine& Name="") {
62*9880d681SAndroid Build Coastguard Worker   CallInst *CI = CallInst::Create(Callee, Ops, Name);
63*9880d681SAndroid Build Coastguard Worker   Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
64*9880d681SAndroid Build Coastguard Worker   Builder->SetInstDebugLocation(CI);
65*9880d681SAndroid Build Coastguard Worker   return CI;
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker 
createInvokeHelper(Value * Invokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,ArrayRef<Value * > Ops,IRBuilderBase * Builder,const Twine & Name="")68*9880d681SAndroid Build Coastguard Worker static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest,
69*9880d681SAndroid Build Coastguard Worker                                       BasicBlock *UnwindDest,
70*9880d681SAndroid Build Coastguard Worker                                       ArrayRef<Value *> Ops,
71*9880d681SAndroid Build Coastguard Worker                                       IRBuilderBase *Builder,
72*9880d681SAndroid Build Coastguard Worker                                       const Twine &Name = "") {
73*9880d681SAndroid Build Coastguard Worker   InvokeInst *II =
74*9880d681SAndroid Build Coastguard Worker       InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name);
75*9880d681SAndroid Build Coastguard Worker   Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),
76*9880d681SAndroid Build Coastguard Worker                                                   II);
77*9880d681SAndroid Build Coastguard Worker   Builder->SetInstDebugLocation(II);
78*9880d681SAndroid Build Coastguard Worker   return II;
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::
CreateMemSet(Value * Ptr,Value * Val,Value * Size,unsigned Align,bool isVolatile,MDNode * TBAATag,MDNode * ScopeTag,MDNode * NoAliasTag)82*9880d681SAndroid Build Coastguard Worker CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
83*9880d681SAndroid Build Coastguard Worker              bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
84*9880d681SAndroid Build Coastguard Worker              MDNode *NoAliasTag) {
85*9880d681SAndroid Build Coastguard Worker   Ptr = getCastedInt8PtrValue(Ptr);
86*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) };
87*9880d681SAndroid Build Coastguard Worker   Type *Tys[] = { Ptr->getType(), Size->getType() };
88*9880d681SAndroid Build Coastguard Worker   Module *M = BB->getParent()->getParent();
89*9880d681SAndroid Build Coastguard Worker   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker   CallInst *CI = createCallHelper(TheFn, Ops, this);
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker   // Set the TBAA info if present.
94*9880d681SAndroid Build Coastguard Worker   if (TBAATag)
95*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
96*9880d681SAndroid Build Coastguard Worker 
97*9880d681SAndroid Build Coastguard Worker   if (ScopeTag)
98*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   if (NoAliasTag)
101*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker   return CI;
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::
CreateMemCpy(Value * Dst,Value * Src,Value * Size,unsigned Align,bool isVolatile,MDNode * TBAATag,MDNode * TBAAStructTag,MDNode * ScopeTag,MDNode * NoAliasTag)107*9880d681SAndroid Build Coastguard Worker CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
108*9880d681SAndroid Build Coastguard Worker              bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag,
109*9880d681SAndroid Build Coastguard Worker              MDNode *ScopeTag, MDNode *NoAliasTag) {
110*9880d681SAndroid Build Coastguard Worker   Dst = getCastedInt8PtrValue(Dst);
111*9880d681SAndroid Build Coastguard Worker   Src = getCastedInt8PtrValue(Src);
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
114*9880d681SAndroid Build Coastguard Worker   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
115*9880d681SAndroid Build Coastguard Worker   Module *M = BB->getParent()->getParent();
116*9880d681SAndroid Build Coastguard Worker   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker   CallInst *CI = createCallHelper(TheFn, Ops, this);
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker   // Set the TBAA info if present.
121*9880d681SAndroid Build Coastguard Worker   if (TBAATag)
122*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   // Set the TBAA Struct info if present.
125*9880d681SAndroid Build Coastguard Worker   if (TBAAStructTag)
126*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   if (ScopeTag)
129*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   if (NoAliasTag)
132*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
133*9880d681SAndroid Build Coastguard Worker 
134*9880d681SAndroid Build Coastguard Worker   return CI;
135*9880d681SAndroid Build Coastguard Worker }
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::
CreateMemMove(Value * Dst,Value * Src,Value * Size,unsigned Align,bool isVolatile,MDNode * TBAATag,MDNode * ScopeTag,MDNode * NoAliasTag)138*9880d681SAndroid Build Coastguard Worker CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
139*9880d681SAndroid Build Coastguard Worker               bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
140*9880d681SAndroid Build Coastguard Worker               MDNode *NoAliasTag) {
141*9880d681SAndroid Build Coastguard Worker   Dst = getCastedInt8PtrValue(Dst);
142*9880d681SAndroid Build Coastguard Worker   Src = getCastedInt8PtrValue(Src);
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
145*9880d681SAndroid Build Coastguard Worker   Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
146*9880d681SAndroid Build Coastguard Worker   Module *M = BB->getParent()->getParent();
147*9880d681SAndroid Build Coastguard Worker   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   CallInst *CI = createCallHelper(TheFn, Ops, this);
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker   // Set the TBAA info if present.
152*9880d681SAndroid Build Coastguard Worker   if (TBAATag)
153*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker   if (ScopeTag)
156*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   if (NoAliasTag)
159*9880d681SAndroid Build Coastguard Worker     CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker   return CI;
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker 
CreateLifetimeStart(Value * Ptr,ConstantInt * Size)164*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
165*9880d681SAndroid Build Coastguard Worker   assert(isa<PointerType>(Ptr->getType()) &&
166*9880d681SAndroid Build Coastguard Worker          "lifetime.start only applies to pointers.");
167*9880d681SAndroid Build Coastguard Worker   Ptr = getCastedInt8PtrValue(Ptr);
168*9880d681SAndroid Build Coastguard Worker   if (!Size)
169*9880d681SAndroid Build Coastguard Worker     Size = getInt64(-1);
170*9880d681SAndroid Build Coastguard Worker   else
171*9880d681SAndroid Build Coastguard Worker     assert(Size->getType() == getInt64Ty() &&
172*9880d681SAndroid Build Coastguard Worker            "lifetime.start requires the size to be an i64");
173*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Size, Ptr };
174*9880d681SAndroid Build Coastguard Worker   Module *M = BB->getParent()->getParent();
175*9880d681SAndroid Build Coastguard Worker   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start);
176*9880d681SAndroid Build Coastguard Worker   return createCallHelper(TheFn, Ops, this);
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
CreateLifetimeEnd(Value * Ptr,ConstantInt * Size)179*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
180*9880d681SAndroid Build Coastguard Worker   assert(isa<PointerType>(Ptr->getType()) &&
181*9880d681SAndroid Build Coastguard Worker          "lifetime.end only applies to pointers.");
182*9880d681SAndroid Build Coastguard Worker   Ptr = getCastedInt8PtrValue(Ptr);
183*9880d681SAndroid Build Coastguard Worker   if (!Size)
184*9880d681SAndroid Build Coastguard Worker     Size = getInt64(-1);
185*9880d681SAndroid Build Coastguard Worker   else
186*9880d681SAndroid Build Coastguard Worker     assert(Size->getType() == getInt64Ty() &&
187*9880d681SAndroid Build Coastguard Worker            "lifetime.end requires the size to be an i64");
188*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Size, Ptr };
189*9880d681SAndroid Build Coastguard Worker   Module *M = BB->getParent()->getParent();
190*9880d681SAndroid Build Coastguard Worker   Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end);
191*9880d681SAndroid Build Coastguard Worker   return createCallHelper(TheFn, Ops, this);
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker 
CreateAssumption(Value * Cond)194*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
195*9880d681SAndroid Build Coastguard Worker   assert(Cond->getType() == getInt1Ty() &&
196*9880d681SAndroid Build Coastguard Worker          "an assumption condition must be of type i1");
197*9880d681SAndroid Build Coastguard Worker 
198*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Cond };
199*9880d681SAndroid Build Coastguard Worker   Module *M = BB->getParent()->getParent();
200*9880d681SAndroid Build Coastguard Worker   Value *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
201*9880d681SAndroid Build Coastguard Worker   return createCallHelper(FnAssume, Ops, this);
202*9880d681SAndroid Build Coastguard Worker }
203*9880d681SAndroid Build Coastguard Worker 
204*9880d681SAndroid Build Coastguard Worker /// \brief Create a call to a Masked Load intrinsic.
205*9880d681SAndroid Build Coastguard Worker /// \p Ptr      - base pointer for the load
206*9880d681SAndroid Build Coastguard Worker /// \p Align    - alignment of the source location
207*9880d681SAndroid Build Coastguard Worker /// \p Mask     - vector of booleans which indicates what vector lanes should
208*9880d681SAndroid Build Coastguard Worker ///               be accessed in memory
209*9880d681SAndroid Build Coastguard Worker /// \p PassThru - pass-through value that is used to fill the masked-off lanes
210*9880d681SAndroid Build Coastguard Worker ///               of the result
211*9880d681SAndroid Build Coastguard Worker /// \p Name     - name of the result variable
CreateMaskedLoad(Value * Ptr,unsigned Align,Value * Mask,Value * PassThru,const Twine & Name)212*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align,
213*9880d681SAndroid Build Coastguard Worker                                           Value *Mask, Value *PassThru,
214*9880d681SAndroid Build Coastguard Worker                                           const Twine &Name) {
215*9880d681SAndroid Build Coastguard Worker   PointerType *PtrTy = cast<PointerType>(Ptr->getType());
216*9880d681SAndroid Build Coastguard Worker   Type *DataTy = PtrTy->getElementType();
217*9880d681SAndroid Build Coastguard Worker   assert(DataTy->isVectorTy() && "Ptr should point to a vector");
218*9880d681SAndroid Build Coastguard Worker   if (!PassThru)
219*9880d681SAndroid Build Coastguard Worker     PassThru = UndefValue::get(DataTy);
220*9880d681SAndroid Build Coastguard Worker   Type *OverloadedTypes[] = { DataTy, PtrTy };
221*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Ptr, getInt32(Align), Mask,  PassThru};
222*9880d681SAndroid Build Coastguard Worker   return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
223*9880d681SAndroid Build Coastguard Worker                                OverloadedTypes, Name);
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker /// \brief Create a call to a Masked Store intrinsic.
227*9880d681SAndroid Build Coastguard Worker /// \p Val   - data to be stored,
228*9880d681SAndroid Build Coastguard Worker /// \p Ptr   - base pointer for the store
229*9880d681SAndroid Build Coastguard Worker /// \p Align - alignment of the destination location
230*9880d681SAndroid Build Coastguard Worker /// \p Mask  - vector of booleans which indicates what vector lanes should
231*9880d681SAndroid Build Coastguard Worker ///            be accessed in memory
CreateMaskedStore(Value * Val,Value * Ptr,unsigned Align,Value * Mask)232*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
233*9880d681SAndroid Build Coastguard Worker                                            unsigned Align, Value *Mask) {
234*9880d681SAndroid Build Coastguard Worker   PointerType *PtrTy = cast<PointerType>(Ptr->getType());
235*9880d681SAndroid Build Coastguard Worker   Type *DataTy = PtrTy->getElementType();
236*9880d681SAndroid Build Coastguard Worker   assert(DataTy->isVectorTy() && "Ptr should point to a vector");
237*9880d681SAndroid Build Coastguard Worker   Type *OverloadedTypes[] = { DataTy, PtrTy };
238*9880d681SAndroid Build Coastguard Worker   Value *Ops[] = { Val, Ptr, getInt32(Align), Mask };
239*9880d681SAndroid Build Coastguard Worker   return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
240*9880d681SAndroid Build Coastguard Worker }
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker /// Create a call to a Masked intrinsic, with given intrinsic Id,
243*9880d681SAndroid Build Coastguard Worker /// an array of operands - Ops, and an array of overloaded types -
244*9880d681SAndroid Build Coastguard Worker /// OverloadedTypes.
CreateMaskedIntrinsic(Intrinsic::ID Id,ArrayRef<Value * > Ops,ArrayRef<Type * > OverloadedTypes,const Twine & Name)245*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
246*9880d681SAndroid Build Coastguard Worker                                                ArrayRef<Value *> Ops,
247*9880d681SAndroid Build Coastguard Worker                                                ArrayRef<Type *> OverloadedTypes,
248*9880d681SAndroid Build Coastguard Worker                                                const Twine &Name) {
249*9880d681SAndroid Build Coastguard Worker   Module *M = BB->getParent()->getParent();
250*9880d681SAndroid Build Coastguard Worker   Value *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
251*9880d681SAndroid Build Coastguard Worker   return createCallHelper(TheFn, Ops, this, Name);
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker /// \brief Create a call to a Masked Gather intrinsic.
255*9880d681SAndroid Build Coastguard Worker /// \p Ptrs     - vector of pointers for loading
256*9880d681SAndroid Build Coastguard Worker /// \p Align    - alignment for one element
257*9880d681SAndroid Build Coastguard Worker /// \p Mask     - vector of booleans which indicates what vector lanes should
258*9880d681SAndroid Build Coastguard Worker ///               be accessed in memory
259*9880d681SAndroid Build Coastguard Worker /// \p PassThru - pass-through value that is used to fill the masked-off lanes
260*9880d681SAndroid Build Coastguard Worker ///               of the result
261*9880d681SAndroid Build Coastguard Worker /// \p Name     - name of the result variable
CreateMaskedGather(Value * Ptrs,unsigned Align,Value * Mask,Value * PassThru,const Twine & Name)262*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, unsigned Align,
263*9880d681SAndroid Build Coastguard Worker                                             Value *Mask,  Value *PassThru,
264*9880d681SAndroid Build Coastguard Worker                                             const Twine& Name) {
265*9880d681SAndroid Build Coastguard Worker   auto PtrsTy = cast<VectorType>(Ptrs->getType());
266*9880d681SAndroid Build Coastguard Worker   auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
267*9880d681SAndroid Build Coastguard Worker   unsigned NumElts = PtrsTy->getVectorNumElements();
268*9880d681SAndroid Build Coastguard Worker   Type *DataTy = VectorType::get(PtrTy->getElementType(), NumElts);
269*9880d681SAndroid Build Coastguard Worker 
270*9880d681SAndroid Build Coastguard Worker   if (!Mask)
271*9880d681SAndroid Build Coastguard Worker     Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
272*9880d681SAndroid Build Coastguard Worker                                      NumElts));
273*9880d681SAndroid Build Coastguard Worker 
274*9880d681SAndroid Build Coastguard Worker   Value * Ops[] = {Ptrs, getInt32(Align), Mask, UndefValue::get(DataTy)};
275*9880d681SAndroid Build Coastguard Worker 
276*9880d681SAndroid Build Coastguard Worker   // We specify only one type when we create this intrinsic. Types of other
277*9880d681SAndroid Build Coastguard Worker   // arguments are derived from this type.
278*9880d681SAndroid Build Coastguard Worker   return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, { DataTy }, Name);
279*9880d681SAndroid Build Coastguard Worker }
280*9880d681SAndroid Build Coastguard Worker 
281*9880d681SAndroid Build Coastguard Worker /// \brief Create a call to a Masked Scatter intrinsic.
282*9880d681SAndroid Build Coastguard Worker /// \p Data  - data to be stored,
283*9880d681SAndroid Build Coastguard Worker /// \p Ptrs  - the vector of pointers, where the \p Data elements should be
284*9880d681SAndroid Build Coastguard Worker ///            stored
285*9880d681SAndroid Build Coastguard Worker /// \p Align - alignment for one element
286*9880d681SAndroid Build Coastguard Worker /// \p Mask  - vector of booleans which indicates what vector lanes should
287*9880d681SAndroid Build Coastguard Worker ///            be accessed in memory
CreateMaskedScatter(Value * Data,Value * Ptrs,unsigned Align,Value * Mask)288*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
289*9880d681SAndroid Build Coastguard Worker                                              unsigned Align, Value *Mask) {
290*9880d681SAndroid Build Coastguard Worker   auto PtrsTy = cast<VectorType>(Ptrs->getType());
291*9880d681SAndroid Build Coastguard Worker   auto DataTy = cast<VectorType>(Data->getType());
292*9880d681SAndroid Build Coastguard Worker   unsigned NumElts = PtrsTy->getVectorNumElements();
293*9880d681SAndroid Build Coastguard Worker 
294*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
295*9880d681SAndroid Build Coastguard Worker   auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
296*9880d681SAndroid Build Coastguard Worker   assert(NumElts == DataTy->getVectorNumElements() &&
297*9880d681SAndroid Build Coastguard Worker          PtrTy->getElementType() == DataTy->getElementType() &&
298*9880d681SAndroid Build Coastguard Worker          "Incompatible pointer and data types");
299*9880d681SAndroid Build Coastguard Worker #endif
300*9880d681SAndroid Build Coastguard Worker 
301*9880d681SAndroid Build Coastguard Worker   if (!Mask)
302*9880d681SAndroid Build Coastguard Worker     Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
303*9880d681SAndroid Build Coastguard Worker                                      NumElts));
304*9880d681SAndroid Build Coastguard Worker   Value * Ops[] = {Data, Ptrs, getInt32(Align), Mask};
305*9880d681SAndroid Build Coastguard Worker 
306*9880d681SAndroid Build Coastguard Worker   // We specify only one type when we create this intrinsic. Types of other
307*9880d681SAndroid Build Coastguard Worker   // arguments are derived from this type.
308*9880d681SAndroid Build Coastguard Worker   return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, { DataTy });
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker 
311*9880d681SAndroid Build Coastguard Worker template <typename T0, typename T1, typename T2, typename T3>
312*9880d681SAndroid Build Coastguard Worker static std::vector<Value *>
getStatepointArgs(IRBuilderBase & B,uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,uint32_t Flags,ArrayRef<T0> CallArgs,ArrayRef<T1> TransitionArgs,ArrayRef<T2> DeoptArgs,ArrayRef<T3> GCArgs)313*9880d681SAndroid Build Coastguard Worker getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
314*9880d681SAndroid Build Coastguard Worker                   Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
315*9880d681SAndroid Build Coastguard Worker                   ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs,
316*9880d681SAndroid Build Coastguard Worker                   ArrayRef<T3> GCArgs) {
317*9880d681SAndroid Build Coastguard Worker   std::vector<Value *> Args;
318*9880d681SAndroid Build Coastguard Worker   Args.push_back(B.getInt64(ID));
319*9880d681SAndroid Build Coastguard Worker   Args.push_back(B.getInt32(NumPatchBytes));
320*9880d681SAndroid Build Coastguard Worker   Args.push_back(ActualCallee);
321*9880d681SAndroid Build Coastguard Worker   Args.push_back(B.getInt32(CallArgs.size()));
322*9880d681SAndroid Build Coastguard Worker   Args.push_back(B.getInt32(Flags));
323*9880d681SAndroid Build Coastguard Worker   Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
324*9880d681SAndroid Build Coastguard Worker   Args.push_back(B.getInt32(TransitionArgs.size()));
325*9880d681SAndroid Build Coastguard Worker   Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end());
326*9880d681SAndroid Build Coastguard Worker   Args.push_back(B.getInt32(DeoptArgs.size()));
327*9880d681SAndroid Build Coastguard Worker   Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
328*9880d681SAndroid Build Coastguard Worker   Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
329*9880d681SAndroid Build Coastguard Worker 
330*9880d681SAndroid Build Coastguard Worker   return Args;
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker 
333*9880d681SAndroid Build Coastguard Worker template <typename T0, typename T1, typename T2, typename T3>
CreateGCStatepointCallCommon(IRBuilderBase * Builder,uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,uint32_t Flags,ArrayRef<T0> CallArgs,ArrayRef<T1> TransitionArgs,ArrayRef<T2> DeoptArgs,ArrayRef<T3> GCArgs,const Twine & Name)334*9880d681SAndroid Build Coastguard Worker static CallInst *CreateGCStatepointCallCommon(
335*9880d681SAndroid Build Coastguard Worker     IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
336*9880d681SAndroid Build Coastguard Worker     Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
337*9880d681SAndroid Build Coastguard Worker     ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs,
338*9880d681SAndroid Build Coastguard Worker     const Twine &Name) {
339*9880d681SAndroid Build Coastguard Worker   // Extract out the type of the callee.
340*9880d681SAndroid Build Coastguard Worker   PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
341*9880d681SAndroid Build Coastguard Worker   assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
342*9880d681SAndroid Build Coastguard Worker          "actual callee must be a callable value");
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
345*9880d681SAndroid Build Coastguard Worker   // Fill in the one generic type'd argument (the function is also vararg)
346*9880d681SAndroid Build Coastguard Worker   Type *ArgTypes[] = { FuncPtrType };
347*9880d681SAndroid Build Coastguard Worker   Function *FnStatepoint =
348*9880d681SAndroid Build Coastguard Worker     Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
349*9880d681SAndroid Build Coastguard Worker                               ArgTypes);
350*9880d681SAndroid Build Coastguard Worker 
351*9880d681SAndroid Build Coastguard Worker   std::vector<llvm::Value *> Args =
352*9880d681SAndroid Build Coastguard Worker       getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
353*9880d681SAndroid Build Coastguard Worker                         CallArgs, TransitionArgs, DeoptArgs, GCArgs);
354*9880d681SAndroid Build Coastguard Worker   return createCallHelper(FnStatepoint, Args, Builder, Name);
355*9880d681SAndroid Build Coastguard Worker }
356*9880d681SAndroid Build Coastguard Worker 
CreateGCStatepointCall(uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,ArrayRef<Value * > CallArgs,ArrayRef<Value * > DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)357*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateGCStatepointCall(
358*9880d681SAndroid Build Coastguard Worker     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
359*9880d681SAndroid Build Coastguard Worker     ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
360*9880d681SAndroid Build Coastguard Worker     ArrayRef<Value *> GCArgs, const Twine &Name) {
361*9880d681SAndroid Build Coastguard Worker   return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
362*9880d681SAndroid Build Coastguard Worker       this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
363*9880d681SAndroid Build Coastguard Worker       CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
364*9880d681SAndroid Build Coastguard Worker }
365*9880d681SAndroid Build Coastguard Worker 
CreateGCStatepointCall(uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,uint32_t Flags,ArrayRef<Use> CallArgs,ArrayRef<Use> TransitionArgs,ArrayRef<Use> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)366*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateGCStatepointCall(
367*9880d681SAndroid Build Coastguard Worker     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
368*9880d681SAndroid Build Coastguard Worker     ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs,
369*9880d681SAndroid Build Coastguard Worker     ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
370*9880d681SAndroid Build Coastguard Worker   return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
371*9880d681SAndroid Build Coastguard Worker       this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
372*9880d681SAndroid Build Coastguard Worker       DeoptArgs, GCArgs, Name);
373*9880d681SAndroid Build Coastguard Worker }
374*9880d681SAndroid Build Coastguard Worker 
CreateGCStatepointCall(uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,ArrayRef<Use> CallArgs,ArrayRef<Value * > DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)375*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateGCStatepointCall(
376*9880d681SAndroid Build Coastguard Worker     uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
377*9880d681SAndroid Build Coastguard Worker     ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
378*9880d681SAndroid Build Coastguard Worker     ArrayRef<Value *> GCArgs, const Twine &Name) {
379*9880d681SAndroid Build Coastguard Worker   return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
380*9880d681SAndroid Build Coastguard Worker       this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
381*9880d681SAndroid Build Coastguard Worker       CallArgs, None, DeoptArgs, GCArgs, Name);
382*9880d681SAndroid Build Coastguard Worker }
383*9880d681SAndroid Build Coastguard Worker 
384*9880d681SAndroid Build Coastguard Worker template <typename T0, typename T1, typename T2, typename T3>
CreateGCStatepointInvokeCommon(IRBuilderBase * Builder,uint64_t ID,uint32_t NumPatchBytes,Value * ActualInvokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,uint32_t Flags,ArrayRef<T0> InvokeArgs,ArrayRef<T1> TransitionArgs,ArrayRef<T2> DeoptArgs,ArrayRef<T3> GCArgs,const Twine & Name)385*9880d681SAndroid Build Coastguard Worker static InvokeInst *CreateGCStatepointInvokeCommon(
386*9880d681SAndroid Build Coastguard Worker     IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
387*9880d681SAndroid Build Coastguard Worker     Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
388*9880d681SAndroid Build Coastguard Worker     uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs,
389*9880d681SAndroid Build Coastguard Worker     ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) {
390*9880d681SAndroid Build Coastguard Worker   // Extract out the type of the callee.
391*9880d681SAndroid Build Coastguard Worker   PointerType *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
392*9880d681SAndroid Build Coastguard Worker   assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
393*9880d681SAndroid Build Coastguard Worker          "actual callee must be a callable value");
394*9880d681SAndroid Build Coastguard Worker 
395*9880d681SAndroid Build Coastguard Worker   Module *M = Builder->GetInsertBlock()->getParent()->getParent();
396*9880d681SAndroid Build Coastguard Worker   // Fill in the one generic type'd argument (the function is also vararg)
397*9880d681SAndroid Build Coastguard Worker   Function *FnStatepoint = Intrinsic::getDeclaration(
398*9880d681SAndroid Build Coastguard Worker       M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
399*9880d681SAndroid Build Coastguard Worker 
400*9880d681SAndroid Build Coastguard Worker   std::vector<llvm::Value *> Args =
401*9880d681SAndroid Build Coastguard Worker       getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
402*9880d681SAndroid Build Coastguard Worker                         InvokeArgs, TransitionArgs, DeoptArgs, GCArgs);
403*9880d681SAndroid Build Coastguard Worker   return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder,
404*9880d681SAndroid Build Coastguard Worker                             Name);
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker 
CreateGCStatepointInvoke(uint64_t ID,uint32_t NumPatchBytes,Value * ActualInvokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,ArrayRef<Value * > InvokeArgs,ArrayRef<Value * > DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)407*9880d681SAndroid Build Coastguard Worker InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
408*9880d681SAndroid Build Coastguard Worker     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
409*9880d681SAndroid Build Coastguard Worker     BasicBlock *NormalDest, BasicBlock *UnwindDest,
410*9880d681SAndroid Build Coastguard Worker     ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
411*9880d681SAndroid Build Coastguard Worker     ArrayRef<Value *> GCArgs, const Twine &Name) {
412*9880d681SAndroid Build Coastguard Worker   return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
413*9880d681SAndroid Build Coastguard Worker       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
414*9880d681SAndroid Build Coastguard Worker       uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
415*9880d681SAndroid Build Coastguard Worker       DeoptArgs, GCArgs, Name);
416*9880d681SAndroid Build Coastguard Worker }
417*9880d681SAndroid Build Coastguard Worker 
CreateGCStatepointInvoke(uint64_t ID,uint32_t NumPatchBytes,Value * ActualInvokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,uint32_t Flags,ArrayRef<Use> InvokeArgs,ArrayRef<Use> TransitionArgs,ArrayRef<Use> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)418*9880d681SAndroid Build Coastguard Worker InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
419*9880d681SAndroid Build Coastguard Worker     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
420*9880d681SAndroid Build Coastguard Worker     BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
421*9880d681SAndroid Build Coastguard Worker     ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
422*9880d681SAndroid Build Coastguard Worker     ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
423*9880d681SAndroid Build Coastguard Worker   return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
424*9880d681SAndroid Build Coastguard Worker       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
425*9880d681SAndroid Build Coastguard Worker       InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
426*9880d681SAndroid Build Coastguard Worker }
427*9880d681SAndroid Build Coastguard Worker 
CreateGCStatepointInvoke(uint64_t ID,uint32_t NumPatchBytes,Value * ActualInvokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,ArrayRef<Use> InvokeArgs,ArrayRef<Value * > DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)428*9880d681SAndroid Build Coastguard Worker InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
429*9880d681SAndroid Build Coastguard Worker     uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
430*9880d681SAndroid Build Coastguard Worker     BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
431*9880d681SAndroid Build Coastguard Worker     ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
432*9880d681SAndroid Build Coastguard Worker   return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
433*9880d681SAndroid Build Coastguard Worker       this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
434*9880d681SAndroid Build Coastguard Worker       uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
435*9880d681SAndroid Build Coastguard Worker       Name);
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker 
CreateGCResult(Instruction * Statepoint,Type * ResultType,const Twine & Name)438*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
439*9880d681SAndroid Build Coastguard Worker                                        Type *ResultType,
440*9880d681SAndroid Build Coastguard Worker                                        const Twine &Name) {
441*9880d681SAndroid Build Coastguard Worker  Intrinsic::ID ID = Intrinsic::experimental_gc_result;
442*9880d681SAndroid Build Coastguard Worker  Module *M = BB->getParent()->getParent();
443*9880d681SAndroid Build Coastguard Worker  Type *Types[] = {ResultType};
444*9880d681SAndroid Build Coastguard Worker  Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
445*9880d681SAndroid Build Coastguard Worker 
446*9880d681SAndroid Build Coastguard Worker  Value *Args[] = {Statepoint};
447*9880d681SAndroid Build Coastguard Worker  return createCallHelper(FnGCResult, Args, this, Name);
448*9880d681SAndroid Build Coastguard Worker }
449*9880d681SAndroid Build Coastguard Worker 
CreateGCRelocate(Instruction * Statepoint,int BaseOffset,int DerivedOffset,Type * ResultType,const Twine & Name)450*9880d681SAndroid Build Coastguard Worker CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
451*9880d681SAndroid Build Coastguard Worker                                          int BaseOffset,
452*9880d681SAndroid Build Coastguard Worker                                          int DerivedOffset,
453*9880d681SAndroid Build Coastguard Worker                                          Type *ResultType,
454*9880d681SAndroid Build Coastguard Worker                                          const Twine &Name) {
455*9880d681SAndroid Build Coastguard Worker  Module *M = BB->getParent()->getParent();
456*9880d681SAndroid Build Coastguard Worker  Type *Types[] = {ResultType};
457*9880d681SAndroid Build Coastguard Worker  Value *FnGCRelocate =
458*9880d681SAndroid Build Coastguard Worker    Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
459*9880d681SAndroid Build Coastguard Worker 
460*9880d681SAndroid Build Coastguard Worker  Value *Args[] = {Statepoint,
461*9880d681SAndroid Build Coastguard Worker                   getInt32(BaseOffset),
462*9880d681SAndroid Build Coastguard Worker                   getInt32(DerivedOffset)};
463*9880d681SAndroid Build Coastguard Worker  return createCallHelper(FnGCRelocate, Args, this, Name);
464*9880d681SAndroid Build Coastguard Worker }
465