1249259Sdim//===---- llvm/IRBuilder.h - Builder for LLVM Instructions ------*- C++ -*-===//
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 defines 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#ifndef LLVM_IR_IRBUILDER_H
16249259Sdim#define LLVM_IR_IRBUILDER_H
17249259Sdim
18249259Sdim#include "llvm/ADT/ArrayRef.h"
19249259Sdim#include "llvm/ADT/StringRef.h"
20249259Sdim#include "llvm/ADT/Twine.h"
21249259Sdim#include "llvm/IR/BasicBlock.h"
22249259Sdim#include "llvm/IR/DataLayout.h"
23249259Sdim#include "llvm/IR/Instructions.h"
24249259Sdim#include "llvm/IR/LLVMContext.h"
25249259Sdim#include "llvm/IR/Operator.h"
26251662Sdim#include "llvm/Support/CBindingWrapping.h"
27249259Sdim#include "llvm/Support/ConstantFolder.h"
28263508Sdim#include "llvm/Support/ValueHandle.h"
29249259Sdim
30249259Sdimnamespace llvm {
31249259Sdim  class MDNode;
32249259Sdim
33249259Sdim/// \brief This provides the default implementation of the IRBuilder
34249259Sdim/// 'InsertHelper' method that is called whenever an instruction is created by
35249259Sdim/// IRBuilder and needs to be inserted.
36249259Sdim///
37249259Sdim/// By default, this inserts the instruction at the insertion point.
38249259Sdimtemplate <bool preserveNames = true>
39249259Sdimclass IRBuilderDefaultInserter {
40249259Sdimprotected:
41249259Sdim  void InsertHelper(Instruction *I, const Twine &Name,
42249259Sdim                    BasicBlock *BB, BasicBlock::iterator InsertPt) const {
43249259Sdim    if (BB) BB->getInstList().insert(InsertPt, I);
44249259Sdim    if (preserveNames)
45249259Sdim      I->setName(Name);
46249259Sdim  }
47249259Sdim};
48249259Sdim
49249259Sdim/// \brief Common base class shared among various IRBuilders.
50249259Sdimclass IRBuilderBase {
51249259Sdim  DebugLoc CurDbgLocation;
52249259Sdimprotected:
53249259Sdim  BasicBlock *BB;
54249259Sdim  BasicBlock::iterator InsertPt;
55249259Sdim  LLVMContext &Context;
56263508Sdim
57263508Sdim  MDNode *DefaultFPMathTag;
58263508Sdim  FastMathFlags FMF;
59249259Sdimpublic:
60249259Sdim
61263508Sdim  IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = 0)
62263508Sdim    : Context(context), DefaultFPMathTag(FPMathTag), FMF() {
63249259Sdim    ClearInsertionPoint();
64249259Sdim  }
65249259Sdim
66249259Sdim  //===--------------------------------------------------------------------===//
67249259Sdim  // Builder configuration methods
68249259Sdim  //===--------------------------------------------------------------------===//
69249259Sdim
70249259Sdim  /// \brief Clear the insertion point: created instructions will not be
71249259Sdim  /// inserted into a block.
72249259Sdim  void ClearInsertionPoint() {
73249259Sdim    BB = 0;
74263508Sdim    InsertPt = 0;
75249259Sdim  }
76249259Sdim
77249259Sdim  BasicBlock *GetInsertBlock() const { return BB; }
78249259Sdim  BasicBlock::iterator GetInsertPoint() const { return InsertPt; }
79249259Sdim  LLVMContext &getContext() const { return Context; }
80249259Sdim
81249259Sdim  /// \brief This specifies that created instructions should be appended to the
82249259Sdim  /// end of the specified block.
83249259Sdim  void SetInsertPoint(BasicBlock *TheBB) {
84249259Sdim    BB = TheBB;
85249259Sdim    InsertPt = BB->end();
86249259Sdim  }
87249259Sdim
88249259Sdim  /// \brief This specifies that created instructions should be inserted before
89249259Sdim  /// the specified instruction.
90249259Sdim  void SetInsertPoint(Instruction *I) {
91249259Sdim    BB = I->getParent();
92249259Sdim    InsertPt = I;
93263508Sdim    assert(I != BB->end() && "Can't read debug loc from end()");
94249259Sdim    SetCurrentDebugLocation(I->getDebugLoc());
95249259Sdim  }
96249259Sdim
97249259Sdim  /// \brief This specifies that created instructions should be inserted at the
98249259Sdim  /// specified point.
99249259Sdim  void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
100249259Sdim    BB = TheBB;
101249259Sdim    InsertPt = IP;
102249259Sdim  }
103249259Sdim
104249259Sdim  /// \brief Find the nearest point that dominates this use, and specify that
105249259Sdim  /// created instructions should be inserted at this point.
106249259Sdim  void SetInsertPoint(Use &U) {
107249259Sdim    Instruction *UseInst = cast<Instruction>(U.getUser());
108249259Sdim    if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) {
109249259Sdim      BasicBlock *PredBB = Phi->getIncomingBlock(U);
110249259Sdim      assert(U != PredBB->getTerminator() && "critical edge not split");
111249259Sdim      SetInsertPoint(PredBB, PredBB->getTerminator());
112249259Sdim      return;
113249259Sdim    }
114249259Sdim    SetInsertPoint(UseInst);
115249259Sdim  }
116249259Sdim
117249259Sdim  /// \brief Set location information used by debugging information.
118249259Sdim  void SetCurrentDebugLocation(const DebugLoc &L) {
119249259Sdim    CurDbgLocation = L;
120249259Sdim  }
121249259Sdim
122249259Sdim  /// \brief Get location information used by debugging information.
123249259Sdim  DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
124249259Sdim
125249259Sdim  /// \brief If this builder has a current debug location, set it on the
126249259Sdim  /// specified instruction.
127249259Sdim  void SetInstDebugLocation(Instruction *I) const {
128249259Sdim    if (!CurDbgLocation.isUnknown())
129249259Sdim      I->setDebugLoc(CurDbgLocation);
130249259Sdim  }
131249259Sdim
132249259Sdim  /// \brief Get the return type of the current function that we're emitting
133249259Sdim  /// into.
134249259Sdim  Type *getCurrentFunctionReturnType() const;
135249259Sdim
136249259Sdim  /// InsertPoint - A saved insertion point.
137249259Sdim  class InsertPoint {
138249259Sdim    BasicBlock *Block;
139249259Sdim    BasicBlock::iterator Point;
140249259Sdim
141249259Sdim  public:
142249259Sdim    /// \brief Creates a new insertion point which doesn't point to anything.
143249259Sdim    InsertPoint() : Block(0) {}
144249259Sdim
145249259Sdim    /// \brief Creates a new insertion point at the given location.
146249259Sdim    InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint)
147249259Sdim      : Block(InsertBlock), Point(InsertPoint) {}
148249259Sdim
149249259Sdim    /// \brief Returns true if this insert point is set.
150249259Sdim    bool isSet() const { return (Block != 0); }
151249259Sdim
152249259Sdim    llvm::BasicBlock *getBlock() const { return Block; }
153249259Sdim    llvm::BasicBlock::iterator getPoint() const { return Point; }
154249259Sdim  };
155249259Sdim
156249259Sdim  /// \brief Returns the current insert point.
157249259Sdim  InsertPoint saveIP() const {
158249259Sdim    return InsertPoint(GetInsertBlock(), GetInsertPoint());
159249259Sdim  }
160249259Sdim
161249259Sdim  /// \brief Returns the current insert point, clearing it in the process.
162249259Sdim  InsertPoint saveAndClearIP() {
163249259Sdim    InsertPoint IP(GetInsertBlock(), GetInsertPoint());
164249259Sdim    ClearInsertionPoint();
165249259Sdim    return IP;
166249259Sdim  }
167249259Sdim
168249259Sdim  /// \brief Sets the current insert point to a previously-saved location.
169249259Sdim  void restoreIP(InsertPoint IP) {
170249259Sdim    if (IP.isSet())
171249259Sdim      SetInsertPoint(IP.getBlock(), IP.getPoint());
172249259Sdim    else
173249259Sdim      ClearInsertionPoint();
174249259Sdim  }
175249259Sdim
176263508Sdim  /// \brief Get the floating point math metadata being used.
177263508Sdim  MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; }
178263508Sdim
179263508Sdim  /// \brief Get the flags to be applied to created floating point ops
180263508Sdim  FastMathFlags getFastMathFlags() const { return FMF; }
181263508Sdim
182263508Sdim  /// \brief Clear the fast-math flags.
183263508Sdim  void clearFastMathFlags() { FMF.clear(); }
184263508Sdim
185263508Sdim  /// \brief Set the floating point math metadata to be used.
186263508Sdim  void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; }
187263508Sdim
188263508Sdim  /// \brief Set the fast-math flags to be used with generated fp-math operators
189263508Sdim  void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
190263508Sdim
191249259Sdim  //===--------------------------------------------------------------------===//
192263508Sdim  // RAII helpers.
193263508Sdim  //===--------------------------------------------------------------------===//
194263508Sdim
195263508Sdim  // \brief RAII object that stores the current insertion point and restores it
196263508Sdim  // when the object is destroyed. This includes the debug location.
197263508Sdim  class InsertPointGuard {
198263508Sdim    IRBuilderBase &Builder;
199263508Sdim    AssertingVH<BasicBlock> Block;
200263508Sdim    BasicBlock::iterator Point;
201263508Sdim    DebugLoc DbgLoc;
202263508Sdim
203263508Sdim    InsertPointGuard(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
204263508Sdim    InsertPointGuard &operator=(const InsertPointGuard &) LLVM_DELETED_FUNCTION;
205263508Sdim
206263508Sdim  public:
207263508Sdim    InsertPointGuard(IRBuilderBase &B)
208263508Sdim        : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()),
209263508Sdim          DbgLoc(B.getCurrentDebugLocation()) {}
210263508Sdim
211263508Sdim    ~InsertPointGuard() {
212263508Sdim      Builder.restoreIP(InsertPoint(Block, Point));
213263508Sdim      Builder.SetCurrentDebugLocation(DbgLoc);
214263508Sdim    }
215263508Sdim  };
216263508Sdim
217263508Sdim  // \brief RAII object that stores the current fast math settings and restores
218263508Sdim  // them when the object is destroyed.
219263508Sdim  class FastMathFlagGuard {
220263508Sdim    IRBuilderBase &Builder;
221263508Sdim    FastMathFlags FMF;
222263508Sdim    MDNode *FPMathTag;
223263508Sdim
224263508Sdim    FastMathFlagGuard(const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
225263508Sdim    FastMathFlagGuard &operator=(
226263508Sdim        const FastMathFlagGuard &) LLVM_DELETED_FUNCTION;
227263508Sdim
228263508Sdim  public:
229263508Sdim    FastMathFlagGuard(IRBuilderBase &B)
230263508Sdim        : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag) {}
231263508Sdim
232263508Sdim    ~FastMathFlagGuard() {
233263508Sdim      Builder.FMF = FMF;
234263508Sdim      Builder.DefaultFPMathTag = FPMathTag;
235263508Sdim    }
236263508Sdim  };
237263508Sdim
238263508Sdim  //===--------------------------------------------------------------------===//
239249259Sdim  // Miscellaneous creation methods.
240249259Sdim  //===--------------------------------------------------------------------===//
241249259Sdim
242249259Sdim  /// \brief Make a new global variable with initializer type i8*
243249259Sdim  ///
244249259Sdim  /// Make a new global variable with an initializer that has array of i8 type
245249259Sdim  /// filled in with the null terminated string value specified.  The new global
246249259Sdim  /// variable will be marked mergable with any others of the same contents.  If
247249259Sdim  /// Name is specified, it is the name of the global variable created.
248249259Sdim  Value *CreateGlobalString(StringRef Str, const Twine &Name = "");
249249259Sdim
250249259Sdim  /// \brief Get a constant value representing either true or false.
251249259Sdim  ConstantInt *getInt1(bool V) {
252249259Sdim    return ConstantInt::get(getInt1Ty(), V);
253249259Sdim  }
254249259Sdim
255249259Sdim  /// \brief Get the constant value for i1 true.
256249259Sdim  ConstantInt *getTrue() {
257249259Sdim    return ConstantInt::getTrue(Context);
258249259Sdim  }
259249259Sdim
260249259Sdim  /// \brief Get the constant value for i1 false.
261249259Sdim  ConstantInt *getFalse() {
262249259Sdim    return ConstantInt::getFalse(Context);
263249259Sdim  }
264249259Sdim
265249259Sdim  /// \brief Get a constant 8-bit value.
266249259Sdim  ConstantInt *getInt8(uint8_t C) {
267249259Sdim    return ConstantInt::get(getInt8Ty(), C);
268249259Sdim  }
269249259Sdim
270249259Sdim  /// \brief Get a constant 16-bit value.
271249259Sdim  ConstantInt *getInt16(uint16_t C) {
272249259Sdim    return ConstantInt::get(getInt16Ty(), C);
273249259Sdim  }
274249259Sdim
275249259Sdim  /// \brief Get a constant 32-bit value.
276249259Sdim  ConstantInt *getInt32(uint32_t C) {
277249259Sdim    return ConstantInt::get(getInt32Ty(), C);
278249259Sdim  }
279249259Sdim
280249259Sdim  /// \brief Get a constant 64-bit value.
281249259Sdim  ConstantInt *getInt64(uint64_t C) {
282249259Sdim    return ConstantInt::get(getInt64Ty(), C);
283249259Sdim  }
284249259Sdim
285249259Sdim  /// \brief Get a constant integer value.
286249259Sdim  ConstantInt *getInt(const APInt &AI) {
287249259Sdim    return ConstantInt::get(Context, AI);
288249259Sdim  }
289249259Sdim
290249259Sdim  //===--------------------------------------------------------------------===//
291249259Sdim  // Type creation methods
292249259Sdim  //===--------------------------------------------------------------------===//
293249259Sdim
294249259Sdim  /// \brief Fetch the type representing a single bit
295249259Sdim  IntegerType *getInt1Ty() {
296249259Sdim    return Type::getInt1Ty(Context);
297249259Sdim  }
298249259Sdim
299249259Sdim  /// \brief Fetch the type representing an 8-bit integer.
300249259Sdim  IntegerType *getInt8Ty() {
301249259Sdim    return Type::getInt8Ty(Context);
302249259Sdim  }
303249259Sdim
304249259Sdim  /// \brief Fetch the type representing a 16-bit integer.
305249259Sdim  IntegerType *getInt16Ty() {
306249259Sdim    return Type::getInt16Ty(Context);
307249259Sdim  }
308249259Sdim
309249259Sdim  /// \brief Fetch the type representing a 32-bit integer.
310249259Sdim  IntegerType *getInt32Ty() {
311249259Sdim    return Type::getInt32Ty(Context);
312249259Sdim  }
313249259Sdim
314249259Sdim  /// \brief Fetch the type representing a 64-bit integer.
315249259Sdim  IntegerType *getInt64Ty() {
316249259Sdim    return Type::getInt64Ty(Context);
317249259Sdim  }
318249259Sdim
319249259Sdim  /// \brief Fetch the type representing a 32-bit floating point value.
320249259Sdim  Type *getFloatTy() {
321249259Sdim    return Type::getFloatTy(Context);
322249259Sdim  }
323249259Sdim
324249259Sdim  /// \brief Fetch the type representing a 64-bit floating point value.
325249259Sdim  Type *getDoubleTy() {
326249259Sdim    return Type::getDoubleTy(Context);
327249259Sdim  }
328249259Sdim
329249259Sdim  /// \brief Fetch the type representing void.
330249259Sdim  Type *getVoidTy() {
331249259Sdim    return Type::getVoidTy(Context);
332249259Sdim  }
333249259Sdim
334249259Sdim  /// \brief Fetch the type representing a pointer to an 8-bit integer value.
335249259Sdim  PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
336249259Sdim    return Type::getInt8PtrTy(Context, AddrSpace);
337249259Sdim  }
338249259Sdim
339249259Sdim  /// \brief Fetch the type representing a pointer to an integer value.
340263508Sdim  IntegerType* getIntPtrTy(const DataLayout *DL, unsigned AddrSpace = 0) {
341249259Sdim    return DL->getIntPtrType(Context, AddrSpace);
342249259Sdim  }
343249259Sdim
344249259Sdim  //===--------------------------------------------------------------------===//
345249259Sdim  // Intrinsic creation methods
346249259Sdim  //===--------------------------------------------------------------------===//
347249259Sdim
348249259Sdim  /// \brief Create and insert a memset to the specified pointer and the
349249259Sdim  /// specified value.
350249259Sdim  ///
351249259Sdim  /// If the pointer isn't an i8*, it will be converted.  If a TBAA tag is
352249259Sdim  /// specified, it will be added to the instruction.
353249259Sdim  CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
354249259Sdim                         bool isVolatile = false, MDNode *TBAATag = 0) {
355249259Sdim    return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
356249259Sdim  }
357249259Sdim
358249259Sdim  CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
359249259Sdim                         bool isVolatile = false, MDNode *TBAATag = 0);
360249259Sdim
361249259Sdim  /// \brief Create and insert a memcpy between the specified pointers.
362249259Sdim  ///
363249259Sdim  /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is
364249259Sdim  /// specified, it will be added to the instruction.
365249259Sdim  CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
366249259Sdim                         bool isVolatile = false, MDNode *TBAATag = 0,
367249259Sdim                         MDNode *TBAAStructTag = 0) {
368249259Sdim    return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag,
369249259Sdim                        TBAAStructTag);
370249259Sdim  }
371249259Sdim
372249259Sdim  CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
373249259Sdim                         bool isVolatile = false, MDNode *TBAATag = 0,
374249259Sdim                         MDNode *TBAAStructTag = 0);
375249259Sdim
376249259Sdim  /// \brief Create and insert a memmove between the specified
377249259Sdim  /// pointers.
378249259Sdim  ///
379249259Sdim  /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is
380249259Sdim  /// specified, it will be added to the instruction.
381249259Sdim  CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
382249259Sdim                          bool isVolatile = false, MDNode *TBAATag = 0) {
383249259Sdim    return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
384249259Sdim  }
385249259Sdim
386249259Sdim  CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
387249259Sdim                          bool isVolatile = false, MDNode *TBAATag = 0);
388249259Sdim
389249259Sdim  /// \brief Create a lifetime.start intrinsic.
390249259Sdim  ///
391249259Sdim  /// If the pointer isn't i8* it will be converted.
392249259Sdim  CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0);
393249259Sdim
394249259Sdim  /// \brief Create a lifetime.end intrinsic.
395249259Sdim  ///
396249259Sdim  /// If the pointer isn't i8* it will be converted.
397249259Sdim  CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0);
398249259Sdim
399249259Sdimprivate:
400249259Sdim  Value *getCastedInt8PtrValue(Value *Ptr);
401249259Sdim};
402249259Sdim
403249259Sdim/// \brief This provides a uniform API for creating instructions and inserting
404249259Sdim/// them into a basic block: either at the end of a BasicBlock, or at a specific
405249259Sdim/// iterator location in a block.
406249259Sdim///
407249259Sdim/// Note that the builder does not expose the full generality of LLVM
408249259Sdim/// instructions.  For access to extra instruction properties, use the mutators
409249259Sdim/// (e.g. setVolatile) on the instructions after they have been
410249259Sdim/// created. Convenience state exists to specify fast-math flags and fp-math
411249259Sdim/// tags.
412249259Sdim///
413249259Sdim/// The first template argument handles whether or not to preserve names in the
414249259Sdim/// final instruction output. This defaults to on.  The second template argument
415249259Sdim/// specifies a class to use for creating constants.  This defaults to creating
416249259Sdim/// minimally folded constants.  The fourth template argument allows clients to
417249259Sdim/// specify custom insertion hooks that are called on every newly created
418249259Sdim/// insertion.
419249259Sdimtemplate<bool preserveNames = true, typename T = ConstantFolder,
420249259Sdim         typename Inserter = IRBuilderDefaultInserter<preserveNames> >
421249259Sdimclass IRBuilder : public IRBuilderBase, public Inserter {
422249259Sdim  T Folder;
423249259Sdimpublic:
424249259Sdim  IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(),
425249259Sdim            MDNode *FPMathTag = 0)
426263508Sdim    : IRBuilderBase(C, FPMathTag), Inserter(I), Folder(F) {
427249259Sdim  }
428249259Sdim
429249259Sdim  explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0)
430263508Sdim    : IRBuilderBase(C, FPMathTag), Folder() {
431249259Sdim  }
432249259Sdim
433249259Sdim  explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0)
434263508Sdim    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder(F) {
435249259Sdim    SetInsertPoint(TheBB);
436249259Sdim  }
437249259Sdim
438249259Sdim  explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0)
439263508Sdim    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder() {
440249259Sdim    SetInsertPoint(TheBB);
441249259Sdim  }
442249259Sdim
443249259Sdim  explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0)
444263508Sdim    : IRBuilderBase(IP->getContext(), FPMathTag), Folder() {
445249259Sdim    SetInsertPoint(IP);
446249259Sdim    SetCurrentDebugLocation(IP->getDebugLoc());
447249259Sdim  }
448249259Sdim
449249259Sdim  explicit IRBuilder(Use &U, MDNode *FPMathTag = 0)
450263508Sdim    : IRBuilderBase(U->getContext(), FPMathTag), Folder() {
451249259Sdim    SetInsertPoint(U);
452249259Sdim    SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
453249259Sdim  }
454249259Sdim
455249259Sdim  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F,
456249259Sdim            MDNode *FPMathTag = 0)
457263508Sdim    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder(F) {
458249259Sdim    SetInsertPoint(TheBB, IP);
459249259Sdim  }
460249259Sdim
461249259Sdim  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0)
462263508Sdim    : IRBuilderBase(TheBB->getContext(), FPMathTag), Folder() {
463249259Sdim    SetInsertPoint(TheBB, IP);
464249259Sdim  }
465249259Sdim
466249259Sdim  /// \brief Get the constant folder being used.
467249259Sdim  const T &getFolder() { return Folder; }
468249259Sdim
469249259Sdim  /// \brief Return true if this builder is configured to actually add the
470249259Sdim  /// requested names to IR created through it.
471249259Sdim  bool isNamePreserving() const { return preserveNames; }
472249259Sdim
473249259Sdim  /// \brief Insert and return the specified instruction.
474249259Sdim  template<typename InstTy>
475249259Sdim  InstTy *Insert(InstTy *I, const Twine &Name = "") const {
476249259Sdim    this->InsertHelper(I, Name, BB, InsertPt);
477249259Sdim    this->SetInstDebugLocation(I);
478249259Sdim    return I;
479249259Sdim  }
480249259Sdim
481249259Sdim  /// \brief No-op overload to handle constants.
482249259Sdim  Constant *Insert(Constant *C, const Twine& = "") const {
483249259Sdim    return C;
484249259Sdim  }
485249259Sdim
486249259Sdim  //===--------------------------------------------------------------------===//
487249259Sdim  // Instruction creation methods: Terminators
488249259Sdim  //===--------------------------------------------------------------------===//
489249259Sdim
490249259Sdimprivate:
491249259Sdim  /// \brief Helper to add branch weight metadata onto an instruction.
492249259Sdim  /// \returns The annotated instruction.
493249259Sdim  template <typename InstTy>
494249259Sdim  InstTy *addBranchWeights(InstTy *I, MDNode *Weights) {
495249259Sdim    if (Weights)
496249259Sdim      I->setMetadata(LLVMContext::MD_prof, Weights);
497249259Sdim    return I;
498249259Sdim  }
499249259Sdim
500249259Sdimpublic:
501249259Sdim  /// \brief Create a 'ret void' instruction.
502249259Sdim  ReturnInst *CreateRetVoid() {
503249259Sdim    return Insert(ReturnInst::Create(Context));
504249259Sdim  }
505249259Sdim
506249259Sdim  /// \brief Create a 'ret <val>' instruction.
507249259Sdim  ReturnInst *CreateRet(Value *V) {
508249259Sdim    return Insert(ReturnInst::Create(Context, V));
509249259Sdim  }
510249259Sdim
511249259Sdim  /// \brief Create a sequence of N insertvalue instructions,
512249259Sdim  /// with one Value from the retVals array each, that build a aggregate
513249259Sdim  /// return value one value at a time, and a ret instruction to return
514249259Sdim  /// the resulting aggregate value.
515249259Sdim  ///
516249259Sdim  /// This is a convenience function for code that uses aggregate return values
517249259Sdim  /// as a vehicle for having multiple return values.
518249259Sdim  ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) {
519249259Sdim    Value *V = UndefValue::get(getCurrentFunctionReturnType());
520249259Sdim    for (unsigned i = 0; i != N; ++i)
521249259Sdim      V = CreateInsertValue(V, retVals[i], i, "mrv");
522249259Sdim    return Insert(ReturnInst::Create(Context, V));
523249259Sdim  }
524249259Sdim
525249259Sdim  /// \brief Create an unconditional 'br label X' instruction.
526249259Sdim  BranchInst *CreateBr(BasicBlock *Dest) {
527249259Sdim    return Insert(BranchInst::Create(Dest));
528249259Sdim  }
529249259Sdim
530249259Sdim  /// \brief Create a conditional 'br Cond, TrueDest, FalseDest'
531249259Sdim  /// instruction.
532249259Sdim  BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False,
533249259Sdim                           MDNode *BranchWeights = 0) {
534249259Sdim    return Insert(addBranchWeights(BranchInst::Create(True, False, Cond),
535249259Sdim                                   BranchWeights));
536249259Sdim  }
537249259Sdim
538249259Sdim  /// \brief Create a switch instruction with the specified value, default dest,
539249259Sdim  /// and with a hint for the number of cases that will be added (for efficient
540249259Sdim  /// allocation).
541249259Sdim  SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10,
542249259Sdim                           MDNode *BranchWeights = 0) {
543249259Sdim    return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases),
544249259Sdim                                   BranchWeights));
545249259Sdim  }
546249259Sdim
547249259Sdim  /// \brief Create an indirect branch instruction with the specified address
548249259Sdim  /// operand, with an optional hint for the number of destinations that will be
549249259Sdim  /// added (for efficient allocation).
550249259Sdim  IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) {
551249259Sdim    return Insert(IndirectBrInst::Create(Addr, NumDests));
552249259Sdim  }
553249259Sdim
554249259Sdim  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
555249259Sdim                           BasicBlock *UnwindDest, const Twine &Name = "") {
556249259Sdim    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
557249259Sdim                                     ArrayRef<Value *>()),
558249259Sdim                  Name);
559249259Sdim  }
560249259Sdim  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
561249259Sdim                           BasicBlock *UnwindDest, Value *Arg1,
562249259Sdim                           const Twine &Name = "") {
563249259Sdim    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Arg1),
564249259Sdim                  Name);
565249259Sdim  }
566249259Sdim  InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest,
567249259Sdim                            BasicBlock *UnwindDest, Value *Arg1,
568249259Sdim                            Value *Arg2, Value *Arg3,
569249259Sdim                            const Twine &Name = "") {
570249259Sdim    Value *Args[] = { Arg1, Arg2, Arg3 };
571249259Sdim    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
572249259Sdim                  Name);
573249259Sdim  }
574249259Sdim  /// \brief Create an invoke instruction.
575249259Sdim  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
576249259Sdim                           BasicBlock *UnwindDest, ArrayRef<Value *> Args,
577249259Sdim                           const Twine &Name = "") {
578249259Sdim    return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
579249259Sdim                  Name);
580249259Sdim  }
581249259Sdim
582249259Sdim  ResumeInst *CreateResume(Value *Exn) {
583249259Sdim    return Insert(ResumeInst::Create(Exn));
584249259Sdim  }
585249259Sdim
586249259Sdim  UnreachableInst *CreateUnreachable() {
587249259Sdim    return Insert(new UnreachableInst(Context));
588249259Sdim  }
589249259Sdim
590249259Sdim  //===--------------------------------------------------------------------===//
591249259Sdim  // Instruction creation methods: Binary Operators
592249259Sdim  //===--------------------------------------------------------------------===//
593249259Sdimprivate:
594249259Sdim  BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc,
595249259Sdim                                          Value *LHS, Value *RHS,
596249259Sdim                                          const Twine &Name,
597249259Sdim                                          bool HasNUW, bool HasNSW) {
598249259Sdim    BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
599249259Sdim    if (HasNUW) BO->setHasNoUnsignedWrap();
600249259Sdim    if (HasNSW) BO->setHasNoSignedWrap();
601249259Sdim    return BO;
602249259Sdim  }
603249259Sdim
604249259Sdim  Instruction *AddFPMathAttributes(Instruction *I,
605249259Sdim                                   MDNode *FPMathTag,
606249259Sdim                                   FastMathFlags FMF) const {
607249259Sdim    if (!FPMathTag)
608249259Sdim      FPMathTag = DefaultFPMathTag;
609249259Sdim    if (FPMathTag)
610249259Sdim      I->setMetadata(LLVMContext::MD_fpmath, FPMathTag);
611249259Sdim    I->setFastMathFlags(FMF);
612249259Sdim    return I;
613249259Sdim  }
614249259Sdimpublic:
615249259Sdim  Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "",
616249259Sdim                   bool HasNUW = false, bool HasNSW = false) {
617249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
618249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
619249259Sdim        return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name);
620249259Sdim    return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name,
621249259Sdim                                   HasNUW, HasNSW);
622249259Sdim  }
623249259Sdim  Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
624249259Sdim    return CreateAdd(LHS, RHS, Name, false, true);
625249259Sdim  }
626249259Sdim  Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
627249259Sdim    return CreateAdd(LHS, RHS, Name, true, false);
628249259Sdim  }
629249259Sdim  Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "",
630249259Sdim                    MDNode *FPMathTag = 0) {
631249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
632249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
633249259Sdim        return Insert(Folder.CreateFAdd(LC, RC), Name);
634249259Sdim    return Insert(AddFPMathAttributes(BinaryOperator::CreateFAdd(LHS, RHS),
635249259Sdim                                      FPMathTag, FMF), Name);
636249259Sdim  }
637249259Sdim  Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "",
638249259Sdim                   bool HasNUW = false, bool HasNSW = false) {
639249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
640249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
641249259Sdim        return Insert(Folder.CreateSub(LC, RC), Name);
642249259Sdim    return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name,
643249259Sdim                                   HasNUW, HasNSW);
644249259Sdim  }
645249259Sdim  Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
646249259Sdim    return CreateSub(LHS, RHS, Name, false, true);
647249259Sdim  }
648249259Sdim  Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
649249259Sdim    return CreateSub(LHS, RHS, Name, true, false);
650249259Sdim  }
651249259Sdim  Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "",
652249259Sdim                    MDNode *FPMathTag = 0) {
653249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
654249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
655249259Sdim        return Insert(Folder.CreateFSub(LC, RC), Name);
656249259Sdim    return Insert(AddFPMathAttributes(BinaryOperator::CreateFSub(LHS, RHS),
657249259Sdim                                      FPMathTag, FMF), Name);
658249259Sdim  }
659249259Sdim  Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "",
660249259Sdim                   bool HasNUW = false, bool HasNSW = false) {
661249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
662249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
663249259Sdim        return Insert(Folder.CreateMul(LC, RC), Name);
664249259Sdim    return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name,
665249259Sdim                                   HasNUW, HasNSW);
666249259Sdim  }
667249259Sdim  Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
668249259Sdim    return CreateMul(LHS, RHS, Name, false, true);
669249259Sdim  }
670249259Sdim  Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
671249259Sdim    return CreateMul(LHS, RHS, Name, true, false);
672249259Sdim  }
673249259Sdim  Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "",
674249259Sdim                    MDNode *FPMathTag = 0) {
675249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
676249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
677249259Sdim        return Insert(Folder.CreateFMul(LC, RC), Name);
678249259Sdim    return Insert(AddFPMathAttributes(BinaryOperator::CreateFMul(LHS, RHS),
679249259Sdim                                      FPMathTag, FMF), Name);
680249259Sdim  }
681249259Sdim  Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
682249259Sdim                    bool isExact = false) {
683249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
684249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
685249259Sdim        return Insert(Folder.CreateUDiv(LC, RC, isExact), Name);
686249259Sdim    if (!isExact)
687249259Sdim      return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
688249259Sdim    return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name);
689249259Sdim  }
690249259Sdim  Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
691249259Sdim    return CreateUDiv(LHS, RHS, Name, true);
692249259Sdim  }
693249259Sdim  Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "",
694249259Sdim                    bool isExact = false) {
695249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
696249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
697249259Sdim        return Insert(Folder.CreateSDiv(LC, RC, isExact), Name);
698249259Sdim    if (!isExact)
699249259Sdim      return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
700249259Sdim    return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
701249259Sdim  }
702249259Sdim  Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
703249259Sdim    return CreateSDiv(LHS, RHS, Name, true);
704249259Sdim  }
705249259Sdim  Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "",
706249259Sdim                    MDNode *FPMathTag = 0) {
707249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
708249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
709249259Sdim        return Insert(Folder.CreateFDiv(LC, RC), Name);
710249259Sdim    return Insert(AddFPMathAttributes(BinaryOperator::CreateFDiv(LHS, RHS),
711249259Sdim                                      FPMathTag, FMF), Name);
712249259Sdim  }
713249259Sdim  Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
714249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
715249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
716249259Sdim        return Insert(Folder.CreateURem(LC, RC), Name);
717249259Sdim    return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
718249259Sdim  }
719249259Sdim  Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") {
720249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
721249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
722249259Sdim        return Insert(Folder.CreateSRem(LC, RC), Name);
723249259Sdim    return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
724249259Sdim  }
725249259Sdim  Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "",
726249259Sdim                    MDNode *FPMathTag = 0) {
727249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
728249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
729249259Sdim        return Insert(Folder.CreateFRem(LC, RC), Name);
730249259Sdim    return Insert(AddFPMathAttributes(BinaryOperator::CreateFRem(LHS, RHS),
731249259Sdim                                      FPMathTag, FMF), Name);
732249259Sdim  }
733249259Sdim
734249259Sdim  Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "",
735249259Sdim                   bool HasNUW = false, bool HasNSW = false) {
736249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
737249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
738249259Sdim        return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name);
739249259Sdim    return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name,
740249259Sdim                                   HasNUW, HasNSW);
741249259Sdim  }
742249259Sdim  Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "",
743249259Sdim                   bool HasNUW = false, bool HasNSW = false) {
744249259Sdim    return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
745249259Sdim                     HasNUW, HasNSW);
746249259Sdim  }
747249259Sdim  Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "",
748249259Sdim                   bool HasNUW = false, bool HasNSW = false) {
749249259Sdim    return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
750249259Sdim                     HasNUW, HasNSW);
751249259Sdim  }
752249259Sdim
753249259Sdim  Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "",
754249259Sdim                    bool isExact = false) {
755249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
756249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
757249259Sdim        return Insert(Folder.CreateLShr(LC, RC, isExact), Name);
758249259Sdim    if (!isExact)
759249259Sdim      return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
760249259Sdim    return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name);
761249259Sdim  }
762249259Sdim  Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
763249259Sdim                    bool isExact = false) {
764249259Sdim    return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
765249259Sdim  }
766249259Sdim  Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
767249259Sdim                    bool isExact = false) {
768249259Sdim    return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
769249259Sdim  }
770249259Sdim
771249259Sdim  Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "",
772249259Sdim                    bool isExact = false) {
773249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
774249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
775249259Sdim        return Insert(Folder.CreateAShr(LC, RC, isExact), Name);
776249259Sdim    if (!isExact)
777249259Sdim      return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
778249259Sdim    return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name);
779249259Sdim  }
780249259Sdim  Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
781249259Sdim                    bool isExact = false) {
782249259Sdim    return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
783249259Sdim  }
784249259Sdim  Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
785249259Sdim                    bool isExact = false) {
786249259Sdim    return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
787249259Sdim  }
788249259Sdim
789249259Sdim  Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
790249259Sdim    if (Constant *RC = dyn_cast<Constant>(RHS)) {
791249259Sdim      if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())
792249259Sdim        return LHS;  // LHS & -1 -> LHS
793249259Sdim      if (Constant *LC = dyn_cast<Constant>(LHS))
794249259Sdim        return Insert(Folder.CreateAnd(LC, RC), Name);
795249259Sdim    }
796249259Sdim    return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
797249259Sdim  }
798249259Sdim  Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") {
799249259Sdim    return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
800249259Sdim  }
801249259Sdim  Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") {
802249259Sdim    return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
803249259Sdim  }
804249259Sdim
805249259Sdim  Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
806249259Sdim    if (Constant *RC = dyn_cast<Constant>(RHS)) {
807249259Sdim      if (RC->isNullValue())
808249259Sdim        return LHS;  // LHS | 0 -> LHS
809249259Sdim      if (Constant *LC = dyn_cast<Constant>(LHS))
810249259Sdim        return Insert(Folder.CreateOr(LC, RC), Name);
811249259Sdim    }
812249259Sdim    return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
813249259Sdim  }
814249259Sdim  Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
815249259Sdim    return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
816249259Sdim  }
817249259Sdim  Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
818249259Sdim    return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
819249259Sdim  }
820249259Sdim
821249259Sdim  Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
822249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
823249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
824249259Sdim        return Insert(Folder.CreateXor(LC, RC), Name);
825249259Sdim    return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
826249259Sdim  }
827249259Sdim  Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") {
828249259Sdim    return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
829249259Sdim  }
830249259Sdim  Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") {
831249259Sdim    return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
832249259Sdim  }
833249259Sdim
834249259Sdim  Value *CreateBinOp(Instruction::BinaryOps Opc,
835249259Sdim                     Value *LHS, Value *RHS, const Twine &Name = "") {
836249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
837249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
838249259Sdim        return Insert(Folder.CreateBinOp(Opc, LC, RC), Name);
839249259Sdim    return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
840249259Sdim  }
841249259Sdim
842249259Sdim  Value *CreateNeg(Value *V, const Twine &Name = "",
843249259Sdim                   bool HasNUW = false, bool HasNSW = false) {
844249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
845249259Sdim      return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name);
846249259Sdim    BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name);
847249259Sdim    if (HasNUW) BO->setHasNoUnsignedWrap();
848249259Sdim    if (HasNSW) BO->setHasNoSignedWrap();
849249259Sdim    return BO;
850249259Sdim  }
851249259Sdim  Value *CreateNSWNeg(Value *V, const Twine &Name = "") {
852249259Sdim    return CreateNeg(V, Name, false, true);
853249259Sdim  }
854249259Sdim  Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
855249259Sdim    return CreateNeg(V, Name, true, false);
856249259Sdim  }
857249259Sdim  Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) {
858249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
859249259Sdim      return Insert(Folder.CreateFNeg(VC), Name);
860249259Sdim    return Insert(AddFPMathAttributes(BinaryOperator::CreateFNeg(V),
861249259Sdim                                      FPMathTag, FMF), Name);
862249259Sdim  }
863249259Sdim  Value *CreateNot(Value *V, const Twine &Name = "") {
864249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
865249259Sdim      return Insert(Folder.CreateNot(VC), Name);
866249259Sdim    return Insert(BinaryOperator::CreateNot(V), Name);
867249259Sdim  }
868249259Sdim
869249259Sdim  //===--------------------------------------------------------------------===//
870249259Sdim  // Instruction creation methods: Memory Instructions
871249259Sdim  //===--------------------------------------------------------------------===//
872249259Sdim
873249259Sdim  AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = 0,
874249259Sdim                           const Twine &Name = "") {
875249259Sdim    return Insert(new AllocaInst(Ty, ArraySize), Name);
876249259Sdim  }
877249259Sdim  // \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
878249259Sdim  // converting the string to 'bool' for the isVolatile parameter.
879249259Sdim  LoadInst *CreateLoad(Value *Ptr, const char *Name) {
880249259Sdim    return Insert(new LoadInst(Ptr), Name);
881249259Sdim  }
882249259Sdim  LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") {
883249259Sdim    return Insert(new LoadInst(Ptr), Name);
884249259Sdim  }
885249259Sdim  LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") {
886249259Sdim    return Insert(new LoadInst(Ptr, 0, isVolatile), Name);
887249259Sdim  }
888249259Sdim  StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
889249259Sdim    return Insert(new StoreInst(Val, Ptr, isVolatile));
890249259Sdim  }
891249259Sdim  // \brief Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")'
892249259Sdim  // correctly, instead of converting the string to 'bool' for the isVolatile
893249259Sdim  // parameter.
894249259Sdim  LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) {
895249259Sdim    LoadInst *LI = CreateLoad(Ptr, Name);
896249259Sdim    LI->setAlignment(Align);
897249259Sdim    return LI;
898249259Sdim  }
899249259Sdim  LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align,
900249259Sdim                              const Twine &Name = "") {
901249259Sdim    LoadInst *LI = CreateLoad(Ptr, Name);
902249259Sdim    LI->setAlignment(Align);
903249259Sdim    return LI;
904249259Sdim  }
905249259Sdim  LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile,
906249259Sdim                              const Twine &Name = "") {
907249259Sdim    LoadInst *LI = CreateLoad(Ptr, isVolatile, Name);
908249259Sdim    LI->setAlignment(Align);
909249259Sdim    return LI;
910249259Sdim  }
911249259Sdim  StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align,
912249259Sdim                                bool isVolatile = false) {
913249259Sdim    StoreInst *SI = CreateStore(Val, Ptr, isVolatile);
914249259Sdim    SI->setAlignment(Align);
915249259Sdim    return SI;
916249259Sdim  }
917249259Sdim  FenceInst *CreateFence(AtomicOrdering Ordering,
918249259Sdim                         SynchronizationScope SynchScope = CrossThread) {
919249259Sdim    return Insert(new FenceInst(Context, Ordering, SynchScope));
920249259Sdim  }
921249259Sdim  AtomicCmpXchgInst *CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
922249259Sdim                                         AtomicOrdering Ordering,
923249259Sdim                               SynchronizationScope SynchScope = CrossThread) {
924249259Sdim    return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, SynchScope));
925249259Sdim  }
926249259Sdim  AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val,
927249259Sdim                                 AtomicOrdering Ordering,
928249259Sdim                               SynchronizationScope SynchScope = CrossThread) {
929249259Sdim    return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SynchScope));
930249259Sdim  }
931249259Sdim  Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
932249259Sdim                   const Twine &Name = "") {
933249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
934249259Sdim      // Every index must be constant.
935249259Sdim      size_t i, e;
936249259Sdim      for (i = 0, e = IdxList.size(); i != e; ++i)
937249259Sdim        if (!isa<Constant>(IdxList[i]))
938249259Sdim          break;
939249259Sdim      if (i == e)
940249259Sdim        return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name);
941249259Sdim    }
942249259Sdim    return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name);
943249259Sdim  }
944249259Sdim  Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
945249259Sdim                           const Twine &Name = "") {
946249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
947249259Sdim      // Every index must be constant.
948249259Sdim      size_t i, e;
949249259Sdim      for (i = 0, e = IdxList.size(); i != e; ++i)
950249259Sdim        if (!isa<Constant>(IdxList[i]))
951249259Sdim          break;
952249259Sdim      if (i == e)
953249259Sdim        return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
954249259Sdim    }
955249259Sdim    return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name);
956249259Sdim  }
957249259Sdim  Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
958249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
959249259Sdim      if (Constant *IC = dyn_cast<Constant>(Idx))
960249259Sdim        return Insert(Folder.CreateGetElementPtr(PC, IC), Name);
961249259Sdim    return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
962249259Sdim  }
963249259Sdim  Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
964249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
965249259Sdim      if (Constant *IC = dyn_cast<Constant>(Idx))
966249259Sdim        return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name);
967249259Sdim    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
968249259Sdim  }
969249259Sdim  Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
970249259Sdim    Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
971249259Sdim
972249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
973249259Sdim      return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
974249259Sdim
975249259Sdim    return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
976249259Sdim  }
977249259Sdim  Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
978249259Sdim                                    const Twine &Name = "") {
979249259Sdim    Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
980249259Sdim
981249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
982249259Sdim      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
983249259Sdim
984249259Sdim    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
985249259Sdim  }
986249259Sdim  Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
987249259Sdim                    const Twine &Name = "") {
988249259Sdim    Value *Idxs[] = {
989249259Sdim      ConstantInt::get(Type::getInt32Ty(Context), Idx0),
990249259Sdim      ConstantInt::get(Type::getInt32Ty(Context), Idx1)
991249259Sdim    };
992249259Sdim
993249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
994249259Sdim      return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
995249259Sdim
996249259Sdim    return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
997249259Sdim  }
998249259Sdim  Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
999249259Sdim                                    const Twine &Name = "") {
1000249259Sdim    Value *Idxs[] = {
1001249259Sdim      ConstantInt::get(Type::getInt32Ty(Context), Idx0),
1002249259Sdim      ConstantInt::get(Type::getInt32Ty(Context), Idx1)
1003249259Sdim    };
1004249259Sdim
1005249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
1006249259Sdim      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
1007249259Sdim
1008249259Sdim    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
1009249259Sdim  }
1010249259Sdim  Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
1011249259Sdim    Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
1012249259Sdim
1013249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
1014249259Sdim      return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
1015249259Sdim
1016249259Sdim    return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
1017249259Sdim  }
1018249259Sdim  Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
1019249259Sdim                                    const Twine &Name = "") {
1020249259Sdim    Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
1021249259Sdim
1022249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
1023249259Sdim      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
1024249259Sdim
1025249259Sdim    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
1026249259Sdim  }
1027249259Sdim  Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
1028249259Sdim                    const Twine &Name = "") {
1029249259Sdim    Value *Idxs[] = {
1030249259Sdim      ConstantInt::get(Type::getInt64Ty(Context), Idx0),
1031249259Sdim      ConstantInt::get(Type::getInt64Ty(Context), Idx1)
1032249259Sdim    };
1033249259Sdim
1034249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
1035249259Sdim      return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
1036249259Sdim
1037249259Sdim    return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
1038249259Sdim  }
1039249259Sdim  Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
1040249259Sdim                                    const Twine &Name = "") {
1041249259Sdim    Value *Idxs[] = {
1042249259Sdim      ConstantInt::get(Type::getInt64Ty(Context), Idx0),
1043249259Sdim      ConstantInt::get(Type::getInt64Ty(Context), Idx1)
1044249259Sdim    };
1045249259Sdim
1046249259Sdim    if (Constant *PC = dyn_cast<Constant>(Ptr))
1047249259Sdim      return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
1048249259Sdim
1049249259Sdim    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
1050249259Sdim  }
1051249259Sdim  Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
1052249259Sdim    return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
1053249259Sdim  }
1054249259Sdim
1055249259Sdim  /// \brief Same as CreateGlobalString, but return a pointer with "i8*" type
1056249259Sdim  /// instead of a pointer to array of i8.
1057249259Sdim  Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") {
1058249259Sdim    Value *gv = CreateGlobalString(Str, Name);
1059249259Sdim    Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
1060249259Sdim    Value *Args[] = { zero, zero };
1061249259Sdim    return CreateInBoundsGEP(gv, Args, Name);
1062249259Sdim  }
1063249259Sdim
1064249259Sdim  //===--------------------------------------------------------------------===//
1065249259Sdim  // Instruction creation methods: Cast/Conversion Operators
1066249259Sdim  //===--------------------------------------------------------------------===//
1067249259Sdim
1068249259Sdim  Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") {
1069249259Sdim    return CreateCast(Instruction::Trunc, V, DestTy, Name);
1070249259Sdim  }
1071249259Sdim  Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") {
1072249259Sdim    return CreateCast(Instruction::ZExt, V, DestTy, Name);
1073249259Sdim  }
1074249259Sdim  Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") {
1075249259Sdim    return CreateCast(Instruction::SExt, V, DestTy, Name);
1076249259Sdim  }
1077249259Sdim  /// \brief Create a ZExt or Trunc from the integer value V to DestTy. Return
1078249259Sdim  /// the value untouched if the type of V is already DestTy.
1079249259Sdim  Value *CreateZExtOrTrunc(Value *V, Type *DestTy,
1080249259Sdim                           const Twine &Name = "") {
1081249259Sdim    assert(V->getType()->isIntOrIntVectorTy() &&
1082249259Sdim           DestTy->isIntOrIntVectorTy() &&
1083249259Sdim           "Can only zero extend/truncate integers!");
1084249259Sdim    Type *VTy = V->getType();
1085249259Sdim    if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits())
1086249259Sdim      return CreateZExt(V, DestTy, Name);
1087249259Sdim    if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
1088249259Sdim      return CreateTrunc(V, DestTy, Name);
1089249259Sdim    return V;
1090249259Sdim  }
1091249259Sdim  /// \brief Create a SExt or Trunc from the integer value V to DestTy. Return
1092249259Sdim  /// the value untouched if the type of V is already DestTy.
1093249259Sdim  Value *CreateSExtOrTrunc(Value *V, Type *DestTy,
1094249259Sdim                           const Twine &Name = "") {
1095249259Sdim    assert(V->getType()->isIntOrIntVectorTy() &&
1096249259Sdim           DestTy->isIntOrIntVectorTy() &&
1097249259Sdim           "Can only sign extend/truncate integers!");
1098249259Sdim    Type *VTy = V->getType();
1099249259Sdim    if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits())
1100249259Sdim      return CreateSExt(V, DestTy, Name);
1101249259Sdim    if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
1102249259Sdim      return CreateTrunc(V, DestTy, Name);
1103249259Sdim    return V;
1104249259Sdim  }
1105249259Sdim  Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){
1106249259Sdim    return CreateCast(Instruction::FPToUI, V, DestTy, Name);
1107249259Sdim  }
1108249259Sdim  Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){
1109249259Sdim    return CreateCast(Instruction::FPToSI, V, DestTy, Name);
1110249259Sdim  }
1111249259Sdim  Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
1112249259Sdim    return CreateCast(Instruction::UIToFP, V, DestTy, Name);
1113249259Sdim  }
1114249259Sdim  Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
1115249259Sdim    return CreateCast(Instruction::SIToFP, V, DestTy, Name);
1116249259Sdim  }
1117249259Sdim  Value *CreateFPTrunc(Value *V, Type *DestTy,
1118249259Sdim                       const Twine &Name = "") {
1119249259Sdim    return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
1120249259Sdim  }
1121249259Sdim  Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") {
1122249259Sdim    return CreateCast(Instruction::FPExt, V, DestTy, Name);
1123249259Sdim  }
1124249259Sdim  Value *CreatePtrToInt(Value *V, Type *DestTy,
1125249259Sdim                        const Twine &Name = "") {
1126249259Sdim    return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
1127249259Sdim  }
1128249259Sdim  Value *CreateIntToPtr(Value *V, Type *DestTy,
1129249259Sdim                        const Twine &Name = "") {
1130249259Sdim    return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
1131249259Sdim  }
1132249259Sdim  Value *CreateBitCast(Value *V, Type *DestTy,
1133249259Sdim                       const Twine &Name = "") {
1134249259Sdim    return CreateCast(Instruction::BitCast, V, DestTy, Name);
1135249259Sdim  }
1136263508Sdim  Value *CreateAddrSpaceCast(Value *V, Type *DestTy,
1137263508Sdim                             const Twine &Name = "") {
1138263508Sdim    return CreateCast(Instruction::AddrSpaceCast, V, DestTy, Name);
1139263508Sdim  }
1140249259Sdim  Value *CreateZExtOrBitCast(Value *V, Type *DestTy,
1141249259Sdim                             const Twine &Name = "") {
1142249259Sdim    if (V->getType() == DestTy)
1143249259Sdim      return V;
1144249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
1145249259Sdim      return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name);
1146249259Sdim    return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name);
1147249259Sdim  }
1148249259Sdim  Value *CreateSExtOrBitCast(Value *V, Type *DestTy,
1149249259Sdim                             const Twine &Name = "") {
1150249259Sdim    if (V->getType() == DestTy)
1151249259Sdim      return V;
1152249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
1153249259Sdim      return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name);
1154249259Sdim    return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name);
1155249259Sdim  }
1156249259Sdim  Value *CreateTruncOrBitCast(Value *V, Type *DestTy,
1157249259Sdim                              const Twine &Name = "") {
1158249259Sdim    if (V->getType() == DestTy)
1159249259Sdim      return V;
1160249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
1161249259Sdim      return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name);
1162249259Sdim    return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name);
1163249259Sdim  }
1164249259Sdim  Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy,
1165249259Sdim                    const Twine &Name = "") {
1166249259Sdim    if (V->getType() == DestTy)
1167249259Sdim      return V;
1168249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
1169249259Sdim      return Insert(Folder.CreateCast(Op, VC, DestTy), Name);
1170249259Sdim    return Insert(CastInst::Create(Op, V, DestTy), Name);
1171249259Sdim  }
1172249259Sdim  Value *CreatePointerCast(Value *V, Type *DestTy,
1173249259Sdim                           const Twine &Name = "") {
1174249259Sdim    if (V->getType() == DestTy)
1175249259Sdim      return V;
1176249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
1177249259Sdim      return Insert(Folder.CreatePointerCast(VC, DestTy), Name);
1178249259Sdim    return Insert(CastInst::CreatePointerCast(V, DestTy), Name);
1179249259Sdim  }
1180249259Sdim  Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned,
1181249259Sdim                       const Twine &Name = "") {
1182249259Sdim    if (V->getType() == DestTy)
1183249259Sdim      return V;
1184249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
1185249259Sdim      return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name);
1186249259Sdim    return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
1187249259Sdim  }
1188249259Sdimprivate:
1189249259Sdim  // \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
1190249259Sdim  // compile time error, instead of converting the string to bool for the
1191249259Sdim  // isSigned parameter.
1192249259Sdim  Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION;
1193249259Sdimpublic:
1194249259Sdim  Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") {
1195249259Sdim    if (V->getType() == DestTy)
1196249259Sdim      return V;
1197249259Sdim    if (Constant *VC = dyn_cast<Constant>(V))
1198249259Sdim      return Insert(Folder.CreateFPCast(VC, DestTy), Name);
1199249259Sdim    return Insert(CastInst::CreateFPCast(V, DestTy), Name);
1200249259Sdim  }
1201249259Sdim
1202249259Sdim  //===--------------------------------------------------------------------===//
1203249259Sdim  // Instruction creation methods: Compare Instructions
1204249259Sdim  //===--------------------------------------------------------------------===//
1205249259Sdim
1206249259Sdim  Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
1207249259Sdim    return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
1208249259Sdim  }
1209249259Sdim  Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") {
1210249259Sdim    return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name);
1211249259Sdim  }
1212249259Sdim  Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
1213249259Sdim    return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name);
1214249259Sdim  }
1215249259Sdim  Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
1216249259Sdim    return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name);
1217249259Sdim  }
1218249259Sdim  Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
1219249259Sdim    return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name);
1220249259Sdim  }
1221249259Sdim  Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
1222249259Sdim    return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name);
1223249259Sdim  }
1224249259Sdim  Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") {
1225249259Sdim    return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name);
1226249259Sdim  }
1227249259Sdim  Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") {
1228249259Sdim    return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name);
1229249259Sdim  }
1230249259Sdim  Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") {
1231249259Sdim    return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name);
1232249259Sdim  }
1233249259Sdim  Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") {
1234249259Sdim    return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
1235249259Sdim  }
1236249259Sdim
1237249259Sdim  Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
1238249259Sdim    return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
1239249259Sdim  }
1240249259Sdim  Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") {
1241249259Sdim    return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
1242249259Sdim  }
1243249259Sdim  Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") {
1244249259Sdim    return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
1245249259Sdim  }
1246249259Sdim  Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") {
1247249259Sdim    return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
1248249259Sdim  }
1249249259Sdim  Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") {
1250249259Sdim    return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
1251249259Sdim  }
1252249259Sdim  Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") {
1253249259Sdim    return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
1254249259Sdim  }
1255249259Sdim  Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") {
1256249259Sdim    return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
1257249259Sdim  }
1258249259Sdim  Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") {
1259249259Sdim    return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
1260249259Sdim  }
1261249259Sdim  Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
1262249259Sdim    return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
1263249259Sdim  }
1264249259Sdim  Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
1265249259Sdim    return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
1266249259Sdim  }
1267249259Sdim  Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
1268249259Sdim    return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
1269249259Sdim  }
1270249259Sdim  Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
1271249259Sdim    return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
1272249259Sdim  }
1273249259Sdim  Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
1274249259Sdim    return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
1275249259Sdim  }
1276249259Sdim  Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") {
1277249259Sdim    return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
1278249259Sdim  }
1279249259Sdim
1280249259Sdim  Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
1281249259Sdim                    const Twine &Name = "") {
1282249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
1283249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
1284249259Sdim        return Insert(Folder.CreateICmp(P, LC, RC), Name);
1285249259Sdim    return Insert(new ICmpInst(P, LHS, RHS), Name);
1286249259Sdim  }
1287249259Sdim  Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
1288249259Sdim                    const Twine &Name = "") {
1289249259Sdim    if (Constant *LC = dyn_cast<Constant>(LHS))
1290249259Sdim      if (Constant *RC = dyn_cast<Constant>(RHS))
1291249259Sdim        return Insert(Folder.CreateFCmp(P, LC, RC), Name);
1292249259Sdim    return Insert(new FCmpInst(P, LHS, RHS), Name);
1293249259Sdim  }
1294249259Sdim
1295249259Sdim  //===--------------------------------------------------------------------===//
1296249259Sdim  // Instruction creation methods: Other Instructions
1297249259Sdim  //===--------------------------------------------------------------------===//
1298249259Sdim
1299249259Sdim  PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues,
1300249259Sdim                     const Twine &Name = "") {
1301249259Sdim    return Insert(PHINode::Create(Ty, NumReservedValues), Name);
1302249259Sdim  }
1303249259Sdim
1304249259Sdim  CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
1305249259Sdim    return Insert(CallInst::Create(Callee), Name);
1306249259Sdim  }
1307249259Sdim  CallInst *CreateCall(Value *Callee, Value *Arg, const Twine &Name = "") {
1308249259Sdim    return Insert(CallInst::Create(Callee, Arg), Name);
1309249259Sdim  }
1310249259Sdim  CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
1311249259Sdim                        const Twine &Name = "") {
1312249259Sdim    Value *Args[] = { Arg1, Arg2 };
1313249259Sdim    return Insert(CallInst::Create(Callee, Args), Name);
1314249259Sdim  }
1315249259Sdim  CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
1316249259Sdim                        const Twine &Name = "") {
1317249259Sdim    Value *Args[] = { Arg1, Arg2, Arg3 };
1318249259Sdim    return Insert(CallInst::Create(Callee, Args), Name);
1319249259Sdim  }
1320249259Sdim  CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
1321249259Sdim                        Value *Arg4, const Twine &Name = "") {
1322249259Sdim    Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
1323249259Sdim    return Insert(CallInst::Create(Callee, Args), Name);
1324249259Sdim  }
1325249259Sdim  CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
1326249259Sdim                        Value *Arg4, Value *Arg5, const Twine &Name = "") {
1327249259Sdim    Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 };
1328249259Sdim    return Insert(CallInst::Create(Callee, Args), Name);
1329249259Sdim  }
1330249259Sdim
1331249259Sdim  CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
1332249259Sdim                       const Twine &Name = "") {
1333249259Sdim    return Insert(CallInst::Create(Callee, Args), Name);
1334249259Sdim  }
1335249259Sdim
1336249259Sdim  Value *CreateSelect(Value *C, Value *True, Value *False,
1337249259Sdim                      const Twine &Name = "") {
1338249259Sdim    if (Constant *CC = dyn_cast<Constant>(C))
1339249259Sdim      if (Constant *TC = dyn_cast<Constant>(True))
1340249259Sdim        if (Constant *FC = dyn_cast<Constant>(False))
1341249259Sdim          return Insert(Folder.CreateSelect(CC, TC, FC), Name);
1342249259Sdim    return Insert(SelectInst::Create(C, True, False), Name);
1343249259Sdim  }
1344249259Sdim
1345249259Sdim  VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") {
1346249259Sdim    return Insert(new VAArgInst(List, Ty), Name);
1347249259Sdim  }
1348249259Sdim
1349249259Sdim  Value *CreateExtractElement(Value *Vec, Value *Idx,
1350249259Sdim                              const Twine &Name = "") {
1351249259Sdim    if (Constant *VC = dyn_cast<Constant>(Vec))
1352249259Sdim      if (Constant *IC = dyn_cast<Constant>(Idx))
1353249259Sdim        return Insert(Folder.CreateExtractElement(VC, IC), Name);
1354249259Sdim    return Insert(ExtractElementInst::Create(Vec, Idx), Name);
1355249259Sdim  }
1356249259Sdim
1357249259Sdim  Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
1358249259Sdim                             const Twine &Name = "") {
1359249259Sdim    if (Constant *VC = dyn_cast<Constant>(Vec))
1360249259Sdim      if (Constant *NC = dyn_cast<Constant>(NewElt))
1361249259Sdim        if (Constant *IC = dyn_cast<Constant>(Idx))
1362249259Sdim          return Insert(Folder.CreateInsertElement(VC, NC, IC), Name);
1363249259Sdim    return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
1364249259Sdim  }
1365249259Sdim
1366249259Sdim  Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
1367249259Sdim                             const Twine &Name = "") {
1368249259Sdim    if (Constant *V1C = dyn_cast<Constant>(V1))
1369249259Sdim      if (Constant *V2C = dyn_cast<Constant>(V2))
1370249259Sdim        if (Constant *MC = dyn_cast<Constant>(Mask))
1371249259Sdim          return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name);
1372249259Sdim    return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
1373249259Sdim  }
1374249259Sdim
1375249259Sdim  Value *CreateExtractValue(Value *Agg,
1376249259Sdim                            ArrayRef<unsigned> Idxs,
1377249259Sdim                            const Twine &Name = "") {
1378249259Sdim    if (Constant *AggC = dyn_cast<Constant>(Agg))
1379249259Sdim      return Insert(Folder.CreateExtractValue(AggC, Idxs), Name);
1380249259Sdim    return Insert(ExtractValueInst::Create(Agg, Idxs), Name);
1381249259Sdim  }
1382249259Sdim
1383249259Sdim  Value *CreateInsertValue(Value *Agg, Value *Val,
1384249259Sdim                           ArrayRef<unsigned> Idxs,
1385249259Sdim                           const Twine &Name = "") {
1386249259Sdim    if (Constant *AggC = dyn_cast<Constant>(Agg))
1387249259Sdim      if (Constant *ValC = dyn_cast<Constant>(Val))
1388249259Sdim        return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name);
1389249259Sdim    return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
1390249259Sdim  }
1391249259Sdim
1392249259Sdim  LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses,
1393249259Sdim                                   const Twine &Name = "") {
1394249259Sdim    return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses), Name);
1395249259Sdim  }
1396249259Sdim
1397249259Sdim  //===--------------------------------------------------------------------===//
1398249259Sdim  // Utility creation methods
1399249259Sdim  //===--------------------------------------------------------------------===//
1400249259Sdim
1401249259Sdim  /// \brief Return an i1 value testing if \p Arg is null.
1402249259Sdim  Value *CreateIsNull(Value *Arg, const Twine &Name = "") {
1403249259Sdim    return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
1404249259Sdim                        Name);
1405249259Sdim  }
1406249259Sdim
1407249259Sdim  /// \brief Return an i1 value testing if \p Arg is not null.
1408249259Sdim  Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") {
1409249259Sdim    return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
1410249259Sdim                        Name);
1411249259Sdim  }
1412249259Sdim
1413249259Sdim  /// \brief Return the i64 difference between two pointer values, dividing out
1414249259Sdim  /// the size of the pointed-to objects.
1415249259Sdim  ///
1416249259Sdim  /// This is intended to implement C-style pointer subtraction. As such, the
1417249259Sdim  /// pointers must be appropriately aligned for their element types and
1418249259Sdim  /// pointing into the same object.
1419249259Sdim  Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
1420249259Sdim    assert(LHS->getType() == RHS->getType() &&
1421249259Sdim           "Pointer subtraction operand types must match!");
1422249259Sdim    PointerType *ArgType = cast<PointerType>(LHS->getType());
1423249259Sdim    Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
1424249259Sdim    Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
1425249259Sdim    Value *Difference = CreateSub(LHS_int, RHS_int);
1426249259Sdim    return CreateExactSDiv(Difference,
1427249259Sdim                           ConstantExpr::getSizeOf(ArgType->getElementType()),
1428249259Sdim                           Name);
1429249259Sdim  }
1430249259Sdim
1431249259Sdim  /// \brief Return a vector value that contains \arg V broadcasted to \p
1432249259Sdim  /// NumElts elements.
1433249259Sdim  Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") {
1434249259Sdim    assert(NumElts > 0 && "Cannot splat to an empty vector!");
1435249259Sdim
1436249259Sdim    // First insert it into an undef vector so we can shuffle it.
1437249259Sdim    Type *I32Ty = getInt32Ty();
1438249259Sdim    Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts));
1439249259Sdim    V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0),
1440249259Sdim                            Name + ".splatinsert");
1441249259Sdim
1442249259Sdim    // Shuffle the value across the desired number of elements.
1443249259Sdim    Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts));
1444249259Sdim    return CreateShuffleVector(V, Undef, Zeros, Name + ".splat");
1445249259Sdim  }
1446249259Sdim};
1447249259Sdim
1448251662Sdim// Create wrappers for C Binding types (see CBindingWrapping.h).
1449251662SdimDEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)
1450251662Sdim
1451249259Sdim}
1452249259Sdim
1453249259Sdim#endif
1454