Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions compiler/src/dotty/tools/dotc/transform/init/Cache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,41 +85,46 @@ class Cache[Config, Res]:
*
* The algorithmic skeleton is as follows:
*
* if don't cache result then
* return eval(expr)
* if this.current.contains(config, expr) then
* return cached value
* else
* val assumed = this.last(config, expr) or bottom value if absent
* this.current(config, expr) = assumed
* val actual = eval(exp)
* val actual = eval(expr)
*
* if assumed != actual then
* this.changed = true
* this.current(config, expr) = actual
*
*/
def cachedEval(config: Config, expr: Tree, cacheResult: Boolean, default: Res)(eval: Tree => Res): Res =
this.get(config, expr) match
case Some(value) => value
case None =>
val assumeValue: Res =
this.last.get(config, expr) match
case Some(value) => value
case None =>
this.last = this.last.updatedNested(config, expr, default)
default

this.current = this.current.updatedNested(config, expr, assumeValue)

val actual = eval(expr)
if actual != assumeValue then
// println("Changed! from = " + assumeValue + ", to = " + actual)
this.changed = true
// TODO: respect cacheResult to reduce cache size
this.current = this.current.updatedNested(config, expr, actual)
// this.current = this.current.removed(config, expr)
end if

actual
if !cacheResult then
eval(expr)
else
this.get(config, expr) match
case Some(value) => value
case None =>
val assumeValue: Res =
this.last.get(config, expr) match
case Some(value) => value
case None =>
this.last = this.last.updatedNested(config, expr, default)
default

this.current = this.current.updatedNested(config, expr, assumeValue)

val actual = eval(expr)
if actual != assumeValue then
// println("Changed! from = " + assumeValue + ", to = " + actual)
this.changed = true
this.current = this.current.updatedNested(config, expr, actual)
// this.current = this.current.removed(config, expr)
end if

actual
end if
end cachedEval

def hasChanged = changed
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/init/Semantic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ object Semantic:

case Cold => Cold

case ref: Ref => eval(vdef.rhs, ref, enclosingClass)
case ref: Ref => eval(vdef.rhs, ref, enclosingClass, cacheResult = true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add test cases that motivated the two changes in Semantic.scala.


case _ =>
report.error("[Internal error] unexpected this value when accessing local variable, sym = " + sym.show + ", thisValue = " + thisValue2.show + Trace.show, Trace.position)
Expand Down Expand Up @@ -989,7 +989,7 @@ object Semantic:
val errors = Reporter.stopEarly {
val res = {
given Trace = Trace.empty
eval(body, thisV, klass)
eval(body, thisV, klass, cacheResult = true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, it seems we miss a test for this one.

}
given Trace = Trace.empty.add(body)
res.promote("The function return value is not hot. Found = " + res.show + ".")
Expand Down
4 changes: 2 additions & 2 deletions tests/init/neg/apply2.scala
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ object O:
println(n)

class B:
val a = A(this)
val a = A(this) // error

val b = new B
val n = 10 // error
val n = 10
end O