@@ -94,6 +94,10 @@ class PerformanceDiagnostics {
9494 return visitFunction (function, perfConstr, /* parentLoc*/ nullptr );
9595 }
9696
97+ bool visitFunctionEmbeddedSwift (SILFunction *function) {
98+ return visitFunctionEmbeddedSwift (function, /* parentLoc*/ nullptr );
99+ }
100+
97101 // / Check functions _without_ performance annotations.
98102 // /
99103 // / This is need to check closure arguments of called performance-annotated
@@ -104,6 +108,9 @@ class PerformanceDiagnostics {
104108 bool visitFunction (SILFunction *function, PerformanceConstraints perfConstr,
105109 LocWithParent *parentLoc);
106110
111+ bool visitFunctionEmbeddedSwift (SILFunction *function,
112+ LocWithParent *parentLoc);
113+
107114 bool visitInst (SILInstruction *inst, PerformanceConstraints perfConstr,
108115 LocWithParent *parentLoc);
109116
@@ -150,6 +157,75 @@ static bool isEffectFreeArraySemanticCall(SILInstruction *inst) {
150157 }
151158}
152159
160+ // / Prints Embedded Swift specific performance diagnostics (no existentials,
161+ // / no metatypes, optionally no allocations) for \p function.
162+ bool PerformanceDiagnostics::visitFunctionEmbeddedSwift (
163+ SILFunction *function, LocWithParent *parentLoc) {
164+ // Don't check generic functions in embedded Swift, they're about to be
165+ // removed anyway.
166+ if (function->getLoweredFunctionType ()->getSubstGenericSignature ())
167+ return false ;
168+
169+ if (!function->isDefinition ())
170+ return false ;
171+
172+ if (visitedFuncs.contains (function))
173+ return false ;
174+ visitedFuncs[function] = PerformanceConstraints::None;
175+
176+ NonErrorHandlingBlocks neBlocks (function);
177+
178+ for (SILBasicBlock &block : *function) {
179+ for (SILInstruction &inst : block) {
180+ if (visitInst (&inst, PerformanceConstraints::None, parentLoc)) {
181+ if (inst.getLoc ().getSourceLoc ().isInvalid ()) {
182+ auto demangledName = Demangle::demangleSymbolAsString (
183+ inst.getFunction ()->getName (),
184+ Demangle::DemangleOptions::SimplifiedUIDemangleOptions ());
185+ llvm::errs () << " in function " << demangledName << " \n " ;
186+ }
187+ LLVM_DEBUG (llvm::dbgs () << inst << *inst.getFunction ());
188+ return true ;
189+ }
190+
191+ if (auto as = FullApplySite::isa (&inst)) {
192+ LocWithParent asLoc (inst.getLoc ().getSourceLoc (), parentLoc);
193+ LocWithParent *loc = &asLoc;
194+ if (parentLoc &&
195+ asLoc.loc == inst.getFunction ()->getLocation ().getSourceLoc ())
196+ loc = parentLoc;
197+
198+ for (SILFunction *callee : bca->getCalleeList (as)) {
199+ if (visitFunctionEmbeddedSwift (callee, loc))
200+ return true ;
201+ }
202+ } else if (auto *bi = dyn_cast<BuiltinInst>(&inst)) {
203+ PrettyStackTracePerformanceDiagnostics stackTrace (
204+ " visitFunction::BuiltinInst (once, once with context)" , &inst);
205+
206+ switch (bi->getBuiltinInfo ().ID ) {
207+ case BuiltinValueKind::Once:
208+ case BuiltinValueKind::OnceWithContext:
209+ if (auto *fri = dyn_cast<FunctionRefInst>(bi->getArguments ()[1 ])) {
210+ LocWithParent asLoc (bi->getLoc ().getSourceLoc (), parentLoc);
211+ LocWithParent *loc = &asLoc;
212+ if (parentLoc &&
213+ asLoc.loc == bi->getFunction ()->getLocation ().getSourceLoc ())
214+ loc = parentLoc;
215+
216+ if (visitFunctionEmbeddedSwift (fri->getReferencedFunction (), loc))
217+ return true ;
218+ }
219+ break ;
220+ default :
221+ break ;
222+ }
223+ }
224+ }
225+ }
226+ return false ;
227+ }
228+
153229// / Prints performance diagnostics for \p function.
154230bool PerformanceDiagnostics::visitFunction (SILFunction *function,
155231 PerformanceConstraints perfConstr,
@@ -438,6 +514,18 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
438514 return true ;
439515 }
440516 }
517+
518+ if (module .getOptions ().NoAllocations ) {
519+ if (impact & RuntimeEffect::Allocating) {
520+ PrettyStackTracePerformanceDiagnostics stackTrace (" allocation" , inst);
521+ if (impactType) {
522+ diagnose (loc, diag::embedded_swift_allocating_type, impactType.getASTType ());
523+ } else {
524+ diagnose (loc, diag::embedded_swift_allocating);
525+ }
526+ return true ;
527+ }
528+ }
441529 }
442530
443531 if (perfConstr == PerformanceConstraints::None ||
@@ -585,19 +673,6 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
585673void PerformanceDiagnostics::checkNonAnnotatedFunction (SILFunction *function) {
586674 for (SILBasicBlock &block : *function) {
587675 for (SILInstruction &inst : block) {
588- if (function->getModule ().getOptions ().EmbeddedSwift ) {
589- auto loc = LocWithParent (inst.getLoc ().getSourceLoc (), nullptr );
590- if (visitInst (&inst, PerformanceConstraints::None, &loc)) {
591- if (inst.getLoc ().getSourceLoc ().isInvalid ()) {
592- auto demangledName = Demangle::demangleSymbolAsString (
593- inst.getFunction ()->getName (),
594- Demangle::DemangleOptions::SimplifiedUIDemangleOptions ());
595- llvm::errs () << " in function " << demangledName << " \n " ;
596- }
597- LLVM_DEBUG (llvm::dbgs () << inst << *inst.getFunction ());
598- }
599- }
600-
601676 auto as = FullApplySite::isa (&inst);
602677 if (!as)
603678 continue ;
@@ -701,16 +776,25 @@ class PerformanceDiagnosticsPass : public SILModuleTransform {
701776 if (function.wasDeserializedCanonical ())
702777 continue ;
703778
704- // Don't check generic functions in embedded Swift, they're about to be
705- // removed anyway.
706- if (getModule ()->getOptions ().EmbeddedSwift &&
707- function.getLoweredFunctionType ()->getSubstGenericSignature ())
708- continue ;
709-
710779 if (function.getPerfConstraints () == PerformanceConstraints::None) {
711780 diagnoser.checkNonAnnotatedFunction (&function);
712781 }
713782 }
783+
784+ if (getModule ()->getOptions ().EmbeddedSwift ) {
785+ for (SILFunction &function : *module ) {
786+ // Don't check constructors and destructors directly, they will be
787+ // checked if called from other functions, with better source loc info.
788+ auto func = function.getLocation ().getAsASTNode <AbstractFunctionDecl>();
789+ if (func) {
790+ if (isa<DestructorDecl>(func) || isa<ConstructorDecl>(func)) {
791+ continue ;
792+ }
793+ }
794+
795+ diagnoser.visitFunctionEmbeddedSwift (&function);
796+ }
797+ }
714798 }
715799};
716800
0 commit comments