1//===---- IRBuilder.cpp - Builder for LLVM Instrs -------------------------===// 2// 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 15#include "llvm/IR/Function.h" 16#include "llvm/IR/GlobalVariable.h" 17#include "llvm/IR/IRBuilder.h" 18#include "llvm/IR/Intrinsics.h" 19#include "llvm/IR/LLVMContext.h" 20using namespace llvm; 21 22/// CreateGlobalString - Make a new global variable with an initializer that 23/// has array of i8 type filled in with the nul terminated string value 24/// specified. If Name is specified, it is the name of the global variable 25/// created. 26GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str, 27 const Twine &Name) { 28 Constant *StrConstant = ConstantDataArray::getString(Context, Str); 29 Module &M = *BB->getParent()->getParent(); 30 GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(), 31 true, GlobalValue::PrivateLinkage, 32 StrConstant); 33 GV->setName(Name); 34 GV->setUnnamedAddr(true); 35 return GV; 36} 37 38Type *IRBuilderBase::getCurrentFunctionReturnType() const { 39 assert(BB && BB->getParent() && "No current function!"); 40 return BB->getParent()->getReturnType(); 41} 42 43Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) { 44 PointerType *PT = cast<PointerType>(Ptr->getType()); 45 if (PT->getElementType()->isIntegerTy(8)) 46 return Ptr; 47 48 // Otherwise, we need to insert a bitcast. 49 PT = getInt8PtrTy(PT->getAddressSpace()); 50 BitCastInst *BCI = new BitCastInst(Ptr, PT, ""); 51 BB->getInstList().insert(InsertPt, BCI); 52 SetInstDebugLocation(BCI); 53 return BCI; 54} 55 56static CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops, 57 IRBuilderBase *Builder, 58 const Twine& Name="") { 59 CallInst *CI = CallInst::Create(Callee, Ops, Name); 60 Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI); 61 Builder->SetInstDebugLocation(CI); 62 return CI; 63} 64 65CallInst *IRBuilderBase:: 66CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, 67 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag, 68 MDNode *NoAliasTag) { 69 Ptr = getCastedInt8PtrValue(Ptr); 70 Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) }; 71 Type *Tys[] = { Ptr->getType(), Size->getType() }; 72 Module *M = BB->getParent()->getParent(); 73 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys); 74 75 CallInst *CI = createCallHelper(TheFn, Ops, this); 76 77 // Set the TBAA info if present. 78 if (TBAATag) 79 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); 80 81 if (ScopeTag) 82 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag); 83 84 if (NoAliasTag) 85 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag); 86 87 return CI; 88} 89 90CallInst *IRBuilderBase:: 91CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, 92 bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag, 93 MDNode *ScopeTag, MDNode *NoAliasTag) { 94 Dst = getCastedInt8PtrValue(Dst); 95 Src = getCastedInt8PtrValue(Src); 96 97 Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; 98 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; 99 Module *M = BB->getParent()->getParent(); 100 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys); 101 102 CallInst *CI = createCallHelper(TheFn, Ops, this); 103 104 // Set the TBAA info if present. 105 if (TBAATag) 106 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); 107 108 // Set the TBAA Struct info if present. 109 if (TBAAStructTag) 110 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag); 111 112 if (ScopeTag) 113 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag); 114 115 if (NoAliasTag) 116 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag); 117 118 return CI; 119} 120 121CallInst *IRBuilderBase:: 122CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, 123 bool isVolatile, MDNode *TBAATag, MDNode *ScopeTag, 124 MDNode *NoAliasTag) { 125 Dst = getCastedInt8PtrValue(Dst); 126 Src = getCastedInt8PtrValue(Src); 127 128 Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; 129 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; 130 Module *M = BB->getParent()->getParent(); 131 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys); 132 133 CallInst *CI = createCallHelper(TheFn, Ops, this); 134 135 // Set the TBAA info if present. 136 if (TBAATag) 137 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); 138 139 if (ScopeTag) 140 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag); 141 142 if (NoAliasTag) 143 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag); 144 145 return CI; 146} 147 148CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) { 149 assert(isa<PointerType>(Ptr->getType()) && 150 "lifetime.start only applies to pointers."); 151 Ptr = getCastedInt8PtrValue(Ptr); 152 if (!Size) 153 Size = getInt64(-1); 154 else 155 assert(Size->getType() == getInt64Ty() && 156 "lifetime.start requires the size to be an i64"); 157 Value *Ops[] = { Size, Ptr }; 158 Module *M = BB->getParent()->getParent(); 159 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start); 160 return createCallHelper(TheFn, Ops, this); 161} 162 163CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) { 164 assert(isa<PointerType>(Ptr->getType()) && 165 "lifetime.end only applies to pointers."); 166 Ptr = getCastedInt8PtrValue(Ptr); 167 if (!Size) 168 Size = getInt64(-1); 169 else 170 assert(Size->getType() == getInt64Ty() && 171 "lifetime.end requires the size to be an i64"); 172 Value *Ops[] = { Size, Ptr }; 173 Module *M = BB->getParent()->getParent(); 174 Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end); 175 return createCallHelper(TheFn, Ops, this); 176} 177 178CallInst *IRBuilderBase::CreateAssumption(Value *Cond) { 179 assert(Cond->getType() == getInt1Ty() && 180 "an assumption condition must be of type i1"); 181 182 Value *Ops[] = { Cond }; 183 Module *M = BB->getParent()->getParent(); 184 Value *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume); 185 return createCallHelper(FnAssume, Ops, this); 186} 187 188/// Create a call to a Masked Load intrinsic. 189/// Ptr - the base pointer for the load 190/// Align - alignment of the source location 191/// Mask - an vector of booleans which indicates what vector lanes should 192/// be accessed in memory 193/// PassThru - a pass-through value that is used to fill the masked-off lanes 194/// of the result 195/// Name - name of the result variable 196CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, unsigned Align, 197 Value *Mask, Value *PassThru, 198 const Twine &Name) { 199 assert(Ptr->getType()->isPointerTy() && "Ptr must be of pointer type"); 200 // DataTy is the overloaded type 201 Type *DataTy = cast<PointerType>(Ptr->getType())->getElementType(); 202 assert(DataTy->isVectorTy() && "Ptr should point to a vector"); 203 if (!PassThru) 204 PassThru = UndefValue::get(DataTy); 205 Value *Ops[] = { Ptr, getInt32(Align), Mask, PassThru}; 206 return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops, DataTy, Name); 207} 208 209/// Create a call to a Masked Store intrinsic. 210/// Val - the data to be stored, 211/// Ptr - the base pointer for the store 212/// Align - alignment of the destination location 213/// Mask - an vector of booleans which indicates what vector lanes should 214/// be accessed in memory 215CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr, 216 unsigned Align, Value *Mask) { 217 Value *Ops[] = { Val, Ptr, getInt32(Align), Mask }; 218 // Type of the data to be stored - the only one overloaded type 219 return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, Val->getType()); 220} 221 222/// Create a call to a Masked intrinsic, with given intrinsic Id, 223/// an array of operands - Ops, and one overloaded type - DataTy 224CallInst *IRBuilderBase::CreateMaskedIntrinsic(unsigned Id, 225 ArrayRef<Value *> Ops, 226 Type *DataTy, 227 const Twine &Name) { 228 Module *M = BB->getParent()->getParent(); 229 Type *OverloadedTypes[] = { DataTy }; 230 Value *TheFn = Intrinsic::getDeclaration(M, (Intrinsic::ID)Id, OverloadedTypes); 231 return createCallHelper(TheFn, Ops, this, Name); 232} 233 234CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, 235 ArrayRef<Value *> CallArgs, 236 ArrayRef<Value *> DeoptArgs, 237 ArrayRef<Value *> GCArgs, 238 const Twine &Name) { 239 // Extract out the type of the callee. 240 PointerType *FuncPtrType = cast<PointerType>(ActualCallee->getType()); 241 assert(isa<FunctionType>(FuncPtrType->getElementType()) && 242 "actual callee must be a callable value"); 243 244 245 Module *M = BB->getParent()->getParent(); 246 // Fill in the one generic type'd argument (the function is also vararg) 247 Type *ArgTypes[] = { FuncPtrType }; 248 Function *FnStatepoint = 249 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint, 250 ArgTypes); 251 252 std::vector<llvm::Value *> args; 253 args.push_back(ActualCallee); 254 args.push_back(getInt32(CallArgs.size())); 255 args.push_back(getInt32(0 /*unused*/)); 256 args.insert(args.end(), CallArgs.begin(), CallArgs.end()); 257 args.push_back(getInt32(DeoptArgs.size())); 258 args.insert(args.end(), DeoptArgs.begin(), DeoptArgs.end()); 259 args.insert(args.end(), GCArgs.begin(), GCArgs.end()); 260 261 return createCallHelper(FnStatepoint, args, this, Name); 262} 263 264CallInst *IRBuilderBase::CreateGCStatepoint(Value *ActualCallee, 265 ArrayRef<Use> CallArgs, 266 ArrayRef<Value *> DeoptArgs, 267 ArrayRef<Value *> GCArgs, 268 const Twine &Name) { 269 std::vector<Value *> VCallArgs; 270 for (auto &U : CallArgs) 271 VCallArgs.push_back(U.get()); 272 return CreateGCStatepoint(ActualCallee, VCallArgs, DeoptArgs, GCArgs, Name); 273} 274 275CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint, 276 Type *ResultType, 277 const Twine &Name) { 278 Intrinsic::ID ID = Intrinsic::experimental_gc_result; 279 Module *M = BB->getParent()->getParent(); 280 Type *Types[] = {ResultType}; 281 Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types); 282 283 Value *Args[] = {Statepoint}; 284 return createCallHelper(FnGCResult, Args, this, Name); 285} 286 287CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint, 288 int BaseOffset, 289 int DerivedOffset, 290 Type *ResultType, 291 const Twine &Name) { 292 Module *M = BB->getParent()->getParent(); 293 Type *Types[] = {ResultType}; 294 Value *FnGCRelocate = 295 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types); 296 297 Value *Args[] = {Statepoint, 298 getInt32(BaseOffset), 299 getInt32(DerivedOffset)}; 300 return createCallHelper(FnGCRelocate, Args, this, Name); 301} 302