From 74b26388a62a644b8d33bcedc60d013115449c98 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 8 Jul 2025 22:08:40 +0200 Subject: [PATCH] -Yprofile-trace profiles all inline calls (#23490) Previously we only profiled macro expansion, but even non-macro inline calls can have a significant impact on performance (e.g. if we're doing typeclass derivation) and are worth tracking. This does not seem to significantly impact the size of traces in practice. [Cherry-picked 8a14de3ce985cba4b864f1a3623c6bb82dfe5a6d] --- .../src/dotty/tools/dotc/inlines/Inliner.scala | 3 +-- .../src/dotty/tools/dotc/inlines/Inlines.scala | 2 +- .../src/dotty/tools/dotc/profile/Profiler.scala | 16 ++++++++-------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala index 5410866c1dd4..d5b10f853784 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inliner.scala @@ -1100,8 +1100,7 @@ class Inliner(val call: tpd.Tree)(using Context): val evaluatedSplice = inContext(quoted.MacroExpansion.context(inlinedFrom)): - ctx.profiler.onMacroSplice(inlinedFrom.symbol): - Splicer.splice(body, splicePos, inlinedFrom.srcPos, MacroClassLoader.fromContext) + Splicer.splice(body, splicePos, inlinedFrom.srcPos, MacroClassLoader.fromContext) val inlinedNormalizer = new TreeMap { override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match { case tree @ Inlined(_, Nil, expr) if tree.inlinedFromOuterScope && enclosingInlineds.isEmpty => transform(expr) diff --git a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala index e84fe174a6d0..f535a7925451 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala @@ -101,7 +101,7 @@ object Inlines: * @return An `Inlined` node that refers to the original call and the inlined bindings * and body that replace it. */ - def inlineCall(tree: Tree)(using Context): Tree = + def inlineCall(tree: Tree)(using Context): Tree = ctx.profiler.onInlineCall(tree.symbol): if tree.symbol.denot != SymDenotations.NoDenotation && tree.symbol.effectiveOwner == defn.CompiletimeTestingPackage.moduleClass then diff --git a/compiler/src/dotty/tools/dotc/profile/Profiler.scala b/compiler/src/dotty/tools/dotc/profile/Profiler.scala index ab3e73468385..8b1192871cff 100644 --- a/compiler/src/dotty/tools/dotc/profile/Profiler.scala +++ b/compiler/src/dotty/tools/dotc/profile/Profiler.scala @@ -117,12 +117,12 @@ sealed trait Profiler { protected def beforeImplicitSearch(pt: Type): TracedEventId = TracedEventId.Empty protected def afterImplicitSearch(event: TracedEventId): Unit = () - inline def onMacroSplice[T](macroSym: Symbol)(inline body: T): T = - val event = beforeMacroSplice(macroSym) + inline def onInlineCall[T](inlineSym: Symbol)(inline body: T): T = + val event = beforeInlineCall(inlineSym) try body - finally afterMacroSplice(event) - protected def beforeMacroSplice(macroSym: Symbol): TracedEventId = TracedEventId.Empty - protected def afterMacroSplice(event: TracedEventId): Unit = () + finally afterInlineCall(event) + protected def beforeInlineCall(inlineSym: Symbol): TracedEventId = TracedEventId.Empty + protected def afterInlineCall(event: TracedEventId): Unit = () inline def onCompletion[T](root: Symbol, associatedFile: => AbstractFile)(inline body: T): T = val (event, completionName) = beforeCompletion(root, associatedFile) @@ -178,7 +178,7 @@ private [profile] class RealProfiler(reporter : ProfileReporter)(using Context) enum Category: def name: String = this.toString().toLowerCase() - case Run, Phase, File, TypeCheck, Implicit, Macro, Completion + case Run, Phase, File, TypeCheck, Implicit, Inline, Completion private [profile] val chromeTrace = if ctx.settings.YprofileTrace.isDefault then null @@ -317,8 +317,8 @@ private [profile] class RealProfiler(reporter : ProfileReporter)(using Context) override def beforeImplicitSearch(pt: Type): TracedEventId = traceDurationStart(Category.Implicit, s"?[${symbolName(pt.typeSymbol)}]", colour = "yellow") override def afterImplicitSearch(event: TracedEventId): Unit = traceDurationEnd(Category.Implicit, event, colour = "yellow") - override def beforeMacroSplice(macroSym: Symbol): TracedEventId = traceDurationStart(Category.Macro, s"«${symbolName(macroSym)}»", colour = "olive") - override def afterMacroSplice(event: TracedEventId): Unit = traceDurationEnd(Category.Macro, event, colour = "olive") + override def beforeInlineCall(inlineSym: Symbol): TracedEventId = traceDurationStart(Category.Inline, s"«${symbolName(inlineSym)}»", colour = "olive") + override def afterInlineCall(event: TracedEventId): Unit = traceDurationEnd(Category.Inline, event, colour = "olive") override def beforeCompletion(root: Symbol, associatedFile: => AbstractFile): (TracedEventId, String) = if chromeTrace == null