diff options
author | Talin <viridia@gmail.com> | 2010-02-18 21:43:45 +0000 |
---|---|---|
committer | Talin <viridia@gmail.com> | 2010-02-18 21:43:45 +0000 |
commit | 196c60a571f9dc1d2d627f37f664e4607ff2cac0 (patch) | |
tree | 557a28b6f82511671232dc79ff578f4623bd8a86 | |
parent | 814f2b2d1927a5397c0e923588527277b9f67d6b (diff) |
replaceUsesOfWithOnConstant implementation for unions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96616 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/VMCore/Constants.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 37f670e419..10f88794f5 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -2113,7 +2113,52 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, void ConstantUnion::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { - assert(false && "Implement replaceUsesOfWithOnConstant for unions"); + assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!"); + Constant *ToC = cast<Constant>(To); + + assert(U == OperandList && "Union constants can only have one use!"); + assert(getNumOperands() == 1 && "Union constants can only have one use!"); + assert(getOperand(0) == From && "ReplaceAllUsesWith broken!"); + + std::pair<LLVMContextImpl::UnionConstantsTy::MapKey, ConstantUnion*> Lookup; + Lookup.first.first = getType(); + Lookup.second = this; + Lookup.first.second = ToC; + + LLVMContext &Context = getType()->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + + Constant *Replacement = 0; + if (ToC->isNullValue()) { + Replacement = ConstantAggregateZero::get(getType()); + } else { + // Check to see if we have this union type already. + bool Exists; + LLVMContextImpl::UnionConstantsTy::MapTy::iterator I = + pImpl->UnionConstants.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 union, inserting it, replaceallusesof'ing the + // old with the new, then deleting the old... just update the current one + // in place! + pImpl->UnionConstants.MoveConstantToNewSlot(this, I); + + // Update to the new value. + setOperand(0, 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 ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To, |