mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-28 08:16:05 +00:00
IR: De-duplicate code for replacing operands in place
This is non-trivial and sits in three places. Move it to ConstantUniqueMap. llvm-svn: 216007
This commit is contained in:
parent
15f8549d05
commit
62fccf853a
@ -2671,8 +2671,6 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
|
||||
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
|
||||
Constant *ToC = cast<Constant>(To);
|
||||
|
||||
LLVMContextImpl *pImpl = getType()->getContext().pImpl;
|
||||
|
||||
SmallVector<Constant*, 8> 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<ArrayType>(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<StructType>(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,
|
||||
|
@ -341,6 +341,8 @@ template <> struct ConstantInfo<ConstantVector> {
|
||||
template <class ConstantClass> struct ConstantAggrKeyType {
|
||||
ArrayRef<Constant *> Operands;
|
||||
ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {}
|
||||
ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *)
|
||||
: Operands(Operands) {}
|
||||
ConstantAggrKeyType(const ConstantClass *C,
|
||||
SmallVectorImpl<Constant *> &Storage) {
|
||||
assert(Storage.empty() && "Expected empty storage");
|
||||
@ -425,6 +427,11 @@ struct ConstantExprKeyType {
|
||||
ArrayRef<unsigned> Indexes = None)
|
||||
: Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
|
||||
SubclassData(SubclassData), Ops(Ops), Indexes(Indexes) {}
|
||||
ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
|
||||
: Opcode(CE->getOpcode()),
|
||||
SubclassOptionalData(CE->getRawSubclassOptionalData()),
|
||||
SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
|
||||
Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
|
||||
ConstantExprKeyType(const ConstantExpr *CE,
|
||||
SmallVectorImpl<Constant *> &Storage)
|
||||
: Opcode(CE->getOpcode()),
|
||||
@ -594,6 +601,31 @@ public:
|
||||
Map.erase(I);
|
||||
}
|
||||
|
||||
ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> 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"); }
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user