+//===----------------------------------------------------------------------===//
+// replaceUsesOfWithOnConstant implementations
+
+void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
+ Use *U) {
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+ Constant *ToC = cast<Constant>(To);
+
+ unsigned OperandToUpdate = U-OperandList;
+ assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
+
+ std::pair<ArrayConstantsTy::MapKey, ConstantArray*> Lookup;
+ Lookup.first.first = getType();
+ Lookup.second = this;
+
+ std::vector<Constant*> &Values = Lookup.first.second;
+ Values.reserve(getNumOperands()); // Build replacement array.
+
+ // Fill values with the modified operands of the constant array. Also,
+ // compute whether this turns into an all-zeros array.
+ bool isAllZeros = false;
+ if (!ToC->isNullValue()) {
+ for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O)
+ Values.push_back(cast<Constant>(O->get()));
+ } else {
+ isAllZeros = true;
+ for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
+ Constant *Val = cast<Constant>(O->get());
+ Values.push_back(Val);
+ if (isAllZeros) isAllZeros = Val->isNullValue();
+ }
+ }
+ Values[OperandToUpdate] = ToC;
+
+ Constant *Replacement = 0;
+ if (isAllZeros) {
+ Replacement = ConstantAggregateZero::get(getType());
+ } else {
+ // Check to see if we have this array type already.
+ bool Exists;
+ ArrayConstantsTy::MapIterator I =
+ ArrayConstants.InsertOrGetItem(Lookup, Exists);
+
+ if (Exists) {
+ Replacement = I->second;
+ } else {
+ // 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!
+ ArrayConstants.MoveConstantToNewSlot(this, I);
+
+ // Update to the new value.
+ setOperand(OperandToUpdate, ToC);
+ return;
+ }
+ }
+
+ // Otherwise, I do need to replace this with an existing value.
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement.
+ uncheckedReplaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}
+
+void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
+ Use *U) {
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+ Constant *ToC = cast<Constant>(To);
+
+ unsigned OperandToUpdate = U-OperandList;
+ assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
+
+ std::pair<StructConstantsTy::MapKey, ConstantStruct*> Lookup;
+ Lookup.first.first = getType();
+ Lookup.second = this;
+ std::vector<Constant*> &Values = Lookup.first.second;
+ Values.reserve(getNumOperands()); // Build replacement struct.
+
+
+ // Fill values with the modified operands of the constant struct. Also,
+ // compute whether this turns into an all-zeros struct.
+ bool isAllZeros = false;
+ if (!ToC->isNullValue()) {
+ for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O)
+ Values.push_back(cast<Constant>(O->get()));
+ } else {
+ isAllZeros = true;
+ for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) {
+ Constant *Val = cast<Constant>(O->get());
+ Values.push_back(Val);
+ if (isAllZeros) isAllZeros = Val->isNullValue();
+ }
+ }
+ Values[OperandToUpdate] = ToC;
+
+ Constant *Replacement = 0;
+ if (isAllZeros) {
+ Replacement = ConstantAggregateZero::get(getType());
+ } else {
+ // Check to see if we have this array type already.
+ bool Exists;
+ StructConstantsTy::MapIterator I =
+ StructConstants.InsertOrGetItem(Lookup, Exists);
+
+ if (Exists) {
+ Replacement = I->second;
+ } else {
+ // 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!
+ StructConstants.MoveConstantToNewSlot(this, I);
+
+ // Update to the new value.
+ setOperand(OperandToUpdate, ToC);
+ return;
+ }
+ }
+
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement.
+ uncheckedReplaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}
+
+void ConstantPacked::replaceUsesOfWithOnConstant(Value *From, Value *To,
+ Use *U) {
+ assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+ std::vector<Constant*> Values;
+ Values.reserve(getNumOperands()); // Build replacement array...
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ Constant *Val = getOperand(i);
+ if (Val == From) Val = cast<Constant>(To);
+ Values.push_back(Val);
+ }
+
+ Constant *Replacement = ConstantPacked::get(getType(), Values);
+ assert(Replacement != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement.
+ uncheckedReplaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}