1249259Sdim//===---- IRBuilder.cpp - Builder for LLVM Instrs -------------------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file implements the IRBuilder class, which is used as a convenient way 11249259Sdim// to create LLVM instructions with a consistent and simplified interface. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#include "llvm/IR/Function.h" 16249259Sdim#include "llvm/IR/GlobalVariable.h" 17249259Sdim#include "llvm/IR/IRBuilder.h" 18249259Sdim#include "llvm/IR/Intrinsics.h" 19249259Sdim#include "llvm/IR/LLVMContext.h" 20249259Sdimusing namespace llvm; 21249259Sdim 22249259Sdim/// CreateGlobalString - Make a new global variable with an initializer that 23249259Sdim/// has array of i8 type filled in with the nul terminated string value 24249259Sdim/// specified. If Name is specified, it is the name of the global variable 25249259Sdim/// created. 26249259SdimValue *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) { 27249259Sdim Constant *StrConstant = ConstantDataArray::getString(Context, Str); 28249259Sdim Module &M = *BB->getParent()->getParent(); 29249259Sdim GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(), 30249259Sdim true, GlobalValue::PrivateLinkage, 31249259Sdim StrConstant); 32249259Sdim GV->setName(Name); 33249259Sdim GV->setUnnamedAddr(true); 34249259Sdim return GV; 35249259Sdim} 36249259Sdim 37249259SdimType *IRBuilderBase::getCurrentFunctionReturnType() const { 38249259Sdim assert(BB && BB->getParent() && "No current function!"); 39249259Sdim return BB->getParent()->getReturnType(); 40249259Sdim} 41249259Sdim 42249259SdimValue *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) { 43249259Sdim PointerType *PT = cast<PointerType>(Ptr->getType()); 44249259Sdim if (PT->getElementType()->isIntegerTy(8)) 45249259Sdim return Ptr; 46249259Sdim 47249259Sdim // Otherwise, we need to insert a bitcast. 48249259Sdim PT = getInt8PtrTy(PT->getAddressSpace()); 49249259Sdim BitCastInst *BCI = new BitCastInst(Ptr, PT, ""); 50249259Sdim BB->getInstList().insert(InsertPt, BCI); 51249259Sdim SetInstDebugLocation(BCI); 52249259Sdim return BCI; 53249259Sdim} 54249259Sdim 55249259Sdimstatic CallInst *createCallHelper(Value *Callee, ArrayRef<Value *> Ops, 56249259Sdim IRBuilderBase *Builder) { 57249259Sdim CallInst *CI = CallInst::Create(Callee, Ops, ""); 58249259Sdim Builder->GetInsertBlock()->getInstList().insert(Builder->GetInsertPoint(),CI); 59249259Sdim Builder->SetInstDebugLocation(CI); 60249259Sdim return CI; 61249259Sdim} 62249259Sdim 63249259SdimCallInst *IRBuilderBase:: 64249259SdimCreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align, 65249259Sdim bool isVolatile, MDNode *TBAATag) { 66249259Sdim Ptr = getCastedInt8PtrValue(Ptr); 67249259Sdim Value *Ops[] = { Ptr, Val, Size, getInt32(Align), getInt1(isVolatile) }; 68249259Sdim Type *Tys[] = { Ptr->getType(), Size->getType() }; 69249259Sdim Module *M = BB->getParent()->getParent(); 70249259Sdim Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys); 71249259Sdim 72249259Sdim CallInst *CI = createCallHelper(TheFn, Ops, this); 73249259Sdim 74249259Sdim // Set the TBAA info if present. 75249259Sdim if (TBAATag) 76249259Sdim CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); 77249259Sdim 78249259Sdim return CI; 79249259Sdim} 80249259Sdim 81249259SdimCallInst *IRBuilderBase:: 82249259SdimCreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align, 83249259Sdim bool isVolatile, MDNode *TBAATag, MDNode *TBAAStructTag) { 84249259Sdim Dst = getCastedInt8PtrValue(Dst); 85249259Sdim Src = getCastedInt8PtrValue(Src); 86249259Sdim 87249259Sdim Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; 88249259Sdim Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; 89249259Sdim Module *M = BB->getParent()->getParent(); 90249259Sdim Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys); 91249259Sdim 92249259Sdim CallInst *CI = createCallHelper(TheFn, Ops, this); 93249259Sdim 94249259Sdim // Set the TBAA info if present. 95249259Sdim if (TBAATag) 96249259Sdim CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); 97249259Sdim 98249259Sdim // Set the TBAA Struct info if present. 99249259Sdim if (TBAAStructTag) 100249259Sdim CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag); 101249259Sdim 102249259Sdim return CI; 103249259Sdim} 104249259Sdim 105249259SdimCallInst *IRBuilderBase:: 106249259SdimCreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align, 107249259Sdim bool isVolatile, MDNode *TBAATag) { 108249259Sdim Dst = getCastedInt8PtrValue(Dst); 109249259Sdim Src = getCastedInt8PtrValue(Src); 110249259Sdim 111249259Sdim Value *Ops[] = { Dst, Src, Size, getInt32(Align), getInt1(isVolatile) }; 112249259Sdim Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() }; 113249259Sdim Module *M = BB->getParent()->getParent(); 114249259Sdim Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys); 115249259Sdim 116249259Sdim CallInst *CI = createCallHelper(TheFn, Ops, this); 117249259Sdim 118249259Sdim // Set the TBAA info if present. 119249259Sdim if (TBAATag) 120249259Sdim CI->setMetadata(LLVMContext::MD_tbaa, TBAATag); 121249259Sdim 122249259Sdim return CI; 123249259Sdim} 124249259Sdim 125249259SdimCallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) { 126249259Sdim assert(isa<PointerType>(Ptr->getType()) && 127249259Sdim "lifetime.start only applies to pointers."); 128249259Sdim Ptr = getCastedInt8PtrValue(Ptr); 129249259Sdim if (!Size) 130249259Sdim Size = getInt64(-1); 131249259Sdim else 132249259Sdim assert(Size->getType() == getInt64Ty() && 133249259Sdim "lifetime.start requires the size to be an i64"); 134249259Sdim Value *Ops[] = { Size, Ptr }; 135249259Sdim Module *M = BB->getParent()->getParent(); 136249259Sdim Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start); 137249259Sdim return createCallHelper(TheFn, Ops, this); 138249259Sdim} 139249259Sdim 140249259SdimCallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) { 141249259Sdim assert(isa<PointerType>(Ptr->getType()) && 142249259Sdim "lifetime.end only applies to pointers."); 143249259Sdim Ptr = getCastedInt8PtrValue(Ptr); 144249259Sdim if (!Size) 145249259Sdim Size = getInt64(-1); 146249259Sdim else 147249259Sdim assert(Size->getType() == getInt64Ty() && 148249259Sdim "lifetime.end requires the size to be an i64"); 149249259Sdim Value *Ops[] = { Size, Ptr }; 150249259Sdim Module *M = BB->getParent()->getParent(); 151249259Sdim Value *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end); 152249259Sdim return createCallHelper(TheFn, Ops, this); 153249259Sdim} 154