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