[PATCH] D64884: [PHINode] Preserve use-list order when removing incoming values.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 18 07:01:28 PDT 2019


fhahn updated this revision to Diff 210554.
fhahn added a comment.

Add move assignment operator that preserves the uselist order and use
std::move instead of std::copy. This preserves the original order of operands instead
of swapping them, which is slightly better IMO as swapping would mean that the order
of the remaining operands is dependent on the order in which we remove incoming values.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D64884

Files:
  llvm/include/llvm/IR/Use.h
  llvm/include/llvm/IR/Value.h
  llvm/lib/IR/Instructions.cpp


Index: llvm/lib/IR/Instructions.cpp
===================================================================
--- llvm/lib/IR/Instructions.cpp
+++ llvm/lib/IR/Instructions.cpp
@@ -123,12 +123,8 @@
   Value *Removed = getIncomingValue(Idx);
 
   // Move everything after this operand down.
-  //
-  // FIXME: we could just swap with the end of the list, then erase.  However,
-  // clients might not expect this to happen.  The code as it is thrashes the
-  // use/def lists, which is kinda lame.
-  std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx);
-  std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx);
+  std::move(op_begin() + Idx + 1, op_end(), op_begin() + Idx);
+  std::move(block_begin() + Idx + 1, block_end(), block_begin() + Idx);
 
   // Nuke the last value.
   Op<-1>().set(nullptr);
Index: llvm/include/llvm/IR/Value.h
===================================================================
--- llvm/include/llvm/IR/Value.h
+++ llvm/include/llvm/IR/Value.h
@@ -77,6 +77,7 @@
 
   friend class ValueAsMetadata; // Allow access to IsUsedByMD.
   friend class ValueHandleBase;
+  friend class Use;
 
   const unsigned char SubclassID;   // Subclass identifier (for isa/dyn_cast)
   unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this?
@@ -723,6 +724,28 @@
   return *this;
 }
 
+const Use &Use::operator=(Use &&RHS) {
+  if (Val)
+    removeFromList();
+
+  if (RHS.Val) {
+    Val = RHS.Val;
+    Next = RHS.Next;
+    Prev.setPointer(RHS.Prev.getPointer());
+
+    // Replace pointers to RHS with pointers to this in RHS's uselist.
+    if (RHS.Next)
+      RHS.Next->setPrev(&Next);
+    if (Val->UseList == &RHS)
+      Val->UseList = this;
+    else
+      (*Prev.getPointer()) = this;
+  }
+
+  RHS.Val = nullptr;
+  return *this;
+}
+
 template <class Compare> void Value::sortUseList(Compare Cmp) {
   if (!UseList || !UseList->Next)
     // No need to sort 0 or 1 uses.
Index: llvm/include/llvm/IR/Use.h
===================================================================
--- llvm/include/llvm/IR/Use.h
+++ llvm/include/llvm/IR/Use.h
@@ -116,6 +116,7 @@
 
   inline Value *operator=(Value *RHS);
   inline const Use &operator=(const Use &RHS);
+  inline const Use &operator=(Use &&RHS);
 
   Value *operator->() { return Val; }
   const Value *operator->() const { return Val; }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D64884.210554.patch
Type: text/x-patch
Size: 2337 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190718/917dcd9e/attachment.bin>


More information about the llvm-commits mailing list