[llvm] r216007 - IR: De-duplicate code for replacing operands in place

Duncan P. N. Exon Smith dexonsmith at apple.com
Tue Aug 19 12:13:30 PDT 2014


Author: dexonsmith
Date: Tue Aug 19 14:13:30 2014
New Revision: 216007

URL: http://llvm.org/viewvc/llvm-project?rev=216007&view=rev
Log:
IR: De-duplicate code for replacing operands in place

This is non-trivial and sits in three places.  Move it to
ConstantUniqueMap.

Modified:
    llvm/trunk/lib/IR/Constants.cpp
    llvm/trunk/lib/IR/ConstantsContext.h

Modified: llvm/trunk/lib/IR/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=216007&r1=216006&r2=216007&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Constants.cpp (original)
+++ llvm/trunk/lib/IR/Constants.cpp Tue Aug 19 14:13:30 2014
@@ -2671,8 +2671,6 @@ void ConstantArray::replaceUsesOfWithOnC
   assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
   Constant *ToC = cast<Constant>(To);
 
-  LLVMContextImpl *pImpl = getType()->getContext().pImpl;
-
   SmallVector<Constant*, 8> Values;
   Values.reserve(getNumOperands());  // Build replacement array.
 
@@ -2707,36 +2705,10 @@ void ConstantArray::replaceUsesOfWithOnC
     return;
   }
 
-  // Check to see if we have this array type already.
-  LLVMContextImpl::ArrayConstantsTy::LookupKey Lookup(
-    cast<ArrayType>(getType()), makeArrayRef(Values));
-  LLVMContextImpl::ArrayConstantsTy::MapTy::iterator I =
-    pImpl->ArrayConstants.find(Lookup);
-
-  if (I != pImpl->ArrayConstants.map_end()) {
-    replaceUsesOfWithOnConstantImpl(I->first);
-    return;
-  }
-
-  // Okay, the new shape doesn't exist in the system yet.  Instead of
-  // creating a new constant array, inserting it, replaceallusesof'ing the
-  // old with the new, then deleting the old... just update the current one
-  // in place!
-  pImpl->ArrayConstants.remove(this);
-
-  // Update to the new value.  Optimize for the case when we have a single
-  // operand that we're changing, but handle bulk updates efficiently.
-  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->ArrayConstants.insert(this);
+  // Update to the new value.
+  if (Constant *C = getContext().pImpl->ArrayConstants.replaceOperandsInPlace(
+          Values, this, From, ToC, NumUpdated, U - OperandList))
+    replaceUsesOfWithOnConstantImpl(C);
 }
 
 void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
@@ -2774,8 +2746,6 @@ void ConstantStruct::replaceUsesOfWithOn
   }
   Values[OperandToUpdate] = ToC;
 
-  LLVMContextImpl *pImpl = getContext().pImpl;
-
   if (isAllZeros) {
     replaceUsesOfWithOnConstantImpl(ConstantAggregateZero::get(getType()));
     return;
@@ -2785,26 +2755,10 @@ void ConstantStruct::replaceUsesOfWithOn
     return;
   }
 
-  // Check to see if we have this struct type already.
-  LLVMContextImpl::StructConstantsTy::LookupKey Lookup(
-      cast<StructType>(getType()), makeArrayRef(Values));
-  LLVMContextImpl::StructConstantsTy::MapTy::iterator I =
-      pImpl->StructConstants.find(Lookup);
-
-  if (I != pImpl->StructConstants.map_end()) {
-    replaceUsesOfWithOnConstantImpl(I->first);
-    return;
-  }
-
-  // Okay, the new shape doesn't exist in the system yet.  Instead of
-  // creating a new constant struct, inserting it, replaceallusesof'ing the
-  // old with the new, then deleting the old... just update the current one
-  // in place!
-  pImpl->StructConstants.remove(this);
-
   // Update to the new value.
-  setOperand(OperandToUpdate, ToC);
-  pImpl->StructConstants.insert(this);
+  if (Constant *C = getContext().pImpl->StructConstants.replaceOperandsInPlace(
+          Values, this, From, ToC))
+    replaceUsesOfWithOnConstantImpl(C);
 }
 
 void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
@@ -2829,22 +2783,10 @@ void ConstantVector::replaceUsesOfWithOn
     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);
+  // Update to the new value.
+  if (Constant *C = getContext().pImpl->VectorConstants.replaceOperandsInPlace(
+          Values, this, From, ToC, NumUpdated, U - OperandList))
+    replaceUsesOfWithOnConstantImpl(C);
 }
 
 void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,

Modified: llvm/trunk/lib/IR/ConstantsContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantsContext.h?rev=216007&r1=216006&r2=216007&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantsContext.h (original)
+++ llvm/trunk/lib/IR/ConstantsContext.h Tue Aug 19 14:13:30 2014
@@ -341,6 +341,8 @@ template <> struct ConstantInfo<Constant
 template <class ConstantClass> struct ConstantAggrKeyType {
   ArrayRef<Constant *> Operands;
   ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {}
+  ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *)
+      : Operands(Operands) {}
   ConstantAggrKeyType(const ConstantClass *C,
                       SmallVectorImpl<Constant *> &Storage) {
     assert(Storage.empty() && "Expected empty storage");
@@ -425,6 +427,11 @@ struct ConstantExprKeyType {
                       ArrayRef<unsigned> Indexes = None)
       : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
         SubclassData(SubclassData), Ops(Ops), Indexes(Indexes) {}
+  ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
+      : Opcode(CE->getOpcode()),
+        SubclassOptionalData(CE->getRawSubclassOptionalData()),
+        SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
+        Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
   ConstantExprKeyType(const ConstantExpr *CE,
                       SmallVectorImpl<Constant *> &Storage)
       : Opcode(CE->getOpcode()),
@@ -594,6 +601,31 @@ public:
     Map.erase(I);
   }
 
+  ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> Operands,
+                                        ConstantClass *CP, Value *From,
+                                        Constant *To, unsigned NumUpdated = 0,
+                                        unsigned OperandNo = ~0u) {
+    LookupKey Lookup(CP->getType(), ValType(Operands, CP));
+    auto I = find(Lookup);
+    if (I != Map.end())
+      return I->first;
+
+    // Update to the new value.  Optimize for the case when we have a single
+    // operand that we're changing, but handle bulk updates efficiently.
+    remove(CP);
+    if (NumUpdated == 1) {
+      assert(OperandNo < CP->getNumOperands() && "Invalid index");
+      assert(CP->getOperand(OperandNo) != To && "I didn't contain From!");
+      CP->setOperand(OperandNo, To);
+    } else {
+      for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I)
+        if (CP->getOperand(I) == From)
+          CP->setOperand(I, To);
+    }
+    insert(CP);
+    return nullptr;
+  }
+
   void dump() const { DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); }
 };
 





More information about the llvm-commits mailing list