X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FIRBuilder.h;h=bdbd89854752fd57e64ff877581d51adc5129d0f;hb=08826a50e18524decc7f725153fbab49bcbaadd3;hp=09859092aee960da15ac9951391a02e42edad3a1;hpb=25b825b3b848eeb25d49a51f0c78a16db7677465;p=oota-llvm.git diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 09859092aee..bdbd8985475 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -15,14 +15,16 @@ #ifndef LLVM_SUPPORT_IRBUILDER_H #define LLVM_SUPPORT_IRBUILDER_H -#include "llvm/BasicBlock.h" -#include "llvm/Instructions.h" #include "llvm/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Function.h" +#include "llvm/Support/ConstantFolder.h" namespace llvm { /// IRBuilder - This provides a uniform API for creating instructions and -/// inserting them into a basic block: either at the end of a BasicBlock, or +/// 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 @@ -31,16 +33,28 @@ namespace llvm { /// supports nul-terminated C strings. For fully generic names, use /// I->setName(). For access to extra instruction properties, use the mutators /// (e.g. setVolatile) on the instructions after they have been created. -class IRBuilder { +/// 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. +template class IRBuilder{ BasicBlock *BB; BasicBlock::iterator InsertPt; + T Folder; public: - IRBuilder() { ClearInsertionPoint(); } - explicit IRBuilder(BasicBlock *TheBB) { SetInsertPoint(TheBB); } - IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) { - SetInsertPoint(TheBB, IP); - } + IRBuilder(const T& F = T()) : Folder(F) { ClearInsertionPoint(); } + explicit IRBuilder(BasicBlock *TheBB, const T& F = T()) + : Folder(F) { SetInsertPoint(TheBB); } + IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F = T()) + : Folder(F) { 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 //===--------------------------------------------------------------------===// @@ -50,39 +64,41 @@ public: void ClearInsertionPoint() { BB = 0; } - + BasicBlock *GetInsertBlock() const { return BB; } - + + BasicBlock::iterator GetInsertPoint() const { return InsertPt; } + /// 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; } - + /// Insert - Insert and return the specified instruction. template InstTy *Insert(InstTy *I, const char *Name = "") const { InsertHelper(I, Name); return I; } - + /// InsertHelper - Insert the specified instruction at the specified insertion /// point. This is split out of Insert so that it isn't duplicated for every /// template instantiation. void InsertHelper(Instruction *I, const char *Name) const { if (BB) BB->getInstList().insert(InsertPt, I); - if (Name[0]) + if (preserveNames && Name[0]) I->setName(Name); } - + //===--------------------------------------------------------------------===// // Instruction creation methods: Terminators //===--------------------------------------------------------------------===// @@ -92,22 +108,28 @@ public: return Insert(ReturnInst::Create()); } - /// @verbatim - /// CreateRet - Create a 'ret ' instruction. + /// @verbatim + /// CreateRet - Create a 'ret ' instruction. /// @endverbatim ReturnInst *CreateRet(Value *V) { return Insert(ReturnInst::Create(V)); } - ReturnInst *CreateRet(Value * const* retVals, unsigned N) { - return Insert(ReturnInst::Create(retVals, N)); - } - - GetResultInst *CreateGetResult(Value *V, unsigned Index, - const char *Name = "") { - return Insert(new GetResultInst(V, Index), Name); + /// 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 + /// the resulting aggregate value. This is a convenience function for + /// 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); + for (unsigned i = 0; i != N; ++i) + V = CreateInsertValue(V, retVals[i], i, "mrv"); + return Insert(ReturnInst::Create(V)); } - + /// CreateBr - Create an unconditional 'br label X' instruction. BranchInst *CreateBr(BasicBlock *Dest) { return Insert(BranchInst::Create(Dest)); @@ -118,23 +140,23 @@ public: BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) { return Insert(BranchInst::Create(True, False, Cond)); } - + /// CreateSwitch - Create a switch instruction with the specified value, /// default dest, and with a hint for the number of cases that will be added /// (for efficient allocation). SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) { return Insert(SwitchInst::Create(V, Dest, NumCases)); } - + /// CreateInvoke - Create an invoke instruction. template - InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, - BasicBlock *UnwindDest, InputIterator ArgBegin, + InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, InputIterator ArgBegin, InputIterator ArgEnd, const char *Name = "") { return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, ArgBegin, ArgEnd), Name); } - + UnwindInst *CreateUnwind() { return Insert(new UnwindInst()); } @@ -142,7 +164,7 @@ public: UnreachableInst *CreateUnreachable() { return Insert(new UnreachableInst()); } - + //===--------------------------------------------------------------------===// // Instruction creation methods: Binary Operators //===--------------------------------------------------------------------===// @@ -150,110 +172,140 @@ public: Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getAdd(LC, RC); + return Folder.CreateAdd(LC, RC); return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name); } + Value *CreateFAdd(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateFAdd(LC, RC); + return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name); + } Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getSub(LC, RC); + return Folder.CreateSub(LC, RC); return Insert(BinaryOperator::CreateSub(LHS, RHS), Name); } + Value *CreateFSub(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateFSub(LC, RC); + return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name); + } Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getMul(LC, RC); + return Folder.CreateMul(LC, RC); return Insert(BinaryOperator::CreateMul(LHS, RHS), Name); } + Value *CreateFMul(Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateFMul(LC, RC); + return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name); + } Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getUDiv(LC, RC); + return Folder.CreateUDiv(LC, RC); return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name); } Value *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getSDiv(LC, RC); + return Folder.CreateSDiv(LC, RC); return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name); } Value *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getFDiv(LC, RC); + return Folder.CreateFDiv(LC, RC); return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name); } Value *CreateURem(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getURem(LC, RC); + return Folder.CreateURem(LC, RC); return Insert(BinaryOperator::CreateURem(LHS, RHS), Name); } Value *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getSRem(LC, RC); + return Folder.CreateSRem(LC, RC); return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); } Value *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getFRem(LC, RC); + return Folder.CreateFRem(LC, RC); return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name); } Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getShl(LC, RC); + return Folder.CreateShl(LC, RC); return Insert(BinaryOperator::CreateShl(LHS, RHS), Name); } Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getLShr(LC, RC); + return Folder.CreateLShr(LC, RC); return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name); } Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getAShr(LC, RC); + return Folder.CreateAShr(LC, RC); return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); } Value *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getAnd(LC, RC); + return Folder.CreateAnd(LC, RC); return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name); } Value *CreateOr(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getOr(LC, RC); + return Folder.CreateOr(LC, RC); return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); } Value *CreateXor(Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getXor(LC, RC); + return Folder.CreateXor(LC, RC); return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); } - BinaryOperator *CreateBinOp(Instruction::BinaryOps Opc, - Value *LHS, Value *RHS, const char *Name = "") { + Value *CreateBinOp(Instruction::BinaryOps Opc, + Value *LHS, Value *RHS, const char *Name = "") { + if (Constant *LC = dyn_cast(LHS)) + if (Constant *RC = dyn_cast(RHS)) + return Folder.CreateBinOp(Opc, LC, RC); return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name); } - - BinaryOperator *CreateNeg(Value *V, const char *Name = "") { + + Value *CreateNeg(Value *V, const char *Name = "") { + if (Constant *VC = dyn_cast(V)) + return Folder.CreateNeg(VC); return Insert(BinaryOperator::CreateNeg(V), Name); } - BinaryOperator *CreateNot(Value *V, const char *Name = "") { + Value *CreateFNeg(Value *V, const char *Name = "") { + if (Constant *VC = dyn_cast(V)) + return Folder.CreateFNeg(VC); + return Insert(BinaryOperator::CreateFNeg(V), Name); + } + Value *CreateNot(Value *V, const char *Name = "") { + if (Constant *VC = dyn_cast(V)) + return Folder.CreateNot(VC); return Insert(BinaryOperator::CreateNot(V), Name); } - + //===--------------------------------------------------------------------===// // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// - + MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0, const char *Name = "") { return Insert(new MallocInst(Ty, ArraySize), Name); @@ -265,19 +317,18 @@ public: FreeInst *CreateFree(Value *Ptr) { return Insert(new FreeInst(Ptr)); } - LoadInst *CreateLoad(Value *Ptr, const char *Name = 0) { - return Insert(new LoadInst(Ptr, Name)); + LoadInst *CreateLoad(Value *Ptr, const char *Name = "") { + return Insert(new LoadInst(Ptr), Name); } - LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = 0) { - return Insert(new LoadInst(Ptr, Name, isVolatile)); + LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = "") { + return Insert(new LoadInst(Ptr, 0, isVolatile), Name); } StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { return Insert(new StoreInst(Val, Ptr, isVolatile)); } template - Value *CreateGEP(Value *Ptr, InputIterator IdxBegin, - InputIterator IdxEnd, const char *Name = "") { - + Value *CreateGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, + const char *Name = "") { if (Constant *PC = dyn_cast(Ptr)) { // Every index must be constant. InputIterator i; @@ -286,33 +337,81 @@ public: break; } if (i == IdxEnd) - return ConstantExpr::getGetElementPtr(PC, &IdxBegin[0], - IdxEnd - IdxBegin); - } - return(Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name)); + return Folder.CreateGetElementPtr(PC, &IdxBegin[0], IdxEnd - IdxBegin); + } + return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name); } Value *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") { if (Constant *PC = dyn_cast(Ptr)) if (Constant *IC = dyn_cast(Idx)) - return ConstantExpr::getGetElementPtr(PC, &IC, 1); + return Folder.CreateGetElementPtr(PC, &IC, 1); return Insert(GetElementPtrInst::Create(Ptr, Idx), Name); } - Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") { - llvm::Value *Idxs[] = { - ConstantInt::get(llvm::Type::Int32Ty, 0), - ConstantInt::get(llvm::Type::Int32Ty, Idx) + Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const char *Name = "") { + Value *Idx = ConstantInt::get(Type::Int32Ty, Idx0); + + if (Constant *PC = dyn_cast(Ptr)) + return Folder.CreateGetElementPtr(PC, &Idx, 1); + + return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name); + } + Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, + const char *Name = "") { + Value *Idxs[] = { + ConstantInt::get(Type::Int32Ty, Idx0), + ConstantInt::get(Type::Int32Ty, Idx1) }; - + if (Constant *PC = dyn_cast(Ptr)) - return ConstantExpr::getGetElementPtr(PC, Idxs, 2); - - return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name); + return Folder.CreateGetElementPtr(PC, Idxs, 2); + + return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name); + } + Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const char *Name = "") { + Value *Idx = ConstantInt::get(Type::Int64Ty, Idx0); + + if (Constant *PC = dyn_cast(Ptr)) + return Folder.CreateGetElementPtr(PC, &Idx, 1); + + return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name); + } + Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, + const char *Name = "") { + Value *Idxs[] = { + ConstantInt::get(Type::Int64Ty, Idx0), + ConstantInt::get(Type::Int64Ty, Idx1) + }; + + if (Constant *PC = dyn_cast(Ptr)) + return Folder.CreateGetElementPtr(PC, Idxs, 2); + + return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name); + } + Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") { + return CreateConstGEP2_32(Ptr, 0, Idx, Name); + } + Value *CreateGlobalString(const char *Str = "", const char *Name = "") { + Constant *StrConstant = ConstantArray::get(Str, true); + GlobalVariable *gv = new GlobalVariable(StrConstant->getType(), + true, + GlobalValue::InternalLinkage, + StrConstant, + "", + BB->getParent()->getParent(), + false); + gv->setName(Name); + return gv; + } + Value *CreateGlobalStringPtr(const char *Str = "", const char *Name = "") { + Value *gv = CreateGlobalString(Str, Name); + Value *zero = ConstantInt::get(Type::Int32Ty, 0); + Value *Args[] = { zero, zero }; + return CreateGEP(gv, Args, Args+2, Name); } - //===--------------------------------------------------------------------===// // Instruction creation methods: Cast/Conversion Operators //===--------------------------------------------------------------------===// - + Value *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") { return CreateCast(Instruction::Trunc, V, DestTy, Name); } @@ -355,26 +454,26 @@ public: } Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy, - const char *Name = "") { + const char *Name = "") { if (V->getType() == DestTy) return V; if (Constant *VC = dyn_cast(V)) - return ConstantExpr::getCast(Op, VC, DestTy); + return Folder.CreateCast(Op, VC, DestTy); return Insert(CastInst::Create(Op, V, DestTy), Name); } Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned, - const char *Name = "") { + const char *Name = "") { if (V->getType() == DestTy) return V; if (Constant *VC = dyn_cast(V)) - return ConstantExpr::getIntegerCast(VC, DestTy, isSigned); + return Folder.CreateIntCast(VC, DestTy, isSigned); return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name); } //===--------------------------------------------------------------------===// // Instruction creation methods: Compare Instructions //===--------------------------------------------------------------------===// - + Value *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") { return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name); } @@ -405,7 +504,7 @@ public: Value *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") { return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name); } - + Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") { return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name); } @@ -449,33 +548,33 @@ public: return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name); } - Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, + Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getCompare(P, LC, RC); + return Folder.CreateICmp(P, LC, RC); return Insert(new ICmpInst(P, LHS, RHS), Name); } - Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, + Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getCompare(P, LC, RC); + return Folder.CreateFCmp(P, LC, RC); return Insert(new FCmpInst(P, LHS, RHS), Name); } - Value *CreateVICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, + Value *CreateVICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getCompare(P, LC, RC); + return Folder.CreateVICmp(P, LC, RC); return Insert(new VICmpInst(P, LHS, RHS), Name); } - Value *CreateVFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, + Value *CreateVFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const char *Name = "") { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return ConstantExpr::getCompare(P, LC, RC); + return Folder.CreateVFCmp(P, LC, RC); return Insert(new VFCmpInst(P, LHS, RHS), Name); } @@ -508,9 +607,9 @@ public: Value *Args[] = { Arg1, Arg2, Arg3, Arg4 }; return Insert(CallInst::Create(Callee, Args, Args+4), Name); } - + template - CallInst *CreateCall(Value *Callee, InputIterator ArgBegin, + CallInst *CreateCall(Value *Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char *Name = "") { return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name); } @@ -520,7 +619,7 @@ public: if (Constant *CC = dyn_cast(C)) if (Constant *TC = dyn_cast(True)) if (Constant *FC = dyn_cast(False)) - return ConstantExpr::getSelect(CC, TC, FC); + return Folder.CreateSelect(CC, TC, FC); return Insert(SelectInst::Create(C, True, False), Name); } @@ -529,10 +628,10 @@ public: } Value *CreateExtractElement(Value *Vec, Value *Idx, - const char *Name = "") { + const char *Name = "") { if (Constant *VC = dyn_cast(Vec)) if (Constant *IC = dyn_cast(Idx)) - return ConstantExpr::getExtractElement(VC, IC); + return Folder.CreateExtractElement(VC, IC); return Insert(new ExtractElementInst(Vec, Idx), Name); } @@ -541,20 +640,88 @@ public: if (Constant *VC = dyn_cast(Vec)) if (Constant *NC = dyn_cast(NewElt)) if (Constant *IC = dyn_cast(Idx)) - return ConstantExpr::getInsertElement(VC, NC, IC); + return Folder.CreateInsertElement(VC, NC, IC); return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name); } Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask, - const char *Name = "") { + const char *Name = "") { if (Constant *V1C = dyn_cast(V1)) if (Constant *V2C = dyn_cast(V2)) if (Constant *MC = dyn_cast(Mask)) - return ConstantExpr::getShuffleVector(V1C, V2C, MC); + return Folder.CreateShuffleVector(V1C, V2C, MC); return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); } + + Value *CreateExtractValue(Value *Agg, unsigned Idx, + const char *Name = "") { + if (Constant *AggC = dyn_cast(Agg)) + return Folder.CreateExtractValue(AggC, &Idx, 1); + return Insert(ExtractValueInst::Create(Agg, Idx), Name); + } + + template + Value *CreateExtractValue(Value *Agg, + InputIterator IdxBegin, + InputIterator IdxEnd, + const char *Name = "") { + if (Constant *AggC = dyn_cast(Agg)) + return Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd - IdxBegin); + return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name); + } + + Value *CreateInsertValue(Value *Agg, Value *Val, unsigned Idx, + const char *Name = "") { + if (Constant *AggC = dyn_cast(Agg)) + if (Constant *ValC = dyn_cast(Val)) + return Folder.CreateInsertValue(AggC, ValC, &Idx, 1); + return Insert(InsertValueInst::Create(Agg, Val, Idx), Name); + } + + template + Value *CreateInsertValue(Value *Agg, Value *Val, + InputIterator IdxBegin, + InputIterator IdxEnd, + const char *Name = "") { + if (Constant *AggC = dyn_cast(Agg)) + if (Constant *ValC = dyn_cast(Val)) + return Folder.CreateInsertValue(AggC, ValC, + IdxBegin, IdxEnd - IdxBegin); + return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name); + } + + //===--------------------------------------------------------------------===// + // Utility creation methods + //===--------------------------------------------------------------------===// + + /// CreateIsNull - Return an i1 value testing if \arg Arg is null. + Value *CreateIsNull(Value *Arg, const char *Name = "") { + return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()), + Name); + } + + /// CreateIsNotNull - Return an i1 value testing if \arg Arg is not null. + Value *CreateIsNotNull(Value *Arg, const char *Name = "") { + return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()), + Name); + } + + /// CreatePtrDiff - Return the i64 difference between two pointer values, + /// dividing out the size of the pointed-to objects. This is intended to + /// implement C-style pointer subtraction. + Value *CreatePtrDiff(Value *LHS, Value *RHS, const char *Name = "") { + assert(LHS->getType() == RHS->getType() && + "Pointer subtraction operand types must match!"); + const PointerType *ArgType = cast(LHS->getType()); + Value *LHS_int = CreatePtrToInt(LHS, Type::Int64Ty); + Value *RHS_int = CreatePtrToInt(RHS, Type::Int64Ty); + Value *Difference = CreateSub(LHS_int, RHS_int); + return CreateSDiv(Difference, + ConstantExpr::getSizeOf(ArgType->getElementType()), + Name); + } }; - + } #endif