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