Skip to content

Commit 484925c

Browse files
author
Raj Barik
committed
Extend SILCombiner code to handle existential self concrete type propagation using ProtocolConformanceAnalysis
1 parent 82cbee5 commit 484925c

File tree

3 files changed

+35
-21
lines changed

3 files changed

+35
-21
lines changed

include/swift/SILOptimizer/Utils/Existential.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,11 @@ struct ConcreteExistentialInfo {
8888

8989
ConcreteExistentialInfo(ConcreteExistentialInfo &) = delete;
9090

91+
/// We do not not need to check for InitExistential not being not null
92+
/// since if that were the case, we would have everything else null too.
9193
bool isValid() const {
92-
return OpenedArchetype && OpenedArchetypeDef && InitExistential
93-
&& ConcreteType && !ExistentialSubs.empty() && ConcreteValue;
94+
return OpenedArchetype && OpenedArchetypeDef && ConcreteType &&
95+
!ExistentialSubs.empty() && ConcreteValue;
9496
}
9597

9698
// Do a conformance lookup on ConcreteType with the given requirement, P. If P

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,13 @@ class SILCombiner :
291291
WitnessMethodInst *WMI);
292292
SILInstruction *propagateConcreteTypeOfInitExistential(FullApplySite Apply);
293293

294+
// Common utility function to replace the WitnessMethodInst using a
295+
// BuilderCtx.
296+
void replaceWitnessMethodInst(FullApplySite Apply, WitnessMethodInst *WMI,
297+
SILBuilderContext &BuilderCtx,
298+
const CanType &ConcreteType,
299+
const ProtocolConformanceRef ConformanceRef);
300+
294301
/// Perform one SILCombine iteration.
295302
bool doOneIteration(SILFunction &F, unsigned Iteration);
296303

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,23 @@ SILCombiner::optimizeConcatenationOfStringLiterals(ApplyInst *AI) {
603603
return tryToConcatenateStrings(AI, Builder);
604604
}
605605

606+
/// This routine replaces the old witness method inst with a new one.
607+
void SILCombiner::replaceWitnessMethodInst(
608+
FullApplySite Apply, WitnessMethodInst *WMI, SILBuilderContext &BuilderCtx,
609+
const CanType &ConcreteType, const ProtocolConformanceRef ConformanceRef) {
610+
SILBuilderWithScope WMIBuilder(WMI, BuilderCtx);
611+
auto *NewWMI = WMIBuilder.createWitnessMethod(
612+
WMI->getLoc(), ConcreteType, ConformanceRef, WMI->getMember(),
613+
WMI->getType());
614+
MutableArrayRef<Operand> Operands = Apply.getInstruction()->getAllOperands();
615+
for (auto &Op : Operands) {
616+
if (Op.get() == WMI)
617+
Op.set(NewWMI);
618+
}
619+
if (WMI->use_empty())
620+
eraseInstFromFunction(*WMI);
621+
}
622+
606623
/// Given an Apply and an argument value produced by InitExistentialAddrInst,
607624
/// return true if the argument can be replaced by a copy of its value.
608625
///
@@ -712,8 +729,10 @@ SILCombiner::createApplyWithConcreteType(FullApplySite Apply,
712729
}
713730
// The apply can only be rewritten in terms of the concrete value if it is
714731
// legal to pass that value as the self argument.
715-
if (CEI.isCopied && !canReplaceCopiedSelf(Apply, CEI.InitExistential, DA))
732+
if (CEI.isCopied && (!CEI.InitExistential ||
733+
!canReplaceCopiedSelf(Apply, CEI.InitExistential, DA))) {
716734
return nullptr;
735+
}
717736

718737
// Create a set of arguments.
719738
SmallVector<SILValue, 8> NewArgs;
@@ -819,24 +838,10 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite Apply,
819838
// are stuck:
820839
// We will re-create the same instruction and re-populate the worklist
821840
// with it.
822-
if (CEI.ConcreteType != WMI->getLookupType()
823-
|| SelfConformance != WMI->getConformance()) {
824-
SILBuilderWithScope WMIBuilder(WMI, BuilderCtx);
825-
// Keep around the dependence on the open instruction unless we've
826-
// actually eliminated the use.
827-
auto *NewWMI = WMIBuilder.createWitnessMethod(
828-
WMI->getLoc(), CEI.ConcreteType, SelfConformance, WMI->getMember(),
829-
WMI->getType());
830-
// Replace only uses of the witness_method in the apply that was analyzed by
831-
// ConcreteExistentialInfo.
832-
MutableArrayRef<Operand> Operands =
833-
Apply.getInstruction()->getAllOperands();
834-
for (auto &Op : Operands) {
835-
if (Op.get() == WMI)
836-
Op.set(NewWMI);
837-
}
838-
if (WMI->use_empty())
839-
eraseInstFromFunction(*WMI);
841+
if (CEI.ConcreteType != WMI->getLookupType() ||
842+
SelfConformance != WMI->getConformance()) {
843+
replaceWitnessMethodInst(Apply, WMI, BuilderCtx, CEI.ConcreteType,
844+
SelfConformance);
840845
}
841846
// Try to rewrite the apply.
842847
return createApplyWithConcreteType(Apply, CEI, BuilderCtx);

0 commit comments

Comments
 (0)