+ PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
+ return Type::getInt8PtrTy(Context, AddrSpace);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Intrinsic creation methods
+ //===--------------------------------------------------------------------===//
+
+ /// CreateMemSet - Create and insert a memset to the specified pointer and the
+ /// specified value. If the pointer isn't an i8*, it will be converted. If a
+ /// TBAA tag is specified, it will be added to the instruction.
+ CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateMemCpy - Create and insert a memcpy between the specified pointers.
+ /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
+ /// specified, it will be added to the instruction.
+ CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateMemMove - Create and insert a memmove between the specified
+ /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA
+ /// tag is specified, it will be added to the instruction.
+ CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer
+ /// isn't i8* it will be converted.
+ CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0);
+
+ /// CreateLifetimeEnd - Create a lifetime.end intrinsic. If the pointer isn't
+ /// i8* it will be converted.
+ CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0);
+
+private:
+ Value *getCastedInt8PtrValue(Value *Ptr);
+};
+
+/// 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<bool preserveNames = true, typename T = ConstantFolder,
+ typename Inserter = IRBuilderDefaultInserter<preserveNames> >
+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() {
+ }
+
+ explicit IRBuilder(BasicBlock *TheBB, const T &F)
+ : IRBuilderBase(TheBB->getContext()), Folder(F) {
+ SetInsertPoint(TheBB);
+ }
+
+ explicit IRBuilder(BasicBlock *TheBB)
+ : IRBuilderBase(TheBB->getContext()), Folder() {
+ SetInsertPoint(TheBB);
+ }
+
+ explicit IRBuilder(Instruction *IP)
+ : IRBuilderBase(IP->getContext()), Folder() {
+ SetInsertPoint(IP);
+ SetCurrentDebugLocation(IP->getDebugLoc());
+ }
+
+ explicit IRBuilder(Use &U)
+ : IRBuilderBase(U->getContext()), Folder() {
+ SetInsertPoint(U);
+ SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
+ }
+
+ 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() {
+ 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<typename InstTy>
+ InstTy *Insert(InstTy *I, const Twine &Name = "") const {
+ this->InsertHelper(I, Name, BB, InsertPt);
+ if (!getCurrentDebugLocation().isUnknown())
+ this->SetInstDebugLocation(I);
+ return I;
+ }
+
+ /// Insert - No-op overload to handle constants.
+ Constant *Insert(Constant *C, const Twine& = "") const {
+ return C;
+ }
+