mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[sil-combine] Fix a couple of oversights in the propagation of concrete types of existentials
- Do not try to make a lookup type of a witness_method more concrete if it not an opened existential. - Replace witness_method instruction by a new one with a more concrete type only in the specific apply instruction instead of doing it everywhere. This allows for more optimization opportunities if the same witness_method is used by multiple apply instructions.
This commit is contained in:
@@ -871,12 +871,17 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Obtain the protocol whose which should be used by the conformance.
|
||||
// The lookup type is not a opened existential type,
|
||||
// thus it cannot be made more concrete.
|
||||
if (!WMI->getLookupType()->isOpenedExistential())
|
||||
return nullptr;
|
||||
|
||||
// Obtain the protocol which should be used by the conformance.
|
||||
auto *PD = WMI->getLookupProtocol();
|
||||
|
||||
// Propagate the concrete type into a callee-operand, which is a
|
||||
// witness_method instruction.
|
||||
auto PropagateIntoOperand = [this, &WMI](CanType ConcreteType,
|
||||
auto PropagateIntoOperand = [this, &WMI, &AI](CanType ConcreteType,
|
||||
ProtocolConformanceRef Conformance) {
|
||||
// Keep around the dependence on the open instruction unless we've
|
||||
// actually eliminated the use.
|
||||
@@ -885,8 +890,15 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI,
|
||||
Conformance, WMI->getMember(),
|
||||
WMI->getType(),
|
||||
WMI->isVolatile());
|
||||
replaceInstUsesWith(*WMI, NewWMI);
|
||||
eraseInstFromFunction(*WMI);
|
||||
// Replace only uses of the witness_method in the apply that is going to
|
||||
// be changed.
|
||||
MutableArrayRef<Operand> Operands = AI.getInstruction()->getAllOperands();
|
||||
for (auto &Op : Operands) {
|
||||
if (Op.get() == WMI)
|
||||
Op.set(NewWMI);
|
||||
}
|
||||
if (WMI->use_empty())
|
||||
eraseInstFromFunction(*WMI);
|
||||
};
|
||||
|
||||
// Try to perform the propagation.
|
||||
|
||||
Reference in New Issue
Block a user