[llvm] r303362 - [IR] De-virtualize ~Value to save a vptr

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Thu May 18 10:24:11 PDT 2017


Author: rnk
Date: Thu May 18 12:24:10 2017
New Revision: 303362

URL: http://llvm.org/viewvc/llvm-project?rev=303362&view=rev
Log:
[IR] De-virtualize ~Value to save a vptr

Summary:
Implements PR889

Removing the virtual table pointer from Value saves 1% of RSS when doing
LTO of llc on Linux. The impact on time was positive, but too noisy to
conclusively say that performance improved. Here is a link to the
spreadsheet with the original data:

https://docs.google.com/spreadsheets/d/1F4FHir0qYnV0MEp2sYYp_BuvnJgWlWPhWOwZ6LbW7W4/edit?usp=sharing

This change makes it invalid to directly delete a Value, User, or
Instruction pointer. Instead, such code can be rewritten to a null check
and a call Value::deleteValue(). Value objects tend to have their
lifetimes managed through iplist, so for the most part, this isn't a big
deal.  However, there are some places where LLVM deletes values, and
those places had to be migrated to deleteValue.  I have also created
llvm::unique_value, which has a custom deleter, so it can be used in
place of std::unique_ptr<Value>.

I had to add the "DerivedUser" Deleter escape hatch for MemorySSA, which
derives from User outside of lib/IR. Code in IR cannot include MemorySSA
headers or call the MemoryAccess object destructors without introducing
a circular dependency, so we need some level of indirection.
Unfortunately, no class derived from User may have any virtual methods,
because adding a virtual method would break User::getHungOffOperands(),
which assumes that it can find the use list immediately prior to the
User object. I've added a static_assert to the appropriate OperandTraits
templates to help people avoid this trap.

Reviewers: chandlerc, mehdi_amini, pete, dberlin, george.burgess.iv

Reviewed By: chandlerc

Subscribers: krytarowski, eraman, george.burgess.iv, mzolotukhin, Prazek, nlewycky, hans, inglorion, pcc, tejohnson, dberlin, llvm-commits

Differential Revision: https://reviews.llvm.org/D31261

Added:
    llvm/trunk/include/llvm/IR/DerivedUser.h
Modified:
    llvm/trunk/include/llvm/Analysis/MemorySSA.h
    llvm/trunk/include/llvm/IR/Argument.h
    llvm/trunk/include/llvm/IR/BasicBlock.h
    llvm/trunk/include/llvm/IR/Constant.h
    llvm/trunk/include/llvm/IR/Constants.h
    llvm/trunk/include/llvm/IR/Function.h
    llvm/trunk/include/llvm/IR/GlobalValue.h
    llvm/trunk/include/llvm/IR/GlobalVariable.h
    llvm/trunk/include/llvm/IR/InlineAsm.h
    llvm/trunk/include/llvm/IR/InstrTypes.h
    llvm/trunk/include/llvm/IR/Instruction.def
    llvm/trunk/include/llvm/IR/Instruction.h
    llvm/trunk/include/llvm/IR/Instructions.h
    llvm/trunk/include/llvm/IR/Metadata.h
    llvm/trunk/include/llvm/IR/OperandTraits.h
    llvm/trunk/include/llvm/IR/Operator.h
    llvm/trunk/include/llvm/IR/User.h
    llvm/trunk/include/llvm/IR/Value.def
    llvm/trunk/include/llvm/IR/Value.h
    llvm/trunk/lib/Analysis/MemorySSA.cpp
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Reader/ValueList.cpp
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
    llvm/trunk/lib/IR/Constants.cpp
    llvm/trunk/lib/IR/ConstantsContext.h
    llvm/trunk/lib/IR/Function.cpp
    llvm/trunk/lib/IR/InlineAsm.cpp
    llvm/trunk/lib/IR/Instruction.cpp
    llvm/trunk/lib/IR/Instructions.cpp
    llvm/trunk/lib/IR/LLVMContextImpl.cpp
    llvm/trunk/lib/IR/User.cpp
    llvm/trunk/lib/IR/Value.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
    llvm/trunk/lib/Transforms/Scalar/GVN.cpp
    llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
    llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
    llvm/trunk/lib/Transforms/Scalar/SROA.cpp
    llvm/trunk/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
    llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp
    llvm/trunk/unittests/IR/ConstantsTest.cpp
    llvm/trunk/unittests/IR/InstructionsTest.cpp
    llvm/trunk/unittests/IR/MetadataTest.cpp
    llvm/trunk/unittests/Transforms/Utils/Cloning.cpp

Modified: llvm/trunk/include/llvm/Analysis/MemorySSA.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemorySSA.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemorySSA.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemorySSA.h Thu May 18 12:24:10 2017
@@ -84,6 +84,7 @@
 #include "llvm/Analysis/MemoryLocation.h"
 #include "llvm/Analysis/PHITransAddr.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DerivedUser.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/OperandTraits.h"
@@ -127,7 +128,7 @@ using const_memoryaccess_def_iterator =
 // \brief The base for all memory accesses. All memory accesses in a block are
 // linked together using an intrusive list.
 class MemoryAccess
-    : public User,
+    : public DerivedUser,
       public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>,
       public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>> {
 public:
@@ -145,15 +146,14 @@ public:
 
   MemoryAccess(const MemoryAccess &) = delete;
   MemoryAccess &operator=(const MemoryAccess &) = delete;
-  ~MemoryAccess() override;
 
   void *operator new(size_t, unsigned) = delete;
   void *operator new(size_t) = delete;
 
   BasicBlock *getBlock() const { return Block; }
 
-  virtual void print(raw_ostream &OS) const = 0;
-  virtual void dump() const;
+  void print(raw_ostream &OS) const;
+  void dump() const;
 
   /// \brief The user iterators for a memory access
   typedef user_iterator iterator;
@@ -207,11 +207,12 @@ protected:
 
   /// \brief Used for debugging and tracking things about MemoryAccesses.
   /// Guaranteed unique among MemoryAccesses, no guarantees otherwise.
-  virtual unsigned getID() const = 0;
+  inline unsigned getID() const;
 
-  MemoryAccess(LLVMContext &C, unsigned Vty, BasicBlock *BB,
-               unsigned NumOperands)
-      : User(Type::getVoidTy(C), Vty, nullptr, NumOperands), Block(BB) {}
+  MemoryAccess(LLVMContext &C, unsigned Vty, DeleteValueTy DeleteValue,
+               BasicBlock *BB, unsigned NumOperands)
+      : DerivedUser(Type::getVoidTy(C), Vty, nullptr, NumOperands, DeleteValue),
+        Block(BB) {}
 
 private:
   BasicBlock *Block;
@@ -248,21 +249,21 @@ public:
 
   // Sadly, these have to be public because they are needed in some of the
   // iterators.
-  virtual bool isOptimized() const = 0;
-  virtual MemoryAccess *getOptimized() const = 0;
-  virtual void setOptimized(MemoryAccess *) = 0;
+  inline bool isOptimized() const;
+  inline MemoryAccess *getOptimized() const;
+  inline void setOptimized(MemoryAccess *);
 
   /// \brief Reset the ID of what this MemoryUse was optimized to, causing it to
   /// be rewalked by the walker if necessary.
   /// This really should only be called by tests.
-  virtual void resetOptimized() = 0;
+  inline void resetOptimized();
 
 protected:
   friend class MemorySSA;
   friend class MemorySSAUpdater;
   MemoryUseOrDef(LLVMContext &C, MemoryAccess *DMA, unsigned Vty,
-                 Instruction *MI, BasicBlock *BB)
-      : MemoryAccess(C, Vty, BB, 1), MemoryInst(MI) {
+                 DeleteValueTy DeleteValue, Instruction *MI, BasicBlock *BB)
+      : MemoryAccess(C, Vty, DeleteValue, BB, 1), MemoryInst(MI) {
     setDefiningAccess(DMA);
   }
   void setDefiningAccess(MemoryAccess *DMA, bool Optimized = false) {
@@ -292,7 +293,8 @@ public:
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
 
   MemoryUse(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB)
-      : MemoryUseOrDef(C, DMA, MemoryUseVal, MI, BB), OptimizedID(0) {}
+      : MemoryUseOrDef(C, DMA, MemoryUseVal, deleteMe, MI, BB),
+        OptimizedID(0) {}
 
   // allocate space for exactly one operand
   void *operator new(size_t s) { return User::operator new(s, 1); }
@@ -302,32 +304,30 @@ public:
     return MA->getValueID() == MemoryUseVal;
   }
 
-  void print(raw_ostream &OS) const override;
+  void print(raw_ostream &OS) const;
 
-  virtual void setOptimized(MemoryAccess *DMA) override {
+  void setOptimized(MemoryAccess *DMA) {
     OptimizedID = DMA->getID();
     setOperand(0, DMA);
   }
 
-  virtual bool isOptimized() const override {
+  bool isOptimized() const {
     return getDefiningAccess() && OptimizedID == getDefiningAccess()->getID();
   }
 
-  virtual MemoryAccess *getOptimized() const override {
+  MemoryAccess *getOptimized() const {
     return getDefiningAccess();
   }
-  virtual void resetOptimized() override {
+  void resetOptimized() {
     OptimizedID = INVALID_MEMORYACCESS_ID;
   }
 
 protected:
   friend class MemorySSA;
 
-  unsigned getID() const override {
-    llvm_unreachable("MemoryUses do not have IDs");
-  }
-
 private:
+  static void deleteMe(DerivedUser *Self);
+
   unsigned int OptimizedID;
 };
 
@@ -350,8 +350,8 @@ public:
 
   MemoryDef(LLVMContext &C, MemoryAccess *DMA, Instruction *MI, BasicBlock *BB,
             unsigned Ver)
-      : MemoryUseOrDef(C, DMA, MemoryDefVal, MI, BB), ID(Ver),
-        Optimized(nullptr), OptimizedID(INVALID_MEMORYACCESS_ID) {}
+      : MemoryUseOrDef(C, DMA, MemoryDefVal, deleteMe, MI, BB),
+        ID(Ver), Optimized(nullptr), OptimizedID(INVALID_MEMORYACCESS_ID) {}
 
   // allocate space for exactly one operand
   void *operator new(size_t s) { return User::operator new(s, 1); }
@@ -361,27 +361,28 @@ public:
     return MA->getValueID() == MemoryDefVal;
   }
 
-  virtual void setOptimized(MemoryAccess *MA) override {
+  void setOptimized(MemoryAccess *MA) {
     Optimized = MA;
     OptimizedID = getDefiningAccess()->getID();
   }
-  virtual MemoryAccess *getOptimized() const override { return Optimized; }
-  virtual bool isOptimized() const override {
+  MemoryAccess *getOptimized() const { return Optimized; }
+  bool isOptimized() const {
     return getOptimized() && getDefiningAccess() &&
            OptimizedID == getDefiningAccess()->getID();
   }
-  virtual void resetOptimized() override {
+  void resetOptimized() {
     OptimizedID = INVALID_MEMORYACCESS_ID;
   }
 
-  void print(raw_ostream &OS) const override;
+  void print(raw_ostream &OS) const;
 
-protected:
   friend class MemorySSA;
 
-  unsigned getID() const override { return ID; }
+  unsigned getID() const { return ID; }
 
 private:
+  static void deleteMe(DerivedUser *Self);
+
   const unsigned ID;
   MemoryAccess *Optimized;
   unsigned int OptimizedID;
@@ -432,7 +433,8 @@ public:
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
 
   MemoryPhi(LLVMContext &C, BasicBlock *BB, unsigned Ver, unsigned NumPreds = 0)
-      : MemoryAccess(C, MemoryPhiVal, BB, 0), ID(Ver), ReservedSpace(NumPreds) {
+      : MemoryAccess(C, MemoryPhiVal, deleteMe, BB, 0), ID(Ver),
+        ReservedSpace(NumPreds) {
     allocHungoffUses(ReservedSpace);
   }
 
@@ -534,7 +536,9 @@ public:
     return V->getValueID() == MemoryPhiVal;
   }
 
-  void print(raw_ostream &OS) const override;
+  void print(raw_ostream &OS) const;
+
+  unsigned getID() const { return ID; }
 
 protected:
   friend class MemorySSA;
@@ -546,8 +550,6 @@ protected:
     User::allocHungoffUses(N, /* IsPhi */ true);
   }
 
-  unsigned getID() const final { return ID; }
-
 private:
   // For debugging only
   const unsigned ID;
@@ -561,8 +563,45 @@ private:
     ReservedSpace = std::max(E + E / 2, 2u);
     growHungoffUses(ReservedSpace, /* IsPhi */ true);
   }
+
+  static void deleteMe(DerivedUser *Self);
 };
 
+inline unsigned MemoryAccess::getID() const {
+  assert((isa<MemoryDef>(this) || isa<MemoryPhi>(this)) &&
+         "only memory defs and phis have ids");
+  if (const auto *MD = dyn_cast<MemoryDef>(this))
+    return MD->getID();
+  return cast<MemoryPhi>(this)->getID();
+}
+
+inline bool MemoryUseOrDef::isOptimized() const {
+  if (const auto *MD = dyn_cast<MemoryDef>(this))
+    return MD->isOptimized();
+  return cast<MemoryUse>(this)->isOptimized();
+}
+
+inline MemoryAccess *MemoryUseOrDef::getOptimized() const {
+  if (const auto *MD = dyn_cast<MemoryDef>(this))
+    return MD->getOptimized();
+  return cast<MemoryUse>(this)->getOptimized();
+}
+
+inline void MemoryUseOrDef::setOptimized(MemoryAccess *MA) {
+  if (auto *MD = dyn_cast<MemoryDef>(this))
+    MD->setOptimized(MA);
+  else
+    cast<MemoryUse>(this)->setOptimized(MA);
+}
+
+inline void MemoryUseOrDef::resetOptimized() {
+  if (auto *MD = dyn_cast<MemoryDef>(this))
+    MD->resetOptimized();
+  else
+    cast<MemoryUse>(this)->resetOptimized();
+}
+
+
 template <> struct OperandTraits<MemoryPhi> : public HungoffOperandTraits<2> {};
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(MemoryPhi, MemoryAccess)
 

Modified: llvm/trunk/include/llvm/IR/Argument.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Argument.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Argument.h (original)
+++ llvm/trunk/include/llvm/IR/Argument.h Thu May 18 12:24:10 2017
@@ -27,8 +27,7 @@ namespace llvm {
 /// for a specific function. When used in the body of said function, the
 /// argument of course represents the value of the actual argument that the
 /// function was called with.
-class Argument : public Value {
-  virtual void anchor();
+class Argument final : public Value {
   Function *Parent;
   unsigned ArgNo;
 

Modified: llvm/trunk/include/llvm/IR/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/IR/BasicBlock.h Thu May 18 12:24:10 2017
@@ -51,8 +51,8 @@ class ValueSymbolTable;
 /// occur because it may be useful in the intermediate stage of constructing or
 /// modifying a program. However, the verifier will ensure that basic blocks
 /// are "well formed".
-class BasicBlock : public Value, // Basic blocks are data objects also
-                   public ilist_node_with_parent<BasicBlock, Function> {
+class BasicBlock final : public Value, // Basic blocks are data objects also
+                         public ilist_node_with_parent<BasicBlock, Function> {
 public:
   using InstListType = SymbolTableList<Instruction>;
 
@@ -77,7 +77,7 @@ private:
 public:
   BasicBlock(const BasicBlock &) = delete;
   BasicBlock &operator=(const BasicBlock &) = delete;
-  ~BasicBlock() override;
+  ~BasicBlock();
 
   /// \brief Get the context in which this basic block lives.
   LLVMContext &getContext() const;

Modified: llvm/trunk/include/llvm/IR/Constant.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constant.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Constant.h (original)
+++ llvm/trunk/include/llvm/IR/Constant.h Thu May 18 12:24:10 2017
@@ -40,8 +40,6 @@ class APInt;
 /// don't have to worry about the lifetime of the objects.
 /// @brief LLVM Constant Representation
 class Constant : public User {
-  void anchor() override;
-
 protected:
   Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
     : User(ty, vty, Ops, NumOps) {}

Modified: llvm/trunk/include/llvm/IR/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constants.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Constants.h (original)
+++ llvm/trunk/include/llvm/IR/Constants.h Thu May 18 12:24:10 2017
@@ -58,8 +58,6 @@ template <class ConstantClass> struct Co
 class ConstantData : public Constant {
   friend class Constant;
 
-  void anchor() override;
-
   Value *handleOperandChangeImpl(Value *From, Value *To) {
     llvm_unreachable("Constant data does not have operands!");
   }
@@ -93,7 +91,6 @@ class ConstantInt final : public Constan
 
   ConstantInt(IntegerType *Ty, const APInt& V);
 
-  void anchor() override;
   void destroyConstantImpl();
 
 public:
@@ -274,7 +271,6 @@ class ConstantFP final : public Constant
 
   ConstantFP(Type *Ty, const APFloat& V);
 
-  void anchor() override;
   void destroyConstantImpl();
 
 public:
@@ -588,7 +584,7 @@ class ConstantDataSequential : public Co
 protected:
   explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
       : ConstantData(ty, VT), DataElements(Data), Next(nullptr) {}
-  ~ConstantDataSequential() override { delete Next; }
+  ~ConstantDataSequential() { delete Next; }
 
   static Constant *getImpl(StringRef Bytes, Type *Ty);
 
@@ -692,8 +688,6 @@ class ConstantDataArray final : public C
     return User::operator new(s, 0);
   }
 
-  void anchor() override;
-
 public:
   ConstantDataArray(const ConstantDataArray &) = delete;
 
@@ -755,8 +749,6 @@ class ConstantDataVector final : public
     return User::operator new(s, 0);
   }
 
-  void anchor() override;
-
 public:
   ConstantDataVector(const ConstantDataVector &) = delete;
 

Added: llvm/trunk/include/llvm/IR/DerivedUser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DerivedUser.h?rev=303362&view=auto
==============================================================================
--- llvm/trunk/include/llvm/IR/DerivedUser.h (added)
+++ llvm/trunk/include/llvm/IR/DerivedUser.h Thu May 18 12:24:10 2017
@@ -0,0 +1,41 @@
+//===-- DerivedUser.h - Base for non-IR Users -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_DERIVEDUSER_H
+#define LLVM_IR_DERIVEDUSER_H
+
+#include "llvm/IR/User.h"
+
+namespace llvm {
+
+/// Extension point for the Value hierarchy. All classes outside of lib/IR
+/// that wish to inherit from User should instead inherit from DerivedUser
+/// instead. Inheriting from this class is discouraged.
+///
+/// Generally speaking, Value is the base of a closed class hierarchy
+/// that can't be extended by code outside of lib/IR. This class creates a
+/// loophole that allows classes outside of lib/IR to extend User to leverage
+/// its use/def list machinery.
+class DerivedUser : public User {
+protected:
+  typedef void (*DeleteValueTy)(DerivedUser *);
+
+private:
+  friend Value;
+  DeleteValueTy DeleteValue;
+
+public:
+  DerivedUser(Type *Ty, unsigned VK, Use *U, unsigned NumOps,
+              DeleteValueTy DeleteValue)
+      : User(Ty, VK, U, NumOps), DeleteValue(DeleteValue) {}
+};
+
+} // namespace llvm
+
+#endif // LLVM_IR_DERIVEDUSER_H

Modified: llvm/trunk/include/llvm/IR/Function.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Function.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Function.h (original)
+++ llvm/trunk/include/llvm/IR/Function.h Thu May 18 12:24:10 2017
@@ -123,7 +123,7 @@ private:
 public:
   Function(const Function&) = delete;
   void operator=(const Function&) = delete;
-  ~Function() override;
+  ~Function();
 
   static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
                           const Twine &N = "", Module *M = nullptr) {

Modified: llvm/trunk/include/llvm/IR/GlobalValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalValue.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalValue.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalValue.h Thu May 18 12:24:10 2017
@@ -161,6 +161,10 @@ protected:
     Parent = parent;
   }
 
+  ~GlobalValue() {
+    removeDeadConstantUsers();   // remove any dead constants using this.
+  }
+
 public:
   enum ThreadLocalMode {
     NotThreadLocal = 0,
@@ -172,10 +176,6 @@ public:
 
   GlobalValue(const GlobalValue &) = delete;
 
-  ~GlobalValue() override {
-    removeDeadConstantUsers();   // remove any dead constants using this.
-  }
-
   unsigned getAlignment() const;
 
   enum class UnnamedAddr {

Modified: llvm/trunk/include/llvm/IR/GlobalVariable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalVariable.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalVariable.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalVariable.h Thu May 18 12:24:10 2017
@@ -66,7 +66,7 @@ public:
   GlobalVariable(const GlobalVariable &) = delete;
   GlobalVariable &operator=(const GlobalVariable &) = delete;
 
-  ~GlobalVariable() override {
+  ~GlobalVariable() {
     dropAllReferences();
 
     // FIXME: needed by operator delete

Modified: llvm/trunk/include/llvm/IR/InlineAsm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/InlineAsm.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/InlineAsm.h (original)
+++ llvm/trunk/include/llvm/IR/InlineAsm.h Thu May 18 12:24:10 2017
@@ -28,7 +28,7 @@ class FunctionType;
 class PointerType;
 template <class ConstantClass> class ConstantUniqueMap;
 
-class InlineAsm : public Value {
+class InlineAsm final : public Value {
 public:
   enum AsmDialect {
     AD_ATT,
@@ -48,7 +48,6 @@ private:
   InlineAsm(FunctionType *Ty, const std::string &AsmString,
             const std::string &Constraints, bool hasSideEffects,
             bool isAlignStack, AsmDialect asmDialect);
-  ~InlineAsm() override;
 
   /// When the ConstantUniqueMap merges two types and makes two InlineAsms
   /// identical, it destroys one of them with this method.

Modified: llvm/trunk/include/llvm/IR/InstrTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/InstrTypes.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/InstrTypes.h (original)
+++ llvm/trunk/include/llvm/IR/InstrTypes.h Thu May 18 12:24:10 2017
@@ -62,9 +62,6 @@ protected:
                  Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd)
     : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
 
-  // Out of line virtual method, so the vtable, etc has a home.
-  ~TerminatorInst() override;
-
 public:
   /// Return the number of successors that this terminator has.
   unsigned getNumSuccessors() const;
@@ -299,9 +296,6 @@ public:
 
   void *operator new(size_t, unsigned) = delete;
 
-  // Out of line virtual method, so the vtable, etc has a home.
-  ~UnaryInstruction() override;
-
   /// Transparently provide more efficient getOperand methods.
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
@@ -568,8 +562,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(Bin
 /// if (isa<CastInst>(Instr)) { ... }
 /// @brief Base class of casting instructions.
 class CastInst : public UnaryInstruction {
-  void anchor() override;
-
 protected:
   /// @brief Constructor with insert-before-instruction semantics for subclasses
   CastInst(Type *Ty, unsigned iType, Value *S,
@@ -914,8 +906,6 @@ protected:
           Value *LHS, Value *RHS, const Twine &Name,
           BasicBlock *InsertAtEnd);
 
-  void anchor() override; // Out of line virtual method.
-
 public:
   CmpInst() = delete;
 

Modified: llvm/trunk/include/llvm/IR/Instruction.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.def?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.def (original)
+++ llvm/trunk/include/llvm/IR/Instruction.def Thu May 18 12:24:10 2017
@@ -102,6 +102,10 @@
 #define LAST_OTHER_INST(num)
 #endif
 
+#ifndef HANDLE_USER_INST
+#define HANDLE_USER_INST(num, opc, Class) HANDLE_OTHER_INST(num, opc, Class)
+#endif
+
 // Terminator Instructions - These instructions are used to terminate a basic
 // block of the program.   Every basic block must end with one of these
 // instructions for it to be a well formed basic block.
@@ -185,8 +189,8 @@ HANDLE_OTHER_INST(52, FCmp   , FCmpInst
 HANDLE_OTHER_INST(53, PHI    , PHINode    )  // PHI node instruction
 HANDLE_OTHER_INST(54, Call   , CallInst   )  // Call a function
 HANDLE_OTHER_INST(55, Select , SelectInst )  // select instruction
-HANDLE_OTHER_INST(56, UserOp1, Instruction)  // May be used internally in a pass
-HANDLE_OTHER_INST(57, UserOp2, Instruction)  // Internal to passes only
+HANDLE_USER_INST (56, UserOp1, Instruction)  // May be used internally in a pass
+HANDLE_USER_INST (57, UserOp2, Instruction)  // Internal to passes only
 HANDLE_OTHER_INST(58, VAArg  , VAArgInst  )  // vaarg instruction
 HANDLE_OTHER_INST(59, ExtractElement, ExtractElementInst)// extract from vector
 HANDLE_OTHER_INST(60, InsertElement, InsertElementInst)  // insert into vector
@@ -220,6 +224,8 @@ HANDLE_OTHER_INST(64, LandingPad, Landin
 #undef HANDLE_OTHER_INST
 #undef   LAST_OTHER_INST
 
+#undef HANDLE_USER_INST
+
 #ifdef HANDLE_INST
 #undef HANDLE_INST
 #endif

Modified: llvm/trunk/include/llvm/IR/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.h (original)
+++ llvm/trunk/include/llvm/IR/Instruction.h Thu May 18 12:24:10 2017
@@ -36,6 +36,10 @@ class FastMathFlags;
 class MDNode;
 struct AAMDNodes;
 
+template <> struct ilist_alloc_traits<Instruction> {
+  static inline void deleteNode(Instruction *V);
+};
+
 class Instruction : public User,
                     public ilist_node_with_parent<Instruction, BasicBlock> {
   BasicBlock *Parent;
@@ -47,13 +51,13 @@ class Instruction : public User,
     HasMetadataBit = 1 << 15
   };
 
+protected:
+  ~Instruction(); // Use deleteValue() to delete a generic Instruction.
+
 public:
   Instruction(const Instruction &) = delete;
   Instruction &operator=(const Instruction &) = delete;
 
-  // Out of line virtual method, so the vtable, etc has a home.
-  ~Instruction() override;
-
   /// Specialize the methods defined in Value, as we know that an instruction
   /// can only be used by other instructions.
   Instruction       *user_back()       { return cast<Instruction>(*user_begin());}
@@ -640,6 +644,10 @@ private:
   Instruction *cloneImpl() const;
 };
 
+inline void ilist_alloc_traits<Instruction>::deleteNode(Instruction *V) {
+  V->deleteValue();
+}
+
 } // end namespace llvm
 
 #endif // LLVM_IR_INSTRUCTION_H

Modified: llvm/trunk/include/llvm/IR/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instructions.h (original)
+++ llvm/trunk/include/llvm/IR/Instructions.h Thu May 18 12:24:10 2017
@@ -89,9 +89,6 @@ public:
   AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align,
              const Twine &Name, BasicBlock *InsertAtEnd);
 
-  // Out of line virtual method, so the vtable, etc. has a home.
-  ~AllocaInst() override;
-
   /// Return true if there is an allocation size parameter to the allocation
   /// instruction that is not 1.
   bool isArrayAllocation() const;
@@ -856,7 +853,6 @@ class GetElementPtrInst : public Instruc
                            ArrayRef<Value *> IdxList, unsigned Values,
                            const Twine &NameStr, BasicBlock *InsertAtEnd);
 
-  void anchor() override;
   void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
 
 protected:
@@ -1112,8 +1108,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(Get
 /// must be identical types.
 /// Represent an integer comparison operator.
 class ICmpInst: public CmpInst {
-  void anchor() override;
-
   void AssertOK() {
     assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE &&
            getPredicate() <= CmpInst::LAST_ICMP_PREDICATE &&
@@ -1426,8 +1420,6 @@ protected:
   CallInst *cloneImpl() const;
 
 public:
-  ~CallInst() override;
-
   static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
                           ArrayRef<OperandBundleDef> Bundles = None,
                           const Twine &NameStr = "",
@@ -2592,8 +2584,6 @@ class PHINode : public Instruction {
     return User::operator new(s);
   }
 
-  void anchor() override;
-
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
   friend class Instruction;
@@ -2927,8 +2917,6 @@ protected:
   ReturnInst *cloneImpl() const;
 
 public:
-  ~ReturnInst() override;
-
   static ReturnInst* Create(LLVMContext &C, Value *retVal = nullptr,
                             Instruction *InsertBefore = nullptr) {
     return new(!!retVal) ReturnInst(C, retVal, InsertBefore);

Modified: llvm/trunk/include/llvm/IR/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.h (original)
+++ llvm/trunk/include/llvm/IR/Metadata.h Thu May 18 12:24:10 2017
@@ -174,12 +174,13 @@ class MetadataAsValue : public Value {
   Metadata *MD;
 
   MetadataAsValue(Type *Ty, Metadata *MD);
-  ~MetadataAsValue() override;
 
   /// \brief Drop use of metadata (during teardown).
   void dropUse() { MD = nullptr; }
 
 public:
+  ~MetadataAsValue();
+
   static MetadataAsValue *get(LLVMContext &Context, Metadata *MD);
   static MetadataAsValue *getIfExists(LLVMContext &Context, Metadata *MD);
   Metadata *getMetadata() const { return MD; }

Modified: llvm/trunk/include/llvm/IR/OperandTraits.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/OperandTraits.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/OperandTraits.h (original)
+++ llvm/trunk/include/llvm/IR/OperandTraits.h Thu May 18 12:24:10 2017
@@ -30,6 +30,9 @@ namespace llvm {
 template <typename SubClass, unsigned ARITY>
 struct FixedNumOperandTraits {
   static Use *op_begin(SubClass* U) {
+    static_assert(
+        !std::is_polymorphic<SubClass>::value,
+        "adding virtual methods to subclasses of User breaks use lists");
     return reinterpret_cast<Use*>(U) - ARITY;
   }
   static Use *op_end(SubClass* U) {
@@ -65,6 +68,9 @@ struct OptionalOperandTraits : public Fi
 template <typename SubClass, unsigned MINARITY = 0>
 struct VariadicOperandTraits {
   static Use *op_begin(SubClass* U) {
+    static_assert(
+        !std::is_polymorphic<SubClass>::value,
+        "adding virtual methods to subclasses of User breaks use lists");
     return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
   }
   static Use *op_end(SubClass* U) {

Modified: llvm/trunk/include/llvm/IR/Operator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Operator.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Operator.h (original)
+++ llvm/trunk/include/llvm/IR/Operator.h Thu May 18 12:24:10 2017
@@ -29,16 +29,11 @@ namespace llvm {
 /// This is a utility class that provides an abstraction for the common
 /// functionality between Instructions and ConstantExprs.
 class Operator : public User {
-protected:
-  // NOTE: Cannot use = delete because it's not legal to delete
-  // an overridden method that's not deleted in the base class. Cannot leave
-  // this unimplemented because that leads to an ODR-violation.
-  ~Operator() override;
-
 public:
   // The Operator class is intended to be used as a utility, and is never itself
   // instantiated.
   Operator() = delete;
+  ~Operator() = delete;
 
   void *operator new(size_t, unsigned) = delete;
   void *operator new(size_t s) = delete;

Modified: llvm/trunk/include/llvm/IR/User.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/User.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/User.h (original)
+++ llvm/trunk/include/llvm/IR/User.h Thu May 18 12:24:10 2017
@@ -46,8 +46,6 @@ class User : public Value {
   template <unsigned>
   friend struct HungoffOperandTraits;
 
-  virtual void anchor();
-
   LLVM_ATTRIBUTE_ALWAYS_INLINE inline static void *
   allocateFixedOperandUser(size_t, unsigned, unsigned);
 
@@ -93,9 +91,11 @@ protected:
   /// should be called if there are no uses.
   void growHungoffUses(unsigned N, bool IsPhi = false);
 
+protected:
+  ~User() = default; // Use deleteValue() to delete a generic Instruction.
+
 public:
   User(const User &) = delete;
-  ~User() override = default;
 
   /// \brief Free memory allocated for User and Use objects.
   void operator delete(void *Usr);

Modified: llvm/trunk/include/llvm/IR/Value.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.def?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Value.def (original)
+++ llvm/trunk/include/llvm/IR/Value.def Thu May 18 12:24:10 2017
@@ -20,10 +20,14 @@
 #if !(defined HANDLE_GLOBAL_VALUE || defined HANDLE_CONSTANT ||                \
       defined HANDLE_INSTRUCTION || defined HANDLE_INLINE_ASM_VALUE ||         \
       defined HANDLE_METADATA_VALUE || defined HANDLE_VALUE ||                 \
-      defined HANDLE_CONSTANT_MARKER)
+      defined HANDLE_CONSTANT_MARKER || defined HANDLE_MEMORY_VALUE)
 #error "Missing macro definition of HANDLE_VALUE*"
 #endif
 
+#ifndef HANDLE_MEMORY_VALUE
+#define HANDLE_MEMORY_VALUE(ValueName) HANDLE_VALUE(ValueName)
+#endif
+
 #ifndef HANDLE_GLOBAL_VALUE
 #define HANDLE_GLOBAL_VALUE(ValueName) HANDLE_CONSTANT(ValueName)
 #endif
@@ -54,9 +58,13 @@
 
 HANDLE_VALUE(Argument)
 HANDLE_VALUE(BasicBlock)
-HANDLE_VALUE(MemoryUse)
-HANDLE_VALUE(MemoryDef)
-HANDLE_VALUE(MemoryPhi)
+
+// FIXME: It's awkward that Value.def knows about classes in Analysis. While
+// this doesn't introduce a strict link or include dependency, we should remove
+// the circular dependency eventually.
+HANDLE_MEMORY_VALUE(MemoryUse)
+HANDLE_MEMORY_VALUE(MemoryDef)
+HANDLE_MEMORY_VALUE(MemoryPhi)
 
 HANDLE_GLOBAL_VALUE(Function)
 HANDLE_GLOBAL_VALUE(GlobalAlias)
@@ -94,6 +102,7 @@ HANDLE_CONSTANT_MARKER(ConstantDataLastV
 HANDLE_CONSTANT_MARKER(ConstantAggregateFirstVal, ConstantArray)
 HANDLE_CONSTANT_MARKER(ConstantAggregateLastVal, ConstantVector)
 
+#undef HANDLE_MEMORY_VALUE
 #undef HANDLE_GLOBAL_VALUE
 #undef HANDLE_CONSTANT
 #undef HANDLE_INSTRUCTION

Modified: llvm/trunk/include/llvm/IR/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Value.h (original)
+++ llvm/trunk/include/llvm/IR/Value.h Thu May 18 12:24:10 2017
@@ -21,6 +21,7 @@
 #include "llvm-c/Types.h"
 #include <cassert>
 #include <iterator>
+#include <memory>
 
 namespace llvm {
 
@@ -69,6 +70,8 @@ using ValueName = StringMapEntry<Value*>
 /// objects that watch it and listen to RAUW and Destroy events.  See
 /// llvm/IR/ValueHandle.h for details.
 class Value {
+  // The least-significant bit of the first word of Value *must* be zero:
+  //   http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
   Type *VTy;
   Use *UseList;
 
@@ -200,10 +203,19 @@ private:
 protected:
   Value(Type *Ty, unsigned scid);
 
+  /// Value's destructor should be virtual by design, but that would require
+  /// that Value and all of its subclasses have a vtable that effectively
+  /// duplicates the information in the value ID. As a size optimization, the
+  /// destructor has been protected, and the caller should manually call
+  /// deleteValue.
+  ~Value(); // Use deleteValue() to delete a generic Value.
+
 public:
   Value(const Value &) = delete;
   void operator=(const Value &) = delete;
-  virtual ~Value();
+
+  /// Delete a pointer to a generic Value.
+  void deleteValue();
 
   /// \brief Support for debugging, callable in GDB: V->dump()
   void dump() const;
@@ -643,6 +655,13 @@ protected:
   void setValueSubclassData(unsigned short D) { SubclassData = D; }
 };
 
+struct ValueDeleter { void operator()(Value *V) { V->deleteValue(); } };
+
+/// Use this instead of std::unique_ptr<Value> or std::unique_ptr<Instruction>.
+/// Those don't work because Value and Instruction's destructors are protected,
+/// aren't virtual, and won't destroy the complete object.
+typedef std::unique_ptr<Value, ValueDeleter> unique_value;
+
 inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
   V.print(OS);
   return OS;

Modified: llvm/trunk/lib/Analysis/MemorySSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSA.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSA.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSA.cpp Thu May 18 12:24:10 2017
@@ -1799,6 +1799,15 @@ bool MemorySSA::dominates(const MemoryAc
 
 const static char LiveOnEntryStr[] = "liveOnEntry";
 
+void MemoryAccess::print(raw_ostream &OS) const {
+  switch (getValueID()) {
+  case MemoryPhiVal: return static_cast<const MemoryPhi *>(this)->print(OS);
+  case MemoryDefVal: return static_cast<const MemoryDef *>(this)->print(OS);
+  case MemoryUseVal: return static_cast<const MemoryUse *>(this)->print(OS);
+  }
+  llvm_unreachable("invalid value id");
+}
+
 void MemoryDef::print(raw_ostream &OS) const {
   MemoryAccess *UO = getDefiningAccess();
 
@@ -1836,8 +1845,6 @@ void MemoryPhi::print(raw_ostream &OS) c
   OS << ')';
 }
 
-MemoryAccess::~MemoryAccess() {}
-
 void MemoryUse::print(raw_ostream &OS) const {
   MemoryAccess *UO = getDefiningAccess();
   OS << "MemoryUse(";
@@ -2054,3 +2061,15 @@ MemoryAccess *DoNothingMemorySSAWalker::
   return StartingAccess;
 }
 } // namespace llvm
+
+void MemoryPhi::deleteMe(DerivedUser *Self) {
+  delete static_cast<MemoryPhi *>(Self);
+}
+
+void MemoryDef::deleteMe(DerivedUser *Self) {
+  delete static_cast<MemoryDef *>(Self);
+}
+
+void MemoryUse::deleteMe(DerivedUser *Self) {
+  delete static_cast<MemoryUse *>(Self);
+}

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Thu May 18 12:24:10 2017
@@ -2502,7 +2502,7 @@ LLParser::PerFunctionState::~PerFunction
       continue;
     P.second.first->replaceAllUsesWith(
         UndefValue::get(P.second.first->getType()));
-    delete P.second.first;
+    P.second.first->deleteValue();
   }
 
   for (const auto &P : ForwardRefValIDs) {
@@ -2510,7 +2510,7 @@ LLParser::PerFunctionState::~PerFunction
       continue;
     P.second.first->replaceAllUsesWith(
         UndefValue::get(P.second.first->getType()));
-    delete P.second.first;
+    P.second.first->deleteValue();
   }
 }
 
@@ -2642,7 +2642,7 @@ bool LLParser::PerFunctionState::SetInst
                        getTypeString(FI->second.first->getType()) + "'");
 
       Sentinel->replaceAllUsesWith(Inst);
-      delete Sentinel;
+      Sentinel->deleteValue();
       ForwardRefValIDs.erase(FI);
     }
 
@@ -2659,7 +2659,7 @@ bool LLParser::PerFunctionState::SetInst
                      getTypeString(FI->second.first->getType()) + "'");
 
     Sentinel->replaceAllUsesWith(Inst);
-    delete Sentinel;
+    Sentinel->deleteValue();
     ForwardRefVals.erase(FI);
   }
 

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Thu May 18 12:24:10 2017
@@ -4489,11 +4489,11 @@ Error BitcodeReader::parseFunctionBody(F
     // Add instruction to end of current BB.  If there is no current BB, reject
     // this file.
     if (!CurBB) {
-      delete I;
+      I->deleteValue();
       return error("Invalid instruction with no BB");
     }
     if (!OperandBundles.empty()) {
-      delete I;
+      I->deleteValue();
       return error("Operand bundles found with no consumer");
     }
     CurBB->getInstList().push_back(I);

Modified: llvm/trunk/lib/Bitcode/Reader/ValueList.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/ValueList.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/ValueList.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/ValueList.cpp Thu May 18 12:24:10 2017
@@ -73,7 +73,7 @@ void BitcodeReaderValueList::assignValue
     // If there was a forward reference to this value, replace it.
     Value *PrevVal = OldV;
     OldV->replaceAllUsesWith(V);
-    delete PrevVal;
+    PrevVal->deleteValue();
   }
 }
 
@@ -194,6 +194,6 @@ void BitcodeReaderValueList::resolveCons
 
     // Update all ValueHandles, they should be the only users at this point.
     Placeholder->replaceAllUsesWith(RealVal);
-    delete Placeholder;
+    Placeholder->deleteValue();
   }
 }

Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Thu May 18 12:24:10 2017
@@ -350,7 +350,7 @@ bool CodeGenPrepare::runOnFunction(Funct
 
     // Really free removed instructions during promotion.
     for (Instruction *I : RemovedInsts)
-      delete I;
+      I->deleteValue();
 
     EverMadeChange |= MadeChange;
   }

Modified: llvm/trunk/lib/IR/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Constants.cpp (original)
+++ llvm/trunk/lib/IR/Constants.cpp Thu May 18 12:24:10 2017
@@ -37,10 +37,6 @@ using namespace llvm;
 //                              Constant Class
 //===----------------------------------------------------------------------===//
 
-void Constant::anchor() { }
-
-void ConstantData::anchor() {}
-
 bool Constant::isNegativeZeroValue() const {
   // Floating point values have an explicit -0.0 value.
   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
@@ -496,8 +492,6 @@ void Constant::removeDeadConstantUsers()
 //                                ConstantInt
 //===----------------------------------------------------------------------===//
 
-void ConstantInt::anchor() { }
-
 ConstantInt::ConstantInt(IntegerType *Ty, const APInt &V)
     : ConstantData(Ty, ConstantIntVal), Val(V) {
   assert(V.getBitWidth() == Ty->getBitWidth() && "Invalid constant for type");
@@ -610,8 +604,6 @@ static const fltSemantics *TypeToFloatSe
   return &APFloat::PPCDoubleDouble();
 }
 
-void ConstantFP::anchor() { }
-
 Constant *ConstantFP::get(Type *Ty, double V) {
   LLVMContext &Context = Ty->getContext();
 
@@ -2266,9 +2258,6 @@ Type *GetElementPtrConstantExpr::getResu
 //===----------------------------------------------------------------------===//
 //                       ConstantData* implementations
 
-void ConstantDataArray::anchor() {}
-void ConstantDataVector::anchor() {}
-
 Type *ConstantDataSequential::getElementType() const {
   return getType()->getElementType();
 }

Modified: llvm/trunk/lib/IR/ConstantsContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantsContext.h?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantsContext.h (original)
+++ llvm/trunk/lib/IR/ConstantsContext.h Thu May 18 12:24:10 2017
@@ -44,8 +44,6 @@ namespace llvm {
 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement unary constant exprs.
 class UnaryConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
     : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
@@ -65,8 +63,6 @@ public:
 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement binary constant exprs.
 class BinaryConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
                      unsigned Flags)
@@ -90,8 +86,6 @@ public:
 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
 /// behind the scenes to implement select constant exprs.
 class SelectConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
@@ -115,8 +109,6 @@ public:
 /// Constants.cpp, and is used behind the scenes to implement
 /// extractelement constant exprs.
 class ExtractElementConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   ExtractElementConstantExpr(Constant *C1, Constant *C2)
     : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
@@ -140,8 +132,6 @@ public:
 /// Constants.cpp, and is used behind the scenes to implement
 /// insertelement constant exprs.
 class InsertElementConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
     : ConstantExpr(C1->getType(), Instruction::InsertElement,
@@ -166,8 +156,6 @@ public:
 /// Constants.cpp, and is used behind the scenes to implement
 /// shufflevector constant exprs.
 class ShuffleVectorConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
   : ConstantExpr(VectorType::get(
@@ -195,8 +183,6 @@ public:
 /// Constants.cpp, and is used behind the scenes to implement
 /// extractvalue constant exprs.
 class ExtractValueConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList,
                            Type *DestTy)
@@ -230,8 +216,6 @@ public:
 /// Constants.cpp, and is used behind the scenes to implement
 /// insertvalue constant exprs.
 class InsertValueConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   InsertValueConstantExpr(Constant *Agg, Constant *Val,
                           ArrayRef<unsigned> IdxList, Type *DestTy)
@@ -271,8 +255,6 @@ class GetElementPtrConstantExpr : public
   GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
                             ArrayRef<Constant *> IdxList, Type *DestTy);
 
-  void anchor() override;
-
 public:
   static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
                                            ArrayRef<Constant *> IdxList,
@@ -301,8 +283,6 @@ public:
 // behind the scenes to implement ICmp and FCmp constant expressions. This is
 // needed in order to store the predicate value for these instructions.
 class CompareConstantExpr : public ConstantExpr {
-  void anchor() override;
-
 public:
   unsigned short predicate;
   CompareConstantExpr(Type *ty, Instruction::OtherOps opc,

Modified: llvm/trunk/lib/IR/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Function.cpp (original)
+++ llvm/trunk/lib/IR/Function.cpp Thu May 18 12:24:10 2017
@@ -66,8 +66,6 @@ template class llvm::SymbolTableListTrai
 // Argument Implementation
 //===----------------------------------------------------------------------===//
 
-void Argument::anchor() {}
-
 Argument::Argument(Type *Ty, const Twine &Name, Function *Par, unsigned ArgNo)
     : Value(Ty, Value::ArgumentVal), Parent(Par), ArgNo(ArgNo) {
   setName(Name);

Modified: llvm/trunk/lib/IR/InlineAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/InlineAsm.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/InlineAsm.cpp (original)
+++ llvm/trunk/lib/IR/InlineAsm.cpp Thu May 18 12:24:10 2017
@@ -40,10 +40,6 @@ InlineAsm::InlineAsm(FunctionType *FTy,
          "Function type not legal for constraints!");
 }
 
-// Implement the first virtual method in this class in this file so the
-// InlineAsm vtable is emitted here.
-InlineAsm::~InlineAsm() = default;
-
 InlineAsm *InlineAsm::get(FunctionType *FTy, StringRef AsmString,
                           StringRef Constraints, bool hasSideEffects,
                           bool isAlignStack, AsmDialect asmDialect) {

Modified: llvm/trunk/lib/IR/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instruction.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instruction.cpp (original)
+++ llvm/trunk/lib/IR/Instruction.cpp Thu May 18 12:24:10 2017
@@ -43,8 +43,6 @@ Instruction::Instruction(Type *ty, unsig
   InsertAtEnd->getInstList().push_back(this);
 }
 
-
-// Out of line virtual method, so the vtable, etc has a home.
 Instruction::~Instruction() {
   assert(!Parent && "Instruction still linked in the program!");
   if (hasMetadataHashEntry())

Modified: llvm/trunk/lib/IR/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instructions.cpp (original)
+++ llvm/trunk/lib/IR/Instructions.cpp Thu May 18 12:24:10 2017
@@ -59,9 +59,6 @@ User::op_iterator CallSite::getCallee()
 //                            TerminatorInst Class
 //===----------------------------------------------------------------------===//
 
-// Out of line virtual method, so the vtable, etc has a home.
-TerminatorInst::~TerminatorInst() = default;
-
 unsigned TerminatorInst::getNumSuccessors() const {
   switch (getOpcode()) {
 #define HANDLE_TERM_INST(N, OPC, CLASS)                                        \
@@ -99,13 +96,6 @@ void TerminatorInst::setSuccessor(unsign
 }
 
 //===----------------------------------------------------------------------===//
-//                           UnaryInstruction Class
-//===----------------------------------------------------------------------===//
-
-// Out of line virtual method, so the vtable, etc has a home.
-UnaryInstruction::~UnaryInstruction() = default;
-
-//===----------------------------------------------------------------------===//
 //                              SelectInst Class
 //===----------------------------------------------------------------------===//
 
@@ -138,8 +128,6 @@ const char *SelectInst::areInvalidOperan
 //                               PHINode Class
 //===----------------------------------------------------------------------===//
 
-void PHINode::anchor() {}
-
 PHINode::PHINode(const PHINode &PN)
     : Instruction(PN.getType(), Instruction::PHI, nullptr, PN.getNumOperands()),
       ReservedSpace(PN.getNumOperands()) {
@@ -293,8 +281,6 @@ void LandingPadInst::addClause(Constant
 //                        CallInst Implementation
 //===----------------------------------------------------------------------===//
 
-CallInst::~CallInst() = default;
-
 void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
                     ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) {
   this->FTy = FTy;
@@ -900,8 +886,6 @@ BasicBlock *ReturnInst::getSuccessorV(un
   llvm_unreachable("ReturnInst has no successors!");
 }
 
-ReturnInst::~ReturnInst() = default;
-
 //===----------------------------------------------------------------------===//
 //                        ResumeInst Implementation
 //===----------------------------------------------------------------------===//
@@ -1337,9 +1321,6 @@ AllocaInst::AllocaInst(Type *Ty, unsigne
   setName(Name);
 }
 
-// Out of line virtual method, so the vtable, etc has a home.
-AllocaInst::~AllocaInst() = default;
-
 void AllocaInst::setAlignment(unsigned Align) {
   assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
   assert(Align <= MaximumAlignment &&
@@ -1689,8 +1670,6 @@ FenceInst::FenceInst(LLVMContext &C, Ato
 //                       GetElementPtrInst Implementation
 //===----------------------------------------------------------------------===//
 
-void GetElementPtrInst::anchor() {}
-
 void GetElementPtrInst::init(Value *Ptr, ArrayRef<Value *> IdxList,
                              const Twine &Name) {
   assert(getNumOperands() == 1 + IdxList.size() &&
@@ -2357,8 +2336,6 @@ float FPMathOperator::getFPAccuracy() co
 //                                CastInst Class
 //===----------------------------------------------------------------------===//
 
-void CastInst::anchor() {}
-
 // Just determine if this cast only deals with integral->integral conversion.
 bool CastInst::isIntegerCast() const {
   switch (getOpcode()) {
@@ -3387,8 +3364,6 @@ AddrSpaceCastInst::AddrSpaceCastInst(
 //                               CmpInst Classes
 //===----------------------------------------------------------------------===//
 
-void CmpInst::anchor() {}
-
 CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS,
                  Value *RHS, const Twine &Name, Instruction *InsertBefore)
   : Instruction(ty, op,
@@ -3528,8 +3503,6 @@ StringRef CmpInst::getPredicateName(Pred
   }
 }
 
-void ICmpInst::anchor() {}
-
 ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) {
   switch (pred) {
     default: llvm_unreachable("Unknown icmp predicate!");

Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Thu May 18 12:24:10 2017
@@ -215,27 +215,6 @@ uint32_t LLVMContextImpl::getOperandBund
   return I->second;
 }
 
-// ConstantsContext anchors
-void UnaryConstantExpr::anchor() { }
-
-void BinaryConstantExpr::anchor() { }
-
-void SelectConstantExpr::anchor() { }
-
-void ExtractElementConstantExpr::anchor() { }
-
-void InsertElementConstantExpr::anchor() { }
-
-void ShuffleVectorConstantExpr::anchor() { }
-
-void ExtractValueConstantExpr::anchor() { }
-
-void InsertValueConstantExpr::anchor() { }
-
-void GetElementPtrConstantExpr::anchor() { }
-
-void CompareConstantExpr::anchor() { }
-
 /// Singleton instance of the OptBisect class.
 ///
 /// This singleton is accessed via the LLVMContext::getOptBisect() function.  It

Modified: llvm/trunk/lib/IR/User.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/User.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/User.cpp (original)
+++ llvm/trunk/lib/IR/User.cpp Thu May 18 12:24:10 2017
@@ -19,8 +19,6 @@ class BasicBlock;
 //                                 User Class
 //===----------------------------------------------------------------------===//
 
-void User::anchor() {}
-
 void User::replaceUsesOfWith(Value *From, Value *To) {
   if (From == To) return;   // Duh what?
 
@@ -193,12 +191,4 @@ void User::operator delete(void *Usr) {
   }
 }
 
-//===----------------------------------------------------------------------===//
-//                             Operator Class
-//===----------------------------------------------------------------------===//
-
-Operator::~Operator() {
-  llvm_unreachable("should never destroy an Operator");
-}
-
 } // End llvm namespace

Modified: llvm/trunk/lib/IR/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Value.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Value.cpp (original)
+++ llvm/trunk/lib/IR/Value.cpp Thu May 18 12:24:10 2017
@@ -20,6 +20,7 @@
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DerivedUser.h"
 #include "llvm/IR/GetElementPtrTypeIterator.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instructions.h"
@@ -59,7 +60,7 @@ Value::Value(Type *ty, unsigned scid)
            (SubclassID < ConstantFirstVal || SubclassID > ConstantLastVal))
     assert((VTy->isFirstClassType() || VTy->isVoidTy()) &&
            "Cannot create non-first-class values except for constants!");
-  static_assert(sizeof(Value) == 3 * sizeof(void *) + 2 * sizeof(unsigned),
+  static_assert(sizeof(Value) == 2 * sizeof(void *) + 2 * sizeof(unsigned),
                 "Value too big");
 }
 
@@ -89,6 +90,32 @@ Value::~Value() {
   destroyValueName();
 }
 
+void Value::deleteValue() {
+  switch (getValueID()) {
+#define HANDLE_VALUE(Name)                                                     \
+  case Value::Name##Val:                                                       \
+    delete static_cast<Name *>(this);                                          \
+    break;
+#define HANDLE_MEMORY_VALUE(Name)                                              \
+  case Value::Name##Val:                                                       \
+    static_cast<DerivedUser *>(this)->DeleteValue(                             \
+        static_cast<DerivedUser *>(this));                                     \
+    break;
+#define HANDLE_INSTRUCTION(Name)  /* nothing */
+#include "llvm/IR/Value.def"
+
+#define HANDLE_INST(N, OPC, CLASS)                                             \
+  case Value::InstructionVal + Instruction::OPC:                               \
+    delete static_cast<CLASS *>(this);                                         \
+    break;
+#define HANDLE_USER_INST(N, OPC, CLASS)
+#include "llvm/IR/Instruction.def"
+
+  default:
+    llvm_unreachable("attempting to delete unknown value kind");
+  }
+}
+
 void Value::destroyValueName() {
   ValueName *Name = getValueName();
   if (Name)

Modified: llvm/trunk/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp Thu May 18 12:24:10 2017
@@ -399,7 +399,7 @@ void Simplifier::Context::cleanup() {
   for (Value *V : Clones) {
     Instruction *U = cast<Instruction>(V);
     if (!U->getParent())
-      delete U;
+      U->deleteValue();
   }
 }
 

Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Thu May 18 12:24:10 2017
@@ -2057,7 +2057,7 @@ bool GVN::performScalarPRE(Instruction *
     if (!performScalarPREInsertion(PREInstr, PREPred, ValNo)) {
       // If we failed insertion, make sure we remove the instruction.
       DEBUG(verifyRemoved(PREInstr));
-      delete PREInstr;
+      PREInstr->deleteValue();
       return false;
     }
   }

Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu May 18 12:24:10 2017
@@ -1906,7 +1906,7 @@ bool JumpThreadingPass::DuplicateCondBra
             {BB->getModule()->getDataLayout(), TLI, nullptr, nullptr, New})) {
       ValueMapping[&*BI] = IV;
       if (!New->mayHaveSideEffects()) {
-        delete New;
+        New->deleteValue();
         New = nullptr;
       }
     } else {

Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Thu May 18 12:24:10 2017
@@ -347,7 +347,7 @@ bool LoopRotate::rotateLoop(Loop *L, boo
       // in the map.
       ValueMap[Inst] = V;
       if (!C->mayHaveSideEffects()) {
-        delete C;
+        C->deleteValue();
         C = nullptr;
       }
     } else {

Modified: llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp Thu May 18 12:24:10 2017
@@ -1582,7 +1582,7 @@ Value *ReassociatePass::OptimizeAdd(Inst
     }
 
     // No need for extra uses anymore.
-    delete DummyInst;
+    DummyInst->deleteValue();
 
     unsigned NumAddedValues = NewMulOps.size();
     Value *V = EmitAddTreeOfValues(I, NewMulOps);

Modified: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Thu May 18 12:24:10 2017
@@ -2443,7 +2443,7 @@ private:
                         "insert");
       LI.replaceAllUsesWith(V);
       Placeholder->replaceAllUsesWith(&LI);
-      delete Placeholder;
+      Placeholder->deleteValue();
     } else {
       LI.replaceAllUsesWith(V);
     }

Modified: llvm/trunk/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp Thu May 18 12:24:10 2017
@@ -693,7 +693,7 @@ bool StraightLineStrengthReduce::runOnFu
       UnlinkedInst->setOperand(I, nullptr);
       RecursivelyDeleteTriviallyDeadInstructions(Op);
     }
-    delete UnlinkedInst;
+    UnlinkedInst->deleteValue();
   }
   bool Ret = !UnlinkedInstructions.empty();
   UnlinkedInstructions.clear();

Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Thu May 18 12:24:10 2017
@@ -317,7 +317,7 @@ void PruningFunctionCloner::CloneBlock(c
 
         if (!NewInst->mayHaveSideEffects()) {
           VMap[&*II] = V;
-          delete NewInst;
+          NewInst->deleteValue();
           continue;
         }
       }

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu May 18 12:24:10 2017
@@ -2235,7 +2235,7 @@ static bool FoldCondBranchOnPHI(BranchIn
         if (!BBI->use_empty())
           TranslateMap[&*BBI] = V;
         if (!N->mayHaveSideEffects()) {
-          delete N; // Instruction folded away, don't need actual inst
+          N->deleteValue(); // Instruction folded away, don't need actual inst
           N = nullptr;
         }
       } else {

Modified: llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Vectorize/SLPVectorizer.cpp Thu May 18 12:24:10 2017
@@ -578,12 +578,12 @@ private:
   void eraseInstruction(Instruction *I) {
     I->removeFromParent();
     I->dropAllReferences();
-    DeletedInstructions.push_back(std::unique_ptr<Instruction>(I));
+    DeletedInstructions.emplace_back(I);
   }
 
   /// Temporary store for deleted instructions. Instructions will be deleted
   /// eventually when the BoUpSLP is destructed.
-  SmallVector<std::unique_ptr<Instruction>, 8> DeletedInstructions;
+  SmallVector<unique_value, 8> DeletedInstructions;
 
   /// A list of values that need to extracted out of the tree.
   /// This list holds pairs of (Internal Scalar : External User). External User

Modified: llvm/trunk/unittests/IR/ConstantsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/ConstantsTest.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/ConstantsTest.cpp (original)
+++ llvm/trunk/unittests/IR/ConstantsTest.cpp Thu May 18 12:24:10 2017
@@ -178,14 +178,15 @@ TEST(ConstantsTest, PointerCast) {
             ConstantExpr::getAddrSpaceCast(NullInt32Ptr1, Int32PtrTy));
 }
 
-#define CHECK(x, y) {                                         		\
-    std::string __s;                                            	\
-    raw_string_ostream __o(__s);                                	\
-    Instruction *__I = cast<ConstantExpr>(x)->getAsInstruction();	\
-    __I->print(__o);      						\
-    delete __I; 							\
-    __o.flush();                                                	\
-    EXPECT_EQ(std::string("  <badref> = " y), __s);             	\
+#define CHECK(x, y)                                                            \
+  {                                                                            \
+    std::string __s;                                                           \
+    raw_string_ostream __o(__s);                                               \
+    Instruction *__I = cast<ConstantExpr>(x)->getAsInstruction();              \
+    __I->print(__o);                                                           \
+    __I->deleteValue();                                                        \
+    __o.flush();                                                               \
+    EXPECT_EQ(std::string("  <badref> = " y), __s);                            \
   }
 
 TEST(ConstantsTest, AsInstructionsTest) {

Modified: llvm/trunk/unittests/IR/InstructionsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/InstructionsTest.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/InstructionsTest.cpp (original)
+++ llvm/trunk/unittests/IR/InstructionsTest.cpp Thu May 18 12:24:10 2017
@@ -406,8 +406,8 @@ TEST(InstructionsTest, FPMathOperator) {
   EXPECT_TRUE(isa<FPMathOperator>(V1));
   FPMathOperator *O1 = cast<FPMathOperator>(V1);
   EXPECT_EQ(O1->getFPAccuracy(), 1.0);
-  delete V1;
-  delete I;
+  V1->deleteValue();
+  I->deleteValue();
 }
 
 

Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
+++ llvm/trunk/unittests/IR/MetadataTest.cpp Thu May 18 12:24:10 2017
@@ -218,7 +218,7 @@ TEST_F(MDNodeTest, Delete) {
 
   EXPECT_EQ(n, wvh);
 
-  delete I;
+  I->deleteValue();
 }
 
 TEST_F(MDNodeTest, SelfReference) {

Modified: llvm/trunk/unittests/Transforms/Utils/Cloning.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Cloning.cpp?rev=303362&r1=303361&r2=303362&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/Cloning.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/Cloning.cpp Thu May 18 12:24:10 2017
@@ -41,13 +41,18 @@ protected:
   }
 
   void eraseClones() {
-    DeleteContainerPointers(Clones);
+    for (Value *V : Clones)
+      V->deleteValue();
+    Clones.clear();
   }
 
   void TearDown() override {
     eraseClones();
-    DeleteContainerPointers(Orig);
-    delete V;
+    for (Value *V : Orig)
+      V->deleteValue();
+    Orig.clear();
+    if (V)
+      V->deleteValue();
   }
 
   SmallPtrSet<Value *, 4> Orig;   // Erase on exit




More information about the llvm-commits mailing list