Skip to content

Commit 7815b6a

Browse files
authored
Merge pull request #9597 from dotty-staging/optimize-megaphase
Optimize megaphase
2 parents b526579 + dd9dbf4 commit 7815b6a

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,37 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
10831083
}
10841084
}
10851085

1086+
inline val MapRecursionLimit = 10
1087+
1088+
extension (trees: List[Tree])
1089+
1090+
/** A map that expands to a recursive function. It's equivalent to
1091+
*
1092+
* flatten(trees.mapConserve(op))
1093+
*
1094+
* and falls back to it after `MaxRecursionLimit` recursions.
1095+
* Before that it uses a simpler method that uses stackspace
1096+
* instead of heap.
1097+
* Note `op` is duplicated in the generated code, so it should be
1098+
* kept small.
1099+
*/
1100+
inline def mapInline(inline op: Tree => Tree): List[Tree] =
1101+
def recur(trees: List[Tree], count: Int): List[Tree] =
1102+
if count > MapRecursionLimit then
1103+
// use a slower implementation that avoids stack overflows
1104+
flatten(trees.mapConserve(op))
1105+
else trees match
1106+
case tree :: rest =>
1107+
val tree1 = op(tree)
1108+
val rest1 = recur(rest, count + 1)
1109+
if (tree1 eq tree) && (rest1 eq rest) then trees
1110+
else tree1 match
1111+
case Thicket(elems1) => elems1 ::: rest1
1112+
case _ => tree1 :: rest1
1113+
case nil => nil
1114+
recur(trees, 0)
1115+
end extension
1116+
10861117
/** Map Inlined nodes, NamedArgs, Blocks with no statements and local references to underlying arguments.
10871118
* Also drops Inline and Block with no statements.
10881119
*/

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
438438
case _ => transformTree(stat, start)(using ctx.exprContext(stat, exprOwner))
439439
}
440440
val nestedCtx = prepStats(trees, start)
441-
val trees1 = flatten(trees.mapConserve(transformStat(_)(using nestedCtx)))
441+
val trees1 = trees.mapInline(transformStat(_)(using nestedCtx))
442442
goStats(trees1, start)(using nestedCtx)
443443
}
444444

@@ -449,7 +449,7 @@ class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
449449
}
450450

451451
def transformTrees(trees: List[Tree], start: Int)(using Context): List[Tree] =
452-
flatten(trees.mapConserve(transformTree(_, start)))
452+
trees.mapInline(transformTree(_, start))
453453

454454
def transformSpecificTrees[T <: Tree](trees: List[T], start: Int)(using Context): List[T] =
455455
transformTrees(trees, start).asInstanceOf[List[T]]

0 commit comments

Comments
 (0)