- Add new Constant::replaceUsesOfWithOnConstant which has an end result
authorChris Lattner <sabre@nondot.org>
Wed, 9 Oct 2002 23:12:25 +0000 (23:12 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 9 Oct 2002 23:12:25 +0000 (23:12 +0000)
    similar to User::replaceUsesOfWith but actually does the right thing for
    constants.

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

include/llvm/Constant.h
include/llvm/Constants.h
lib/VMCore/Constants.cpp

index 708573874d61d1062692e17f19fb6a6ecd7bcb83..3105cea319d9943fa254decf246a0d8cf18d636c 100644 (file)
@@ -16,10 +16,11 @@ protected:
 
   void destroyConstantImpl();
 public:
-  /// setName - Specialize setName to handle symbol table majik...
+  // setName - Specialize setName to handle symbol table majik...
   virtual void setName(const std::string &name, SymbolTable *ST = 0);
 
   /// Static constructor to get a '0' constant of arbitrary type...
+  ///
   static Constant *getNullValue(const Type *Ty);
 
   /// isNullValue - Return true if this is the value that would be returned by
@@ -29,6 +30,7 @@ public:
   virtual void print(std::ostream &O) const;
 
   /// isConstantExpr - Return true if this is a ConstantExpr
+  ///
   virtual bool isConstantExpr() const { return false; }
 
 
@@ -49,12 +51,31 @@ public:
   virtual void destroyConstant() { assert(0 && "Not reached!"); }
 
   
-  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  //// Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Constant *) { return true; }
   static inline bool classof(const Value *V) {
     return V->getValueType() == Value::ConstantVal;
   }
 
+  /// replaceUsesOfWithOnConstant - This method is a special form of
+  /// User::replaceUsesOfWith (which does not work on constants) that does work
+  /// on constants.  Basically this method goes through the trouble of building
+  /// a new constant that is equivalent to the current one, with all uses of
+  /// From replaced with uses of To.  After this construction is completed, all
+  /// of the users of 'this' are replaced to use the new constant, and then
+  /// 'this' is deleted.  In general, you should not call this method, instead,
+  /// use Value::replaceAllUsesWith, which automatically dispatches to this
+  /// method as needed.
+  ///
+  virtual void replaceUsesOfWithOnConstant(Value *From, Value *To) {
+    // Provide a default implementation for constants (like integers) that
+    // cannot use any other values.  This cannot be called at runtime, but needs
+    // to be here to avoid link errors.
+    assert(getNumOperands() == 0 && "replaceUsesOfWithOnConstant must be "
+           "implemented for all constants that have operands!");
+    assert(0 && "Constants that do not have operands cannot be using 'From'!");
+  }
+
   // WARNING: Only to be used by Bytecode & Assembly Parsers!  USER CODE SHOULD
   // NOT USE THIS!!
   // Returns the number of uses of OldV that were replaced.
index 63d1bfdd559271f9fcacc3385c852cd82eb1487a..a91c1971fa4f7712b3d9b571dca0b49a8866c75e 100644 (file)
@@ -292,6 +292,7 @@ public:
   virtual bool isNullValue() const { return false; }
 
   virtual void destroyConstant();
+  virtual void replaceUsesOfWithOnConstant(Value *From, Value *To);
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const ConstantArray *) { return true; }
@@ -330,6 +331,7 @@ public:
   virtual bool isNullValue() const { return false; }
 
   virtual void destroyConstant();
+  virtual void replaceUsesOfWithOnConstant(Value *From, Value *To);
   
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const ConstantStruct *) { return true; }
@@ -423,6 +425,7 @@ public:
   }
 
   virtual void destroyConstant();
+  virtual void replaceUsesOfWithOnConstant(Value *From, Value *To);
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const ConstantPointerRef *) { return true; }
@@ -489,6 +492,7 @@ public:
   virtual bool isConstantExpr() const { return true; }
 
   virtual void destroyConstant();
+  virtual void replaceUsesOfWithOnConstant(Value *From, Value *To);
     
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const ConstantExpr *) { return true; }
index de61c37d6e32b4cb0e888677d83b9fe8d14c58eb..d0413f12b3437f7f41ea48aefff557d905f94e20 100644 (file)
@@ -326,6 +326,112 @@ bool ConstantFP::isValueValidForType(const Type *Ty, double Val) {
   }
 };
 
+//===----------------------------------------------------------------------===//
+//                replaceUsesOfWithOnConstant implementations
+
+void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+  assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+  std::vector<Constant*> Values;
+  Values.reserve(getValues().size());  // Build replacement array...
+  for (unsigned i = 0, e = getValues().size(); i != e; ++i) {
+    Constant *Val = cast<Constant>(getValues()[i]);
+    if (Val == From) Val = cast<Constant>(To);
+    Values.push_back(Val);
+  }
+  
+  ConstantArray *Replacement = ConstantArray::get(getType(), Values);
+  assert(Replacement != this && "I didn't contain From!");
+
+  // Everyone using this now uses the replacement...
+  replaceAllUsesWith(Replacement);
+  
+  // Delete the old constant!
+  destroyConstant();  
+}
+
+void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+  assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+  std::vector<Constant*> Values;
+  Values.reserve(getValues().size());
+  for (unsigned i = 0, e = getValues().size(); i != e; ++i) {
+    Constant *Val = cast<Constant>(getValues()[i]);
+    if (Val == From) Val = cast<Constant>(To);
+    Values.push_back(Val);
+  }
+  
+  ConstantStruct *Replacement = ConstantStruct::get(getType(), Values);
+  assert(Replacement != this && "I didn't contain From!");
+
+  // Everyone using this now uses the replacement...
+  replaceAllUsesWith(Replacement);
+  
+  // Delete the old constant!
+  destroyConstant();
+}
+
+void ConstantPointerRef::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+  if (isa<GlobalValue>(To)) {
+    assert(From == getOperand(0) && "Doesn't contain from!");
+    ConstantPointerRef *Replacement =
+      ConstantPointerRef::get(cast<GlobalValue>(To));
+    
+    // Everyone using this now uses the replacement...
+    replaceAllUsesWith(Replacement);
+    
+    // Delete the old constant!
+    destroyConstant();
+  } else {
+    // Just replace ourselves with the To value specified.
+    replaceAllUsesWith(To);
+  
+    // Delete the old constant!
+    destroyConstant();
+  }
+}
+
+void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *To) {
+  assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+  ConstantExpr *Replacement = 0;
+  if (getOpcode() == Instruction::GetElementPtr) {
+    std::vector<Constant*> Indices;
+    Constant *Pointer = cast<Constant>(getOperand(0));
+    Indices.reserve(getNumOperands()-1);
+    if (Pointer == From) Pointer = cast<Constant>(To);
+    
+    for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
+      Constant *Val = cast<Constant>(getOperand(i));
+      if (Val == From) Val = cast<Constant>(To);
+      Indices.push_back(Val);
+    }
+    Replacement = ConstantExpr::getGetElementPtr(Pointer, Indices);
+  } else if (getOpcode() == Instruction::Cast) {
+    assert(getOperand(0) == From && "Cast only has one use!");
+    Replacement = ConstantExpr::getCast(cast<Constant>(To), getType());
+  } else if (getNumOperands() == 2) {
+    Constant *C1 = cast<Constant>(getOperand(0));
+    Constant *C2 = cast<Constant>(getOperand(1));
+    if (C1 == From) C1 = cast<Constant>(To);
+    if (C2 == From) C2 = cast<Constant>(To);
+    Replacement = ConstantExpr::get(getOpcode(), C1, C2);
+  } else {
+    assert(0 && "Unknown ConstantExpr type!");
+    return;
+  }
+  
+  assert(Replacement != this && "I didn't contain From!");
+
+  // Everyone using this now uses the replacement...
+  replaceAllUsesWith(Replacement);
+  
+  // Delete the old constant!
+  destroyConstant();
+}
+
+
+
 //===----------------------------------------------------------------------===//
 //                      Factory Function Implementation