+//===----------------------------------------------------------------------===//
+// 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();
+}
+
+void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
+ Use *U) {
+ assert(isa<Constant>(ToV) && "Cannot make Constant refer to non-constant!");
+ Constant *To = cast<Constant>(ToV);
+
+ Constant *Replacement = 0;
+ if (getOpcode() == Instruction::GetElementPtr) {
+ std::vector<Constant*> Indices;
+ Constant *Pointer = getOperand(0);
+ Indices.reserve(getNumOperands()-1);
+ if (Pointer == From) Pointer = To;
+
+ for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
+ Constant *Val = getOperand(i);
+ if (Val == From) Val = 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(To, getType());
+ } else if (getOpcode() == Instruction::Select) {
+ Constant *C1 = getOperand(0);
+ Constant *C2 = getOperand(1);
+ Constant *C3 = getOperand(2);
+ if (C1 == From) C1 = To;
+ if (C2 == From) C2 = To;
+ if (C3 == From) C3 = To;
+ Replacement = ConstantExpr::getSelect(C1, C2, C3);
+ } else if (getOpcode() == Instruction::ExtractElement) {
+ Constant *C1 = getOperand(0);
+ Constant *C2 = getOperand(1);
+ if (C1 == From) C1 = To;
+ if (C2 == From) C2 = To;
+ Replacement = ConstantExpr::getExtractElement(C1, C2);
+ } else if (getNumOperands() == 2) {
+ Constant *C1 = getOperand(0);
+ Constant *C2 = getOperand(1);
+ if (C1 == From) C1 = To;
+ if (C2 == From) C2 = 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.
+ uncheckedReplaceAllUsesWith(Replacement);
+
+ // Delete the old constant!
+ destroyConstant();
+}
+
+
+
+/// clearAllValueMaps - This method frees all internal memory used by the
+/// constant subsystem, which can be used in environments where this memory
+/// is otherwise reported as a leak.
+void Constant::clearAllValueMaps() {
+ std::vector<Constant *> Constants;
+
+ DoubleConstants.clear(Constants);
+ FloatConstants.clear(Constants);
+ SIntConstants.clear(Constants);
+ UIntConstants.clear(Constants);
+ AggZeroConstants.clear(Constants);
+ ArrayConstants.clear(Constants);
+ StructConstants.clear(Constants);
+ PackedConstants.clear(Constants);
+ NullPtrConstants.clear(Constants);
+ UndefValueConstants.clear(Constants);
+ ExprConstants.clear(Constants);
+
+ for (std::vector<Constant *>::iterator I = Constants.begin(),
+ E = Constants.end(); I != E; ++I)
+ (*I)->dropAllReferences();
+ for (std::vector<Constant *>::iterator I = Constants.begin(),
+ E = Constants.end(); I != E; ++I)
+ (*I)->destroyConstantImpl();
+ Constants.clear();
+}
+
+/// getStringValue - Turn an LLVM constant pointer that eventually points to a
+/// global into a string value. Return an empty string if we can't do it.
+/// Parameter Chop determines if the result is chopped at the first null
+/// terminator.
+///
+std::string Constant::getStringValue(bool Chop, unsigned Offset) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(this)) {
+ if (GV->hasInitializer() && isa<ConstantArray>(GV->getInitializer())) {
+ ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
+ if (Init->isString()) {
+ std::string Result = Init->getAsString();
+ if (Offset < Result.size()) {
+ // If we are pointing INTO The string, erase the beginning...
+ Result.erase(Result.begin(), Result.begin()+Offset);
+
+ // Take off the null terminator, and any string fragments after it.
+ if (Chop) {
+ std::string::size_type NullPos = Result.find_first_of((char)0);
+ if (NullPos != std::string::npos)
+ Result.erase(Result.begin()+NullPos, Result.end());
+ }
+ return Result;
+ }
+ }
+ }
+ } else if (Constant *C = dyn_cast<Constant>(this)) {
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
+ return GV->getStringValue(Chop, Offset);
+ else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ // Turn a gep into the specified offset.
+ if (CE->getNumOperands() == 3 &&
+ cast<Constant>(CE->getOperand(1))->isNullValue() &&
+ isa<ConstantInt>(CE->getOperand(2))) {
+ Offset += cast<ConstantInt>(CE->getOperand(2))->getRawValue();
+ return CE->getOperand(0)->getStringValue(Chop, Offset);
+ }
+ }
+ }
+ }
+ return "";
+}
+