[llvm] 3eaa53e - Reapply "[IRBuilder] Virtualize IRBuilder"

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 17 11:34:40 PST 2020


On Mon, Feb 17, 2020 at 8:23 PM Vedant Kumar <vedant_kumar at apple.com> wrote:

> Speculative fix landed in
>
> commit 7424705157ba051d8e2f21815f5e051c4d786b94 (HEAD
> -> master, origin/master, origin/HEAD)
> Author: Vedant Kumar <vsk at apple.com>
> Date:   Mon Feb 17 11:21:32 2020
>
>     Fix modules build after https://reviews.llvm.org/D73835 (IRBuilder
> virtualization change)
>
> vedant
>

Hi Vedant,

Thanks for landing this fix. I arrived at a similar patch, but didn't
manage to test the full build yet (for some reason, module-enabled build
compiles *much* slower for me and gets interrupted by "signature mismatch"
sometimes).

Regards,
Nikita


> On Feb 17, 2020, at 11:10 AM, Vedant Kumar via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
> Hey Nikita,
>
> We’re seeing some cyclic dependency issues on the lldb modules-enabled
> bot, could you please take a look?
>
>
> http://lab.llvm.org:8080/green/view/LLDB/job/lldb-cmake/9404/consoleFull#-361314398a1ca8a51-895e-46c6-af87-ce24fa4cd561
>
> ```
> /Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/include/llvm/IR/IRBuilderFolder.h:18:10:
> fatal error: cyclic dependency in module 'LLVM_intrinsic_gen':
> LLVM_intrinsic_gen -> LLVM_IR -> LLVM_intrinsic_gen
>
> #include "llvm/IR/InstrTypes.h"
>          ^
> While building module 'LLVM_intrinsic_gen' imported from
> /Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/lib/IR/IRBuilder.cpp:14:
> In file included from <module-includes>:1:
> /Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/include/llvm/IR/Argument.h:19:10:
> fatal error: could not build module 'LLVM_IR'
> #include "llvm/IR/Value.h"
>  ~~~~~~~~^~~~~~~~~~~~~~~~~
> /Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/lib/IR/IRBuilder.cpp:14:10:
> fatal error: could not build module 'LLVM_intrinsic_gen'
> #include "llvm/IR/IRBuilder.h”
> ```
>
> I’m trying to reproduce this now and will try to fix forwards if possible.
> Here’s my configure command:
>
> cmake -G
> Ninja /Users/vsk/src/llvm-backup-master/llvm -DCLANG_ENABLE_ARCMT=Off
> -DCLANG_ENABLE_STATIC_ANALYZER=Off -D
> LLVM_ENABLE_PROJECTS='clang;clang-tools-extra;lld;libcxx;libcxxabi;compiler-rt;libunwind;lldb'
> -DLLDB_USE_SYSTEM_DEBUGSERVER=On -DCMAKE_BUILD_TYPE=RelWithDebInfo
> -DLLVM_ENABLE_ASSERTIONS=
> On -DLLVM_ENABLE_MODULES=On
>
> vedant
>
> On Feb 17, 2020, at 10:18 AM, Nikita Popov via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>
> Author: Nikita Popov
> Date: 2020-02-17T19:04:11+01:00
> New Revision: 3eaa53e80543813a2274391956e91d275950fbf8
>
> URL:
> https://github.com/llvm/llvm-project/commit/3eaa53e80543813a2274391956e91d275950fbf8
> DIFF:
> https://github.com/llvm/llvm-project/commit/3eaa53e80543813a2274391956e91d275950fbf8.diff
>
> LOG: Reapply "[IRBuilder] Virtualize IRBuilder"
>
> Relative to the original commit, this fixes some warnings,
> and is based on the deletion of the IRBuilder copy constructor
> in D74693. The automatic copy constructor would no longer be
> safe.
>
> -----
>
> Related llvm-dev thread:
> http://lists.llvm.org/pipermail/llvm-dev/2020-February/138951.html
>
> This patch moves the IRBuilder from templating over the constant
> folder and inserter towards making both of these virtual.
> There are a couple of motivations for this:
>
> 1. It's not possible to share code between use-sites that use
> different IRBuilder folders/inserters (short of templating the code
> and moving it into headers).
> 2. Methods currently defined on IRBuilderBase (which is not templated)
> do not use the custom inserter, resulting in subtle bugs (e.g.
> incorrect InstCombine worklist management). It would be possible to
> move those into the templated IRBuilder, but...
> 3. The vast majority of the IRBuilder implementation has to live
> in the header, because it depends on the template arguments.
> 4. We have many unnecessary dependencies on IRBuilder.h,
> because it is not easy to forward-declare. (Significant parts of
> the backend depend on it via TargetLowering.h, for example.)
>
> This patch addresses the issue by making the following changes:
>
> * IRBuilderDefaultInserter::InsertHelper becomes virtual.
>  IRBuilderBase accepts a reference to it.
> * IRBuilderFolder is introduced as a virtual base class. It is
> implemented by ConstantFolder (default), NoFolder and TargetFolder.
>  IRBuilderBase has a reference to this as well.
> * All the logic is moved from IRBuilder to IRBuilderBase. This means
>  that methods can in the future replace their IRBuilder<> & uses
>  (or other specific IRBuilder types) with IRBuilderBase & and thus
>  be usable with different IRBuilders.
> * The IRBuilder class is now a thin wrapper around IRBuilderBase.
>  Essentially it only stores the folder and inserter and takes care
>  of constructing the base builder.
>
> What this patch doesn't do, but should be simple followups after this
> change:
>
> * Fixing use of the inserter for creation methods originally defined
>  on IRBuilderBase.
> * Replacing IRBuilder<> uses in arguments with IRBuilderBase, where useful.
> * Moving code from the IRBuilder header to the source file.
>
> From the user perspective, these changes should be mostly transparent:
>
> The only thing that consumers using a custom inserted may need to do is
> inherit from IRBuilderDefaultInserter publicly and mark their InsertHelper
> as public.
>
> Differential Revision: https://reviews.llvm.org/D73835
>
> Added:
>    llvm/include/llvm/IR/IRBuilderFolder.h
>
> Modified:
>    clang/lib/CodeGen/CGBuilder.h
>    llvm/include/llvm/Analysis/TargetFolder.h
>    llvm/include/llvm/IR/ConstantFolder.h
>    llvm/include/llvm/IR/IRBuilder.h
>    llvm/include/llvm/IR/NoFolder.h
>    llvm/lib/Analysis/ConstantFolding.cpp
>    llvm/lib/IR/IRBuilder.cpp
>    llvm/lib/Transforms/Scalar/SROA.cpp
>    polly/include/polly/CodeGen/IRBuilder.h
>
> Removed:
>
>
>
>
> ################################################################################
> diff  --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h
> index 7687f7990d99..38e96c0f4ee6 100644
> --- a/clang/lib/CodeGen/CGBuilder.h
> +++ b/clang/lib/CodeGen/CGBuilder.h
> @@ -22,16 +22,15 @@ class CodeGenFunction;
> /// This is an IRBuilder insertion helper that forwards to
> /// CodeGenFunction::InsertHelper, which adds necessary metadata to
> /// instructions.
> -class CGBuilderInserter : protected llvm::IRBuilderDefaultInserter {
> +class CGBuilderInserter final : public llvm::IRBuilderDefaultInserter {
> public:
>   CGBuilderInserter() = default;
>   explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
>
> -protected:
>   /// This forwards to CodeGenFunction::InsertHelper.
>   void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
>                     llvm::BasicBlock *BB,
> -                    llvm::BasicBlock::iterator InsertPt) const;
> +                    llvm::BasicBlock::iterator InsertPt) const override;
> private:
>   CodeGenFunction *CGF = nullptr;
> };
>
> diff  --git a/llvm/include/llvm/Analysis/TargetFolder.h
> b/llvm/include/llvm/Analysis/TargetFolder.h
> index 7ab6562be440..712c1a2e8118 100644
> --- a/llvm/include/llvm/Analysis/TargetFolder.h
> +++ b/llvm/include/llvm/Analysis/TargetFolder.h
> @@ -22,13 +22,14 @@
> #include "llvm/Analysis/ConstantFolding.h"
> #include "llvm/IR/Constants.h"
> #include "llvm/IR/InstrTypes.h"
> +#include "llvm/IR/IRBuilderFolder.h"
>
> namespace llvm {
>
> class DataLayout;
>
> /// TargetFolder - Create constants with target dependent folding.
> -class TargetFolder {
> +class TargetFolder final : public IRBuilderFolder {
>   const DataLayout &DL;
>
>   /// Fold - Fold the constant using target specific information.
> @@ -38,6 +39,8 @@ class TargetFolder {
>     return C;
>   }
>
> +  virtual void anchor();
> +
> public:
>   explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
>
> @@ -46,66 +49,70 @@ class TargetFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateAdd(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
>   }
> -  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getFAdd(LHS, RHS));
>   }
>   Constant *CreateSub(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
>   }
> -  Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getFSub(LHS, RHS));
>   }
>   Constant *CreateMul(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
>   }
> -  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getFMul(LHS, RHS));
>   }
> -  Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact =
> false)const{
> +  Constant *CreateUDiv(Constant *LHS, Constant *RHS,
> +                       bool isExact = false) const override {
>     return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
>   }
> -  Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact =
> false)const{
> +  Constant *CreateSDiv(Constant *LHS, Constant *RHS,
> +                       bool isExact = false) const override {
>     return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
>   }
> -  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getFDiv(LHS, RHS));
>   }
> -  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getURem(LHS, RHS));
>   }
> -  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getSRem(LHS, RHS));
>   }
> -  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getFRem(LHS, RHS));
>   }
>   Constant *CreateShl(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
>   }
> -  Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact =
> false)const{
> +  Constant *CreateLShr(Constant *LHS, Constant *RHS,
> +                       bool isExact = false) const override {
>     return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
>   }
> -  Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact =
> false)const{
> +  Constant *CreateAShr(Constant *LHS, Constant *RHS,
> +                       bool isExact = false) const override {
>     return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
>   }
> -  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getAnd(LHS, RHS));
>   }
> -  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getOr(LHS, RHS));
>   }
> -  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::getXor(LHS, RHS));
>   }
>
>   Constant *CreateBinOp(Instruction::BinaryOps Opc,
> -                        Constant *LHS, Constant *RHS) const {
> +                        Constant *LHS, Constant *RHS) const override {
>     return Fold(ConstantExpr::get(Opc, LHS, RHS));
>   }
>
> @@ -114,17 +121,17 @@ class TargetFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateNeg(Constant *C,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
>   }
> -  Constant *CreateFNeg(Constant *C) const {
> +  Constant *CreateFNeg(Constant *C) const override {
>     return Fold(ConstantExpr::getFNeg(C));
>   }
> -  Constant *CreateNot(Constant *C) const {
> +  Constant *CreateNot(Constant *C) const override {
>     return Fold(ConstantExpr::getNot(C));
>   }
>
> -  Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
> +  Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const
> override {
>     return Fold(ConstantExpr::get(Opc, C));
>   }
>
> @@ -133,33 +140,34 @@ class TargetFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> -                                ArrayRef<Constant *> IdxList) const {
> +                                ArrayRef<Constant *> IdxList) const
> override {
>     return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
>   }
> -  Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx)
> const {
> +  Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> +                                Constant *Idx) const override {
>     // This form of the function only exists to avoid ambiguous overload
>     // warnings about whether to convert Idx to ArrayRef<Constant *> or
>     // ArrayRef<Value *>.
>     return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
>   }
>   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> -                                ArrayRef<Value *> IdxList) const {
> +                                ArrayRef<Value *> IdxList) const override
> {
>     return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
>   }
>
> -  Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        ArrayRef<Constant *> IdxList)
> const {
> +  Constant *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override
> {
>     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
>   }
>   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        Constant *Idx) const {
> +                                        Constant *Idx) const override {
>     // This form of the function only exists to avoid ambiguous overload
>     // warnings about whether to convert Idx to ArrayRef<Constant *> or
>     // ArrayRef<Value *>.
>     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
>   }
> -  Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        ArrayRef<Value *> IdxList) const {
> +  Constant *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
>     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
>   }
>
> @@ -168,54 +176,54 @@ class TargetFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateCast(Instruction::CastOps Op, Constant *C,
> -                       Type *DestTy) const {
> +                       Type *DestTy) const override {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getCast(Op, C, DestTy));
>   }
>   Constant *CreateIntCast(Constant *C, Type *DestTy,
> -                          bool isSigned) const {
> +                          bool isSigned) const override {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
>   }
> -  Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
> +  Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getPointerCast(C, DestTy));
>   }
> -  Constant *CreateFPCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getFPCast(C, DestTy));
>   }
> -  Constant *CreateBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::BitCast, C, DestTy);
>   }
> -  Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
> +  Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::IntToPtr, C, DestTy);
>   }
> -  Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
> +  Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::PtrToInt, C, DestTy);
>   }
> -  Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override
> {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
>   }
> -  Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override
> {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
>   }
> -  Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const
> override {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
>   }
>
>   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
> -                                                Type *DestTy) const {
> +                                                Type *DestTy) const
> override {
>     if (C->getType() == DestTy)
>       return C; // avoid calling Fold
>     return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
> @@ -226,11 +234,11 @@ class TargetFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
> -                       Constant *RHS) const {
> +                       Constant *RHS) const override {
>     return Fold(ConstantExpr::getCompare(P, LHS, RHS));
>   }
>   Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
> -                       Constant *RHS) const {
> +                       Constant *RHS) const override {
>     return Fold(ConstantExpr::getCompare(P, LHS, RHS));
>   }
>
> @@ -238,31 +246,32 @@ class TargetFolder {
>   // Other Instructions
>
>   //===--------------------------------------------------------------------===//
>
> -  Constant *CreateSelect(Constant *C, Constant *True, Constant *False)
> const {
> +  Constant *CreateSelect(Constant *C, Constant *True,
> +                         Constant *False) const override {
>     return Fold(ConstantExpr::getSelect(C, True, False));
>   }
>
> -  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
> +  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const
> override {
>     return Fold(ConstantExpr::getExtractElement(Vec, Idx));
>   }
>
>   Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
> -                                Constant *Idx) const {
> +                                Constant *Idx) const override {
>     return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
>   }
>
>   Constant *CreateShuffleVector(Constant *V1, Constant *V2,
> -                                Constant *Mask) const {
> +                                Constant *Mask) const override {
>     return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
>   }
>
>   Constant *CreateExtractValue(Constant *Agg,
> -                               ArrayRef<unsigned> IdxList) const {
> +                               ArrayRef<unsigned> IdxList) const override
> {
>     return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
>   }
>
>   Constant *CreateInsertValue(Constant *Agg, Constant *Val,
> -                              ArrayRef<unsigned> IdxList) const {
> +                              ArrayRef<unsigned> IdxList) const override {
>     return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
>   }
> };
>
> diff  --git a/llvm/include/llvm/IR/ConstantFolder.h
> b/llvm/include/llvm/IR/ConstantFolder.h
> index 5a5cabfd0206..32939e79cd1d 100644
> --- a/llvm/include/llvm/IR/ConstantFolder.h
> +++ b/llvm/include/llvm/IR/ConstantFolder.h
> @@ -20,11 +20,14 @@
> #include "llvm/IR/Constants.h"
> #include "llvm/IR/InstrTypes.h"
> #include "llvm/IR/Instruction.h"
> +#include "llvm/IR/IRBuilderFolder.h"
>
> namespace llvm {
>
> /// ConstantFolder - Create constants with minimum, target independent,
> folding.
> -class ConstantFolder {
> +class ConstantFolder final : public IRBuilderFolder {
> +  virtual void anchor();
> +
> public:
>   explicit ConstantFolder() = default;
>
> @@ -33,87 +36,87 @@ class ConstantFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateAdd(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
>   }
>
> -  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getFAdd(LHS, RHS);
>   }
>
>   Constant *CreateSub(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
>   }
>
> -  Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getFSub(LHS, RHS);
>   }
>
>   Constant *CreateMul(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
>   }
>
> -  Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getFMul(LHS, RHS);
>   }
>
>   Constant *CreateUDiv(Constant *LHS, Constant *RHS,
> -                       bool isExact = false) const {
> +                               bool isExact = false) const override {
>     return ConstantExpr::getUDiv(LHS, RHS, isExact);
>   }
>
>   Constant *CreateSDiv(Constant *LHS, Constant *RHS,
> -                       bool isExact = false) const {
> +                               bool isExact = false) const override {
>     return ConstantExpr::getSDiv(LHS, RHS, isExact);
>   }
>
> -  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getFDiv(LHS, RHS);
>   }
>
> -  Constant *CreateURem(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getURem(LHS, RHS);
>   }
>
> -  Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getSRem(LHS, RHS);
>   }
>
> -  Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getFRem(LHS, RHS);
>   }
>
>   Constant *CreateShl(Constant *LHS, Constant *RHS,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
>   }
>
>   Constant *CreateLShr(Constant *LHS, Constant *RHS,
> -                       bool isExact = false) const {
> +                       bool isExact = false) const override {
>     return ConstantExpr::getLShr(LHS, RHS, isExact);
>   }
>
>   Constant *CreateAShr(Constant *LHS, Constant *RHS,
> -                       bool isExact = false) const {
> +                       bool isExact = false) const override {
>     return ConstantExpr::getAShr(LHS, RHS, isExact);
>   }
>
> -  Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getAnd(LHS, RHS);
>   }
>
> -  Constant *CreateOr(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getOr(LHS, RHS);
>   }
>
> -  Constant *CreateXor(Constant *LHS, Constant *RHS) const {
> +  Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::getXor(LHS, RHS);
>   }
>
>   Constant *CreateBinOp(Instruction::BinaryOps Opc,
> -                        Constant *LHS, Constant *RHS) const {
> +                        Constant *LHS, Constant *RHS) const override {
>     return ConstantExpr::get(Opc, LHS, RHS);
>   }
>
> @@ -122,19 +125,19 @@ class ConstantFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateNeg(Constant *C,
> -                      bool HasNUW = false, bool HasNSW = false) const {
> +                      bool HasNUW = false, bool HasNSW = false) const
> override {
>     return ConstantExpr::getNeg(C, HasNUW, HasNSW);
>   }
>
> -  Constant *CreateFNeg(Constant *C) const {
> +  Constant *CreateFNeg(Constant *C) const override {
>     return ConstantExpr::getFNeg(C);
>   }
>
> -  Constant *CreateNot(Constant *C) const {
> +  Constant *CreateNot(Constant *C) const override {
>     return ConstantExpr::getNot(C);
>   }
>
> -  Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
> +  Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const
> override {
>     return ConstantExpr::get(Opc, C);
>   }
>
> @@ -143,11 +146,12 @@ class ConstantFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> -                                ArrayRef<Constant *> IdxList) const {
> +                                ArrayRef<Constant *> IdxList) const
> override {
>     return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
>   }
>
> -  Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx)
> const {
> +  Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> +                                Constant *Idx) const override {
>     // This form of the function only exists to avoid ambiguous overload
>     // warnings about whether to convert Idx to ArrayRef<Constant *> or
>     // ArrayRef<Value *>.
> @@ -155,25 +159,25 @@ class ConstantFolder {
>   }
>
>   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> -                                ArrayRef<Value *> IdxList) const {
> +                                ArrayRef<Value *> IdxList) const override
> {
>     return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
>   }
>
> -  Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        ArrayRef<Constant *> IdxList)
> const {
> +  Constant *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override
> {
>     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
>   }
>
>   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        Constant *Idx) const {
> +                                        Constant *Idx) const override {
>     // This form of the function only exists to avoid ambiguous overload
>     // warnings about whether to convert Idx to ArrayRef<Constant *> or
>     // ArrayRef<Value *>.
>     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
>   }
>
> -  Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        ArrayRef<Value *> IdxList) const {
> +  Constant *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
>     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
>   }
>
> @@ -182,49 +186,49 @@ class ConstantFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateCast(Instruction::CastOps Op, Constant *C,
> -                       Type *DestTy) const {
> +                       Type *DestTy) const override {
>     return ConstantExpr::getCast(Op, C, DestTy);
>   }
>
> -  Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
> +  Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
>     return ConstantExpr::getPointerCast(C, DestTy);
>   }
>
>   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
> -                                                Type *DestTy) const {
> +                                                Type *DestTy) const
> override {
>     return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
>   }
>
>   Constant *CreateIntCast(Constant *C, Type *DestTy,
> -                          bool isSigned) const {
> +                          bool isSigned) const override {
>     return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
>   }
>
> -  Constant *CreateFPCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
>     return ConstantExpr::getFPCast(C, DestTy);
>   }
>
> -  Constant *CreateBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::BitCast, C, DestTy);
>   }
>
> -  Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
> +  Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::IntToPtr, C, DestTy);
>   }
>
> -  Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
> +  Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::PtrToInt, C, DestTy);
>   }
>
> -  Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override
> {
>     return ConstantExpr::getZExtOrBitCast(C, DestTy);
>   }
>
> -  Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override
> {
>     return ConstantExpr::getSExtOrBitCast(C, DestTy);
>   }
>
> -  Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
> +  Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const
> override {
>     return ConstantExpr::getTruncOrBitCast(C, DestTy);
>   }
>
> @@ -233,12 +237,12 @@ class ConstantFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
> -                       Constant *RHS) const {
> +                       Constant *RHS) const override {
>     return ConstantExpr::getCompare(P, LHS, RHS);
>   }
>
>   Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
> -                       Constant *RHS) const {
> +                       Constant *RHS) const override {
>     return ConstantExpr::getCompare(P, LHS, RHS);
>   }
>
> @@ -246,31 +250,32 @@ class ConstantFolder {
>   // Other Instructions
>
>   //===--------------------------------------------------------------------===//
>
> -  Constant *CreateSelect(Constant *C, Constant *True, Constant *False)
> const {
> +  Constant *CreateSelect(Constant *C, Constant *True,
> +                         Constant *False) const override {
>     return ConstantExpr::getSelect(C, True, False);
>   }
>
> -  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
> +  Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const
> override {
>     return ConstantExpr::getExtractElement(Vec, Idx);
>   }
>
>   Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
> -                                Constant *Idx) const {
> +                                Constant *Idx) const override {
>     return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
>   }
>
>   Constant *CreateShuffleVector(Constant *V1, Constant *V2,
> -                                Constant *Mask) const {
> +                                Constant *Mask) const override {
>     return ConstantExpr::getShuffleVector(V1, V2, Mask);
>   }
>
>   Constant *CreateExtractValue(Constant *Agg,
> -                               ArrayRef<unsigned> IdxList) const {
> +                               ArrayRef<unsigned> IdxList) const override
> {
>     return ConstantExpr::getExtractValue(Agg, IdxList);
>   }
>
>   Constant *CreateInsertValue(Constant *Agg, Constant *Val,
> -                              ArrayRef<unsigned> IdxList) const {
> +                              ArrayRef<unsigned> IdxList) const override {
>     return ConstantExpr::getInsertValue(Agg, Val, IdxList);
>   }
> };
>
> diff  --git a/llvm/include/llvm/IR/IRBuilder.h
> b/llvm/include/llvm/IR/IRBuilder.h
> index c9ae136f4d6c..825a2426b742 100644
> --- a/llvm/include/llvm/IR/IRBuilder.h
> +++ b/llvm/include/llvm/IR/IRBuilder.h
> @@ -59,9 +59,12 @@ class Use;
> ///
> /// By default, this inserts the instruction at the insertion point.
> class IRBuilderDefaultInserter {
> -protected:
> -  void InsertHelper(Instruction *I, const Twine &Name,
> -                    BasicBlock *BB, BasicBlock::iterator InsertPt) const {
> +public:
> +  virtual ~IRBuilderDefaultInserter();
> +
> +  virtual void InsertHelper(Instruction *I, const Twine &Name,
> +                            BasicBlock *BB,
> +                            BasicBlock::iterator InsertPt) const {
>     if (BB) BB->getInstList().insert(InsertPt, I);
>     I->setName(Name);
>   }
> @@ -69,16 +72,18 @@ class IRBuilderDefaultInserter {
>
> /// Provides an 'InsertHelper' that calls a user-provided callback after
> /// performing the default insertion.
> -class IRBuilderCallbackInserter : IRBuilderDefaultInserter {
> +class IRBuilderCallbackInserter : public IRBuilderDefaultInserter {
>   std::function<void(Instruction *)> Callback;
>
> public:
> +  virtual ~IRBuilderCallbackInserter();
> +
>   IRBuilderCallbackInserter(std::function<void(Instruction *)> Callback)
>       : Callback(std::move(Callback)) {}
>
> -protected:
>   void InsertHelper(Instruction *I, const Twine &Name,
> -                    BasicBlock *BB, BasicBlock::iterator InsertPt) const {
> +                    BasicBlock *BB,
> +                    BasicBlock::iterator InsertPt) const override {
>     IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
>     Callback(I);
>   }
> @@ -92,6 +97,8 @@ class IRBuilderBase {
>   BasicBlock *BB;
>   BasicBlock::iterator InsertPt;
>   LLVMContext &Context;
> +  const IRBuilderFolder &Folder;
> +  const IRBuilderDefaultInserter &Inserter;
>
>   MDNode *DefaultFPMathTag;
>   FastMathFlags FMF;
> @@ -103,15 +110,37 @@ class IRBuilderBase {
>   ArrayRef<OperandBundleDef> DefaultOperandBundles;
>
> public:
> -  IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr,
> -                ArrayRef<OperandBundleDef> OpBundles = None)
> -      : Context(context), DefaultFPMathTag(FPMathTag),
> IsFPConstrained(false),
> +  IRBuilderBase(LLVMContext &context, const IRBuilderFolder &Folder,
> +                const IRBuilderDefaultInserter &Inserter,
> +                MDNode *FPMathTag, ArrayRef<OperandBundleDef> OpBundles)
> +      : Context(context), Folder(Folder), Inserter(Inserter),
> +        DefaultFPMathTag(FPMathTag), IsFPConstrained(false),
>         DefaultConstrainedExcept(fp::ebStrict),
>         DefaultConstrainedRounding(fp::rmDynamic),
>         DefaultOperandBundles(OpBundles) {
>     ClearInsertionPoint();
>   }
>
> +  /// Insert and return the specified instruction.
> +  template<typename InstTy>
> +  InstTy *Insert(InstTy *I, const Twine &Name = "") const {
> +    Inserter.InsertHelper(I, Name, BB, InsertPt);
> +    SetInstDebugLocation(I);
> +    return I;
> +  }
> +
> +  /// No-op overload to handle constants.
> +  Constant *Insert(Constant *C, const Twine& = "") const {
> +    return C;
> +  }
> +
> +  Value *Insert(Value *V, const Twine& = "") const {
> +    if (Instruction *I = dyn_cast<Instruction>(V))
> +      return Insert(I);
> +    assert(isa<Constant>(V));
> +    return V;
> +  }
> +
>
>   //===--------------------------------------------------------------------===//
>   // Builder configuration methods
>
>   //===--------------------------------------------------------------------===//
> @@ -920,89 +949,6 @@ class IRBuilderBase {
>                                   const Twine &Name = "");
>
>   Value *getCastedInt8PtrValue(Value *Ptr);
> -};
> -
> -/// 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. Convenience state exists to specify fast-math flags and
> fp-math
> -/// tags.
> -///
> -/// The first template argument specifies a class to use for creating
> constants.
> -/// This defaults to creating minimally folded constants.  The second
> template
> -/// argument allows clients to specify custom insertion hooks that are
> called on
> -/// every newly created insertion.
> -template <typename T = ConstantFolder,
> -          typename Inserter = IRBuilderDefaultInserter>
> -class IRBuilder : public IRBuilderBase, public Inserter {
> -  T Folder;
> -
> -public:
> -  IRBuilder(LLVMContext &C, const T &F, Inserter I = Inserter(),
> -            MDNode *FPMathTag = nullptr,
> -            ArrayRef<OperandBundleDef> OpBundles = None)
> -      : IRBuilderBase(C, FPMathTag, OpBundles), Inserter(std::move(I)),
> -        Folder(F) {}
> -
> -  explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr,
> -                     ArrayRef<OperandBundleDef> OpBundles = None)
> -      : IRBuilderBase(C, FPMathTag, OpBundles) {}
> -
> -  explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag =
> nullptr,
> -                     ArrayRef<OperandBundleDef> OpBundles = None)
> -      : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles),
> Folder(F) {
> -    SetInsertPoint(TheBB);
> -  }
> -
> -  explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr,
> -                     ArrayRef<OperandBundleDef> OpBundles = None)
> -      : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) {
> -    SetInsertPoint(TheBB);
> -  }
> -
> -  explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr,
> -                     ArrayRef<OperandBundleDef> OpBundles = None)
> -      : IRBuilderBase(IP->getContext(), FPMathTag, OpBundles) {
> -    SetInsertPoint(IP);
> -  }
> -
> -  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T &F,
> -            MDNode *FPMathTag = nullptr,
> -            ArrayRef<OperandBundleDef> OpBundles = None)
> -      : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles),
> Folder(F) {
> -    SetInsertPoint(TheBB, IP);
> -  }
> -
> -  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
> -            MDNode *FPMathTag = nullptr,
> -            ArrayRef<OperandBundleDef> OpBundles = None)
> -      : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) {
> -    SetInsertPoint(TheBB, IP);
> -  }
> -
> -  /// Avoid copying the full IRBuilder. Prefer using InsertPointGuard
> -  /// or FastMathFlagGuard instead.
> -  IRBuilder(const IRBuilder &) = delete;
> -
> -  /// Get the constant folder being used.
> -  const T &getFolder() { return Folder; }
> -
> -  /// Insert and return the specified instruction.
> -  template<typename InstTy>
> -  InstTy *Insert(InstTy *I, const Twine &Name = "") const {
> -    this->InsertHelper(I, Name, BB, InsertPt);
> -    this->SetInstDebugLocation(I);
> -    return I;
> -  }
> -
> -  /// No-op overload to handle constants.
> -  Constant *Insert(Constant *C, const Twine& = "") const {
> -    return C;
> -  }
>
>
>   //===--------------------------------------------------------------------===//
>   // Instruction creation methods: Terminators
> @@ -2980,6 +2926,83 @@ class IRBuilder : public IRBuilderBase, public
> Inserter {
>   }
> };
>
> +/// 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. Convenience state exists to specify fast-math flags and
> fp-math
> +/// tags.
> +///
> +/// The first template argument specifies a class to use for creating
> constants.
> +/// This defaults to creating minimally folded constants.  The second
> template
> +/// argument allows clients to specify custom insertion hooks that are
> called on
> +/// every newly created insertion.
> +template <typename FolderTy = ConstantFolder,
> +          typename InserterTy = IRBuilderDefaultInserter>
> +class IRBuilder : public IRBuilderBase {
> +private:
> +  FolderTy Folder;
> +  InserterTy Inserter;
> +
> +public:
> +  IRBuilder(LLVMContext &C, FolderTy Folder, InserterTy Inserter =
> InserterTy(),
> +            MDNode *FPMathTag = nullptr,
> +            ArrayRef<OperandBundleDef> OpBundles = None)
> +      : IRBuilderBase(C, this->Folder, this->Inserter, FPMathTag,
> OpBundles),
> +        Folder(Folder), Inserter(Inserter) {}
> +
> +  explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr,
> +                     ArrayRef<OperandBundleDef> OpBundles = None)
> +      : IRBuilderBase(C, this->Folder, this->Inserter, FPMathTag,
> OpBundles) {}
> +
> +  explicit IRBuilder(BasicBlock *TheBB, FolderTy Folder,
> +                     MDNode *FPMathTag = nullptr,
> +                     ArrayRef<OperandBundleDef> OpBundles = None)
> +      : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
> +                      FPMathTag, OpBundles), Folder(Folder) {
> +    SetInsertPoint(TheBB);
> +  }
> +
> +  explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr,
> +                     ArrayRef<OperandBundleDef> OpBundles = None)
> +      : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
> +                      FPMathTag, OpBundles) {
> +    SetInsertPoint(TheBB);
> +  }
> +
> +  explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr,
> +                     ArrayRef<OperandBundleDef> OpBundles = None)
> +      : IRBuilderBase(IP->getContext(), this->Folder, this->Inserter,
> +                      FPMathTag, OpBundles) {
> +    SetInsertPoint(IP);
> +  }
> +
> +  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, FolderTy Folder,
> +            MDNode *FPMathTag = nullptr,
> +            ArrayRef<OperandBundleDef> OpBundles = None)
> +      : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
> +                      FPMathTag, OpBundles), Folder(Folder) {
> +    SetInsertPoint(TheBB, IP);
> +  }
> +
> +  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
> +            MDNode *FPMathTag = nullptr,
> +            ArrayRef<OperandBundleDef> OpBundles = None)
> +      : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
> +                      FPMathTag, OpBundles) {
> +    SetInsertPoint(TheBB, IP);
> +  }
> +
> +  /// Avoid copying the full IRBuilder. Prefer using InsertPointGuard
> +  /// or FastMathFlagGuard instead.
> +  IRBuilder(const IRBuilder &) = delete;
> +
> +  InserterTy &getInserter() { return Inserter; }
> +};
> +
> // Create wrappers for C Binding types (see CBindingWrapping.h).
> DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)
>
>
> diff  --git a/llvm/include/llvm/IR/IRBuilderFolder.h
> b/llvm/include/llvm/IR/IRBuilderFolder.h
> new file mode 100644
> index 000000000000..a77a5213dcea
> --- /dev/null
> +++ b/llvm/include/llvm/IR/IRBuilderFolder.h
> @@ -0,0 +1,141 @@
> +//===- IRBuilderFolder.h - Const folder interface for IRBuilder -*- C++
> -*-===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This file defines for constant folding interface used by IRBuilder.
> +// It is implemented by ConstantFolder (default), TargetFolder and
> NoFoler.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_IR_IRBUILDERFOLDER_H
> +#define LLVM_IR_IRBUILDERFOLDER_H
> +
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/IR/InstrTypes.h"
> +#include "llvm/IR/Instruction.h"
> +
> +namespace llvm {
> +
> +/// IRBuilderFolder - Interface for constant folding in IRBuilder.
> +class IRBuilderFolder {
> +public:
> +  virtual ~IRBuilderFolder();
> +
> +
>  //===--------------------------------------------------------------------===//
> +  // Binary Operators
> +
>  //===--------------------------------------------------------------------===//
> +
> +  virtual Value *CreateAdd(Constant *LHS, Constant *RHS,
> +                           bool HasNUW = false, bool HasNSW = false)
> const = 0;
> +  virtual Value *CreateFAdd(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateSub(Constant *LHS, Constant *RHS,
> +                           bool HasNUW = false, bool HasNSW = false)
> const = 0;
> +  virtual Value *CreateFSub(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateMul(Constant *LHS, Constant *RHS,
> +                           bool HasNUW = false, bool HasNSW = false)
> const = 0;
> +  virtual Value *CreateFMul(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateUDiv(Constant *LHS, Constant *RHS,
> +                            bool isExact = false) const = 0;
> +  virtual Value *CreateSDiv(Constant *LHS, Constant *RHS,
> +                            bool isExact = false) const = 0;
> +  virtual Value *CreateFDiv(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateURem(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateSRem(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateFRem(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateShl(Constant *LHS, Constant *RHS,
> +                           bool HasNUW = false, bool HasNSW = false)
> const = 0;
> +  virtual Value *CreateLShr(Constant *LHS, Constant *RHS,
> +                            bool isExact = false) const = 0;
> +  virtual Value *CreateAShr(Constant *LHS, Constant *RHS,
> +                            bool isExact = false) const = 0;
> +  virtual Value *CreateAnd(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateOr(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateXor(Constant *LHS, Constant *RHS) const = 0;
> +  virtual Value *CreateBinOp(Instruction::BinaryOps Opc,
> +                             Constant *LHS, Constant *RHS) const = 0;
> +
> +
>  //===--------------------------------------------------------------------===//
> +  // Unary Operators
> +
>  //===--------------------------------------------------------------------===//
> +
> +  virtual Value *CreateNeg(Constant *C,
> +                           bool HasNUW = false, bool HasNSW = false)
> const = 0;
> +  virtual Value *CreateFNeg(Constant *C) const = 0;
> +  virtual Value *CreateNot(Constant *C) const = 0;
> +  virtual Value *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const
> = 0;
> +
> +
>  //===--------------------------------------------------------------------===//
> +  // Memory Instructions
> +
>  //===--------------------------------------------------------------------===//
> +
> +  virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
> +                                     ArrayRef<Constant *> IdxList) const
> = 0;
> +  // This form of the function only exists to avoid ambiguous overload
> +  // warnings about whether to convert Idx to ArrayRef<Constant *> or
> +  // ArrayRef<Value *>.
> +  virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
> +                                     Constant *Idx) const = 0;
> +  virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
> +                                     ArrayRef<Value *> IdxList) const = 0;
> +  virtual Value *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const = 0;
> +  // This form of the function only exists to avoid ambiguous overload
> +  // warnings about whether to convert Idx to ArrayRef<Constant *> or
> +  // ArrayRef<Value *>.
> +  virtual Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> +                                             Constant *Idx) const = 0;
> +  virtual Value *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const = 0;
> +
> +
>  //===--------------------------------------------------------------------===//
> +  // Cast/Conversion Operators
> +
>  //===--------------------------------------------------------------------===//
> +
> +  virtual Value *CreateCast(Instruction::CastOps Op, Constant *C,
> +                            Type *DestTy) const = 0;
> +  virtual Value *CreatePointerCast(Constant *C, Type *DestTy) const = 0;
> +  virtual Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
> +                                                     Type *DestTy) const
> = 0;
> +  virtual Value *CreateIntCast(Constant *C, Type *DestTy,
> +                               bool isSigned) const = 0;
> +  virtual Value *CreateFPCast(Constant *C, Type *DestTy) const = 0;
> +  virtual Value *CreateBitCast(Constant *C, Type *DestTy) const = 0;
> +  virtual Value *CreateIntToPtr(Constant *C, Type *DestTy) const = 0;
> +  virtual Value *CreatePtrToInt(Constant *C, Type *DestTy) const = 0;
> +  virtual Value *CreateZExtOrBitCast(Constant *C, Type *DestTy) const = 0;
> +  virtual Value *CreateSExtOrBitCast(Constant *C, Type *DestTy) const = 0;
> +  virtual Value *CreateTruncOrBitCast(Constant *C, Type *DestTy) const =
> 0;
> +
> +
>  //===--------------------------------------------------------------------===//
> +  // Compare Instructions
> +
>  //===--------------------------------------------------------------------===//
> +
> +  virtual Value *CreateICmp(CmpInst::Predicate P, Constant *LHS,
> +                            Constant *RHS) const = 0;
> +  virtual Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
> +                            Constant *RHS) const = 0;
> +
> +
>  //===--------------------------------------------------------------------===//
> +  // Other Instructions
> +
>  //===--------------------------------------------------------------------===//
> +
> +  virtual Value *CreateSelect(Constant *C, Constant *True,
> +                              Constant *False) const = 0;
> +  virtual Value *CreateExtractElement(Constant *Vec, Constant *Idx) const
> = 0;
> +  virtual Value *CreateInsertElement(Constant *Vec, Constant *NewElt,
> +                                     Constant *Idx) const = 0;
> +  virtual Value *CreateShuffleVector(Constant *V1, Constant *V2,
> +                                     Constant *Mask) const = 0;
> +  virtual Value *CreateExtractValue(Constant *Agg,
> +                                    ArrayRef<unsigned> IdxList) const = 0;
> +  virtual Value *CreateInsertValue(Constant *Agg, Constant *Val,
> +                                   ArrayRef<unsigned> IdxList) const = 0;
> +};
> +
> +} // end namespace llvm
> +
> +#endif // LLVM_IR_IRBUILDERFOLDER_H
>
> diff  --git a/llvm/include/llvm/IR/NoFolder.h
> b/llvm/include/llvm/IR/NoFolder.h
> index c03cdee1eb83..1e35cfe096eb 100644
> --- a/llvm/include/llvm/IR/NoFolder.h
> +++ b/llvm/include/llvm/IR/NoFolder.h
> @@ -26,11 +26,14 @@
> #include "llvm/IR/InstrTypes.h"
> #include "llvm/IR/Instruction.h"
> #include "llvm/IR/Instructions.h"
> +#include "llvm/IR/IRBuilderFolder.h"
>
> namespace llvm {
>
> /// NoFolder - Create "constants" (actually, instructions) with no folding.
> -class NoFolder {
> +class NoFolder final : public IRBuilderFolder {
> +  virtual void anchor();
> +
> public:
>   explicit NoFolder() = default;
>
> @@ -39,73 +42,76 @@ class NoFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Instruction *CreateAdd(Constant *LHS, Constant *RHS,
> -                         bool HasNUW = false, bool HasNSW = false) const {
> +                         bool HasNUW = false,
> +                         bool HasNSW = false) const override {
>     BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
>     if (HasNUW) BO->setHasNoUnsignedWrap();
>     if (HasNSW) BO->setHasNoSignedWrap();
>     return BO;
>   }
>
> -  Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateFAdd(LHS, RHS);
>   }
>
>   Instruction *CreateSub(Constant *LHS, Constant *RHS,
> -                         bool HasNUW = false, bool HasNSW = false) const {
> +                         bool HasNUW = false,
> +                         bool HasNSW = false) const override {
>     BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
>     if (HasNUW) BO->setHasNoUnsignedWrap();
>     if (HasNSW) BO->setHasNoSignedWrap();
>     return BO;
>   }
>
> -  Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateFSub(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateFSub(LHS, RHS);
>   }
>
>   Instruction *CreateMul(Constant *LHS, Constant *RHS,
> -                         bool HasNUW = false, bool HasNSW = false) const {
> +                         bool HasNUW = false,
> +                         bool HasNSW = false) const override {
>     BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
>     if (HasNUW) BO->setHasNoUnsignedWrap();
>     if (HasNSW) BO->setHasNoSignedWrap();
>     return BO;
>   }
>
> -  Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateFMul(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateFMul(LHS, RHS);
>   }
>
>   Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
> -                          bool isExact = false) const {
> +                          bool isExact = false) const override {
>     if (!isExact)
>       return BinaryOperator::CreateUDiv(LHS, RHS);
>     return BinaryOperator::CreateExactUDiv(LHS, RHS);
>   }
>
>   Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
> -                          bool isExact = false) const {
> +                          bool isExact = false) const override {
>     if (!isExact)
>       return BinaryOperator::CreateSDiv(LHS, RHS);
>     return BinaryOperator::CreateExactSDiv(LHS, RHS);
>   }
>
> -  Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateFDiv(LHS, RHS);
>   }
>
> -  Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateURem(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateURem(LHS, RHS);
>   }
>
> -  Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateSRem(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateSRem(LHS, RHS);
>   }
>
> -  Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateFRem(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateFRem(LHS, RHS);
>   }
>
>   Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
> -                         bool HasNSW = false) const {
> +                         bool HasNSW = false) const override {
>     BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
>     if (HasNUW) BO->setHasNoUnsignedWrap();
>     if (HasNSW) BO->setHasNoSignedWrap();
> @@ -113,33 +119,33 @@ class NoFolder {
>   }
>
>   Instruction *CreateLShr(Constant *LHS, Constant *RHS,
> -                          bool isExact = false) const {
> +                          bool isExact = false) const override {
>     if (!isExact)
>       return BinaryOperator::CreateLShr(LHS, RHS);
>     return BinaryOperator::CreateExactLShr(LHS, RHS);
>   }
>
>   Instruction *CreateAShr(Constant *LHS, Constant *RHS,
> -                          bool isExact = false) const {
> +                          bool isExact = false) const override {
>     if (!isExact)
>       return BinaryOperator::CreateAShr(LHS, RHS);
>     return BinaryOperator::CreateExactAShr(LHS, RHS);
>   }
>
> -  Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateAnd(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateAnd(LHS, RHS);
>   }
>
> -  Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateOr(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateOr(LHS, RHS);
>   }
>
> -  Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
> +  Instruction *CreateXor(Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::CreateXor(LHS, RHS);
>   }
>
>   Instruction *CreateBinOp(Instruction::BinaryOps Opc,
> -                           Constant *LHS, Constant *RHS) const {
> +                           Constant *LHS, Constant *RHS) const override {
>     return BinaryOperator::Create(Opc, LHS, RHS);
>   }
>
> @@ -148,22 +154,24 @@ class NoFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Instruction *CreateNeg(Constant *C,
> -                         bool HasNUW = false, bool HasNSW = false) const {
> +                         bool HasNUW = false,
> +                         bool HasNSW = false) const override {
>     BinaryOperator *BO = BinaryOperator::CreateNeg(C);
>     if (HasNUW) BO->setHasNoUnsignedWrap();
>     if (HasNSW) BO->setHasNoSignedWrap();
>     return BO;
>   }
>
> -  Instruction *CreateFNeg(Constant *C) const {
> +  Instruction *CreateFNeg(Constant *C) const override {
>     return UnaryOperator::CreateFNeg(C);
>   }
>
> -  Instruction *CreateNot(Constant *C) const {
> +  Instruction *CreateNot(Constant *C) const override {
>     return BinaryOperator::CreateNot(C);
>   }
>
> -  Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
> +  Instruction *CreateUnOp(Instruction::UnaryOps Opc,
> +                          Constant *C) const override {
>     return UnaryOperator::Create(Opc, C);
>   }
>
> @@ -172,11 +180,12 @@ class NoFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> -                                ArrayRef<Constant *> IdxList) const {
> +                                ArrayRef<Constant *> IdxList) const
> override {
>     return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
>   }
>
> -  Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx)
> const {
> +  Constant *CreateGetElementPtr(Type *Ty, Constant *C,
> +                                Constant *Idx) const override {
>     // This form of the function only exists to avoid ambiguous overload
>     // warnings about whether to convert Idx to ArrayRef<Constant *> or
>     // ArrayRef<Value *>.
> @@ -184,25 +193,25 @@ class NoFolder {
>   }
>
>   Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
> -                                   ArrayRef<Value *> IdxList) const {
> +                                   ArrayRef<Value *> IdxList) const
> override {
>     return GetElementPtrInst::Create(Ty, C, IdxList);
>   }
>
> -  Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        ArrayRef<Constant *> IdxList)
> const {
> +  Constant *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override
> {
>     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
>   }
>
>   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                        Constant *Idx) const {
> +                                        Constant *Idx) const override {
>     // This form of the function only exists to avoid ambiguous overload
>     // warnings about whether to convert Idx to ArrayRef<Constant *> or
>     // ArrayRef<Value *>.
>     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
>   }
>
> -  Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
> -                                           ArrayRef<Value *> IdxList)
> const {
> +  Instruction *CreateInBoundsGetElementPtr(
> +      Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
>     return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
>   }
>
> @@ -211,49 +220,49 @@ class NoFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
> -                    Type *DestTy) const {
> +                          Type *DestTy) const override {
>     return CastInst::Create(Op, C, DestTy);
>   }
>
> -  Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
> +  Instruction *CreatePointerCast(Constant *C, Type *DestTy) const
> override {
>     return CastInst::CreatePointerCast(C, DestTy);
>   }
>
>   Instruction *CreatePointerBitCastOrAddrSpaceCast(
> -      Constant *C, Type *DestTy) const {
> +      Constant *C, Type *DestTy) const override {
>     return CastInst::CreatePointerBitCastOrAddrSpaceCast(C, DestTy);
>   }
>
>   Instruction *CreateIntCast(Constant *C, Type *DestTy,
> -                       bool isSigned) const {
> +                             bool isSigned) const override {
>     return CastInst::CreateIntegerCast(C, DestTy, isSigned);
>   }
>
> -  Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
> +  Instruction *CreateFPCast(Constant *C, Type *DestTy) const override {
>     return CastInst::CreateFPCast(C, DestTy);
>   }
>
> -  Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
> +  Instruction *CreateBitCast(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::BitCast, C, DestTy);
>   }
>
> -  Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
> +  Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::IntToPtr, C, DestTy);
>   }
>
> -  Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
> +  Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const override {
>     return CreateCast(Instruction::PtrToInt, C, DestTy);
>   }
>
> -  Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
> +  Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const
> override {
>     return CastInst::CreateZExtOrBitCast(C, DestTy);
>   }
>
> -  Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
> +  Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const
> override {
>     return CastInst::CreateSExtOrBitCast(C, DestTy);
>   }
>
> -  Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
> +  Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const
> override {
>     return CastInst::CreateTruncOrBitCast(C, DestTy);
>   }
>
> @@ -262,12 +271,12 @@ class NoFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Instruction *CreateICmp(CmpInst::Predicate P,
> -                          Constant *LHS, Constant *RHS) const {
> +                          Constant *LHS, Constant *RHS) const override {
>     return new ICmpInst(P, LHS, RHS);
>   }
>
>   Instruction *CreateFCmp(CmpInst::Predicate P,
> -                          Constant *LHS, Constant *RHS) const {
> +                          Constant *LHS, Constant *RHS) const override {
>     return new FCmpInst(P, LHS, RHS);
>   }
>
> @@ -276,31 +285,32 @@ class NoFolder {
>
>   //===--------------------------------------------------------------------===//
>
>   Instruction *CreateSelect(Constant *C,
> -                            Constant *True, Constant *False) const {
> +                            Constant *True, Constant *False) const
> override {
>     return SelectInst::Create(C, True, False);
>   }
>
> -  Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
> +  Instruction *CreateExtractElement(Constant *Vec,
> +                                    Constant *Idx) const override {
>     return ExtractElementInst::Create(Vec, Idx);
>   }
>
>   Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
> -                                   Constant *Idx) const {
> +                                   Constant *Idx) const override {
>     return InsertElementInst::Create(Vec, NewElt, Idx);
>   }
>
>   Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
> -                                   Constant *Mask) const {
> +                                   Constant *Mask) const override {
>     return new ShuffleVectorInst(V1, V2, Mask);
>   }
>
>   Instruction *CreateExtractValue(Constant *Agg,
> -                                  ArrayRef<unsigned> IdxList) const {
> +                                  ArrayRef<unsigned> IdxList) const
> override {
>     return ExtractValueInst::Create(Agg, IdxList);
>   }
>
>   Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
> -                                 ArrayRef<unsigned> IdxList) const {
> +                                 ArrayRef<unsigned> IdxList) const
> override {
>     return InsertValueInst::Create(Agg, Val, IdxList);
>   }
> };
>
> diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp
> b/llvm/lib/Analysis/ConstantFolding.cpp
> index 0e4828d912dc..059bf9a53275 100644
> --- a/llvm/lib/Analysis/ConstantFolding.cpp
> +++ b/llvm/lib/Analysis/ConstantFolding.cpp
> @@ -23,6 +23,7 @@
> #include "llvm/ADT/STLExtras.h"
> #include "llvm/ADT/SmallVector.h"
> #include "llvm/ADT/StringRef.h"
> +#include "llvm/Analysis/TargetFolder.h"
> #include "llvm/Analysis/TargetLibraryInfo.h"
> #include "llvm/Analysis/ValueTracking.h"
> #include "llvm/Analysis/VectorUtils.h"
> @@ -2660,3 +2661,5 @@ bool llvm::isMathLibCallNoop(const CallBase *Call,
>
>   return false;
> }
> +
> +void TargetFolder::anchor() {}
>
> diff  --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
> index 0dd78f2f2d4b..457255b157cc 100644
> --- a/llvm/lib/IR/IRBuilder.cpp
> +++ b/llvm/lib/IR/IRBuilder.cpp
> @@ -24,6 +24,7 @@
> #include "llvm/IR/Intrinsics.h"
> #include "llvm/IR/LLVMContext.h"
> #include "llvm/IR/Operator.h"
> +#include "llvm/IR/NoFolder.h"
> #include "llvm/IR/Statepoint.h"
> #include "llvm/IR/Type.h"
> #include "llvm/IR/Value.h"
> @@ -784,3 +785,9 @@ CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID
> ID,
>   Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
>   return createCallHelper(Fn, Args, this, Name, FMFSource);
> }
> +
> +IRBuilderDefaultInserter::~IRBuilderDefaultInserter() {}
> +IRBuilderCallbackInserter::~IRBuilderCallbackInserter() {}
> +IRBuilderFolder::~IRBuilderFolder() {}
> +void ConstantFolder::anchor() {}
> +void NoFolder::anchor() {}
>
> diff  --git a/llvm/lib/Transforms/Scalar/SROA.cpp
> b/llvm/lib/Transforms/Scalar/SROA.cpp
> index 0038ac5038ca..c65244c1045d 100644
> --- a/llvm/lib/Transforms/Scalar/SROA.cpp
> +++ b/llvm/lib/Transforms/Scalar/SROA.cpp
> @@ -129,7 +129,7 @@ namespace {
>
> /// A custom IRBuilder inserter which prefixes all names, but only in
> /// Assert builds.
> -class IRBuilderPrefixedInserter : public IRBuilderDefaultInserter {
> +class IRBuilderPrefixedInserter final : public IRBuilderDefaultInserter {
>   std::string Prefix;
>
>   const Twine getNameWithPrefix(const Twine &Name) const {
> @@ -139,9 +139,8 @@ class IRBuilderPrefixedInserter : public
> IRBuilderDefaultInserter {
> public:
>   void SetNamePrefix(const Twine &P) { Prefix = P.str(); }
>
> -protected:
>   void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB,
> -                    BasicBlock::iterator InsertPt) const {
> +                    BasicBlock::iterator InsertPt) const override {
>     IRBuilderDefaultInserter::InsertHelper(I, getNameWithPrefix(Name), BB,
>                                            InsertPt);
>   }
> @@ -2368,7 +2367,8 @@ class llvm::sroa::AllocaSliceRewriter
>     Instruction *OldUserI = cast<Instruction>(OldUse->getUser());
>     IRB.SetInsertPoint(OldUserI);
>     IRB.SetCurrentDebugLocation(OldUserI->getDebugLoc());
> -    IRB.SetNamePrefix(Twine(NewAI.getName()) + "." + Twine(BeginOffset) +
> ".");
> +    IRB.getInserter().SetNamePrefix(
> +        Twine(NewAI.getName()) + "." + Twine(BeginOffset) + ".");
>
>     CanSROA &= visit(cast<Instruction>(OldUse->getUser()));
>     if (VecTy || IntTy)
>
> diff  --git a/polly/include/polly/CodeGen/IRBuilder.h
> b/polly/include/polly/CodeGen/IRBuilder.h
> index 8aeef3856a07..fb5d14a8b88b 100644
> --- a/polly/include/polly/CodeGen/IRBuilder.h
> +++ b/polly/include/polly/CodeGen/IRBuilder.h
> @@ -131,15 +131,14 @@ class ScopAnnotator {
> ///
> /// This is used to add additional items such as e.g. the
> llvm.loop.parallel
> /// metadata.
> -class IRInserter : protected llvm::IRBuilderDefaultInserter {
> +class IRInserter final : public llvm::IRBuilderDefaultInserter {
> public:
>   IRInserter() = default;
>   IRInserter(class ScopAnnotator &A) : Annotator(&A) {}
>
> -protected:
>   void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
>                     llvm::BasicBlock *BB,
> -                    llvm::BasicBlock::iterator InsertPt) const {
> +                    llvm::BasicBlock::iterator InsertPt) const override {
>     llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
>     if (Annotator)
>       Annotator->annotate(I);
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200217/42fb0ce9/attachment-0001.html>


More information about the llvm-commits mailing list