Skip to content

Commit 7c28d7a

Browse files
committed
migrate SILInliner to use InstructionDeleter
1 parent 49351c4 commit 7c28d7a

File tree

5 files changed

+55
-77
lines changed

5 files changed

+55
-77
lines changed

include/swift/SILOptimizer/Utils/SILInliner.h

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
namespace swift {
2727

2828
class SILOptFunctionBuilder;
29+
class InstructionDeleter;
2930

3031
// For now Free is 0 and Expensive is 1. This can be changed in the future by
3132
// adding more categories.
@@ -46,15 +47,16 @@ class SILInliner {
4647

4748
private:
4849
SILOptFunctionBuilder &FuncBuilder;
50+
InstructionDeleter &deleter;
51+
4952
InlineKind IKind;
5053
SubstitutionMap ApplySubs;
5154

52-
DeletionFuncTy DeletionCallback;
53-
5455
public:
55-
SILInliner(SILOptFunctionBuilder &FuncBuilder, InlineKind IKind,
56-
SubstitutionMap ApplySubs)
57-
: FuncBuilder(FuncBuilder), IKind(IKind), ApplySubs(ApplySubs) {}
56+
SILInliner(SILOptFunctionBuilder &FuncBuilder, InstructionDeleter &deleter,
57+
InlineKind IKind, SubstitutionMap ApplySubs)
58+
: FuncBuilder(FuncBuilder), deleter(deleter), IKind(IKind),
59+
ApplySubs(ApplySubs) {}
5860

5961
/// Returns true if we are able to inline \arg AI.
6062
///
@@ -73,14 +75,6 @@ class SILInliner {
7375
return isa<BeginApplyInst>(apply);
7476
}
7577

76-
/// Allow the client to track instructions before they are deleted. The
77-
/// registered callback is called from
78-
/// recursivelyDeleteTriviallyDeadInstructions.
79-
///
80-
/// (This is safer than the SILModule deletion callback because the
81-
/// instruction is still in a valid form and its operands can be inspected.)
82-
void setDeletionCallback(DeletionFuncTy f) { DeletionCallback = f; }
83-
8478
/// Inline a callee function at the given apply site with the given
8579
/// arguments. Delete the apply and any dead arguments. Return a valid
8680
/// iterator to the first inlined instruction (or first instruction after the
@@ -108,11 +102,9 @@ class SILInliner {
108102
/// *NOTE*: Inlining can result in improperly nested stack allocations, which
109103
/// must be corrected after inlining. See invalidatesStackNesting().
110104
///
111-
/// Returns an iterator to the first inlined instruction (or the end of the
112-
/// caller block for empty functions) and the last block in function order
113-
/// containing inlined instructions (the original caller block for
114-
/// single-block functions).
115-
std::pair<SILBasicBlock::iterator, SILBasicBlock *>
105+
/// Returns the last block in function order containing inlined instructions
106+
/// (the original caller block for single-block functions).
107+
SILBasicBlock *
116108
inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
117109
ArrayRef<SILValue> appliedArgs);
118110

@@ -131,13 +123,12 @@ class SILInliner {
131123
/// *NOTE*: Inlining can result in improperly nested stack allocations, which
132124
/// must be corrected after inlining. See invalidatesStackNesting().
133125
///
134-
/// Returns an iterator to the first inlined instruction (or the end of the
135-
/// caller block for empty functions) and the last block in function order
136-
/// containing inlined instructions (the original caller block for
137-
/// single-block functions).
138-
static std::pair<SILBasicBlock::iterator, SILBasicBlock *>
126+
/// Returns the last block in function order containing inlined instructions
127+
/// (the original caller block for single-block functions).
128+
static SILBasicBlock *
139129
inlineFullApply(FullApplySite apply, SILInliner::InlineKind inlineKind,
140-
SILOptFunctionBuilder &funcBuilder);
130+
SILOptFunctionBuilder &funcBuilder,
131+
InstructionDeleter &deleter);
141132
};
142133

143134
} // end namespace swift

lib/SILOptimizer/Mandatory/MandatoryInlining.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -874,8 +874,18 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder, SILFunction *F,
874874
? PAI->getSubstitutionMap()
875875
: InnerAI.getSubstitutionMap());
876876

877-
SILInliner Inliner(FuncBuilder, SILInliner::InlineKind::MandatoryInline,
878-
Subs);
877+
878+
// Register a callback to record potentially unused function values after
879+
// inlining.
880+
ClosureCleanup closureCleanup;
881+
882+
InstructionDeleter deleter(InstModCallbacks().onNotifyWillBeDeleted(
883+
[&closureCleanup](SILInstruction *I) {
884+
closureCleanup.recordDeadFunction(I);
885+
}));
886+
887+
SILInliner Inliner(FuncBuilder, deleter,
888+
SILInliner::InlineKind::MandatoryInline, Subs);
879889
if (!Inliner.canInlineApplySite(InnerAI))
880890
continue;
881891

@@ -910,23 +920,18 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder, SILFunction *F,
910920
CapturedArgs, IsCalleeGuaranteed);
911921
}
912922

913-
// Register a callback to record potentially unused function values after
914-
// inlining.
915-
ClosureCleanup closureCleanup;
916-
Inliner.setDeletionCallback([&closureCleanup](SILInstruction *I) {
917-
closureCleanup.recordDeadFunction(I);
918-
});
919-
920923
invalidatedStackNesting |= Inliner.invalidatesStackNesting(InnerAI);
921924

922925
// Inlining deletes the apply, and can introduce multiple new basic
923926
// blocks. After this, CalleeValue and other instructions may be invalid.
924927
// nextBB will point to the last inlined block
925-
auto firstInlinedInstAndLastBB =
928+
SILBasicBlock *lastBB =
926929
Inliner.inlineFunction(CalleeFunction, InnerAI, FullArgs);
927-
nextBB = firstInlinedInstAndLastBB.second->getReverseIterator();
930+
nextBB = lastBB->getReverseIterator();
928931
++NumMandatoryInlines;
929932

933+
deleter.cleanupDeadInstructions();
934+
930935
// The IR is now valid, and trivial dead arguments are removed. However,
931936
// we may be able to remove dead callee computations (e.g. dead
932937
// partial_apply closures).

lib/SILOptimizer/Transforms/CSE.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,8 +732,10 @@ bool CSE::processLazyPropertyGetters() {
732732
SILBasicBlock *callBlock = ai->getParent();
733733

734734
// Inline the getter...
735+
InstructionDeleter deleter;
735736
SILInliner::inlineFullApply(ai, SILInliner::InlineKind::PerformanceInline,
736-
FuncBuilder);
737+
FuncBuilder, deleter);
738+
deleter.cleanupDeadInstructions();
737739

738740
// ...and fold the switch_enum in the first block to the Optional.some case.
739741
// The Optional.none branch becomes dead.

lib/SILOptimizer/Transforms/PerformanceInliner.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,8 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller) {
946946
if (AppliesToInline.empty())
947947
return false;
948948

949+
InstructionDeleter deleter;
950+
949951
// Second step: do the actual inlining.
950952
// We inline in reverse order, because for very large blocks with many applies
951953
// to inline, splitting the block at every apply would be quadratic.
@@ -979,9 +981,11 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller) {
979981
// If for whatever reason we can not inline this function, inlineFullApply
980982
// will assert, so we are safe making this assumption.
981983
SILInliner::inlineFullApply(AI, SILInliner::InlineKind::PerformanceInline,
982-
FuncBuilder);
984+
FuncBuilder, deleter);
983985
++NumFunctionsInlined;
984986
}
987+
deleter.cleanupDeadInstructions();
988+
985989
// The inliner splits blocks at call sites. Re-merge trivial branches to
986990
// reestablish a canonical CFG.
987991
mergeBasicBlocks(Caller);

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ class SILInlineCloner
256256
FullApplySite Apply;
257257
Optional<BeginApplySite> BeginApply;
258258

259-
SILInliner::DeletionFuncTy DeletionCallback;
259+
InstructionDeleter &deleter;
260260

261261
/// The location representing the inlined instructions.
262262
///
@@ -272,18 +272,15 @@ class SILInlineCloner
272272
// control path.
273273
SILBasicBlock *ReturnToBB = nullptr;
274274

275-
// Keep track of the next instruction after inlining the call.
276-
SILBasicBlock::iterator NextIter;
277-
278275
public:
279276
SILInlineCloner(SILFunction *CalleeFunction, FullApplySite Apply,
280277
SILOptFunctionBuilder &FuncBuilder, InlineKind IKind,
281278
SubstitutionMap ApplySubs,
282-
SILInliner::DeletionFuncTy deletionCallback);
279+
InstructionDeleter &deleter);
283280

284281
SILFunction *getCalleeFunction() const { return &Original; }
285282

286-
SILBasicBlock::iterator cloneInline(ArrayRef<SILValue> AppliedArgs);
283+
void cloneInline(ArrayRef<SILValue> AppliedArgs);
287284

288285
protected:
289286
SILValue borrowFunctionArgument(SILValue callArg, FullApplySite AI);
@@ -335,7 +332,7 @@ class SILInlineCloner
335332
};
336333
} // namespace swift
337334

338-
std::pair<SILBasicBlock::iterator, SILBasicBlock *>
335+
SILBasicBlock *
339336
SILInliner::inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
340337
ArrayRef<SILValue> appliedArgs) {
341338
PrettyStackTraceSILFunction calleeTraceRAII("inlining", calleeFunction);
@@ -344,15 +341,16 @@ SILInliner::inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
344341
&& "Asked to inline function that is unable to be inlined?!");
345342

346343
SILInlineCloner cloner(calleeFunction, apply, FuncBuilder, IKind, ApplySubs,
347-
DeletionCallback);
348-
auto nextI = cloner.cloneInline(appliedArgs);
349-
return std::make_pair(nextI, cloner.getLastClonedBB());
344+
deleter);
345+
cloner.cloneInline(appliedArgs);
346+
return cloner.getLastClonedBB();
350347
}
351348

352-
std::pair<SILBasicBlock::iterator, SILBasicBlock *>
349+
SILBasicBlock *
353350
SILInliner::inlineFullApply(FullApplySite apply,
354351
SILInliner::InlineKind inlineKind,
355-
SILOptFunctionBuilder &funcBuilder) {
352+
SILOptFunctionBuilder &funcBuilder,
353+
InstructionDeleter &deleter) {
356354
assert(apply.canOptimize());
357355
assert(!apply.getFunction()->hasOwnership() ||
358356
apply.getReferencedFunctionOrNull()->hasOwnership());
@@ -361,7 +359,7 @@ SILInliner::inlineFullApply(FullApplySite apply,
361359
for (const auto arg : apply.getArguments())
362360
appliedArgs.push_back(arg);
363361

364-
SILInliner Inliner(funcBuilder, inlineKind, apply.getSubstitutionMap());
362+
SILInliner Inliner(funcBuilder, deleter, inlineKind, apply.getSubstitutionMap());
365363
return Inliner.inlineFunction(apply.getReferencedFunctionOrNull(), apply,
366364
appliedArgs);
367365
}
@@ -370,11 +368,11 @@ SILInlineCloner::SILInlineCloner(
370368
SILFunction *calleeFunction, FullApplySite apply,
371369
SILOptFunctionBuilder &funcBuilder, InlineKind inlineKind,
372370
SubstitutionMap applySubs,
373-
SILInliner::DeletionFuncTy deletionCallback)
371+
InstructionDeleter &deleter)
374372
: SuperTy(*apply.getFunction(), *calleeFunction, applySubs,
375373
/*DT=*/nullptr, /*Inlining=*/true),
376374
FuncBuilder(funcBuilder), IKind(inlineKind), Apply(apply),
377-
DeletionCallback(deletionCallback) {
375+
deleter(deleter) {
378376

379377
SILFunction &F = getBuilder().getFunction();
380378
assert(apply.getFunction() && apply.getFunction() == &F
@@ -419,10 +417,8 @@ SILInlineCloner::SILInlineCloner(
419417
}
420418

421419
// Clone the entire callee function into the caller function at the apply site.
422-
// Delete the original apply and all dead arguments except the callee. Return an
423-
// iterator the the first instruction after the original apply.
424-
SILBasicBlock::iterator
425-
SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
420+
// Delete the original apply and all dead arguments except the callee.
421+
void SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
426422
assert(getCalleeFunction()->getArguments().size() == AppliedArgs.size()
427423
&& "Unexpected number of callee arguments.");
428424

@@ -506,8 +502,6 @@ SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
506502

507503
// Visit original BBs in depth-first preorder, starting with the
508504
// entry block, cloning all instructions and terminators.
509-
//
510-
// NextIter is initialized during `fixUp`.
511505
cloneFunctionBody(getCalleeFunction(), callerBlock, entryArgs);
512506

513507
// For non-throwing applies, the inlined body now unconditionally branches to
@@ -520,7 +514,6 @@ SILInlineCloner::cloneInline(ArrayRef<SILValue> AppliedArgs) {
520514
//
521515
// Once all calls in a function are inlined, unconditional branches are
522516
// eliminated by mergeBlocks.
523-
return NextIter;
524517
}
525518

526519
void SILInlineCloner::visitTerminator(SILBasicBlock *BB) {
@@ -578,25 +571,8 @@ void SILInlineCloner::preFixUp(SILFunction *calleeFunction) {
578571
}
579572

580573
void SILInlineCloner::postFixUp(SILFunction *calleeFunction) {
581-
NextIter = std::next(Apply.getInstruction()->getIterator());
582-
583-
assert(!Apply.getInstruction()->hasUsesOfAnyResult());
584-
585-
auto callbacks = InstModCallbacks().onDelete([&](SILInstruction *deadInst) {
586-
if (NextIter == deadInst->getIterator())
587-
++NextIter;
588-
deadInst->eraseFromParent();
589-
});
590-
if (DeletionCallback) {
591-
callbacks =
592-
callbacks.onNotifyWillBeDeleted([this](SILInstruction *toDeleteInst) {
593-
DeletionCallback(toDeleteInst);
594-
});
595-
}
596-
InstructionDeleter deleter(callbacks);
597-
callbacks.notifyWillBeDeleted(Apply.getInstruction());
574+
deleter.getCallbacks().notifyWillBeDeleted(Apply.getInstruction());
598575
deleter.forceDelete(Apply.getInstruction());
599-
deleter.cleanupDeadInstructions();
600576
}
601577

602578
SILValue SILInlineCloner::borrowFunctionArgument(SILValue callArg,

0 commit comments

Comments
 (0)