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