Skip to content

Commit 585bbef

Browse files
authored
Add optimization to reduce extra iterations of the safe init checker. (#17057)
If the cache is never accessed on a certain iteration of safe initializing checking for a class, then another iteration is not needed. Implementing this optimization and compiling Dotty, we observe the following improvements: From 4158 total iterations to 4004. From 460 extra iterations to 306. Running the initialization tests in `tests/init` we have the following improvements: From 790 total iterations to 708. From 139 extra iterations to 57.
2 parents 20dd9a0 + 7347e03 commit 585bbef

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

compiler/src/dotty/tools/dotc/transform/init/Cache.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,19 @@ class Cache[Config, Res]:
7575
*/
7676
protected var changed: Boolean = false
7777

78+
/** Whether any value in the output cache (this.current) was accessed
79+
* after being added. If no cached values are used after they are added
80+
* for the first time then another iteration of analysis is not needed.
81+
*/
82+
protected var cacheUsed: Boolean = false
83+
7884
/** Used to avoid allocation, its state does not matter */
7985
protected given MutableTreeWrapper = new MutableTreeWrapper
8086

8187
def get(config: Config, expr: Tree): Option[Res] =
82-
current.get(config, expr)
88+
val res = current.get(config, expr)
89+
cacheUsed = cacheUsed || res.nonEmpty
90+
res
8391

8492
/** Evaluate an expression with cache
8593
*
@@ -124,6 +132,8 @@ class Cache[Config, Res]:
124132

125133
def hasChanged = changed
126134

135+
def isUsed = cacheUsed
136+
127137
/** Prepare cache for the next iteration
128138
*
129139
* 1. Reset changed flag.
@@ -132,6 +142,7 @@ class Cache[Config, Res]:
132142
*/
133143
def prepareForNextIteration()(using Context) =
134144
this.changed = false
145+
this.cacheUsed = false
135146
this.last = this.current
136147
this.current = Map.empty
137148
end Cache

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ object Semantic:
11201120
log("checking " + classSym) { eval(tpl, thisRef, classSym) }
11211121
reporter.errors.foreach(_.issue)
11221122

1123-
if cache.hasChanged && reporter.errors.isEmpty then
1123+
if cache.hasChanged && reporter.errors.isEmpty && cache.isUsed then
11241124
// code to prepare cache and heap for next iteration
11251125
cache.prepareForNextIteration()
11261126
iterate()

0 commit comments

Comments
 (0)