1 //===---- IRBuilder.cpp - Builder for LLVM Instrs -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/IR/IRBuilder.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/GlobalVariable.h"
18 #include "llvm/IR/Intrinsics.h"
19 #include "llvm/IR/LLVMContext.h"
20 #include "llvm/IR/Statepoint.h"
23 /// CreateGlobalString - Make a new global variable with an initializer that
24 /// has array of i8 type filled in with the nul terminated string value
25 /// specified. If Name is specified, it is the name of the global variable
27 GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
29 unsigned AddressSpace) {
30 Constant *StrConstant = ConstantDataArray::getString(Context, Str);
31 Module &M = *BB->getParent()->getParent();
32 GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
33 true, GlobalValue::PrivateLinkage,
34 StrConstant, Name, nullptr,
35 GlobalVariable::NotThreadLocal,
37 GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
41 Type *IRBuilderBase::getCurrentFunctionReturnType() const {
42 assert(BB && BB->getParent() && "No current function!");
43 return BB->getParent()->getReturnType();
46 Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
47 PointerType *PT = cast<PointerType>(Ptr->getType());
48 if (PT->getElementType()->isIntegerTy(8))
51 // Otherwise, we need to insert a bitcast.
52 PT = getInt8PtrTy(PT->getAddressSpace());
53 BitCastInst *BCI = new BitCastInst(Ptr, PT, "");
54 BB->getInstList().insert(InsertPt, BCI);
55 SetInstDebugLocation(BCI);
59 static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops,
60 IRBuilderBase *Builder,
61 const Twine& Name="") {
62 CallInst *CI = CallInst::Create(Callee, Ops, Name);
63 Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
64 Builder->SetInstDebugLocation(CI);
68 static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest,
69 BasicBlock *UnwindDest,
70 ArrayRef<Value *> Ops,
71 IRBuilderBase *Builder,
72 const Twine &Name = "") {
74 InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name);
75 Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),
77 Builder->SetInstDebugLocation(II);
81 CallInst *IRBuilderBase::
82 CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
83 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
85 Ptr = getCastedInt8PtrValue(Ptr);
86 Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) };
87 Type *Tys[] = { Ptr->getType(), Size->getType() };
88 Module *M = BB->getParent()->getParent();
89 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
91 CallInst *CI = createCallHelper(TheFn, Ops, this);
93 // Set the TBAA info if present.
95 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
98 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
101 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
106 CallInst *IRBuilderBase::
107 CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
108 bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag,
109 MDNode *ScopeTag, MDNode *NoAliasTag) {
110 Dst = getCastedInt8PtrValue(Dst);
111 Src = getCastedInt8PtrValue(Src);
113 Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
114 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
115 Module *M = BB->getParent()->getParent();
116 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
118 CallInst *CI = createCallHelper(TheFn, Ops, this);
120 // Set the TBAA info if present.
122 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
124 // Set the TBAA Struct info if present.
126 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
129 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
132 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
137 CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
138 Value *Dst, Value *Src, Value *Size, uint32_t ElementSize, MDNode *TBAATag,
139 MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
140 Dst = getCastedInt8PtrValue(Dst);
141 Src = getCastedInt8PtrValue(Src);
143 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
144 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
145 Module *M = BB->getParent()->getParent();
146 Value *TheFn = Intrinsic::getDeclaration(
147 M, Intrinsic::memcpy_element_unordered_atomic, Tys);
149 CallInst *CI = createCallHelper(TheFn, Ops, this);
151 // Set the TBAA info if present.
153 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
155 // Set the TBAA Struct info if present.
157 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
160 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
163 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
168 CallInst *IRBuilderBase::
169 CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
170 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
171 MDNode *NoAliasTag) {
172 Dst = getCastedInt8PtrValue(Dst);
173 Src = getCastedInt8PtrValue(Src);
175 Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
176 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
177 Module *M = BB->getParent()->getParent();
178 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
180 CallInst *CI = createCallHelper(TheFn, Ops, this);
182 // Set the TBAA info if present.
184 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
187 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
190 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
195 static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
197 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
198 Value *Ops[] = {Src};
199 Type *Tys[] = { Src->getType()->getVectorElementType(), Src->getType() };
200 auto Decl = Intrinsic::getDeclaration(M, ID, Tys);
201 return createCallHelper(Decl, Ops, Builder);
204 CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
205 Module *M = GetInsertBlock()->getParent()->getParent();
206 Value *Ops[] = {Acc, Src};
207 Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
209 auto Decl = Intrinsic::getDeclaration(
210 M, Intrinsic::experimental_vector_reduce_fadd, Tys);
211 return createCallHelper(Decl, Ops, this);
214 CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
215 Module *M = GetInsertBlock()->getParent()->getParent();
216 Value *Ops[] = {Acc, Src};
217 Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
219 auto Decl = Intrinsic::getDeclaration(
220 M, Intrinsic::experimental_vector_reduce_fmul, Tys);
221 return createCallHelper(Decl, Ops, this);
224 CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
225 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_add,
229 CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
230 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_mul,
234 CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
235 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_and,
239 CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
240 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_or,
244 CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
245 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_xor,
249 CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
250 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smax
251 : Intrinsic::experimental_vector_reduce_umax;
252 return getReductionIntrinsic(this, ID, Src);
255 CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
256 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smin
257 : Intrinsic::experimental_vector_reduce_umin;
258 return getReductionIntrinsic(this, ID, Src);
261 CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src, bool NoNaN) {
262 auto Rdx = getReductionIntrinsic(
263 this, Intrinsic::experimental_vector_reduce_fmax, Src);
267 Rdx->setFastMathFlags(FMF);
272 CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src, bool NoNaN) {
273 auto Rdx = getReductionIntrinsic(
274 this, Intrinsic::experimental_vector_reduce_fmin, Src);
278 Rdx->setFastMathFlags(FMF);
283 CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
284 assert(isa<PointerType>(Ptr->getType()) &&
285 "lifetime.start only applies to pointers.");
286 Ptr = getCastedInt8PtrValue(Ptr);
290 assert(Size->getType() == getInt64Ty() &&
291 "lifetime.start requires the size to be an i64");
292 Value *Ops[] = { Size, Ptr };
293 Module *M = BB->getParent()->getParent();
294 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start,
296 return createCallHelper(TheFn, Ops, this);
299 CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
300 assert(isa<PointerType>(Ptr->getType()) &&
301 "lifetime.end only applies to pointers.");
302 Ptr = getCastedInt8PtrValue(Ptr);
306 assert(Size->getType() == getInt64Ty() &&
307 "lifetime.end requires the size to be an i64");
308 Value *Ops[] = { Size, Ptr };
309 Module *M = BB->getParent()->getParent();
310 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end,
312 return createCallHelper(TheFn, Ops, this);
315 CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
317 assert(isa<PointerType>(Ptr->getType()) &&
318 "invariant.start only applies to pointers.");
319 Ptr = getCastedInt8PtrValue(Ptr);
323 assert(Size->getType() == getInt64Ty() &&
324 "invariant.start requires the size to be an i64");
326 Value *Ops[] = {Size, Ptr};
327 // Fill in the single overloaded type: memory object type.
328 Type *ObjectPtr[1] = {Ptr->getType()};
329 Module *M = BB->getParent()->getParent();
331 Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr);
332 return createCallHelper(TheFn, Ops, this);
335 CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
336 assert(Cond->getType() == getInt1Ty() &&
337 "an assumption condition must be of type i1");
339 Value *Ops[] = { Cond };
340 Module *M = BB->getParent()->getParent();
341 Value *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
342 return createCallHelper(FnAssume, Ops, this);
345 /// \brief Create a call to a Masked Load intrinsic.
346 /// \p Ptr - base pointer for the load
347 /// \p Align - alignment of the source location
348 /// \p Mask - vector of booleans which indicates what vector lanes should
349 /// be accessed in memory
350 /// \p PassThru - pass-through value that is used to fill the masked-off lanes
352 /// \p Name - name of the result variable
353 CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align,
354 Value *Mask, Value *PassThru,
356 PointerType *PtrTy = cast<PointerType>(Ptr->getType());
357 Type *DataTy = PtrTy->getElementType();
358 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
360 PassThru = UndefValue::get(DataTy);
361 Type *OverloadedTypes[] = { DataTy, PtrTy };
362 Value *Ops[] = { Ptr, getInt32(Align), Mask, PassThru};
363 return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
364 OverloadedTypes, Name);
367 /// \brief Create a call to a Masked Store intrinsic.
368 /// \p Val - data to be stored,
369 /// \p Ptr - base pointer for the store
370 /// \p Align - alignment of the destination location
371 /// \p Mask - vector of booleans which indicates what vector lanes should
372 /// be accessed in memory
373 CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
374 unsigned Align, Value *Mask) {
375 PointerType *PtrTy = cast<PointerType>(Ptr->getType());
376 Type *DataTy = PtrTy->getElementType();
377 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
378 Type *OverloadedTypes[] = { DataTy, PtrTy };
379 Value *Ops[] = { Val, Ptr, getInt32(Align), Mask };
380 return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
383 /// Create a call to a Masked intrinsic, with given intrinsic Id,
384 /// an array of operands - Ops, and an array of overloaded types -
386 CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
387 ArrayRef<Value *> Ops,
388 ArrayRef<Type *> OverloadedTypes,
390 Module *M = BB->getParent()->getParent();
391 Value *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
392 return createCallHelper(TheFn, Ops, this, Name);
395 /// \brief Create a call to a Masked Gather intrinsic.
396 /// \p Ptrs - vector of pointers for loading
397 /// \p Align - alignment for one element
398 /// \p Mask - vector of booleans which indicates what vector lanes should
399 /// be accessed in memory
400 /// \p PassThru - pass-through value that is used to fill the masked-off lanes
402 /// \p Name - name of the result variable
403 CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, unsigned Align,
404 Value *Mask, Value *PassThru,
406 auto PtrsTy = cast<VectorType>(Ptrs->getType());
407 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
408 unsigned NumElts = PtrsTy->getVectorNumElements();
409 Type *DataTy = VectorType::get(PtrTy->getElementType(), NumElts);
412 Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
416 PassThru = UndefValue::get(DataTy);
418 Type *OverloadedTypes[] = {DataTy, PtrsTy};
419 Value * Ops[] = {Ptrs, getInt32(Align), Mask, PassThru};
421 // We specify only one type when we create this intrinsic. Types of other
422 // arguments are derived from this type.
423 return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, OverloadedTypes,
427 /// \brief Create a call to a Masked Scatter intrinsic.
428 /// \p Data - data to be stored,
429 /// \p Ptrs - the vector of pointers, where the \p Data elements should be
431 /// \p Align - alignment for one element
432 /// \p Mask - vector of booleans which indicates what vector lanes should
433 /// be accessed in memory
434 CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
435 unsigned Align, Value *Mask) {
436 auto PtrsTy = cast<VectorType>(Ptrs->getType());
437 auto DataTy = cast<VectorType>(Data->getType());
438 unsigned NumElts = PtrsTy->getVectorNumElements();
441 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
442 assert(NumElts == DataTy->getVectorNumElements() &&
443 PtrTy->getElementType() == DataTy->getElementType() &&
444 "Incompatible pointer and data types");
448 Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
451 Type *OverloadedTypes[] = {DataTy, PtrsTy};
452 Value * Ops[] = {Data, Ptrs, getInt32(Align), Mask};
454 // We specify only one type when we create this intrinsic. Types of other
455 // arguments are derived from this type.
456 return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
459 template <typename T0, typename T1, typename T2, typename T3>
460 static std::vector<Value *>
461 getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
462 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
463 ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs,
464 ArrayRef<T3> GCArgs) {
465 std::vector<Value *> Args;
466 Args.push_back(B.getInt64(ID));
467 Args.push_back(B.getInt32(NumPatchBytes));
468 Args.push_back(ActualCallee);
469 Args.push_back(B.getInt32(CallArgs.size()));
470 Args.push_back(B.getInt32(Flags));
471 Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
472 Args.push_back(B.getInt32(TransitionArgs.size()));
473 Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end());
474 Args.push_back(B.getInt32(DeoptArgs.size()));
475 Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
476 Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
481 template <typename T0, typename T1, typename T2, typename T3>
482 static CallInst *CreateGCStatepointCallCommon(
483 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
484 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
485 ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs,
487 // Extract out the type of the callee.
488 PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
489 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
490 "actual callee must be a callable value");
492 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
493 // Fill in the one generic type'd argument (the function is also vararg)
494 Type *ArgTypes[] = { FuncPtrType };
495 Function *FnStatepoint =
496 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
499 std::vector<llvm::Value *> Args =
500 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
501 CallArgs, TransitionArgs, DeoptArgs, GCArgs);
502 return createCallHelper(FnStatepoint, Args, Builder, Name);
505 CallInst *IRBuilderBase::CreateGCStatepointCall(
506 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
507 ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
508 ArrayRef<Value *> GCArgs, const Twine &Name) {
509 return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
510 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
511 CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
514 CallInst *IRBuilderBase::CreateGCStatepointCall(
515 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
516 ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs,
517 ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
518 return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
519 this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
520 DeoptArgs, GCArgs, Name);
523 CallInst *IRBuilderBase::CreateGCStatepointCall(
524 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
525 ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
526 ArrayRef<Value *> GCArgs, const Twine &Name) {
527 return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
528 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
529 CallArgs, None, DeoptArgs, GCArgs, Name);
532 template <typename T0, typename T1, typename T2, typename T3>
533 static InvokeInst *CreateGCStatepointInvokeCommon(
534 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
535 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
536 uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs,
537 ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) {
538 // Extract out the type of the callee.
539 PointerType *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
540 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
541 "actual callee must be a callable value");
543 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
544 // Fill in the one generic type'd argument (the function is also vararg)
545 Function *FnStatepoint = Intrinsic::getDeclaration(
546 M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
548 std::vector<llvm::Value *> Args =
549 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
550 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs);
551 return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder,
555 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
556 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
557 BasicBlock *NormalDest, BasicBlock *UnwindDest,
558 ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
559 ArrayRef<Value *> GCArgs, const Twine &Name) {
560 return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
561 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
562 uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
563 DeoptArgs, GCArgs, Name);
566 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
567 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
568 BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
569 ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
570 ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
571 return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
572 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
573 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
576 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
577 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
578 BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
579 ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
580 return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
581 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
582 uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
586 CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
589 Intrinsic::ID ID = Intrinsic::experimental_gc_result;
590 Module *M = BB->getParent()->getParent();
591 Type *Types[] = {ResultType};
592 Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
594 Value *Args[] = {Statepoint};
595 return createCallHelper(FnGCResult, Args, this, Name);
598 CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
603 Module *M = BB->getParent()->getParent();
604 Type *Types[] = {ResultType};
605 Value *FnGCRelocate =
606 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
608 Value *Args[] = {Statepoint,
609 getInt32(BaseOffset),
610 getInt32(DerivedOffset)};
611 return createCallHelper(FnGCRelocate, Args, this, Name);
614 CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID,
615 Value *LHS, Value *RHS,
617 Module *M = BB->getParent()->getParent();
618 Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
619 return createCallHelper(Fn, { LHS, RHS }, this, Name);