This revision was automatically updated to reflect the committed changes.
Closed by commit rG0765d3824d06: [IRBuilder] Virtualize IRBuilder (authored by 
nikic).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73835/new/

https://reviews.llvm.org/D73835

Files:
  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/IRBuilderFolder.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

Index: polly/include/polly/CodeGen/IRBuilder.h
===================================================================
--- polly/include/polly/CodeGen/IRBuilder.h
+++ polly/include/polly/CodeGen/IRBuilder.h
@@ -131,15 +131,14 @@
 ///
 /// This is used to add additional items such as e.g. the llvm.loop.parallel
 /// metadata.
-class IRInserter : protected llvm::IRBuilderDefaultInserter {
+class IRInserter : 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);
Index: llvm/lib/Transforms/Scalar/SROA.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/SROA.cpp
+++ llvm/lib/Transforms/Scalar/SROA.cpp
@@ -139,9 +139,8 @@
 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 @@
     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)
Index: llvm/lib/IR/IRBuilder.cpp
===================================================================
--- llvm/lib/IR/IRBuilder.cpp
+++ 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,8 @@
   Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
   return createCallHelper(Fn, Args, this, Name, FMFSource);
 }
+
+void IRBuilderDefaultInserter::anchor() {}
+void IRBuilderCallbackInserter::anchor() {}
+void ConstantFolder::anchor() {}
+void NoFolder::anchor() {}
Index: llvm/lib/Analysis/ConstantFolding.cpp
===================================================================
--- llvm/lib/Analysis/ConstantFolding.cpp
+++ 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 @@
 
   return false;
 }
+
+void TargetFolder::anchor() {}
Index: llvm/include/llvm/IR/NoFolder.h
===================================================================
--- llvm/include/llvm/IR/NoFolder.h
+++ 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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   }
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   }
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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);
   }
 };
Index: llvm/include/llvm/IR/IRBuilderFolder.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/IR/IRBuilderFolder.h
@@ -0,0 +1,139 @@
+//===- 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:
+  //===--------------------------------------------------------------------===//
+  // 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
Index: llvm/include/llvm/IR/IRBuilder.h
===================================================================
--- llvm/include/llvm/IR/IRBuilder.h
+++ llvm/include/llvm/IR/IRBuilder.h
@@ -59,9 +59,12 @@
 ///
 /// 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 {
+  virtual void anchor();
+
+public:
+  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,17 @@
 
 /// 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;
+  virtual void anchor();
 
 public:
   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 +96,8 @@
   BasicBlock *BB;
   BasicBlock::iterator InsertPt;
   LLVMContext &Context;
+  const IRBuilderFolder &Folder;
+  const IRBuilderDefaultInserter &Inserter;
 
   MDNode *DefaultFPMathTag;
   FastMathFlags FMF;
@@ -103,15 +109,37 @@
   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,85 +948,7 @@
                                   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);
-  }
-
-  /// 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
@@ -2976,6 +2926,79 @@
   }
 };
 
+/// 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);
+  }
+
+  InserterTy &getInserter() { return Inserter; }
+};
+
 // Create wrappers for C Binding types (see CBindingWrapping.h).
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef)
 
Index: llvm/include/llvm/IR/ConstantFolder.h
===================================================================
--- llvm/include/llvm/IR/ConstantFolder.h
+++ 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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   }
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   // 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);
   }
 };
Index: llvm/include/llvm/Analysis/TargetFolder.h
===================================================================
--- llvm/include/llvm/Analysis/TargetFolder.h
+++ 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 @@
     return C;
   }
 
+  virtual void anchor();
+
 public:
   explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
 
@@ -46,66 +49,70 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   //===--------------------------------------------------------------------===//
 
   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 @@
   // 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));
   }
 };
Index: clang/lib/CodeGen/CGBuilder.h
===================================================================
--- clang/lib/CodeGen/CGBuilder.h
+++ clang/lib/CodeGen/CGBuilder.h
@@ -22,16 +22,15 @@
 /// This is an IRBuilder insertion helper that forwards to
 /// CodeGenFunction::InsertHelper, which adds necessary metadata to
 /// instructions.
-class CGBuilderInserter : protected llvm::IRBuilderDefaultInserter {
+class CGBuilderInserter : 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;
 };
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to