blob: a7290cb8c0f02529913ca946192aa873c312561c [file] [log] [blame]
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001//===- IRBuilder.cpp - Builder for LLVM Instrs ----------------------------===//
Chris Lattner17079fc2009-12-28 21:28:46 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner17079fc2009-12-28 21:28:46 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the IRBuilder class, which is used as a convenient way
10// to create LLVM instructions with a consistent and simplified interface.
11//
12//===----------------------------------------------------------------------===//
13
Chandler Carruth6bda14b2017-06-06 11:49:48 +000014#include "llvm/IR/IRBuilder.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000015#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/None.h"
17#include "llvm/IR/Constant.h"
18#include "llvm/IR/Constants.h"
19#include "llvm/IR/DerivedTypes.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000020#include "llvm/IR/Function.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000021#include "llvm/IR/GlobalValue.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000022#include "llvm/IR/GlobalVariable.h"
Daniel Neilson1e687242018-01-19 17:13:12 +000023#include "llvm/IR/IntrinsicInst.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000024#include "llvm/IR/Intrinsics.h"
25#include "llvm/IR/LLVMContext.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000026#include "llvm/IR/Operator.h"
Pat Gavlincc0431d2015-05-08 18:07:42 +000027#include "llvm/IR/Statepoint.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000028#include "llvm/IR/Type.h"
29#include "llvm/IR/Value.h"
30#include "llvm/Support/Casting.h"
31#include "llvm/Support/MathExtras.h"
32#include <cassert>
33#include <cstdint>
34#include <vector>
35
Chris Lattner17079fc2009-12-28 21:28:46 +000036using namespace llvm;
37
38/// CreateGlobalString - Make a new global variable with an initializer that
Dan Gohman97c59022010-02-10 20:04:19 +000039/// has array of i8 type filled in with the nul terminated string value
Chris Lattner17079fc2009-12-28 21:28:46 +000040/// specified. If Name is specified, it is the name of the global variable
41/// created.
David Blaikieaa41cd52015-04-03 21:33:42 +000042GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
Tobias Grossercdb89142015-06-19 02:12:07 +000043 const Twine &Name,
44 unsigned AddressSpace) {
Chris Lattnercf9e8f62012-02-05 02:29:43 +000045 Constant *StrConstant = ConstantDataArray::getString(Context, Str);
Chris Lattner17079fc2009-12-28 21:28:46 +000046 Module &M = *BB->getParent()->getParent();
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000047 auto *GV = new GlobalVariable(M, StrConstant->getType(), true,
48 GlobalValue::PrivateLinkage, StrConstant, Name,
49 nullptr, GlobalVariable::NotThreadLocal,
50 AddressSpace);
Peter Collingbourne96efdd62016-06-14 21:01:22 +000051 GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
David Greene6918ca2018-09-06 08:42:17 +000052 GV->setAlignment(1);
Chris Lattner17079fc2009-12-28 21:28:46 +000053 return GV;
54}
Chris Lattner7ef1cac2009-12-28 21:45:40 +000055
Chris Lattnerb1907b22011-07-12 04:14:22 +000056Type *IRBuilderBase::getCurrentFunctionReturnType() const {
Chris Lattner49f9f762009-12-28 21:50:56 +000057 assert(BB && BB->getParent() && "No current function!");
58 return BB->getParent()->getReturnType();
59}
Chris Lattner143a07c2010-12-26 22:49:25 +000060
61Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000062 auto *PT = cast<PointerType>(Ptr->getType());
Chris Lattner143a07c2010-12-26 22:49:25 +000063 if (PT->getElementType()->isIntegerTy(8))
64 return Ptr;
Bjorn Petterssonaa025802018-07-03 12:39:52 +000065
Chris Lattner143a07c2010-12-26 22:49:25 +000066 // Otherwise, we need to insert a bitcast.
67 PT = getInt8PtrTy(PT->getAddressSpace());
68 BitCastInst *BCI = new BitCastInst(Ptr, PT, "");
69 BB->getInstList().insert(InsertPt, BCI);
70 SetInstDebugLocation(BCI);
71 return BCI;
72}
73
James Y Knight7976eb52019-02-01 20:43:25 +000074static CallInst *createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
Philip Reames4750dd12014-12-30 05:55:58 +000075 IRBuilderBase *Builder,
Sanjay Pateld32104e2018-02-23 21:16:12 +000076 const Twine &Name = "",
77 Instruction *FMFSource = nullptr) {
Philip Reames4750dd12014-12-30 05:55:58 +000078 CallInst *CI = CallInst::Create(Callee, Ops, Name);
Sanjay Pateld32104e2018-02-23 21:16:12 +000079 if (FMFSource)
80 CI->copyFastMathFlags(FMFSource);
Chris Lattner143a07c2010-12-26 22:49:25 +000081 Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
82 Builder->SetInstDebugLocation(CI);
Bjorn Petterssonaa025802018-07-03 12:39:52 +000083 return CI;
Chris Lattner143a07c2010-12-26 22:49:25 +000084}
85
James Y Knightd9e85a02019-02-01 20:43:34 +000086static InvokeInst *createInvokeHelper(Function *Invokee, BasicBlock *NormalDest,
Sanjoy Dasabe1c682015-05-06 23:53:09 +000087 BasicBlock *UnwindDest,
88 ArrayRef<Value *> Ops,
89 IRBuilderBase *Builder,
90 const Twine &Name = "") {
91 InvokeInst *II =
92 InvokeInst::Create(Invokee, NormalDest, UnwindDest, Ops, Name);
93 Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),
94 II);
95 Builder->SetInstDebugLocation(II);
96 return II;
97}
98
Chris Lattner143a07c2010-12-26 22:49:25 +000099CallInst *IRBuilderBase::
Pete Cooper67cf9a72015-11-19 05:56:52 +0000100CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
Hal Finkel94146652014-07-24 14:25:39 +0000101 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
102 MDNode *NoAliasTag) {
Chris Lattner143a07c2010-12-26 22:49:25 +0000103 Ptr = getCastedInt8PtrValue(Ptr);
Daniel Neilson1e687242018-01-19 17:13:12 +0000104 Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +0000105 Type *Tys[] = { Ptr->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +0000106 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000107 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000108
Jay Foad5bd375a2011-07-15 08:37:34 +0000109 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +0000110
111 if (Align > 0)
112 cast<MemSetInst>(CI)->setDestAlignment(Align);
113
Chris Lattner143a07c2010-12-26 22:49:25 +0000114 // Set the TBAA info if present.
115 if (TBAATag)
116 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Hal Finkel94146652014-07-24 14:25:39 +0000117
118 if (ScopeTag)
119 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000120
Hal Finkel94146652014-07-24 14:25:39 +0000121 if (NoAliasTag)
122 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
Daniel Neilson1e687242018-01-19 17:13:12 +0000123
Chris Lattner143a07c2010-12-26 22:49:25 +0000124 return CI;
125}
126
Daniel Neilson936d50a2018-05-30 20:02:56 +0000127CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet(
128 Value *Ptr, Value *Val, Value *Size, unsigned Align, uint32_t ElementSize,
129 MDNode *TBAATag, MDNode *ScopeTag, MDNode *NoAliasTag) {
130 assert(Align >= ElementSize &&
131 "Pointer alignment must be at least element size.");
132
133 Ptr = getCastedInt8PtrValue(Ptr);
134 Value *Ops[] = {Ptr, Val, Size, getInt32(ElementSize)};
135 Type *Tys[] = {Ptr->getType(), Size->getType()};
136 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000137 Function *TheFn = Intrinsic::getDeclaration(
Daniel Neilson936d50a2018-05-30 20:02:56 +0000138 M, Intrinsic::memset_element_unordered_atomic, Tys);
139
140 CallInst *CI = createCallHelper(TheFn, Ops, this);
141
142 cast<AtomicMemSetInst>(CI)->setDestAlignment(Align);
143
144 // Set the TBAA info if present.
145 if (TBAATag)
146 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
147
148 if (ScopeTag)
149 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
150
151 if (NoAliasTag)
152 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
153
154 return CI;
155}
156
Chris Lattner143a07c2010-12-26 22:49:25 +0000157CallInst *IRBuilderBase::
Daniel Neilson551a4d62018-01-27 17:59:10 +0000158CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
159 Value *Size, bool isVolatile, MDNode *TBAATag,
160 MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
161 assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2");
162 assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2");
Chris Lattner143a07c2010-12-26 22:49:25 +0000163 Dst = getCastedInt8PtrValue(Dst);
164 Src = getCastedInt8PtrValue(Src);
165
Daniel Neilson1e687242018-01-19 17:13:12 +0000166 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +0000167 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +0000168 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000169 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000170
Jay Foad5bd375a2011-07-15 08:37:34 +0000171 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +0000172
Daniel Neilson551a4d62018-01-27 17:59:10 +0000173 auto* MCI = cast<MemCpyInst>(CI);
174 if (DstAlign > 0)
175 MCI->setDestAlignment(DstAlign);
176 if (SrcAlign > 0)
177 MCI->setSourceAlignment(SrcAlign);
Daniel Neilson1e687242018-01-19 17:13:12 +0000178
Chris Lattner143a07c2010-12-26 22:49:25 +0000179 // Set the TBAA info if present.
180 if (TBAATag)
181 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Dan Gohman099727f2012-09-26 22:17:14 +0000182
183 // Set the TBAA Struct info if present.
184 if (TBAAStructTag)
185 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000186
Hal Finkel94146652014-07-24 14:25:39 +0000187 if (ScopeTag)
188 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000189
Hal Finkel94146652014-07-24 14:25:39 +0000190 if (NoAliasTag)
191 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
Daniel Neilson1e687242018-01-19 17:13:12 +0000192
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000193 return CI;
Chris Lattner143a07c2010-12-26 22:49:25 +0000194}
195
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000196CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000197 Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size,
198 uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
199 MDNode *ScopeTag, MDNode *NoAliasTag) {
200 assert(DstAlign >= ElementSize &&
201 "Pointer alignment must be at least element size");
202 assert(SrcAlign >= ElementSize &&
203 "Pointer alignment must be at least element size");
Anna Thomasb2a212c2017-06-06 16:45:25 +0000204 Dst = getCastedInt8PtrValue(Dst);
205 Src = getCastedInt8PtrValue(Src);
206
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000207 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
208 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
Anna Thomasb2a212c2017-06-06 16:45:25 +0000209 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000210 Function *TheFn = Intrinsic::getDeclaration(
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000211 M, Intrinsic::memcpy_element_unordered_atomic, Tys);
Anna Thomasb2a212c2017-06-06 16:45:25 +0000212
213 CallInst *CI = createCallHelper(TheFn, Ops, this);
214
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000215 // Set the alignment of the pointer args.
Daniel Neilson1e687242018-01-19 17:13:12 +0000216 auto *AMCI = cast<AtomicMemCpyInst>(CI);
217 AMCI->setDestAlignment(DstAlign);
218 AMCI->setSourceAlignment(SrcAlign);
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000219
Anna Thomasb2a212c2017-06-06 16:45:25 +0000220 // Set the TBAA info if present.
221 if (TBAATag)
222 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
223
224 // Set the TBAA Struct info if present.
225 if (TBAAStructTag)
226 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
227
228 if (ScopeTag)
229 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
230
231 if (NoAliasTag)
232 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
233
234 return CI;
235}
236
Chris Lattner143a07c2010-12-26 22:49:25 +0000237CallInst *IRBuilderBase::
Daniel Neilson551a4d62018-01-27 17:59:10 +0000238CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
239 Value *Size, bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
Hal Finkel94146652014-07-24 14:25:39 +0000240 MDNode *NoAliasTag) {
Daniel Neilson551a4d62018-01-27 17:59:10 +0000241 assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2");
242 assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2");
Chris Lattner143a07c2010-12-26 22:49:25 +0000243 Dst = getCastedInt8PtrValue(Dst);
244 Src = getCastedInt8PtrValue(Src);
Daniel Neilson1e687242018-01-19 17:13:12 +0000245
246 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +0000247 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +0000248 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000249 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000250
Jay Foad5bd375a2011-07-15 08:37:34 +0000251 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +0000252
253 auto *MMI = cast<MemMoveInst>(CI);
Daniel Neilson551a4d62018-01-27 17:59:10 +0000254 if (DstAlign > 0)
255 MMI->setDestAlignment(DstAlign);
256 if (SrcAlign > 0)
257 MMI->setSourceAlignment(SrcAlign);
Daniel Neilson1e687242018-01-19 17:13:12 +0000258
Chris Lattner143a07c2010-12-26 22:49:25 +0000259 // Set the TBAA info if present.
260 if (TBAATag)
261 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000262
Hal Finkel94146652014-07-24 14:25:39 +0000263 if (ScopeTag)
264 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000265
Hal Finkel94146652014-07-24 14:25:39 +0000266 if (NoAliasTag)
267 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000268
269 return CI;
Chris Lattner143a07c2010-12-26 22:49:25 +0000270}
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000271
Daniel Neilson936d50a2018-05-30 20:02:56 +0000272CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove(
273 Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size,
274 uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
275 MDNode *ScopeTag, MDNode *NoAliasTag) {
276 assert(DstAlign >= ElementSize &&
277 "Pointer alignment must be at least element size");
278 assert(SrcAlign >= ElementSize &&
279 "Pointer alignment must be at least element size");
280 Dst = getCastedInt8PtrValue(Dst);
281 Src = getCastedInt8PtrValue(Src);
282
283 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
284 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
285 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000286 Function *TheFn = Intrinsic::getDeclaration(
Daniel Neilson936d50a2018-05-30 20:02:56 +0000287 M, Intrinsic::memmove_element_unordered_atomic, Tys);
288
289 CallInst *CI = createCallHelper(TheFn, Ops, this);
290
291 // Set the alignment of the pointer args.
292 CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), DstAlign));
293 CI->addParamAttr(1, Attribute::getWithAlignment(CI->getContext(), SrcAlign));
294
295 // Set the TBAA info if present.
296 if (TBAATag)
297 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
298
299 // Set the TBAA Struct info if present.
300 if (TBAAStructTag)
301 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
302
303 if (ScopeTag)
304 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
305
306 if (NoAliasTag)
307 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
308
309 return CI;
310}
311
Amara Emersoncf9daa32017-05-09 10:43:25 +0000312static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
313 Value *Src) {
314 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
315 Value *Ops[] = {Src};
316 Type *Tys[] = { Src->getType()->getVectorElementType(), Src->getType() };
317 auto Decl = Intrinsic::getDeclaration(M, ID, Tys);
318 return createCallHelper(Decl, Ops, Builder);
319}
320
321CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
322 Module *M = GetInsertBlock()->getParent()->getParent();
323 Value *Ops[] = {Acc, Src};
324 Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
325 Src->getType()};
326 auto Decl = Intrinsic::getDeclaration(
327 M, Intrinsic::experimental_vector_reduce_fadd, Tys);
328 return createCallHelper(Decl, Ops, this);
329}
330
331CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
332 Module *M = GetInsertBlock()->getParent()->getParent();
333 Value *Ops[] = {Acc, Src};
334 Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
335 Src->getType()};
336 auto Decl = Intrinsic::getDeclaration(
337 M, Intrinsic::experimental_vector_reduce_fmul, Tys);
338 return createCallHelper(Decl, Ops, this);
339}
340
341CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
342 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_add,
343 Src);
344}
345
346CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
347 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_mul,
348 Src);
349}
350
351CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
352 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_and,
353 Src);
354}
355
356CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
357 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_or,
358 Src);
359}
360
361CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
362 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_xor,
363 Src);
364}
365
366CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
367 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smax
368 : Intrinsic::experimental_vector_reduce_umax;
369 return getReductionIntrinsic(this, ID, Src);
370}
371
372CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
373 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smin
374 : Intrinsic::experimental_vector_reduce_umin;
375 return getReductionIntrinsic(this, ID, Src);
376}
377
378CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src, bool NoNaN) {
379 auto Rdx = getReductionIntrinsic(
380 this, Intrinsic::experimental_vector_reduce_fmax, Src);
381 if (NoNaN) {
382 FastMathFlags FMF;
383 FMF.setNoNaNs();
384 Rdx->setFastMathFlags(FMF);
385 }
386 return Rdx;
387}
388
389CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src, bool NoNaN) {
390 auto Rdx = getReductionIntrinsic(
391 this, Intrinsic::experimental_vector_reduce_fmin, Src);
392 if (NoNaN) {
393 FastMathFlags FMF;
394 FMF.setNoNaNs();
395 Rdx->setFastMathFlags(FMF);
396 }
397 return Rdx;
398}
399
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000400CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
401 assert(isa<PointerType>(Ptr->getType()) &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000402 "lifetime.start only applies to pointers.");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000403 Ptr = getCastedInt8PtrValue(Ptr);
404 if (!Size)
405 Size = getInt64(-1);
406 else
407 assert(Size->getType() == getInt64Ty() &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000408 "lifetime.start requires the size to be an i64");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000409 Value *Ops[] = { Size, Ptr };
410 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000411 Function *TheFn =
412 Intrinsic::getDeclaration(M, Intrinsic::lifetime_start, {Ptr->getType()});
Jay Foad5bd375a2011-07-15 08:37:34 +0000413 return createCallHelper(TheFn, Ops, this);
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000414}
415
416CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
417 assert(isa<PointerType>(Ptr->getType()) &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000418 "lifetime.end only applies to pointers.");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000419 Ptr = getCastedInt8PtrValue(Ptr);
420 if (!Size)
421 Size = getInt64(-1);
422 else
423 assert(Size->getType() == getInt64Ty() &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000424 "lifetime.end requires the size to be an i64");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000425 Value *Ops[] = { Size, Ptr };
426 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000427 Function *TheFn =
428 Intrinsic::getDeclaration(M, Intrinsic::lifetime_end, {Ptr->getType()});
Jay Foad5bd375a2011-07-15 08:37:34 +0000429 return createCallHelper(TheFn, Ops, this);
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000430}
Hal Finkel6f814db2014-10-15 23:44:22 +0000431
Anna Thomas58d11922016-07-22 20:57:23 +0000432CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
433
434 assert(isa<PointerType>(Ptr->getType()) &&
435 "invariant.start only applies to pointers.");
436 Ptr = getCastedInt8PtrValue(Ptr);
437 if (!Size)
438 Size = getInt64(-1);
439 else
440 assert(Size->getType() == getInt64Ty() &&
441 "invariant.start requires the size to be an i64");
442
443 Value *Ops[] = {Size, Ptr};
444 // Fill in the single overloaded type: memory object type.
445 Type *ObjectPtr[1] = {Ptr->getType()};
446 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000447 Function *TheFn =
Anna Thomas58d11922016-07-22 20:57:23 +0000448 Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr);
449 return createCallHelper(TheFn, Ops, this);
450}
451
Hal Finkel6f814db2014-10-15 23:44:22 +0000452CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
453 assert(Cond->getType() == getInt1Ty() &&
454 "an assumption condition must be of type i1");
455
456 Value *Ops[] = { Cond };
457 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000458 Function *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
Hal Finkel6f814db2014-10-15 23:44:22 +0000459 return createCallHelper(FnAssume, Ops, this);
460}
461
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000462/// Create a call to a Masked Load intrinsic.
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000463/// \p Ptr - base pointer for the load
464/// \p Align - alignment of the source location
465/// \p Mask - vector of booleans which indicates what vector lanes should
466/// be accessed in memory
467/// \p PassThru - pass-through value that is used to fill the masked-off lanes
468/// of the result
469/// \p Name - name of the result variable
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000470CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align,
471 Value *Mask, Value *PassThru,
472 const Twine &Name) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000473 auto *PtrTy = cast<PointerType>(Ptr->getType());
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000474 Type *DataTy = PtrTy->getElementType();
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000475 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
Ayal Zakse841b212017-07-31 13:21:42 +0000476 assert(Mask && "Mask should not be all-ones (null)");
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000477 if (!PassThru)
478 PassThru = UndefValue::get(DataTy);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000479 Type *OverloadedTypes[] = { DataTy, PtrTy };
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000480 Value *Ops[] = { Ptr, getInt32(Align), Mask, PassThru};
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000481 return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
482 OverloadedTypes, Name);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000483}
484
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000485/// Create a call to a Masked Store intrinsic.
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000486/// \p Val - data to be stored,
487/// \p Ptr - base pointer for the store
488/// \p Align - alignment of the destination location
489/// \p Mask - vector of booleans which indicates what vector lanes should
490/// be accessed in memory
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000491CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
492 unsigned Align, Value *Mask) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000493 auto *PtrTy = cast<PointerType>(Ptr->getType());
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000494 Type *DataTy = PtrTy->getElementType();
495 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
Ayal Zakse841b212017-07-31 13:21:42 +0000496 assert(Mask && "Mask should not be all-ones (null)");
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000497 Type *OverloadedTypes[] = { DataTy, PtrTy };
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000498 Value *Ops[] = { Val, Ptr, getInt32(Align), Mask };
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000499 return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000500}
501
502/// Create a call to a Masked intrinsic, with given intrinsic Id,
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000503/// an array of operands - Ops, and an array of overloaded types -
504/// OverloadedTypes.
Pete Cooper9e1d3352015-05-20 17:16:39 +0000505CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000506 ArrayRef<Value *> Ops,
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000507 ArrayRef<Type *> OverloadedTypes,
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000508 const Twine &Name) {
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000509 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000510 Function *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000511 return createCallHelper(TheFn, Ops, this, Name);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000512}
Philip Reames4750dd12014-12-30 05:55:58 +0000513
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000514/// Create a call to a Masked Gather intrinsic.
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000515/// \p Ptrs - vector of pointers for loading
516/// \p Align - alignment for one element
517/// \p Mask - vector of booleans which indicates what vector lanes should
518/// be accessed in memory
519/// \p PassThru - pass-through value that is used to fill the masked-off lanes
520/// of the result
521/// \p Name - name of the result variable
522CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, unsigned Align,
523 Value *Mask, Value *PassThru,
524 const Twine& Name) {
525 auto PtrsTy = cast<VectorType>(Ptrs->getType());
526 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
527 unsigned NumElts = PtrsTy->getVectorNumElements();
528 Type *DataTy = VectorType::get(PtrTy->getElementType(), NumElts);
529
530 if (!Mask)
531 Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
532 NumElts));
533
Amara Emerson4d33c862017-05-19 10:40:18 +0000534 if (!PassThru)
535 PassThru = UndefValue::get(DataTy);
536
Elad Cohenef5798a2017-05-03 12:28:54 +0000537 Type *OverloadedTypes[] = {DataTy, PtrsTy};
Amara Emerson4d33c862017-05-19 10:40:18 +0000538 Value * Ops[] = {Ptrs, getInt32(Align), Mask, PassThru};
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000539
540 // We specify only one type when we create this intrinsic. Types of other
541 // arguments are derived from this type.
Elad Cohenef5798a2017-05-03 12:28:54 +0000542 return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, OverloadedTypes,
543 Name);
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000544}
545
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000546/// Create a call to a Masked Scatter intrinsic.
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000547/// \p Data - data to be stored,
548/// \p Ptrs - the vector of pointers, where the \p Data elements should be
549/// stored
550/// \p Align - alignment for one element
551/// \p Mask - vector of booleans which indicates what vector lanes should
552/// be accessed in memory
553CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
554 unsigned Align, Value *Mask) {
555 auto PtrsTy = cast<VectorType>(Ptrs->getType());
556 auto DataTy = cast<VectorType>(Data->getType());
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000557 unsigned NumElts = PtrsTy->getVectorNumElements();
558
Tim Northover5a1a56c2016-02-17 21:16:59 +0000559#ifndef NDEBUG
560 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000561 assert(NumElts == DataTy->getVectorNumElements() &&
Tim Northover5a1a56c2016-02-17 21:16:59 +0000562 PtrTy->getElementType() == DataTy->getElementType() &&
563 "Incompatible pointer and data types");
564#endif
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000565
566 if (!Mask)
567 Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
568 NumElts));
Elad Cohenef5798a2017-05-03 12:28:54 +0000569
570 Type *OverloadedTypes[] = {DataTy, PtrsTy};
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000571 Value * Ops[] = {Data, Ptrs, getInt32(Align), Mask};
572
573 // We specify only one type when we create this intrinsic. Types of other
574 // arguments are derived from this type.
Elad Cohenef5798a2017-05-03 12:28:54 +0000575 return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000576}
577
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000578template <typename T0, typename T1, typename T2, typename T3>
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000579static std::vector<Value *>
580getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000581 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
582 ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs,
583 ArrayRef<T3> GCArgs) {
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000584 std::vector<Value *> Args;
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000585 Args.push_back(B.getInt64(ID));
586 Args.push_back(B.getInt32(NumPatchBytes));
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000587 Args.push_back(ActualCallee);
588 Args.push_back(B.getInt32(CallArgs.size()));
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000589 Args.push_back(B.getInt32(Flags));
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000590 Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000591 Args.push_back(B.getInt32(TransitionArgs.size()));
592 Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end());
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000593 Args.push_back(B.getInt32(DeoptArgs.size()));
594 Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
595 Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
596
597 return Args;
598}
599
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000600template <typename T0, typename T1, typename T2, typename T3>
601static CallInst *CreateGCStatepointCallCommon(
602 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000603 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000604 ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs,
605 const Twine &Name) {
Sanjoy Das63245b52015-05-06 02:36:34 +0000606 // Extract out the type of the callee.
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000607 auto *FuncPtrType = cast<PointerType>(ActualCallee->getType());
Sanjoy Das63245b52015-05-06 02:36:34 +0000608 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
609 "actual callee must be a callable value");
Philip Reames4750dd12014-12-30 05:55:58 +0000610
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000611 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
Sanjoy Das63245b52015-05-06 02:36:34 +0000612 // Fill in the one generic type'd argument (the function is also vararg)
613 Type *ArgTypes[] = { FuncPtrType };
614 Function *FnStatepoint =
615 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
616 ArgTypes);
Philip Reames4750dd12014-12-30 05:55:58 +0000617
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000618 std::vector<Value *> Args =
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000619 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
620 CallArgs, TransitionArgs, DeoptArgs, GCArgs);
621 return createCallHelper(FnStatepoint, Args, Builder, Name);
622}
623
624CallInst *IRBuilderBase::CreateGCStatepointCall(
625 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
626 ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
627 ArrayRef<Value *> GCArgs, const Twine &Name) {
628 return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000629 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
630 CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000631}
632
633CallInst *IRBuilderBase::CreateGCStatepointCall(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000634 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
635 ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000636 ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
637 return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
638 this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
639 DeoptArgs, GCArgs, Name);
Philip Reames4750dd12014-12-30 05:55:58 +0000640}
641
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000642CallInst *IRBuilderBase::CreateGCStatepointCall(
643 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
644 ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
645 ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000646 return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000647 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
648 CallArgs, None, DeoptArgs, GCArgs, Name);
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000649}
650
651template <typename T0, typename T1, typename T2, typename T3>
652static InvokeInst *CreateGCStatepointInvokeCommon(
653 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
654 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000655 uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000656 ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) {
657 // Extract out the type of the callee.
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000658 auto *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000659 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
660 "actual callee must be a callable value");
661
662 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
663 // Fill in the one generic type'd argument (the function is also vararg)
664 Function *FnStatepoint = Intrinsic::getDeclaration(
665 M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
666
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000667 std::vector<Value *> Args =
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000668 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
669 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs);
670 return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder,
671 Name);
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000672}
673
674InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000675 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
676 BasicBlock *NormalDest, BasicBlock *UnwindDest,
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000677 ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
678 ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000679 return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
680 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000681 uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000682 DeoptArgs, GCArgs, Name);
683}
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000684
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000685InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
686 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000687 BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000688 ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
689 ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
690 return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
691 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
692 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000693}
694
695InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000696 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
697 BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
698 ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000699 return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
700 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000701 uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
702 Name);
Ramkumar Ramachandra3408f3e2015-02-26 00:35:56 +0000703}
704
Philip Reames4750dd12014-12-30 05:55:58 +0000705CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
706 Type *ResultType,
707 const Twine &Name) {
Ramkumar Ramachandra75a4f352015-01-22 20:14:38 +0000708 Intrinsic::ID ID = Intrinsic::experimental_gc_result;
Philip Reames4750dd12014-12-30 05:55:58 +0000709 Module *M = BB->getParent()->getParent();
710 Type *Types[] = {ResultType};
James Y Knight7976eb52019-02-01 20:43:25 +0000711 Function *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
Philip Reames4750dd12014-12-30 05:55:58 +0000712
713 Value *Args[] = {Statepoint};
714 return createCallHelper(FnGCResult, Args, this, Name);
715}
716
717CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
718 int BaseOffset,
719 int DerivedOffset,
720 Type *ResultType,
721 const Twine &Name) {
722 Module *M = BB->getParent()->getParent();
723 Type *Types[] = {ResultType};
James Y Knight7976eb52019-02-01 20:43:25 +0000724 Function *FnGCRelocate =
725 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
Philip Reames4750dd12014-12-30 05:55:58 +0000726
727 Value *Args[] = {Statepoint,
728 getInt32(BaseOffset),
729 getInt32(DerivedOffset)};
730 return createCallHelper(FnGCRelocate, Args, this, Name);
731}
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000732
Neil Henning57f5d0a2018-10-08 10:32:33 +0000733CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
734 Instruction *FMFSource,
735 const Twine &Name) {
736 Module *M = BB->getModule();
737 Function *Fn = Intrinsic::getDeclaration(M, ID, {V->getType()});
738 return createCallHelper(Fn, {V}, this, Name, FMFSource);
739}
740
741CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
742 Value *RHS,
743 Instruction *FMFSource,
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000744 const Twine &Name) {
Sanjay Pateld32104e2018-02-23 21:16:12 +0000745 Module *M = BB->getModule();
746 Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
Neil Henning57f5d0a2018-10-08 10:32:33 +0000747 return createCallHelper(Fn, {LHS, RHS}, this, Name, FMFSource);
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000748}
Sanjay Pateld32104e2018-02-23 21:16:12 +0000749
750CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
Neil Henning57f5d0a2018-10-08 10:32:33 +0000751 ArrayRef<Type *> Types,
Sanjay Pateld32104e2018-02-23 21:16:12 +0000752 ArrayRef<Value *> Args,
753 Instruction *FMFSource,
754 const Twine &Name) {
Sanjay Pateld32104e2018-02-23 21:16:12 +0000755 Module *M = BB->getModule();
Neil Henning57f5d0a2018-10-08 10:32:33 +0000756 Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
Sanjay Pateld32104e2018-02-23 21:16:12 +0000757 return createCallHelper(Fn, Args, this, Name, FMFSource);
758}