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

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 17 11:23:24 PST 2020


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

> 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 <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 <mailto: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 <https://github.com/llvm/llvm-project/commit/3eaa53e80543813a2274391956e91d275950fbf8>
>> DIFF: 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 <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/94846b14/attachment-0001.html>


More information about the llvm-commits mailing list