Skip to content

Commit 236632f

Browse files
committed
Address review comments
1 parent 3745f73 commit 236632f

File tree

1 file changed

+41
-30
lines changed

1 file changed

+41
-30
lines changed

lib/SILOptimizer/Transforms/AllocBoxToStack.cpp

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ using namespace swift;
3535

3636
STATISTIC(NumStackPromoted, "Number of alloc_box's promoted to the stack");
3737

38+
// MaxLocalApplyRecurDepth limits the recursive analysis depth while
39+
// checking if a box can be promoted to stack. This is currently set to 4, a
40+
// limit assumed to be sufficient to handle typical call chain of local
41+
// functions through which a box can be passed.
3842
static llvm::cl::opt<unsigned> MaxLocalApplyRecurDepth(
3943
"max-local-apply-recur-depth", llvm::cl::init(4),
40-
llvm::cl::desc("Mac recursove depth for analyzing local functions"));
44+
llvm::cl::desc("Max recursive depth for analyzing local functions"));
4145

4246
//===-----------------------------------------------------------------------===//
4347
// SIL Utilities for alloc_box Promotion
@@ -280,7 +284,7 @@ static bool partialApplyEscapes(SILValue V, bool examineApply) {
280284
return false;
281285
}
282286

283-
static SILInstruction *findUnexpectedBoxUse(SILValue Box,
287+
static SILInstruction *findUnexpectedBoxUseInDFSOrder(SILValue Box,
284288
bool inAppliedFunction,
285289
SmallVectorImpl<Operand *> &,
286290
SmallPtrSetImpl<SILFunction *> &,
@@ -299,22 +303,24 @@ static bool checkLocalApplyBody(Operand *O,
299303
if (!F || F->empty())
300304
return false;
301305

306+
// Since this function can be called recursively while analyzing the same box,
307+
// mark the callee as visited, so that we don't end up in a recursive cycle.
302308
auto iter = VisitedCallees.insert(F);
303309
if (!iter.second)
304310
return false;
305311

306312
auto calleeArg = F->getArgument(ApplySite(O->getUser()).getCalleeArgIndex(*O));
307-
auto res =
308-
!findUnexpectedBoxUse(calleeArg,
309-
/* inAppliedFunction = */ true, PromotedOperands,
310-
VisitedCallees, CurrentRecurDepth + 1);
313+
auto res = !findUnexpectedBoxUseInDFSOrder(calleeArg,
314+
/* inAppliedFunction = */ true,
315+
PromotedOperands, VisitedCallees,
316+
CurrentRecurDepth + 1);
311317
return res;
312318
}
313319

314320
// Returns true if a callee is eligible to be cloned and rewritten for
315321
// AllocBoxToStack opt. We don't want to increase code size, so this is
316322
// restricted only for private local functions currently.
317-
static bool isEligibleApply(ApplySite Apply) {
323+
static bool isOptimizableApplySite(ApplySite Apply) {
318324
auto callee = Apply.getReferencedFunctionOrNull();
319325
if (!callee) {
320326
return false;
@@ -332,21 +338,24 @@ static bool isEligibleApply(ApplySite Apply) {
332338
if (callee->getInlineStrategy() == Inline_t::AlwaysInline)
333339
return false;
334340

335-
if (callee->getLinkage() != SILLinkage::Private) {
341+
if (callee->getLinkage() != SILLinkage::Private)
336342
return false;
337-
}
343+
338344
return true;
339345
}
340346

341347
/// Validate that the uses of a pointer to a box do not eliminate it from
342-
/// consideration for promotion to a stack element. Optionally examine the body
343-
/// of an ApplySite to see if there is an unexpected use inside.
344-
/// Return the instruction with the unexpected use if we find one.
348+
/// consideration for promotion to a stack element. Return the instruction with
349+
/// the unexpected use if we find one.
350+
/// If a box has ApplySite users, we recursively examine the callees to check
351+
/// for unexpected use of the box argument. If all the callees through which the
352+
/// box is passed don't have any unexpected uses, `PromotedOperands` will be
353+
/// populated with the box arguments in DFS order.
345354
static SILInstruction *
346-
findUnexpectedBoxUse(SILValue Box, bool inAppliedFunction,
347-
SmallVectorImpl<Operand *> &PromotedOperands,
348-
SmallPtrSetImpl<SILFunction *> &VisitedCallees,
349-
unsigned CurrentRecurDepth = 0) {
355+
findUnexpectedBoxUseInDFSOrder(SILValue Box, bool inAppliedFunction,
356+
SmallVectorImpl<Operand *> &PromotedOperands,
357+
SmallPtrSetImpl<SILFunction *> &VisitedCallees,
358+
unsigned CurrentRecurDepth = 0) {
350359
assert((Box->getType().is<SILBoxType>()
351360
|| Box->getType()
352361
== SILType::getNativeObjectType(Box->getType().getASTContext()))
@@ -396,7 +405,7 @@ findUnexpectedBoxUse(SILValue Box, bool inAppliedFunction,
396405
case ApplySiteKind::ApplyInst:
397406
case ApplySiteKind::BeginApplyInst:
398407
case ApplySiteKind::TryApplyInst:
399-
if (isEligibleApply(Apply) &&
408+
if (isOptimizableApplySite(Apply) &&
400409
checkLocalApplyBody(Op, LocalPromotedOperands, VisitedCallees,
401410
CurrentRecurDepth)) {
402411
LocalPromotedOperands.push_back(Op);
@@ -425,10 +434,10 @@ static bool canPromoteAllocBox(AllocBoxInst *ABI,
425434
SmallPtrSet<SILFunction *, 8> VisitedCallees;
426435
// Scan all of the uses of the address of the box to see if any
427436
// disqualifies the box from being promoted to the stack.
428-
if (auto *User = findUnexpectedBoxUse(ABI,
429-
/* inAppliedFunction = */ false,
430-
PromotedOperands, VisitedCallees,
431-
/* CurrentRecurDepth = */ 0)) {
437+
if (auto *User = findUnexpectedBoxUseInDFSOrder(
438+
ABI,
439+
/* inAppliedFunction = */ false, PromotedOperands, VisitedCallees,
440+
/* CurrentRecurDepth = */ 0)) {
432441
(void)User;
433442
// Otherwise, we have an unexpected use.
434443
LLVM_DEBUG(llvm::dbgs() << "*** Failed to promote alloc_box in @"
@@ -828,8 +837,10 @@ void PromotedParamCloner::visitProjectBoxInst(ProjectBoxInst *Inst) {
828837

829838
// While cloning during specialization, make sure apply instructions do not have
830839
// box arguments that need to be promoted.
831-
// This is an assertion in debug builds only. This should never be true because
832-
// we process apply callees that take promotable boxes in dfs order
840+
// This is an assertion in debug builds only. The reason why this should never
841+
// be true is that we have cloned our callees in DFS order meaning that any of
842+
// our callees that had a promotable box will have already have been promoted
843+
// away by the time this runs.
833844
void PromotedParamCloner::checkNoPromotedBoxInApply(ApplySite Apply) {
834845
#ifndef NDEBUG
835846
for (auto &O : Apply.getArgumentOperands()) {
@@ -857,10 +868,10 @@ void PromotedParamCloner::visitTryApplyInst(TryApplyInst *Inst) {
857868
/// Specialize ApplySite by promoting the parameters indicated by
858869
/// indices. We expect these parameters to be replaced by stack address
859870
/// references.
860-
static SILInstruction *specializeApply(SILOptFunctionBuilder &FuncBuilder,
861-
ApplySite Apply,
862-
ArgIndexList &PromotedCalleeArgIndices,
863-
AllocBoxToStackState &pass) {
871+
static SILInstruction *
872+
specializeApplySite(SILOptFunctionBuilder &FuncBuilder, ApplySite Apply,
873+
ArgIndexList &PromotedCalleeArgIndices,
874+
AllocBoxToStackState &pass) {
864875
auto *FRI = cast<FunctionRefInst>(Apply.getCallee());
865876
assert(FRI && "Expected a direct ApplySite");
866877
auto *F = FRI->getReferencedFunctionOrNull();
@@ -968,7 +979,7 @@ static SILInstruction *specializeApply(SILOptFunctionBuilder &FuncBuilder,
968979
}
969980
}
970981

971-
static void rewriteApplies(AllocBoxToStackState &pass) {
982+
static void rewriteApplySites(AllocBoxToStackState &pass) {
972983
llvm::DenseMap<ApplySite, ArgIndexList> IndexMap;
973984
llvm::SmallVector<ApplySite, 8> AppliesToSpecialize;
974985
ArgIndexList Indices;
@@ -1009,7 +1020,7 @@ static void rewriteApplies(AllocBoxToStackState &pass) {
10091020
// Sort the indices and unique them.
10101021
sortUnique(Indices);
10111022

1012-
auto *Replacement = specializeApply(FuncBuilder, Apply, Indices, pass);
1023+
auto *Replacement = specializeApplySite(FuncBuilder, Apply, Indices, pass);
10131024
assert(Apply.getKind() == ApplySite(Replacement).getKind());
10141025
Apply.getInstruction()->replaceAllUsesPairwiseWith(Replacement);
10151026

@@ -1027,7 +1038,7 @@ static void rewriteApplies(AllocBoxToStackState &pass) {
10271038
static unsigned rewritePromotedBoxes(AllocBoxToStackState &pass) {
10281039
// First we'll rewrite any ApplySite that we can to remove
10291040
// the box container pointer from the operands.
1030-
rewriteApplies(pass);
1041+
rewriteApplySites(pass);
10311042

10321043
unsigned Count = 0;
10331044
auto rend = pass.Promotable.rend();

0 commit comments

Comments
 (0)