Skip to content

Commit 63f6e97

Browse files
committed
Optimize extractors
Only check trees if there is an enclosing boundary
1 parent 861f5da commit 63f6e97

File tree

1 file changed

+35
-22
lines changed

1 file changed

+35
-22
lines changed

compiler/src/dotty/tools/dotc/transform/DropBreaks.scala

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class DropBreaks extends MiniPhase, RecordStackChange:
5050
override def runsAfterGroupsOf: Set[String] = Set(ElimByName.name)
5151
// we want by-name parameters to be converted to closures
5252

53+
/** The number of boundary nodes enclosing the currently analized tree. */
54+
var enclosingBoundaries: Int = 0
55+
5356
private object LabelTry:
5457

5558
object GuardedThrow:
@@ -136,6 +139,7 @@ class DropBreaks extends MiniPhase, RecordStackChange:
136139
/** If `tree` is a BreakBoundary, associate a fresh `LabelUsage` with its label. */
137140
override def prepareForBlock(tree: Block)(using Context): Context = tree match
138141
case BreakBoundary(label, _) =>
142+
enclosingBoundaries += 1
139143
val mapSoFar = ctx.property(LabelUsages).getOrElse(Map.empty)
140144
val goto = newSymbol(ctx.owner, BoundaryName.fresh(), Synthetic | Label, tree.tpe)
141145
ctx.fresh.setProperty(LabelUsages,
@@ -157,17 +161,22 @@ class DropBreaks extends MiniPhase, RecordStackChange:
157161
/** Need to suppress labeled returns if the stack can change between
158162
* source and target of the jump
159163
*/
160-
protected def stackChange(using Context) = shadowLabels
164+
protected def stackChange(using Context) =
165+
if enclosingBoundaries == 0 then ctx else shadowLabels
161166

162167
/** Need to suppress labeled returns if there is an intervening try
163168
*/
164-
override def prepareForTry(tree: Try)(using Context): Context = tree match
165-
case LabelTry(_, _) => ctx
166-
case _ => shadowLabels
167-
168-
override def prepareForApply(tree: Apply)(using Context): Context = tree match
169-
case Break(_, _) => ctx
170-
case _ => stackChange
169+
override def prepareForTry(tree: Try)(using Context): Context =
170+
if enclosingBoundaries == 0 then ctx
171+
else tree match
172+
case LabelTry(_, _) => ctx
173+
case _ => shadowLabels
174+
175+
override def prepareForApply(tree: Apply)(using Context): Context =
176+
if enclosingBoundaries == 0 then ctx
177+
else tree match
178+
case Break(_, _) => ctx
179+
case _ => stackChange
171180

172181
// other stack changing operations are handled in RecordStackChange
173182

@@ -177,6 +186,7 @@ class DropBreaks extends MiniPhase, RecordStackChange:
177186
*/
178187
override def transformBlock(tree: Block)(using Context): Tree = tree match
179188
case BreakBoundary(label, expr) =>
189+
enclosingBoundaries -= 1
180190
val uses = ctx.property(LabelUsages).get(label)
181191
val tree1 =
182192
if uses.otherRefs > 1 then
@@ -200,26 +210,29 @@ class DropBreaks extends MiniPhase, RecordStackChange:
200210
* and the non-local refcount is decreased, since `local` the `Label_this`
201211
* binding containing `local` is dropped.
202212
*/
203-
override def transformApply(tree: Apply)(using Context): Tree = tree match
204-
case Break(lbl, arg) =>
205-
labelUsage(lbl) match
206-
case Some(uses: LabelUsage)
207-
if uses.enclMeth == ctx.owner.enclosingMethod
208-
&& !ctx.property(ShadowedLabels).getOrElse(Set.empty).contains(lbl)
209-
=>
210-
uses.otherRefs -= 1
211-
uses.returnRefs += 1
212-
Return(arg, ref(uses.goto)).withSpan(arg.span)
213-
case _ => tree
214-
case _ => tree
213+
override def transformApply(tree: Apply)(using Context): Tree =
214+
if enclosingBoundaries == 0 then tree
215+
else tree match
216+
case Break(lbl, arg) =>
217+
labelUsage(lbl) match
218+
case Some(uses: LabelUsage)
219+
if uses.enclMeth == ctx.owner.enclosingMethod
220+
&& !ctx.property(ShadowedLabels).getOrElse(Set.empty).contains(lbl)
221+
=>
222+
uses.otherRefs -= 1
223+
uses.returnRefs += 1
224+
Return(arg, ref(uses.goto)).withSpan(arg.span)
225+
case _ => tree
226+
case _ => tree
215227

216228
/** If `tree` refers to an enclosing label, increase its non local recount.
217229
* This increase is corrected in `transformInlined` if the reference turns
218230
* out to be part of a BreakThrow to a local, non-shadowed label.
219231
*/
220232
override def transformIdent(tree: Ident)(using Context): Tree =
221-
for uses <- labelUsage(tree.symbol) do
222-
uses.otherRefs += 1
233+
if enclosingBoundaries != 0 then
234+
for uses <- labelUsage(tree.symbol) do
235+
uses.otherRefs += 1
223236
tree
224237

225238
end DropBreaks

0 commit comments

Comments
 (0)