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