Skip to content

Commit c3fb485

Browse files
committed
[sil-combine] Refactor rewriteApplyCallee -> cloneFullApplySiteReplacingCallee and move into InstOptUtils.h.
I am going to use this in mandatory combine, and it seems like a generally useful transformation. I also updated the routine to construct its own SILBuilder that injects a user passed in SILBuilderContext eliminating the bad pattern of passing in SILBuilders. This should be an NFC change.
1 parent 102bc6a commit c3fb485

File tree

4 files changed

+54
-33
lines changed

4 files changed

+54
-33
lines changed

include/swift/SILOptimizer/Utils/InstOptUtils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,15 @@ bool tryOptimizeApplyOfPartialApply(
578578
PartialApplyInst *pai, SILBuilderContext &builderCtxt,
579579
InstModCallbacks callbacks = InstModCallbacks());
580580

581+
/// Clone this full apply site, replacing the callee with \p newCallee while
582+
/// doing so.
583+
///
584+
/// The current full apply site is used as an insertion point, so the caller
585+
/// must clean up this full apply site.
586+
FullApplySite cloneFullApplySiteReplacingCallee(FullApplySite applySite,
587+
SILValue newCallee,
588+
SILBuilderContext &builderCtx);
589+
581590
} // end namespace swift
582591

583592
#endif

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,6 @@ class SILCombiner :
260260
});
261261
}
262262

263-
FullApplySite rewriteApplyCallee(FullApplySite apply, SILValue callee);
264-
265263
// Build concrete existential information using findInitExistential.
266264
Optional<ConcreteOpenedExistentialInfo>
267265
buildConcreteOpenedExistentialInfo(Operand &ArgOperand);

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,35 +1209,6 @@ bool SILCombiner::optimizeIdentityCastComposition(ApplyInst *FInverse,
12091209
return true;
12101210
}
12111211

1212-
// Return a new apply with the specified callee. This creates a new apply rather
1213-
// than simply rewriting the callee operand because the apply's SubstCalleeType,
1214-
// derived from the callee and substitution list, may change.
1215-
FullApplySite SILCombiner::rewriteApplyCallee(FullApplySite apply,
1216-
SILValue callee) {
1217-
SmallVector<SILValue, 4> arguments;
1218-
for (SILValue arg : apply.getArguments())
1219-
arguments.push_back(arg);
1220-
1221-
Builder.addOpenedArchetypeOperands(apply.getInstruction());
1222-
if (auto *TAI = dyn_cast<TryApplyInst>(apply)) {
1223-
return Builder.createTryApply(TAI->getLoc(), callee,
1224-
TAI->getSubstitutionMap(), arguments,
1225-
TAI->getNormalBB(), TAI->getErrorBB());
1226-
} else {
1227-
auto *AI = cast<ApplyInst>(apply);
1228-
auto fTy = callee->getType().getAs<SILFunctionType>();
1229-
// The optimizer can generate a thin_to_thick_function from a throwing thin
1230-
// to a non-throwing thick function (in case it can prove that the function
1231-
// is not throwing).
1232-
// Therefore we have to check if the new callee (= the argument of the
1233-
// thin_to_thick_function) is a throwing function and set the not-throwing
1234-
// flag in this case.
1235-
return Builder.createApply(apply.getLoc(), callee,
1236-
apply.getSubstitutionMap(), arguments,
1237-
AI->isNonThrowing() || fTy->hasErrorResult());
1238-
}
1239-
}
1240-
12411212
SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
12421213
if (AI->getFunction()->hasOwnership())
12431214
return nullptr;
@@ -1289,7 +1260,9 @@ SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
12891260
// function when rewriting the callsite. This should be ok because the
12901261
// ABI normally expects a guaranteed callee.
12911262
if (!AI->getOrigCalleeType()->isCalleeConsumed())
1292-
return rewriteApplyCallee(AI, TTTFI->getOperand()).getInstruction();
1263+
return cloneFullApplySiteReplacingCallee(AI, TTTFI->getOperand(),
1264+
Builder.getBuilderContext())
1265+
.getInstruction();
12931266
}
12941267

12951268
// (apply (witness_method)) -> propagate information about
@@ -1424,7 +1397,9 @@ SILInstruction *SILCombiner::visitTryApplyInst(TryApplyInst *AI) {
14241397
// function when rewriting the callsite. This should be ok because the
14251398
// ABI normally expects a guaranteed callee.
14261399
if (!AI->getOrigCalleeType()->isCalleeConsumed())
1427-
return rewriteApplyCallee(AI, TTTFI->getOperand()).getInstruction();
1400+
return cloneFullApplySiteReplacingCallee(AI, TTTFI->getOperand(),
1401+
Builder.getBuilderContext())
1402+
.getInstruction();
14281403
}
14291404

14301405
// (apply (witness_method)) -> propagate information about

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "swift/AST/GenericSignature.h"
1515
#include "swift/AST/SemanticAttrs.h"
1616
#include "swift/AST/SubstitutionMap.h"
17+
#include "swift/SIL/ApplySite.h"
1718
#include "swift/SIL/BasicBlockUtils.h"
1819
#include "swift/SIL/DebugUtils.h"
1920
#include "swift/SIL/DynamicCasts.h"
@@ -2012,3 +2013,41 @@ AbstractFunctionDecl *swift::getBaseMethod(AbstractFunctionDecl *FD) {
20122013
}
20132014
return FD;
20142015
}
2016+
2017+
FullApplySite
2018+
swift::cloneFullApplySiteReplacingCallee(FullApplySite applySite,
2019+
SILValue newCallee,
2020+
SILBuilderContext &builderCtx) {
2021+
SmallVector<SILValue, 16> arguments;
2022+
llvm::copy(applySite.getArguments(), std::back_inserter(arguments));
2023+
2024+
SILBuilderWithScope builder(applySite.getInstruction(), builderCtx);
2025+
builder.addOpenedArchetypeOperands(applySite.getInstruction());
2026+
2027+
switch (applySite.getKind()) {
2028+
case FullApplySiteKind::TryApplyInst: {
2029+
auto *tai = cast<TryApplyInst>(applySite.getInstruction());
2030+
return builder.createTryApply(tai->getLoc(), newCallee,
2031+
tai->getSubstitutionMap(), arguments,
2032+
tai->getNormalBB(), tai->getErrorBB());
2033+
}
2034+
case FullApplySiteKind::ApplyInst: {
2035+
auto *ai = cast<ApplyInst>(applySite);
2036+
auto fTy = newCallee->getType().getAs<SILFunctionType>();
2037+
2038+
// The optimizer can generate a thin_to_thick_function from a throwing thin
2039+
// to a non-throwing thick function (in case it can prove that the function
2040+
// is not throwing).
2041+
// Therefore we have to check if the new callee (= the argument of the
2042+
// thin_to_thick_function) is a throwing function and set the not-throwing
2043+
// flag in this case.
2044+
return builder.createApply(applySite.getLoc(), newCallee,
2045+
applySite.getSubstitutionMap(), arguments,
2046+
ai->isNonThrowing() || fTy->hasErrorResult());
2047+
}
2048+
case FullApplySiteKind::BeginApplyInst: {
2049+
llvm_unreachable("begin_apply support not implemented?!");
2050+
}
2051+
}
2052+
llvm_unreachable("Unhandled case?!");
2053+
}

0 commit comments

Comments
 (0)