Skip to content

Commit 8595d95

Browse files
committed
Add optimization to reduce extra iterations of the safe init checker.
1 parent 3e21f03 commit 8595d95

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

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

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

78+
protected var cacheUsed: Boolean = false
79+
7880
/** Used to avoid allocation, its state does not matter */
7981
protected given MutableTreeWrapper = new MutableTreeWrapper
8082

@@ -99,7 +101,9 @@ class Cache[Config, Res]:
99101
*/
100102
def cachedEval(config: Config, expr: Tree, cacheResult: Boolean, default: Res)(eval: Tree => Res): Res =
101103
this.get(config, expr) match
102-
case Some(value) => value
104+
case Some(value) =>
105+
cacheUsed = true
106+
value
103107
case None =>
104108
val assumeValue: Res =
105109
this.last.get(config, expr) match
@@ -124,6 +128,8 @@ class Cache[Config, Res]:
124128

125129
def hasChanged = changed
126130

131+
def isUsed = cacheUsed
132+
127133
/** Prepare cache for the next iteration
128134
*
129135
* 1. Reset changed flag.
@@ -132,6 +138,7 @@ class Cache[Config, Res]:
132138
*/
133139
def prepareForNextIteration()(using Context) =
134140
this.changed = false
141+
this.cacheUsed = false
135142
this.last = this.current
136143
this.current = Map.empty
137144
end Cache

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,12 +1101,15 @@ object Semantic:
11011101
*
11021102
* The class to be checked must be an instantiable concrete class.
11031103
*/
1104-
private def checkClass(classSym: ClassSymbol)(using Cache.Data, Context): Unit =
1104+
private def checkClass(classSym: ClassSymbol)(using Cache.Data, Context): Int =
11051105
val thisRef = ThisRef(classSym)
11061106
val tpl = classSym.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
11071107

1108+
var accum = 0
1109+
11081110
@tailrec
11091111
def iterate(): Unit = {
1112+
accum += 1
11101113
given Promoted = Promoted.empty(classSym)
11111114
given Trace = Trace.empty.add(classSym.defTree)
11121115
given reporter: Reporter.BufferedReporter = new Reporter.BufferedReporter
@@ -1120,7 +1123,7 @@ object Semantic:
11201123
log("checking " + classSym) { eval(tpl, thisRef, classSym) }
11211124
reporter.errors.foreach(_.issue)
11221125

1123-
if cache.hasChanged && reporter.errors.isEmpty then
1126+
if cache.hasChanged && reporter.errors.isEmpty && cache.isUsed then
11241127
// code to prepare cache and heap for next iteration
11251128
cache.prepareForNextIteration()
11261129
iterate()
@@ -1129,15 +1132,19 @@ object Semantic:
11291132
}
11301133

11311134
iterate()
1135+
1136+
accum - 1
11321137
end checkClass
11331138

11341139
/**
11351140
* Check the specified concrete classes
11361141
*/
11371142
def checkClasses(classes: List[ClassSymbol])(using Context): Unit =
1143+
var total = 0
11381144
given Cache.Data()
11391145
for classSym <- classes if isConcreteClass(classSym) do
1140-
checkClass(classSym)
1146+
total += checkClass(classSym)
1147+
System.err.nn.println(total)
11411148

11421149
// ----- Semantic definition --------------------------------
11431150
type ArgInfo = TraceValue[Value]

0 commit comments

Comments
 (0)