X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FIRBuilder.h;h=1fd965d3e77345735cbbdb443e92d6977fb193e6;hb=070c07f2c881c9f005c411fb113011a2d5af4057;hp=b1f4354f484ce1378ad5b0b7fd1a3d3372d4bb8c;hpb=95c1984e6b0b299f74d8a428fac6b6be266ae169;p=oota-llvm.git diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index b1f4354f484..1fd965d3e77 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -15,17 +15,13 @@ #ifndef LLVM_SUPPORT_IRBUILDER_H #define LLVM_SUPPORT_IRBUILDER_H -#include "llvm/Constants.h" #include "llvm/Instructions.h" -#include "llvm/GlobalAlias.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Function.h" -#include "llvm/Metadata.h" -#include "llvm/LLVMContext.h" +#include "llvm/BasicBlock.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ConstantFolder.h" namespace llvm { + class MDNode; /// IRBuilderDefaultInserter - This provides the default implementation of the /// IRBuilder 'InsertHelper' method that is called whenever an instruction is @@ -41,121 +37,80 @@ protected: I->setName(Name); } }; - - -/// IRBuilder - This provides a uniform API for creating instructions and -/// inserting them into a basic block: either at the end of a BasicBlock, or -/// at a specific iterator location in a block. -/// -/// Note that the builder does not expose the full generality of LLVM -/// instructions. For access to extra instruction properties, use the mutators -/// (e.g. setVolatile) on the instructions after they have been created. -/// The first template argument handles whether or not to preserve names in the -/// final instruction output. This defaults to on. The second template argument -/// specifies a class to use for creating constants. This defaults to creating -/// minimally folded constants. The fourth template argument allows clients to -/// specify custom insertion hooks that are called on every newly created -/// insertion. -template > -class IRBuilder : public Inserter { + +/// IRBuilderBase - Common base class shared among various IRBuilders. +class IRBuilderBase { + DebugLoc CurDbgLocation; +protected: BasicBlock *BB; BasicBlock::iterator InsertPt; - MDKindID MDKind; - MDNode *CurLocation; LLVMContext &Context; - T Folder; public: - IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter()) - : Inserter(I), MDKind(0), CurLocation(0), Context(C), Folder(F) { - ClearInsertionPoint(); - } - explicit IRBuilder(LLVMContext &C) - : MDKind(0), CurLocation(0), Context(C), Folder(C) { + IRBuilderBase(LLVMContext &context) + : Context(context) { ClearInsertionPoint(); } - explicit IRBuilder(BasicBlock *TheBB, const T &F) - : MDKind(0), CurLocation(0), Context(TheBB->getContext()), Folder(F) { - SetInsertPoint(TheBB); - } - - explicit IRBuilder(BasicBlock *TheBB) - : MDKind(0), CurLocation(0), Context(TheBB->getContext()), Folder(Context) { - SetInsertPoint(TheBB); - } - - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) - : MDKind(0), CurLocation(0), Context(TheBB->getContext()), Folder(F) { - SetInsertPoint(TheBB, IP); - } - - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) - : MDKind(0), CurLocation(0), Context(TheBB->getContext()), Folder(Context) { - SetInsertPoint(TheBB, IP); - } - - /// getFolder - Get the constant folder being used. - const T &getFolder() { return Folder; } - - /// isNamePreserving - Return true if this builder is configured to actually - /// add the requested names to IR created through it. - bool isNamePreserving() const { return preserveNames; } - //===--------------------------------------------------------------------===// // Builder configuration methods //===--------------------------------------------------------------------===// - + /// ClearInsertionPoint - Clear the insertion point: created instructions will /// not be inserted into a block. void ClearInsertionPoint() { BB = 0; } - + BasicBlock *GetInsertBlock() const { return BB; } - BasicBlock::iterator GetInsertPoint() const { return InsertPt; } - + LLVMContext &getContext() const { return Context; } + /// SetInsertPoint - This specifies that created instructions should be /// appended to the end of the specified block. void SetInsertPoint(BasicBlock *TheBB) { BB = TheBB; InsertPt = BB->end(); } - + /// SetInsertPoint - This specifies that created instructions should be /// inserted at the specified point. void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; InsertPt = IP; } - - /// SetCurrentLocation - This specifies the location information used - /// by debugging information. - void SetCurrentLocation(MDNode *L) { - if (MDKind == 0) { - Context.getMetadata().RegisterMDKind("dbg"); - MDKind = Context.getMetadata().getMDKind("dbg"); - } - CurLocation = L; + + /// SetCurrentDebugLocation - Set location information used by debugging + /// information. + void SetCurrentDebugLocation(const DebugLoc &L) { + CurDbgLocation = L; } - - MDNode *getCurrentLocation() const { return CurLocation; } - /// Insert - Insert and return the specified instruction. - template - InstTy *Insert(InstTy *I, const Twine &Name = "") const { - this->InsertHelper(I, Name, BB, InsertPt); - if (CurLocation) - Context.getMetadata().setMD(MDKind, CurLocation, I); - return I; + /// getCurrentDebugLocation - Get location information used by debugging + /// information. + const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } + + /// SetInstDebugLocation - If this builder has a current debug location, set + /// it on the specified instruction. + void SetInstDebugLocation(Instruction *I) const { + if (!CurDbgLocation.isUnknown()) + I->setDebugLoc(CurDbgLocation); } + //===--------------------------------------------------------------------===// + // Miscellaneous creation methods. + //===--------------------------------------------------------------------===// + + /// CreateGlobalString - Make a new global variable with an initializer that + /// has array of i8 type filled in with the nul terminated string value + /// specified. If Name is specified, it is the name of the global variable + /// created. + Value *CreateGlobalString(const char *Str = "", const Twine &Name = ""); + //===--------------------------------------------------------------------===// // Type creation methods //===--------------------------------------------------------------------===// - + /// getInt1Ty - Fetch the type representing a single bit const Type *getInt1Ty() { return Type::getInt1Ty(Context); @@ -180,7 +135,7 @@ public: const Type *getInt64Ty() { return Type::getInt64Ty(Context); } - + /// getFloatTy - Fetch the type representing a 32-bit floating point value. const Type *getFloatTy() { return Type::getFloatTy(Context); @@ -195,6 +150,76 @@ public: const Type *getVoidTy() { return Type::getVoidTy(Context); } + + const Type *getInt8PtrTy() { + return Type::getInt8PtrTy(Context); + } + + /// getCurrentFunctionReturnType - Get the return type of the current function + /// that we're emitting into. + const Type *getCurrentFunctionReturnType() const; +}; + +/// IRBuilder - This provides a uniform API for creating instructions and +/// inserting them into a basic block: either at the end of a BasicBlock, or +/// at a specific iterator location in a block. +/// +/// Note that the builder does not expose the full generality of LLVM +/// instructions. For access to extra instruction properties, use the mutators +/// (e.g. setVolatile) on the instructions after they have been created. +/// The first template argument handles whether or not to preserve names in the +/// final instruction output. This defaults to on. The second template argument +/// specifies a class to use for creating constants. This defaults to creating +/// minimally folded constants. The fourth template argument allows clients to +/// specify custom insertion hooks that are called on every newly created +/// insertion. +template > +class IRBuilder : public IRBuilderBase, public Inserter { + T Folder; +public: + IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter()) + : IRBuilderBase(C), Inserter(I), Folder(F) { + } + + explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder(C) { + } + + explicit IRBuilder(BasicBlock *TheBB, const T &F) + : IRBuilderBase(TheBB->getContext()), Folder(F) { + SetInsertPoint(TheBB); + } + + explicit IRBuilder(BasicBlock *TheBB) + : IRBuilderBase(TheBB->getContext()), Folder(Context) { + SetInsertPoint(TheBB); + } + + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F) + : IRBuilderBase(TheBB->getContext()), Folder(F) { + SetInsertPoint(TheBB, IP); + } + + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) + : IRBuilderBase(TheBB->getContext()), Folder(Context) { + SetInsertPoint(TheBB, IP); + } + + /// getFolder - Get the constant folder being used. + const T &getFolder() { return Folder; } + + /// isNamePreserving - Return true if this builder is configured to actually + /// add the requested names to IR created through it. + bool isNamePreserving() const { return preserveNames; } + + /// Insert - Insert and return the specified instruction. + template + InstTy *Insert(InstTy *I, const Twine &Name = "") const { + this->InsertHelper(I, Name, BB, InsertPt); + if (!getCurrentDebugLocation().isUnknown()) + this->SetInstDebugLocation(I); + return I; + } //===--------------------------------------------------------------------===// // Instruction creation methods: Terminators @@ -211,7 +236,7 @@ public: ReturnInst *CreateRet(Value *V) { return Insert(ReturnInst::Create(Context, V)); } - + /// CreateAggregateRet - Create a sequence of N insertvalue instructions, /// with one Value from the retVals array each, that build a aggregate /// return value one value at a time, and a ret instruction to return @@ -219,9 +244,8 @@ public: /// code that uses aggregate return values as a vehicle for having /// multiple return values. /// - ReturnInst *CreateAggregateRet(Value * const* retVals, unsigned N) { - const Type *RetType = BB->getParent()->getReturnType(); - Value *V = UndefValue::get(RetType); + ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) { + Value *V = UndefValue::get(getCurrentFunctionReturnType()); for (unsigned i = 0; i != N; ++i) V = CreateInsertValue(V, retVals[i], i, "mrv"); return Insert(ReturnInst::Create(Context, V)); @@ -245,6 +269,34 @@ public: return Insert(SwitchInst::Create(V, Dest, NumCases)); } + /// CreateIndirectBr - Create an indirect branch instruction with the + /// specified address operand, with an optional hint for the number of + /// destinations that will be added (for efficient allocation). + IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) { + return Insert(IndirectBrInst::Create(Addr, NumDests)); + } + + InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, const Twine &Name = "") { + Value *Args[] = { 0 }; + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + Args), Name); + } + InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, Value *Arg1, + const Twine &Name = "") { + Value *Args[] = { Arg1 }; + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + Args+1), Name); + } + InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, Value *Arg1, + Value *Arg2, Value *Arg3, + const Twine &Name = "") { + Value *Args[] = { Arg1, Arg2, Arg3 }; + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + Args+3), Name); + } /// CreateInvoke - Create an invoke instruction. template InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, @@ -278,6 +330,12 @@ public: return Folder.CreateNSWAdd(LC, RC); return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name); } + Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNUWAdd(LC, RC); + return Insert(BinaryOperator::CreateNUWAdd(LHS, RHS), Name); + } Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) @@ -290,6 +348,18 @@ public: return Folder.CreateSub(LC, RC); return Insert(BinaryOperator::CreateSub(LHS, RHS), Name); } + Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNSWSub(LC, RC); + return Insert(BinaryOperator::CreateNSWSub(LHS, RHS), Name); + } + Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNUWSub(LC, RC); + return Insert(BinaryOperator::CreateNUWSub(LHS, RHS), Name); + } Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) @@ -302,6 +372,18 @@ public: return Folder.CreateMul(LC, RC); return Insert(BinaryOperator::CreateMul(LHS, RHS), Name); } + Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNSWMul(LC, RC); + return Insert(BinaryOperator::CreateNSWMul(LHS, RHS), Name); + } + Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateNUWMul(LC, RC); + return Insert(BinaryOperator::CreateNUWMul(LHS, RHS), Name); + } Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) @@ -350,42 +432,126 @@ public: return Folder.CreateFRem(LC, RC); return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name); } + Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return Folder.CreateShl(LC, RC); return Insert(BinaryOperator::CreateShl(LHS, RHS), Name); } + Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateShl(LC, RHSC); + return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name); + } + Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateShl(LC, RHSC); + return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name); + } + Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return Folder.CreateLShr(LC, RC); return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name); } + Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateLShr(LC, RHSC); + return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name); + } + Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateLShr(LC, RHSC); + return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name); + } + Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return Folder.CreateAShr(LC, RC); return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); } - Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateAShr(LC, RHSC); + return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name); + } + Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateAShr(LC, RHSC); + return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name); + } + + Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *RC = dyn_cast(RHS)) { + if (isa(RC) && cast(RC)->isAllOnesValue()) + return LHS; // LHS & -1 -> LHS + if (Constant *LC = dyn_cast(LHS)) return Folder.CreateAnd(LC, RC); + } return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name); } - Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { + Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); if (Constant *LC = dyn_cast(LHS)) - if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateAnd(LC, RHSC); + return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name); + } + Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateAnd(LC, RHSC); + return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name); + } + + Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") { + if (Constant *RC = dyn_cast(RHS)) { + if (RC->isNullValue()) + return LHS; // LHS | 0 -> LHS + if (Constant *LC = dyn_cast(LHS)) return Folder.CreateOr(LC, RC); + } return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); } + Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateOr(LC, RHSC); + return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name); + } + Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateOr(LC, RHSC); + return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name); + } + Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) return Folder.CreateXor(LC, RC); return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); } + Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateXor(LC, RHSC); + return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name); + } + Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") { + Constant *RHSC = ConstantInt::get(LHS->getType(), RHS); + if (Constant *LC = dyn_cast(LHS)) + return Folder.CreateXor(LC, RHSC); + return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name); + } Value *CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name = "") { @@ -400,6 +566,16 @@ public: return Folder.CreateNeg(VC); return Insert(BinaryOperator::CreateNeg(V), Name); } + Value *CreateNSWNeg(Value *V, const Twine &Name = "") { + if (Constant *VC = dyn_cast(V)) + return Folder.CreateNSWNeg(VC); + return Insert(BinaryOperator::CreateNSWNeg(V), Name); + } + Value *CreateNUWNeg(Value *V, const Twine &Name = "") { + if (Constant *VC = dyn_cast(V)) + return Folder.CreateNUWNeg(VC); + return Insert(BinaryOperator::CreateNUWNeg(V), Name); + } Value *CreateFNeg(Value *V, const Twine &Name = "") { if (Constant *VC = dyn_cast(V)) return Folder.CreateFNeg(VC); @@ -415,17 +591,10 @@ public: // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// - MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0, - const Twine &Name = "") { - return Insert(new MallocInst(Ty, ArraySize), Name); - } AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0, const Twine &Name = "") { return Insert(new AllocaInst(Ty, ArraySize), Name); } - FreeInst *CreateFree(Value *Ptr) { - return Insert(new FreeInst(Ptr)); - } // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of // converting the string to 'bool' for the isVolatile parameter. LoadInst *CreateLoad(Value *Ptr, const char *Name) { @@ -568,26 +737,16 @@ public: Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); } - Value *CreateGlobalString(const char *Str = "", const Twine &Name = "") { - Constant *StrConstant = ConstantArray::get(Context, Str, true); - Module &M = *BB->getParent()->getParent(); - GlobalVariable *gv = new GlobalVariable(M, - StrConstant->getType(), - true, - GlobalValue::InternalLinkage, - StrConstant, - "", - 0, - false); - gv->setName(Name); - return gv; - } + + /// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer + /// with "i8*" type instead of a pointer to array of i8. Value *CreateGlobalStringPtr(const char *Str = "", const Twine &Name = "") { Value *gv = CreateGlobalString(Str, Name); Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); Value *Args[] = { zero, zero }; return CreateInBoundsGEP(gv, Args, Args+2, Name); } + //===--------------------------------------------------------------------===// // Instruction creation methods: Cast/Conversion Operators //===--------------------------------------------------------------------===// @@ -680,6 +839,11 @@ public: return Folder.CreateIntCast(VC, DestTy, isSigned); return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name); } +private: + // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile time + // error, instead of converting the string to bool for the isSigned parameter. + Value *CreateIntCast(Value *, const Type *, const char *); // DO NOT IMPLEMENT +public: Value *CreateFPCast(Value *V, const Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -810,6 +974,11 @@ public: Value *Args[] = { Arg1, Arg2, Arg3, Arg4 }; return Insert(CallInst::Create(Callee, Args, Args+4), Name); } + CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3, + Value *Arg4, Value *Arg5, const Twine &Name = "") { + Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 }; + return Insert(CallInst::Create(Callee, Args, Args+5), Name); + } template CallInst *CreateCall(Value *Callee, InputIterator ArgBegin,