blob: 485b62139ac327b7dd373724922c884f4dea758a [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//
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
Chandler Carruth6bda14b2017-06-06 11:49:48 +000015#include "llvm/IR/IRBuilder.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000016#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/None.h"
18#include "llvm/IR/Constant.h"
19#include "llvm/IR/Constants.h"
20#include "llvm/IR/DerivedTypes.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000021#include "llvm/IR/Function.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000022#include "llvm/IR/GlobalValue.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000023#include "llvm/IR/GlobalVariable.h"
Daniel Neilson1e687242018-01-19 17:13:12 +000024#include "llvm/IR/IntrinsicInst.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000025#include "llvm/IR/Intrinsics.h"
26#include "llvm/IR/LLVMContext.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000027#include "llvm/IR/Operator.h"
Pat Gavlincc0431d2015-05-08 18:07:42 +000028#include "llvm/IR/Statepoint.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000029#include "llvm/IR/Type.h"
30#include "llvm/IR/Value.h"
31#include "llvm/Support/Casting.h"
32#include "llvm/Support/MathExtras.h"
33#include <cassert>
34#include <cstdint>
35#include <vector>
36
Chris Lattner17079fc2009-12-28 21:28:46 +000037using namespace llvm;
38
39/// CreateGlobalString - Make a new global variable with an initializer that
Dan Gohman97c59022010-02-10 20:04:19 +000040/// has array of i8 type filled in with the nul terminated string value
Chris Lattner17079fc2009-12-28 21:28:46 +000041/// specified. If Name is specified, it is the name of the global variable
42/// created.
David Blaikieaa41cd52015-04-03 21:33:42 +000043GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
Tobias Grossercdb89142015-06-19 02:12:07 +000044 const Twine &Name,
45 unsigned AddressSpace) {
Chris Lattnercf9e8f62012-02-05 02:29:43 +000046 Constant *StrConstant = ConstantDataArray::getString(Context, Str);
Chris Lattner17079fc2009-12-28 21:28:46 +000047 Module &M = *BB->getParent()->getParent();
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000048 auto *GV = new GlobalVariable(M, StrConstant->getType(), true,
49 GlobalValue::PrivateLinkage, StrConstant, Name,
50 nullptr, GlobalVariable::NotThreadLocal,
51 AddressSpace);
Peter Collingbourne96efdd62016-06-14 21:01:22 +000052 GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
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;
65
66 // 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
Jay Foad5bd375a2011-07-15 08:37:34 +000074static CallInst *createCallHelper(Value *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);
83 return CI;
84}
85
Sanjoy Dasabe1c682015-05-06 23:53:09 +000086static InvokeInst *createInvokeHelper(Value *Invokee, BasicBlock *NormalDest,
87 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();
Benjamin Kramere6e19332011-07-14 17:45:39 +0000107 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
Chris Lattner143a07c2010-12-26 22:49:25 +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);
120
121 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
127CallInst *IRBuilderBase::
Daniel Neilson551a4d62018-01-27 17:59:10 +0000128CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
129 Value *Size, bool isVolatile, MDNode *TBAATag,
130 MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
131 assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2");
132 assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2");
Chris Lattner143a07c2010-12-26 22:49:25 +0000133 Dst = getCastedInt8PtrValue(Dst);
134 Src = getCastedInt8PtrValue(Src);
135
Daniel Neilson1e687242018-01-19 17:13:12 +0000136 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +0000137 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +0000138 Module *M = BB->getParent()->getParent();
Benjamin Kramere6e19332011-07-14 17:45:39 +0000139 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
Chris Lattner143a07c2010-12-26 22:49:25 +0000140
Jay Foad5bd375a2011-07-15 08:37:34 +0000141 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +0000142
Daniel Neilson551a4d62018-01-27 17:59:10 +0000143 auto* MCI = cast<MemCpyInst>(CI);
144 if (DstAlign > 0)
145 MCI->setDestAlignment(DstAlign);
146 if (SrcAlign > 0)
147 MCI->setSourceAlignment(SrcAlign);
Daniel Neilson1e687242018-01-19 17:13:12 +0000148
Chris Lattner143a07c2010-12-26 22:49:25 +0000149 // Set the TBAA info if present.
150 if (TBAATag)
151 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Dan Gohman099727f2012-09-26 22:17:14 +0000152
153 // Set the TBAA Struct info if present.
154 if (TBAAStructTag)
155 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
Hal Finkel94146652014-07-24 14:25:39 +0000156
157 if (ScopeTag)
158 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
159
160 if (NoAliasTag)
161 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
Daniel Neilson1e687242018-01-19 17:13:12 +0000162
Chris Lattner143a07c2010-12-26 22:49:25 +0000163 return CI;
164}
165
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000166CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000167 Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size,
168 uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
169 MDNode *ScopeTag, MDNode *NoAliasTag) {
170 assert(DstAlign >= ElementSize &&
171 "Pointer alignment must be at least element size");
172 assert(SrcAlign >= ElementSize &&
173 "Pointer alignment must be at least element size");
Anna Thomasb2a212c2017-06-06 16:45:25 +0000174 Dst = getCastedInt8PtrValue(Dst);
175 Src = getCastedInt8PtrValue(Src);
176
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000177 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
178 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
Anna Thomasb2a212c2017-06-06 16:45:25 +0000179 Module *M = BB->getParent()->getParent();
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000180 Value *TheFn = Intrinsic::getDeclaration(
181 M, Intrinsic::memcpy_element_unordered_atomic, Tys);
Anna Thomasb2a212c2017-06-06 16:45:25 +0000182
183 CallInst *CI = createCallHelper(TheFn, Ops, this);
184
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000185 // Set the alignment of the pointer args.
Daniel Neilson1e687242018-01-19 17:13:12 +0000186 auto *AMCI = cast<AtomicMemCpyInst>(CI);
187 AMCI->setDestAlignment(DstAlign);
188 AMCI->setSourceAlignment(SrcAlign);
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000189
Anna Thomasb2a212c2017-06-06 16:45:25 +0000190 // Set the TBAA info if present.
191 if (TBAATag)
192 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
193
194 // Set the TBAA Struct info if present.
195 if (TBAAStructTag)
196 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
197
198 if (ScopeTag)
199 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
200
201 if (NoAliasTag)
202 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
203
204 return CI;
205}
206
Chris Lattner143a07c2010-12-26 22:49:25 +0000207CallInst *IRBuilderBase::
Daniel Neilson551a4d62018-01-27 17:59:10 +0000208CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
209 Value *Size, bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
Hal Finkel94146652014-07-24 14:25:39 +0000210 MDNode *NoAliasTag) {
Daniel Neilson551a4d62018-01-27 17:59:10 +0000211 assert((DstAlign == 0 || isPowerOf2_32(DstAlign)) && "Must be 0 or a power of 2");
212 assert((SrcAlign == 0 || isPowerOf2_32(SrcAlign)) && "Must be 0 or a power of 2");
Chris Lattner143a07c2010-12-26 22:49:25 +0000213 Dst = getCastedInt8PtrValue(Dst);
214 Src = getCastedInt8PtrValue(Src);
Daniel Neilson1e687242018-01-19 17:13:12 +0000215
216 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +0000217 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +0000218 Module *M = BB->getParent()->getParent();
Benjamin Kramere6e19332011-07-14 17:45:39 +0000219 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
Chris Lattner143a07c2010-12-26 22:49:25 +0000220
Jay Foad5bd375a2011-07-15 08:37:34 +0000221 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +0000222
223 auto *MMI = cast<MemMoveInst>(CI);
Daniel Neilson551a4d62018-01-27 17:59:10 +0000224 if (DstAlign > 0)
225 MMI->setDestAlignment(DstAlign);
226 if (SrcAlign > 0)
227 MMI->setSourceAlignment(SrcAlign);
Daniel Neilson1e687242018-01-19 17:13:12 +0000228
Chris Lattner143a07c2010-12-26 22:49:25 +0000229 // Set the TBAA info if present.
230 if (TBAATag)
231 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Hal Finkel94146652014-07-24 14:25:39 +0000232
233 if (ScopeTag)
234 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
235
236 if (NoAliasTag)
237 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
238
Chris Lattner143a07c2010-12-26 22:49:25 +0000239 return CI;
240}
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000241
Amara Emersoncf9daa32017-05-09 10:43:25 +0000242static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
243 Value *Src) {
244 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
245 Value *Ops[] = {Src};
246 Type *Tys[] = { Src->getType()->getVectorElementType(), Src->getType() };
247 auto Decl = Intrinsic::getDeclaration(M, ID, Tys);
248 return createCallHelper(Decl, Ops, Builder);
249}
250
251CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
252 Module *M = GetInsertBlock()->getParent()->getParent();
253 Value *Ops[] = {Acc, Src};
254 Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
255 Src->getType()};
256 auto Decl = Intrinsic::getDeclaration(
257 M, Intrinsic::experimental_vector_reduce_fadd, Tys);
258 return createCallHelper(Decl, Ops, this);
259}
260
261CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
262 Module *M = GetInsertBlock()->getParent()->getParent();
263 Value *Ops[] = {Acc, Src};
264 Type *Tys[] = {Src->getType()->getVectorElementType(), Acc->getType(),
265 Src->getType()};
266 auto Decl = Intrinsic::getDeclaration(
267 M, Intrinsic::experimental_vector_reduce_fmul, Tys);
268 return createCallHelper(Decl, Ops, this);
269}
270
271CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
272 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_add,
273 Src);
274}
275
276CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
277 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_mul,
278 Src);
279}
280
281CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
282 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_and,
283 Src);
284}
285
286CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
287 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_or,
288 Src);
289}
290
291CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
292 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_xor,
293 Src);
294}
295
296CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
297 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smax
298 : Intrinsic::experimental_vector_reduce_umax;
299 return getReductionIntrinsic(this, ID, Src);
300}
301
302CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
303 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smin
304 : Intrinsic::experimental_vector_reduce_umin;
305 return getReductionIntrinsic(this, ID, Src);
306}
307
308CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src, bool NoNaN) {
309 auto Rdx = getReductionIntrinsic(
310 this, Intrinsic::experimental_vector_reduce_fmax, Src);
311 if (NoNaN) {
312 FastMathFlags FMF;
313 FMF.setNoNaNs();
314 Rdx->setFastMathFlags(FMF);
315 }
316 return Rdx;
317}
318
319CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src, bool NoNaN) {
320 auto Rdx = getReductionIntrinsic(
321 this, Intrinsic::experimental_vector_reduce_fmin, Src);
322 if (NoNaN) {
323 FastMathFlags FMF;
324 FMF.setNoNaNs();
325 Rdx->setFastMathFlags(FMF);
326 }
327 return Rdx;
328}
329
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000330CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
331 assert(isa<PointerType>(Ptr->getType()) &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000332 "lifetime.start only applies to pointers.");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000333 Ptr = getCastedInt8PtrValue(Ptr);
334 if (!Size)
335 Size = getInt64(-1);
336 else
337 assert(Size->getType() == getInt64Ty() &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000338 "lifetime.start requires the size to be an i64");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000339 Value *Ops[] = { Size, Ptr };
340 Module *M = BB->getParent()->getParent();
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000341 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start,
342 { Ptr->getType() });
Jay Foad5bd375a2011-07-15 08:37:34 +0000343 return createCallHelper(TheFn, Ops, this);
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000344}
345
346CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
347 assert(isa<PointerType>(Ptr->getType()) &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000348 "lifetime.end only applies to pointers.");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000349 Ptr = getCastedInt8PtrValue(Ptr);
350 if (!Size)
351 Size = getInt64(-1);
352 else
353 assert(Size->getType() == getInt64Ty() &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000354 "lifetime.end requires the size to be an i64");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000355 Value *Ops[] = { Size, Ptr };
356 Module *M = BB->getParent()->getParent();
Matt Arsenaultf10061e2017-04-10 20:18:21 +0000357 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end,
358 { Ptr->getType() });
Jay Foad5bd375a2011-07-15 08:37:34 +0000359 return createCallHelper(TheFn, Ops, this);
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000360}
Hal Finkel6f814db2014-10-15 23:44:22 +0000361
Anna Thomas58d11922016-07-22 20:57:23 +0000362CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
363
364 assert(isa<PointerType>(Ptr->getType()) &&
365 "invariant.start only applies to pointers.");
366 Ptr = getCastedInt8PtrValue(Ptr);
367 if (!Size)
368 Size = getInt64(-1);
369 else
370 assert(Size->getType() == getInt64Ty() &&
371 "invariant.start requires the size to be an i64");
372
373 Value *Ops[] = {Size, Ptr};
374 // Fill in the single overloaded type: memory object type.
375 Type *ObjectPtr[1] = {Ptr->getType()};
376 Module *M = BB->getParent()->getParent();
377 Value *TheFn =
378 Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr);
379 return createCallHelper(TheFn, Ops, this);
380}
381
Hal Finkel6f814db2014-10-15 23:44:22 +0000382CallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
383 assert(Cond->getType() == getInt1Ty() &&
384 "an assumption condition must be of type i1");
385
386 Value *Ops[] = { Cond };
387 Module *M = BB->getParent()->getParent();
388 Value *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
389 return createCallHelper(FnAssume, Ops, this);
390}
391
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000392/// \brief Create a call to a Masked Load intrinsic.
393/// \p Ptr - base pointer for the load
394/// \p Align - alignment of the source location
395/// \p Mask - vector of booleans which indicates what vector lanes should
396/// be accessed in memory
397/// \p PassThru - pass-through value that is used to fill the masked-off lanes
398/// of the result
399/// \p Name - name of the result variable
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000400CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align,
401 Value *Mask, Value *PassThru,
402 const Twine &Name) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000403 auto *PtrTy = cast<PointerType>(Ptr->getType());
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000404 Type *DataTy = PtrTy->getElementType();
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000405 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
Ayal Zakse841b212017-07-31 13:21:42 +0000406 assert(Mask && "Mask should not be all-ones (null)");
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000407 if (!PassThru)
408 PassThru = UndefValue::get(DataTy);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000409 Type *OverloadedTypes[] = { DataTy, PtrTy };
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000410 Value *Ops[] = { Ptr, getInt32(Align), Mask, PassThru};
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000411 return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
412 OverloadedTypes, Name);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000413}
414
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000415/// \brief Create a call to a Masked Store intrinsic.
416/// \p Val - data to be stored,
417/// \p Ptr - base pointer for the store
418/// \p Align - alignment of the destination location
419/// \p Mask - vector of booleans which indicates what vector lanes should
420/// be accessed in memory
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000421CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
422 unsigned Align, Value *Mask) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000423 auto *PtrTy = cast<PointerType>(Ptr->getType());
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000424 Type *DataTy = PtrTy->getElementType();
425 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
Ayal Zakse841b212017-07-31 13:21:42 +0000426 assert(Mask && "Mask should not be all-ones (null)");
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000427 Type *OverloadedTypes[] = { DataTy, PtrTy };
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000428 Value *Ops[] = { Val, Ptr, getInt32(Align), Mask };
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000429 return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000430}
431
432/// Create a call to a Masked intrinsic, with given intrinsic Id,
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000433/// an array of operands - Ops, and an array of overloaded types -
434/// OverloadedTypes.
Pete Cooper9e1d3352015-05-20 17:16:39 +0000435CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000436 ArrayRef<Value *> Ops,
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000437 ArrayRef<Type *> OverloadedTypes,
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000438 const Twine &Name) {
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000439 Module *M = BB->getParent()->getParent();
Pete Cooper9e1d3352015-05-20 17:16:39 +0000440 Value *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000441 return createCallHelper(TheFn, Ops, this, Name);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000442}
Philip Reames4750dd12014-12-30 05:55:58 +0000443
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000444/// \brief Create a call to a Masked Gather intrinsic.
445/// \p Ptrs - vector of pointers for loading
446/// \p Align - alignment for one element
447/// \p Mask - vector of booleans which indicates what vector lanes should
448/// be accessed in memory
449/// \p PassThru - pass-through value that is used to fill the masked-off lanes
450/// of the result
451/// \p Name - name of the result variable
452CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, unsigned Align,
453 Value *Mask, Value *PassThru,
454 const Twine& Name) {
455 auto PtrsTy = cast<VectorType>(Ptrs->getType());
456 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
457 unsigned NumElts = PtrsTy->getVectorNumElements();
458 Type *DataTy = VectorType::get(PtrTy->getElementType(), NumElts);
459
460 if (!Mask)
461 Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
462 NumElts));
463
Amara Emerson4d33c862017-05-19 10:40:18 +0000464 if (!PassThru)
465 PassThru = UndefValue::get(DataTy);
466
Elad Cohenef5798a2017-05-03 12:28:54 +0000467 Type *OverloadedTypes[] = {DataTy, PtrsTy};
Amara Emerson4d33c862017-05-19 10:40:18 +0000468 Value * Ops[] = {Ptrs, getInt32(Align), Mask, PassThru};
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000469
470 // We specify only one type when we create this intrinsic. Types of other
471 // arguments are derived from this type.
Elad Cohenef5798a2017-05-03 12:28:54 +0000472 return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, OverloadedTypes,
473 Name);
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000474}
475
476/// \brief Create a call to a Masked Scatter intrinsic.
477/// \p Data - data to be stored,
478/// \p Ptrs - the vector of pointers, where the \p Data elements should be
479/// stored
480/// \p Align - alignment for one element
481/// \p Mask - vector of booleans which indicates what vector lanes should
482/// be accessed in memory
483CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
484 unsigned Align, Value *Mask) {
485 auto PtrsTy = cast<VectorType>(Ptrs->getType());
486 auto DataTy = cast<VectorType>(Data->getType());
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000487 unsigned NumElts = PtrsTy->getVectorNumElements();
488
Tim Northover5a1a56c2016-02-17 21:16:59 +0000489#ifndef NDEBUG
490 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000491 assert(NumElts == DataTy->getVectorNumElements() &&
Tim Northover5a1a56c2016-02-17 21:16:59 +0000492 PtrTy->getElementType() == DataTy->getElementType() &&
493 "Incompatible pointer and data types");
494#endif
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000495
496 if (!Mask)
497 Mask = Constant::getAllOnesValue(VectorType::get(Type::getInt1Ty(Context),
498 NumElts));
Elad Cohenef5798a2017-05-03 12:28:54 +0000499
500 Type *OverloadedTypes[] = {DataTy, PtrsTy};
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000501 Value * Ops[] = {Data, Ptrs, getInt32(Align), Mask};
502
503 // We specify only one type when we create this intrinsic. Types of other
504 // arguments are derived from this type.
Elad Cohenef5798a2017-05-03 12:28:54 +0000505 return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000506}
507
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000508template <typename T0, typename T1, typename T2, typename T3>
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000509static std::vector<Value *>
510getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000511 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
512 ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs,
513 ArrayRef<T3> GCArgs) {
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000514 std::vector<Value *> Args;
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000515 Args.push_back(B.getInt64(ID));
516 Args.push_back(B.getInt32(NumPatchBytes));
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000517 Args.push_back(ActualCallee);
518 Args.push_back(B.getInt32(CallArgs.size()));
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000519 Args.push_back(B.getInt32(Flags));
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000520 Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000521 Args.push_back(B.getInt32(TransitionArgs.size()));
522 Args.insert(Args.end(), TransitionArgs.begin(), TransitionArgs.end());
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000523 Args.push_back(B.getInt32(DeoptArgs.size()));
524 Args.insert(Args.end(), DeoptArgs.begin(), DeoptArgs.end());
525 Args.insert(Args.end(), GCArgs.begin(), GCArgs.end());
526
527 return Args;
528}
529
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000530template <typename T0, typename T1, typename T2, typename T3>
531static CallInst *CreateGCStatepointCallCommon(
532 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000533 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000534 ArrayRef<T1> TransitionArgs, ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs,
535 const Twine &Name) {
Sanjoy Das63245b52015-05-06 02:36:34 +0000536 // Extract out the type of the callee.
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000537 auto *FuncPtrType = cast<PointerType>(ActualCallee->getType());
Sanjoy Das63245b52015-05-06 02:36:34 +0000538 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
539 "actual callee must be a callable value");
Philip Reames4750dd12014-12-30 05:55:58 +0000540
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000541 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
Sanjoy Das63245b52015-05-06 02:36:34 +0000542 // Fill in the one generic type'd argument (the function is also vararg)
543 Type *ArgTypes[] = { FuncPtrType };
544 Function *FnStatepoint =
545 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
546 ArgTypes);
Philip Reames4750dd12014-12-30 05:55:58 +0000547
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000548 std::vector<Value *> Args =
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000549 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
550 CallArgs, TransitionArgs, DeoptArgs, GCArgs);
551 return createCallHelper(FnStatepoint, Args, Builder, Name);
552}
553
554CallInst *IRBuilderBase::CreateGCStatepointCall(
555 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
556 ArrayRef<Value *> CallArgs, ArrayRef<Value *> DeoptArgs,
557 ArrayRef<Value *> GCArgs, const Twine &Name) {
558 return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000559 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
560 CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000561}
562
563CallInst *IRBuilderBase::CreateGCStatepointCall(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000564 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
565 ArrayRef<Use> CallArgs, ArrayRef<Use> TransitionArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000566 ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
567 return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
568 this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
569 DeoptArgs, GCArgs, Name);
Philip Reames4750dd12014-12-30 05:55:58 +0000570}
571
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000572CallInst *IRBuilderBase::CreateGCStatepointCall(
573 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
574 ArrayRef<Use> CallArgs, ArrayRef<Value *> DeoptArgs,
575 ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000576 return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000577 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
578 CallArgs, None, DeoptArgs, GCArgs, Name);
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000579}
580
581template <typename T0, typename T1, typename T2, typename T3>
582static InvokeInst *CreateGCStatepointInvokeCommon(
583 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
584 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000585 uint32_t Flags, ArrayRef<T0> InvokeArgs, ArrayRef<T1> TransitionArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000586 ArrayRef<T2> DeoptArgs, ArrayRef<T3> GCArgs, const Twine &Name) {
587 // Extract out the type of the callee.
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000588 auto *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000589 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
590 "actual callee must be a callable value");
591
592 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
593 // Fill in the one generic type'd argument (the function is also vararg)
594 Function *FnStatepoint = Intrinsic::getDeclaration(
595 M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
596
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000597 std::vector<Value *> Args =
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000598 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
599 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs);
600 return createInvokeHelper(FnStatepoint, NormalDest, UnwindDest, Args, Builder,
601 Name);
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000602}
603
604InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000605 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
606 BasicBlock *NormalDest, BasicBlock *UnwindDest,
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000607 ArrayRef<Value *> InvokeArgs, ArrayRef<Value *> DeoptArgs,
608 ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000609 return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
610 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000611 uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000612 DeoptArgs, GCArgs, Name);
613}
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000614
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000615InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
616 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000617 BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000618 ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
619 ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
620 return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
621 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
622 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000623}
624
625InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000626 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
627 BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
628 ArrayRef<Value *> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000629 return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
630 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000631 uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
632 Name);
Ramkumar Ramachandra3408f3e2015-02-26 00:35:56 +0000633}
634
Philip Reames4750dd12014-12-30 05:55:58 +0000635CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
636 Type *ResultType,
637 const Twine &Name) {
Ramkumar Ramachandra75a4f352015-01-22 20:14:38 +0000638 Intrinsic::ID ID = Intrinsic::experimental_gc_result;
Philip Reames4750dd12014-12-30 05:55:58 +0000639 Module *M = BB->getParent()->getParent();
640 Type *Types[] = {ResultType};
641 Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
642
643 Value *Args[] = {Statepoint};
644 return createCallHelper(FnGCResult, Args, this, Name);
645}
646
647CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
648 int BaseOffset,
649 int DerivedOffset,
650 Type *ResultType,
651 const Twine &Name) {
652 Module *M = BB->getParent()->getParent();
653 Type *Types[] = {ResultType};
654 Value *FnGCRelocate =
655 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
656
657 Value *Args[] = {Statepoint,
658 getInt32(BaseOffset),
659 getInt32(DerivedOffset)};
660 return createCallHelper(FnGCRelocate, Args, this, Name);
661}
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000662
663CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID,
664 Value *LHS, Value *RHS,
665 const Twine &Name) {
Sanjay Pateld32104e2018-02-23 21:16:12 +0000666 Module *M = BB->getModule();
667 Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000668 return createCallHelper(Fn, { LHS, RHS }, this, Name);
669}
Sanjay Pateld32104e2018-02-23 21:16:12 +0000670
671CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
672 ArrayRef<Value *> Args,
673 Instruction *FMFSource,
674 const Twine &Name) {
675 assert(!Args.empty() && "Expected at least one argument to intrinsic");
676 Module *M = BB->getModule();
677 Function *Fn = Intrinsic::getDeclaration(M, ID, { Args.front()->getType() });
678 return createCallHelper(Fn, Args, this, Name, FMFSource);
679}