From: Duncan P. N. Exon Smith Date: Tue, 19 Aug 2014 19:13:30 +0000 (+0000) Subject: IR: De-duplicate code for replacing operands in place X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bb69ce8c70f6a392fedc6ec520705f55b2e4fb0f;p=oota-llvm.git IR: De-duplicate code for replacing operands in place This is non-trivial and sits in three places. Move it to ConstantUniqueMap. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216007 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index cb7c9e63059..5732bb78a62 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -2671,8 +2671,6 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); - LLVMContextImpl *pImpl = getType()->getContext().pImpl; - SmallVector Values; Values.reserve(getNumOperands()); // Build replacement array. @@ -2707,36 +2705,10 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, return; } - // Check to see if we have this array type already. - LLVMContextImpl::ArrayConstantsTy::LookupKey Lookup( - cast(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::replaceUsesOfWithOnConstant(Value *From, Value *To, } Values[OperandToUpdate] = ToC; - LLVMContextImpl *pImpl = getContext().pImpl; - if (isAllZeros) { replaceUsesOfWithOnConstantImpl(ConstantAggregateZero::get(getType())); return; @@ -2785,26 +2755,10 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, return; } - // Check to see if we have this struct type already. - LLVMContextImpl::StructConstantsTy::LookupKey Lookup( - cast(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::replaceUsesOfWithOnConstant(Value *From, Value *To, 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, diff --git a/lib/IR/ConstantsContext.h b/lib/IR/ConstantsContext.h index 092de718776..571dec2e0f6 100644 --- a/lib/IR/ConstantsContext.h +++ b/lib/IR/ConstantsContext.h @@ -341,6 +341,8 @@ template <> struct ConstantInfo { template struct ConstantAggrKeyType { ArrayRef Operands; ConstantAggrKeyType(ArrayRef Operands) : Operands(Operands) {} + ConstantAggrKeyType(ArrayRef Operands, const ConstantClass *) + : Operands(Operands) {} ConstantAggrKeyType(const ConstantClass *C, SmallVectorImpl &Storage) { assert(Storage.empty() && "Expected empty storage"); @@ -425,6 +427,11 @@ struct ConstantExprKeyType { ArrayRef Indexes = None) : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData), SubclassData(SubclassData), Ops(Ops), Indexes(Indexes) {} + ConstantExprKeyType(ArrayRef Operands, const ConstantExpr *CE) + : Opcode(CE->getOpcode()), + SubclassOptionalData(CE->getRawSubclassOptionalData()), + SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands), + Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef()) {} ConstantExprKeyType(const ConstantExpr *CE, SmallVectorImpl &Storage) : Opcode(CE->getOpcode()), @@ -594,6 +601,31 @@ public: Map.erase(I); } + ConstantClass *replaceOperandsInPlace(ArrayRef 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"); } };