1a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//===---- IRBuilder.cpp - Builder for LLVM Instrs -------------------------===//
2a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//
3a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//                     The LLVM Compiler Infrastructure
4a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//
5a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner// This file is distributed under the University of Illinois Open Source
6a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner// License. See LICENSE.TXT for details.
7a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//
8a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//===----------------------------------------------------------------------===//
9a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//
10a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner// This file implements the IRBuilder class, which is used as a convenient way
11a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner// to create LLVM instructions with a consistent and simplified interface.
12a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//
13a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner//===----------------------------------------------------------------------===//
14a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner
150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h"
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h"
190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
20a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattnerusing namespace llvm;
21a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner
22a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner/// CreateGlobalString - Make a new global variable with an initializer that
23f3b11aa6a72e0c31066a60c2e888e7a5eb5f2399Dan Gohman/// has array of i8 type filled in with the nul terminated string value
24a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner/// specified.  If Name is specified, it is the name of the global variable
25a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner/// created.
262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga NainarGlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar                                                  const Twine &Name) {
2818c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner  Constant *StrConstant = ConstantDataArray::getString(Context, Str);
29a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner  Module &M = *BB->getParent()->getParent();
30a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner  GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(),
31b143ea3739a9f714fff3e11ec472edfe06368748Benjamin Kramer                                          true, GlobalValue::PrivateLinkage,
32ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg                                          StrConstant);
33a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner  GV->setName(Name);
3484025ba08ff23711b9d3d33c6c21819d63d30865Nick Lewycky  GV->setUnnamedAddr(true);
35a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner  return GV;
36a53cfd16f075f22655a8c965b122aea38e635aa3Chris Lattner}
3743469b6957140898709382082ef95dd4b77ac20aChris Lattner
38a17ce80a1e475ab3526a4787b878d55a42727d19Chris LattnerType *IRBuilderBase::getCurrentFunctionReturnType() const {
392ad32752b9a880902550c7c47f1b9ca175ee851cChris Lattner  assert(BB && BB->getParent() && "No current function!");
402ad32752b9a880902550c7c47f1b9ca175ee851cChris Lattner  return BB->getParent()->getReturnType();
412ad32752b9a880902550c7c47f1b9ca175ee851cChris Lattner}
42c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
43c0d5496b8aa9993e61ac5770e58184dd32f709bfChris LattnerValue *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
44db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  PointerType *PT = cast<PointerType>(Ptr->getType());
45c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  if (PT->getElementType()->isIntegerTy(8))
46c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner    return Ptr;
47c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
48c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  // Otherwise, we need to insert a bitcast.
49c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  PT = getInt8PtrTy(PT->getAddressSpace());
50c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  BitCastInst *BCI = new BitCastInst(Ptr, PT, "");
51c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  BB->getInstList().insert(InsertPt, BCI);
52c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  SetInstDebugLocation(BCI);
53c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  return BCI;
54c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner}
55c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
56a3efbb15ddd5aa9006564cd79086723640084878Jay Foadstatic CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops,
57ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  IRBuilderBase *Builder,
58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  const Twine& Name="") {
59ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  CallInst *CI = CallInst::Create(Callee, Ops, Name);
60c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI);
61c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Builder->SetInstDebugLocation(CI);
62c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  return CI;
63c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner}
64c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
65c0d5496b8aa9993e61ac5770e58184dd32f709bfChris LattnerCallInst *IRBuilderBase::
66c0d5496b8aa9993e61ac5770e58184dd32f709bfChris LattnerCreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             MDNode *NoAliasTag) {
69c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Ptr = getCastedInt8PtrValue(Ptr);
70c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) };
715fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Tys[] = { Ptr->getType(), Size->getType() };
72c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Module *M = BB->getParent()->getParent();
73eb9a85f09e18b3fe88499710404b38d3a9128f62Benjamin Kramer  Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
74c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
75a3efbb15ddd5aa9006564cd79086723640084878Jay Foad  CallInst *CI = createCallHelper(TheFn, Ops, this);
76c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
77c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  // Set the TBAA info if present.
78c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  if (TBAATag)
79c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner    CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ScopeTag)
8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (NoAliasTag)
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
87c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  return CI;
88c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner}
89c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
90c0d5496b8aa9993e61ac5770e58184dd32f709bfChris LattnerCallInst *IRBuilderBase::
91c0d5496b8aa9993e61ac5770e58184dd32f709bfChris LattnerCreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
9237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag,
9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             MDNode *ScopeTag, MDNode *NoAliasTag) {
94c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Dst = getCastedInt8PtrValue(Dst);
95c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Src = getCastedInt8PtrValue(Src);
96c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
97c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
985fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
99c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Module *M = BB->getParent()->getParent();
100eb9a85f09e18b3fe88499710404b38d3a9128f62Benjamin Kramer  Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
101c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
102a3efbb15ddd5aa9006564cd79086723640084878Jay Foad  CallInst *CI = createCallHelper(TheFn, Ops, this);
103c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
104c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  // Set the TBAA info if present.
105c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  if (TBAATag)
106c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner    CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
1078a63f99f038e56245d0f5049966727cc87264c0cDan Gohman
1088a63f99f038e56245d0f5049966727cc87264c0cDan Gohman  // Set the TBAA Struct info if present.
1098a63f99f038e56245d0f5049966727cc87264c0cDan Gohman  if (TBAAStructTag)
1108a63f99f038e56245d0f5049966727cc87264c0cDan Gohman    CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ScopeTag)
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (NoAliasTag)
11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
118c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  return CI;
119c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner}
120c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
121c0d5496b8aa9993e61ac5770e58184dd32f709bfChris LattnerCallInst *IRBuilderBase::
122c0d5496b8aa9993e61ac5770e58184dd32f709bfChris LattnerCreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag,
12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              MDNode *NoAliasTag) {
125c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Dst = getCastedInt8PtrValue(Dst);
126c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Src = getCastedInt8PtrValue(Src);
127c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
128c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) };
1295fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
130c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  Module *M = BB->getParent()->getParent();
131eb9a85f09e18b3fe88499710404b38d3a9128f62Benjamin Kramer  Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
132c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
133a3efbb15ddd5aa9006564cd79086723640084878Jay Foad  CallInst *CI = createCallHelper(TheFn, Ops, this);
134c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner
135c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  // Set the TBAA info if present.
136c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  if (TBAATag)
137c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner    CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ScopeTag)
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (NoAliasTag)
14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
145c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner  return CI;
146c0d5496b8aa9993e61ac5770e58184dd32f709bfChris Lattner}
1470cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
1480cf51561eddd659a7b427f40144e22363fd95a57Nick LewyckyCallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
1490cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  assert(isa<PointerType>(Ptr->getType()) &&
15056cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling         "lifetime.start only applies to pointers.");
1510cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Ptr = getCastedInt8PtrValue(Ptr);
1520cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  if (!Size)
1530cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky    Size = getInt64(-1);
1540cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  else
1550cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky    assert(Size->getType() == getInt64Ty() &&
15656cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling           "lifetime.start requires the size to be an i64");
1570cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Value *Ops[] = { Size, Ptr };
1580cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Module *M = BB->getParent()->getParent();
1590cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start);
160a3efbb15ddd5aa9006564cd79086723640084878Jay Foad  return createCallHelper(TheFn, Ops, this);
1610cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky}
1620cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky
1630cf51561eddd659a7b427f40144e22363fd95a57Nick LewyckyCallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
1640cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  assert(isa<PointerType>(Ptr->getType()) &&
16556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling         "lifetime.end only applies to pointers.");
1660cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Ptr = getCastedInt8PtrValue(Ptr);
1670cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  if (!Size)
1680cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky    Size = getInt64(-1);
1690cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  else
1700cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky    assert(Size->getType() == getInt64Ty() &&
17156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling           "lifetime.end requires the size to be an i64");
1720cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Value *Ops[] = { Size, Ptr };
1730cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Module *M = BB->getParent()->getParent();
1740cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky  Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end);
175a3efbb15ddd5aa9006564cd79086723640084878Jay Foad  return createCallHelper(TheFn, Ops, this);
1760cf51561eddd659a7b427f40144e22363fd95a57Nick Lewycky}
17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCallInst *IRBuilderBase::CreateAssumption(Value *Cond) {
17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  assert(Cond->getType() == getInt1Ty() &&
18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         "an assumption condition must be of type i1");
18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Value *Ops[] = { Cond };
18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Module *M = BB->getParent()->getParent();
18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Value *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return createCallHelper(FnAssume, Ops, this);
18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Create a call to a Masked Load intrinsic.
189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Ptr      - the base pointer for the load
190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Align    - alignment of the source location
191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Mask     - an vector of booleans which indicates what vector lanes should
192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///            be accessed in memory
193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// PassThru - a pass-through value that is used to fill the masked-off lanes
194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///            of the result
195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Name     - name of the result variable
196ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align,
197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                          Value *Mask, Value *PassThru,
198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                          const Twine &Name) {
199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  assert(Ptr->getType()->isPointerTy() && "Ptr must be of pointer type");
200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // DataTy is the overloaded type
201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Type *DataTy = cast<PointerType>(Ptr->getType())->getElementType();
202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  assert(DataTy->isVectorTy() && "Ptr should point to a vector");
203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!PassThru)
204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    PassThru = UndefValue::get(DataTy);
205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Value *Ops[] = { Ptr, getInt32(Align), Mask,  PassThru};
206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops, DataTy, Name);
207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
208ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Create a call to a Masked Store intrinsic.
210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Val   - the data to be stored,
211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Ptr   - the base pointer for the store
212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Align - alignment of the destination location
213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Mask  - an vector of booleans which indicates what vector lanes should
214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///         be accessed in memory
215ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                           unsigned Align, Value *Mask) {
217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Value *Ops[] = { Val, Ptr, getInt32(Align), Mask };
218ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Type of the data to be stored - the only one overloaded type
219ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, Val->getType());
220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Create a call to a Masked intrinsic, with given intrinsic Id,
223ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// an array of operands - Ops, and one overloaded type - DataTy
224ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCallInst *IRBuilderBase::CreateMaskedIntrinsic(unsigned Id,
225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                               ArrayRef<Value *> Ops,
226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                               Type *DataTy,
227ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                               const Twine &Name) {
228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Module *M = BB->getParent()->getParent();
229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Type *OverloadedTypes[] = { DataTy };
230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Value *TheFn = Intrinsic::getDeclaration(M, (Intrinsic::ID)Id, OverloadedTypes);
231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return createCallHelper(TheFn, Ops, this, Name);
232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
234ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee,
235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            ArrayRef<Value *> CallArgs,
236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            ArrayRef<Value *> DeoptArgs,
237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            ArrayRef<Value *> GCArgs,
238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            const Twine &Name) {
239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Extract out the type of the callee.
240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType());
241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        "actual callee must be a callable value");
243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Module *M = BB->getParent()->getParent();
246ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Fill in the one generic type'd argument (the function is also vararg)
247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *ArgTypes[] = { FuncPtrType };
248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *FnStatepoint =
249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines   Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                             ArgTypes);
251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<llvm::Value *> args;
253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines args.push_back(ActualCallee);
254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines args.push_back(getInt32(CallArgs.size()));
255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines args.push_back(getInt32(0 /*unused*/));
256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines args.insert(args.end(), CallArgs.begin(), CallArgs.end());
257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines args.push_back(getInt32(DeoptArgs.size()));
258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines args.insert(args.end(), DeoptArgs.begin(), DeoptArgs.end());
259ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines args.insert(args.end(), GCArgs.begin(), GCArgs.end());
260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return createCallHelper(FnStatepoint, args, this, Name);
262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
264ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee,
265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            ArrayRef<Use> CallArgs,
266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            ArrayRef<Value *> DeoptArgs,
267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            ArrayRef<Value *> GCArgs,
268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            const Twine &Name) {
269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::vector<Value *> VCallArgs;
270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (auto &U : CallArgs)
271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    VCallArgs.push_back(U.get());
272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return CreateGCStatepoint(ActualCallee, VCallArgs, DeoptArgs, GCArgs, Name);
273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
274ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
275ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       Type *ResultType,
277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                       const Twine &Name) {
278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Intrinsic::ID ID = Intrinsic::experimental_gc_result;
279ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Module *M = BB->getParent()->getParent();
280ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *Types[] = {ResultType};
281ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Args[] = {Statepoint};
284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return createCallHelper(FnGCResult, Args, this, Name);
285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
287ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesCallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                         int BaseOffset,
289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                         int DerivedOffset,
290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                         Type *ResultType,
291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                         const Twine &Name) {
292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Module *M = BB->getParent()->getParent();
293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *Types[] = {ResultType};
294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FnGCRelocate =
295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines   Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Args[] = {Statepoint,
298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  getInt32(BaseOffset),
299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  getInt32(DerivedOffset)};
300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return createCallHelper(FnGCRelocate, Args, this, Name);
301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
302