IR: Reduce RAUW traffic in ConstantVector
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 19 Aug 2014 02:24:46 +0000 (02:24 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 19 Aug 2014 02:24:46 +0000 (02:24 +0000)
Avoid creating a new `ConstantVector` on an RAUW of one of its members.
This reduces RAUW traffic on any containing constant.

This is part of PR20515.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215966 91177308-0d34-0410-b5e6-96231b3b80d8

lib/IR/Constants.cpp

index c2c3c40df1c4dba6604da278ad8c395f0ff8bb4e..cb7c9e63059ad86c1a92ae44b479b402ea7dc18f 100644 (file)
@@ -2810,17 +2810,41 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
 void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
                                                  Use *U) {
   assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+  Constant *ToC = cast<Constant>(To);
 
   SmallVector<Constant*, 8> Values;
   Values.reserve(getNumOperands());  // Build replacement array...
+  unsigned NumUpdated = 0;
   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
     Constant *Val = getOperand(i);
-    if (Val == From) Val = cast<Constant>(To);
+    if (Val == From) {
+      ++NumUpdated;
+      Val = ToC;
+    }
     Values.push_back(Val);
   }
 
-  Constant *Replacement = get(Values);
-  replaceUsesOfWithOnConstantImpl(Replacement);
+  if (Constant *C = getImpl(Values)) {
+    replaceUsesOfWithOnConstantImpl(C);
+    return;
+  }
+
+  // Update to the new value.  Optimize for the case when we have a single
+  // operand that we're changing, but handle bulk updates efficiently.
+  auto &pImpl = getType()->getContext().pImpl;
+  pImpl->VectorConstants.remove(this);
+
+  if (NumUpdated == 1) {
+    unsigned OperandToUpdate = U - OperandList;
+    assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
+    setOperand(OperandToUpdate, ToC);
+  } else {
+    for (unsigned I = 0, E = getNumOperands(); I != E; ++I)
+      if (getOperand(I) == From)
+        setOperand(I, ToC);
+  }
+
+  pImpl->VectorConstants.insert(this);
 }
 
 void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,