Skip to content

Commit bed34d6

Browse files
committed
[SIL Inlining] Extract out a reusable code snippet in PerformanceInliner
into a utility function in SILInliner.
1 parent d912e33 commit bed34d6

File tree

3 files changed

+55
-21
lines changed

3 files changed

+55
-21
lines changed

include/swift/SILOptimizer/Utils/SILInliner.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,29 @@ class SILInliner {
120120
std::pair<SILBasicBlock::iterator, SILBasicBlock *>
121121
inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
122122
ArrayRef<SILValue> appliedArgs);
123+
124+
/// Inline the function called by the given full apply site. This creates
125+
/// an instance of SILInliner by constructing a substitution map and
126+
/// OpenedArchetypesTracker from the given apply site, and invokes
127+
/// `inlineFunction` method on the SILInliner instance to inline the callee.
128+
/// This requires the full apply site to be a direct call i.e., the apply
129+
/// instruction must have a function ref.
130+
///
131+
/// *NOTE*:This attempts to perform inlining unconditionally and thus asserts
132+
/// if inlining will fail. All users /must/ check that a function is allowed
133+
/// to be inlined using SILInliner::canInlineApplySite before calling this
134+
/// function.
135+
///
136+
/// *NOTE*: Inlining can result in improperly nested stack allocations, which
137+
/// must be corrected after inlining. See needsUpdateStackNesting().
138+
///
139+
/// Returns an iterator to the first inlined instruction (or the end of the
140+
/// caller block for empty functions) and the last block in function order
141+
/// containing inlined instructions (the original caller block for
142+
/// single-block functions).
143+
static std::pair<SILBasicBlock::iterator, SILBasicBlock *>
144+
inlineFullApply(FullApplySite apply, SILInliner::InlineKind inlineKind,
145+
SILOptFunctionBuilder &funcBuilder);
123146
};
124147

125148
} // end namespace swift

lib/SILOptimizer/Transforms/PerformanceInliner.cpp

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -901,33 +901,22 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller) {
901901
continue;
902902
}
903903

904-
SmallVector<SILValue, 8> Args;
905-
for (const auto &Arg : AI.getArguments())
906-
Args.push_back(Arg);
904+
LLVM_DEBUG(dumpCaller(Caller); llvm::dbgs()
905+
<< " inline [" << Callee->size() << "->"
906+
<< Caller->size() << "] "
907+
<< Callee->getName() << "\n");
907908

908-
LLVM_DEBUG(dumpCaller(Caller);
909-
llvm::dbgs() << " inline [" << Callee->size() << "->"
910-
<< Caller->size()
911-
<< "] " << Callee->getName() << "\n");
912-
913-
SILOpenedArchetypesTracker OpenedArchetypesTracker(Caller);
914-
Caller->getModule().registerDeleteNotificationHandler(
915-
&OpenedArchetypesTracker);
916-
// The callee only needs to know about opened archetypes used in
917-
// the substitution list.
918-
OpenedArchetypesTracker.registerUsedOpenedArchetypes(AI.getInstruction());
919-
920-
SILInliner Inliner(FuncBuilder, SILInliner::InlineKind::PerformanceInline,
921-
AI.getSubstitutionMap(), OpenedArchetypesTracker);
922-
923-
needUpdateStackNesting |= Inliner.needsUpdateStackNesting(AI);
909+
// Note that this must happen before inlining as the apply instruction
910+
// will be deleted after inlining.
911+
needUpdateStackNesting |= SILInliner::needsUpdateStackNesting(AI);
924912

925913
// We've already determined we should be able to inline this, so
926914
// unconditionally inline the function.
927915
//
928-
// If for whatever reason we can not inline this function, inlineFunction
916+
// If for whatever reason we can not inline this function, inlineFullApply
929917
// will assert, so we are safe making this assumption.
930-
Inliner.inlineFunction(Callee, AI, Args);
918+
SILInliner::inlineFullApply(AI, SILInliner::InlineKind::PerformanceInline,
919+
FuncBuilder);
931920
NumFunctionsInlined++;
932921
}
933922
// The inliner splits blocks at call sites. Re-merge trivial branches to

lib/SILOptimizer/Utils/SILInliner.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,28 @@ SILInliner::inlineFunction(SILFunction *calleeFunction, FullApplySite apply,
334334
return std::make_pair(nextI, cloner.getLastClonedBB());
335335
}
336336

337+
std::pair<SILBasicBlock::iterator, SILBasicBlock *>
338+
SILInliner::inlineFullApply(FullApplySite apply,
339+
SILInliner::InlineKind inlineKind,
340+
SILOptFunctionBuilder &funcBuilder) {
341+
SmallVector<SILValue, 8> appliedArgs;
342+
for (const auto &arg : apply.getArguments())
343+
appliedArgs.push_back(arg);
344+
345+
SILFunction *caller = apply.getFunction();
346+
SILOpenedArchetypesTracker OpenedArchetypesTracker(caller);
347+
caller->getModule().registerDeleteNotificationHandler(
348+
&OpenedArchetypesTracker);
349+
// The callee only needs to know about opened archetypes used in
350+
// the substitution list.
351+
OpenedArchetypesTracker.registerUsedOpenedArchetypes(apply.getInstruction());
352+
353+
SILInliner Inliner(funcBuilder, inlineKind, apply.getSubstitutionMap(),
354+
OpenedArchetypesTracker);
355+
return Inliner.inlineFunction(apply.getReferencedFunction(), apply,
356+
appliedArgs);
357+
}
358+
337359
SILInlineCloner::SILInlineCloner(
338360
SILFunction *calleeFunction, FullApplySite apply,
339361
SILOptFunctionBuilder &funcBuilder, InlineKind inlineKind,

0 commit comments

Comments
 (0)