IRBuilder.cpp 29 KB

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