[llvm] r281181 - Analysis: Only allow the move-constructor for IVUsers

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 11 15:11:38 PDT 2016


Author: dexonsmith
Date: Sun Sep 11 17:11:37 2016
New Revision: 281181

URL: http://llvm.org/viewvc/llvm-project?rev=281181&view=rev
Log:
Analysis: Only allow the move-constructor for IVUsers

Force IVUsers to be moved instead of copied, properly update Parent
pointers in IVStrideUse when IVUsers is moved, and make sure we have
move constructors available in iplist and ilist.

I came across this in a WIP patch that deleted the copy constructors
from ilist.  I was surprised to find that IVUsersAnalysis couldn't be
registered in the new pass manager.

It's not clear to me whether IVUsers was getting moved only when empty,
but if it was being moved when it was non-empty then this fixes a
pointer invalidation bug and should give some sort of speedup.  Note
that the bugfix would be necessary even for a copy constructor.

Modified:
    llvm/trunk/include/llvm/ADT/ilist.h
    llvm/trunk/include/llvm/Analysis/IVUsers.h

Modified: llvm/trunk/include/llvm/ADT/ilist.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist.h?rev=281181&r1=281180&r2=281181&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/ilist.h (original)
+++ llvm/trunk/include/llvm/ADT/ilist.h Sun Sep 11 17:11:37 2016
@@ -161,6 +161,9 @@ template <class IntrusiveListT, class Tr
 class iplist_impl : public TraitsT, IntrusiveListT {
   typedef IntrusiveListT base_list_type;
 
+protected:
+  typedef iplist_impl iplist_impl_type;
+
 public:
   typedef typename base_list_type::pointer pointer;
   typedef typename base_list_type::const_pointer const_pointer;
@@ -192,6 +195,13 @@ private:
 
 public:
   iplist_impl() = default;
+  iplist_impl(iplist_impl &&X)
+      : TraitsT(std::move(X)), IntrusiveListT(std::move(X)) {}
+  iplist_impl &operator=(iplist_impl &&X) {
+    *static_cast<TraitsT *>(this) = std::move(X);
+    *static_cast<IntrusiveListT *>(this) = std::move(X);
+    return *this;
+  }
   ~iplist_impl() { clear(); }
 
   // Miscellaneous inspection routines.
@@ -367,7 +377,19 @@ public:
 /// there for a description of what's available.
 template <class T, class... Options>
 class iplist
-    : public iplist_impl<simple_ilist<T, Options...>, ilist_traits<T>> {};
+    : public iplist_impl<simple_ilist<T, Options...>, ilist_traits<T>> {
+  typedef typename iplist::iplist_impl_type iplist_impl_type;
+
+public:
+  iplist() = default;
+  iplist(iplist &&X) : iplist_impl_type(std::move(X)) {}
+  iplist(const iplist &X) = delete;
+  iplist &operator=(iplist &&X) {
+    *static_cast<iplist_impl_type *>(this) = std::move(X);
+    return *this;
+  }
+  iplist &operator=(const iplist &X) = delete;
+};
 
 /// An intrusive list with ownership and callbacks specified/controlled by
 /// ilist_traits, with API that is unsafe for polymorphic types.
@@ -395,6 +417,12 @@ public:
     insert(this->begin(), first, last);
   }
 
+  ilist(ilist &&X) : base_list_type(std::move(X)) {}
+  ilist &operator=(ilist &&X) {
+    *static_cast<base_list_type *>(this) = std::move(X);
+    return *this;
+  }
+
   // bring hidden functions into scope
   using base_list_type::insert;
   using base_list_type::push_front;

Modified: llvm/trunk/include/llvm/Analysis/IVUsers.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IVUsers.h?rev=281181&r1=281180&r2=281181&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/IVUsers.h (original)
+++ llvm/trunk/include/llvm/Analysis/IVUsers.h Sun Sep 11 17:11:37 2016
@@ -111,6 +111,17 @@ public:
   IVUsers(Loop *L, AssumptionCache *AC, LoopInfo *LI, DominatorTree *DT,
           ScalarEvolution *SE);
 
+  IVUsers(IVUsers &&X)
+      : L(std::move(X.L)), AC(std::move(X.AC)), DT(std::move(X.DT)),
+        SE(std::move(X.SE)), Processed(std::move(X.Processed)),
+        IVUses(std::move(X.IVUses)), EphValues(std::move(X.EphValues)) {
+    for (IVStrideUse &U : IVUses)
+      U.Parent = this;
+  }
+  IVUsers(const IVUsers &) = delete;
+  IVUsers &operator=(IVUsers &&) = delete;
+  IVUsers &operator=(const IVUsers &) = delete;
+
   Loop *getLoop() const { return L; }
 
   /// AddUsersIfInteresting - Inspect the specified Instruction.  If it is a




More information about the llvm-commits mailing list