Skip to content

Commit f1940ee

Browse files
authored
Merge pull request #3265 from dotty-staging/try-optimize-8
Optimizations: Make code inlining friendlier
2 parents 4d39ba2 + 745fa3d commit f1940ee

25 files changed

+277
-124
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import typer.FrontEnd
1212
import collection.mutable.ListBuffer
1313
import util.Property
1414
import reporting.diagnostic.messages._
15+
import reporting.trace
1516

1617
object desugar {
1718
import untpd._
@@ -886,7 +887,7 @@ object desugar {
886887
* @param enums The enumerators in the for expression
887888
* @param body The body of the for expression
888889
*/
889-
def makeFor(mapName: TermName, flatMapName: TermName, enums: List[Tree], body: Tree): Tree = ctx.traceIndented(i"make for ${ForYield(enums, body)}", show = true) {
890+
def makeFor(mapName: TermName, flatMapName: TermName, enums: List[Tree], body: Tree): Tree = trace(i"make for ${ForYield(enums, body)}", show = true) {
890891

891892
/** Make a function value pat => body.
892893
* If pat is a var pattern id: T then this gives (id: T) => body

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Flags._, Trees._, Types._, Contexts._
77
import Names._, StdNames._, NameOps._, Decorators._, Symbols._
88
import util.HashSet
99
import typer.ConstFold
10+
import reporting.trace
1011

1112
trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
1213
import TreeInfo._
@@ -578,7 +579,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
578579
* if no such path exists.
579580
* Pre: `sym` must have a position.
580581
*/
581-
def defPath(sym: Symbol, root: Tree)(implicit ctx: Context): List[Tree] = ctx.debugTraceIndented(s"defpath($sym with position ${sym.pos}, ${root.show})") {
582+
def defPath(sym: Symbol, root: Tree)(implicit ctx: Context): List[Tree] = trace.onDebug(s"defpath($sym with position ${sym.pos}, ${root.show})") {
582583
require(sym.pos.exists)
583584
object accum extends TreeAccumulator[List[Tree]] {
584585
def apply(x: List[Tree], tree: Tree)(implicit ctx: Context): List[Tree] = {

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,11 @@ object Config {
144144
*/
145145
final val simplifyApplications = true
146146

147-
/** Initial size of superId table */
148-
final val InitialSuperIdsSize = 4096
147+
/** If set, prints a trace of all symbol completions */
148+
final val showCompletions = false
149+
150+
/** If set, enables tracing */
151+
final val tracingEnabled = false
149152

150153
/** Initial capacity of uniques HashMap.
151154
* Note: This MUST BE a power of two to work with util.HashSet

compiler/src/dotty/tools/dotc/config/Printers.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ object Printers {
2727
val incremental: Printer = noPrinter
2828
val config: Printer = noPrinter
2929
val transforms: Printer = noPrinter
30-
val completions: Printer = noPrinter
3130
val cyclicErrors: Printer = noPrinter
3231
val pickling: Printer = noPrinter
3332
val inlining: Printer = noPrinter

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import util.SimpleIdentityMap
1717
import util.Stats
1818
import java.util.WeakHashMap
1919
import config.Config
20-
import config.Printers.{completions, incremental, noPrinter}
20+
import config.Printers.{incremental, noPrinter}
21+
import reporting.trace
2122

2223
trait SymDenotations { this: Context =>
2324
import SymDenotations._
@@ -214,28 +215,31 @@ object SymDenotations {
214215
case _ => Some(myInfo)
215216
}
216217

217-
private def completeFrom(completer: LazyType)(implicit ctx: Context): Unit = {
218-
if (completions ne noPrinter) {
219-
completions.println(i"${" " * indent}completing ${if (isType) "type" else "val"} $name")
218+
private def completeFrom(completer: LazyType)(implicit ctx: Context): Unit =
219+
if (Config.showCompletions) {
220+
println(i"${" " * indent}completing ${if (isType) "type" else "val"} $name")
220221
indent += 1
221-
}
222-
if (myFlags is Touched) throw CyclicReference(this)
223-
myFlags |= Touched
224-
225-
// completions.println(s"completing ${this.debugString}")
226-
try completer.complete(this)(ctx.withPhase(validFor.firstPhaseId))
227-
catch {
228-
case ex: CyclicReference =>
229-
completions.println(s"error while completing ${this.debugString}")
230-
throw ex
231-
}
232-
finally
233-
if (completions ne noPrinter) {
222+
223+
if (myFlags is Touched) throw CyclicReference(this)
224+
myFlags |= Touched
225+
226+
// completions.println(s"completing ${this.debugString}")
227+
try completer.complete(this)(ctx.withPhase(validFor.firstPhaseId))
228+
catch {
229+
case ex: CyclicReference =>
230+
println(s"error while completing ${this.debugString}")
231+
throw ex
232+
}
233+
finally {
234234
indent -= 1
235-
completions.println(i"${" " * indent}completed $name in $owner")
235+
println(i"${" " * indent}completed $name in $owner")
236236
}
237-
// completions.println(s"completed ${this.debugString}")
238-
}
237+
}
238+
else {
239+
if (myFlags is Touched) throw CyclicReference(this)
240+
myFlags |= Touched
241+
completer.complete(this)(ctx.withPhase(validFor.firstPhaseId))
242+
}
239243

240244
protected[dotc] def info_=(tp: Type) = {
241245
/* // DEBUG
@@ -797,7 +801,10 @@ object SymDenotations {
797801
*/
798802
/** The class implementing this module, NoSymbol if not applicable. */
799803
final def moduleClass(implicit ctx: Context): Symbol = {
800-
def notFound = { completions.println(s"missing module class for $name: $myInfo"); NoSymbol }
804+
def notFound = {
805+
if (Config.showCompletions) println(s"missing module class for $name: $myInfo")
806+
NoSymbol
807+
}
801808
if (this is ModuleVal)
802809
myInfo match {
803810
case info: TypeRef => info.symbol
@@ -1666,7 +1673,7 @@ object SymDenotations {
16661673
}
16671674
}
16681675

1669-
/*>|>*/ ctx.debugTraceIndented(s"$tp.baseType($this)") /*<|<*/ {
1676+
/*>|>*/ trace.onDebug(s"$tp.baseType($this)") /*<|<*/ {
16701677
Stats.record("baseTypeOf")
16711678
tp.stripTypeVar match { // @!!! dealias?
16721679
case tp: CachedType =>

compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import classfile.ClassfileParser
1818
import util.Stats
1919
import scala.util.control.NonFatal
2020
import ast.Trees._
21+
import reporting.trace
2122

2223
object SymbolLoaders {
2324
/** A marker trait for a completer that replaces the original
@@ -265,7 +266,7 @@ abstract class SymbolLoader extends LazyType {
265266
try {
266267
val start = currentTime
267268
if (ctx.settings.debugTrace.value)
268-
ctx.doTraceIndented(s">>>> loading ${root.debugString}", _ => s"<<<< loaded ${root.debugString}") {
269+
trace(s">>>> loading ${root.debugString}", _ => s"<<<< loaded ${root.debugString}") {
269270
doComplete(root)
270271
}
271272
else

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import config.Printers.{typr, constr, subtyping, noPrinter}
1212
import TypeErasure.{erasedLub, erasedGlb}
1313
import TypeApplications._
1414
import scala.util.control.NonFatal
15+
import reporting.trace
1516

1617
/** Provides methods to compare types.
1718
*/
@@ -105,7 +106,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
105106
assert(isSatisfiable, constraint.show)
106107
}
107108

108-
protected def isSubType(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSubType ${traceInfo(tp1, tp2)}", subtyping) {
109+
protected def isSubType(tp1: Type, tp2: Type): Boolean = trace(s"isSubType ${traceInfo(tp1, tp2)}", subtyping) {
109110
if (tp2 eq NoType) false
110111
else if (tp1 eq tp2) true
111112
else {
@@ -948,7 +949,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
948949
* rebase both itself and the member info of `tp` on a freshly created skolem type.
949950
*/
950951
protected def hasMatchingMember(name: Name, tp1: Type, tp2: RefinedType): Boolean =
951-
/*>|>*/ ctx.traceIndented(i"hasMatchingMember($tp1 . $name :? ${tp2.refinedInfo}), mbr: ${tp1.member(name).info}", subtyping) /*<|<*/ {
952+
/*>|>*/ trace(i"hasMatchingMember($tp1 . $name :? ${tp2.refinedInfo}), mbr: ${tp1.member(name).info}", subtyping) /*<|<*/ {
952953
val rinfo2 = tp2.refinedInfo
953954

954955
// If the member is an abstract type, compare the member itself
@@ -1159,7 +1160,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
11591160
/** Same as `isSameType` but also can be applied to overloaded TermRefs, where
11601161
* two overloaded refs are the same if they have pairwise equal alternatives
11611162
*/
1162-
def isSameRef(tp1: Type, tp2: Type): Boolean = ctx.traceIndented(s"isSameRef($tp1, $tp2") {
1163+
def isSameRef(tp1: Type, tp2: Type): Boolean = trace(s"isSameRef($tp1, $tp2") {
11631164
def isSubRef(tp1: Type, tp2: Type): Boolean = tp1 match {
11641165
case tp1: TermRef if tp1.isOverloaded =>
11651166
tp1.alternatives forall (isSubRef(_, tp2))
@@ -1175,7 +1176,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
11751176
}
11761177

11771178
/** The greatest lower bound of two types */
1178-
def glb(tp1: Type, tp2: Type): Type = /*>|>*/ ctx.traceIndented(s"glb(${tp1.show}, ${tp2.show})", subtyping, show = true) /*<|<*/ {
1179+
def glb(tp1: Type, tp2: Type): Type = /*>|>*/ trace(s"glb(${tp1.show}, ${tp2.show})", subtyping, show = true) /*<|<*/ {
11791180
if (tp1 eq tp2) tp1
11801181
else if (!tp1.exists) tp2
11811182
else if (!tp2.exists) tp1
@@ -1224,7 +1225,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12241225
* @param canConstrain If true, new constraints might be added to simplify the lub.
12251226
* @note We do not admit singleton types in or-types as lubs.
12261227
*/
1227-
def lub(tp1: Type, tp2: Type, canConstrain: Boolean = false): Type = /*>|>*/ ctx.traceIndented(s"lub(${tp1.show}, ${tp2.show}, canConstrain=$canConstrain)", subtyping, show = true) /*<|<*/ {
1228+
def lub(tp1: Type, tp2: Type, canConstrain: Boolean = false): Type = /*>|>*/ trace(s"lub(${tp1.show}, ${tp2.show}, canConstrain=$canConstrain)", subtyping, show = true) /*<|<*/ {
12281229
if (tp1 eq tp2) tp1
12291230
else if (!tp1.exists) tp1
12301231
else if (!tp2.exists) tp2
@@ -1383,7 +1384,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
13831384
*
13841385
* In these cases, a MergeError is thrown.
13851386
*/
1386-
final def andType(tp1: Type, tp2: Type, erased: Boolean = ctx.erasedTypes) = ctx.traceIndented(s"glb(${tp1.show}, ${tp2.show})", subtyping, show = true) {
1387+
final def andType(tp1: Type, tp2: Type, erased: Boolean = ctx.erasedTypes) = trace(s"glb(${tp1.show}, ${tp2.show})", subtyping, show = true) {
13871388
val t1 = distributeAnd(tp1, tp2)
13881389
if (t1.exists) t1
13891390
else {

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import config.Config
1616
import util.Property
1717
import collection.mutable
1818
import ast.tpd._
19+
import reporting.trace
1920

2021
trait TypeOps { this: Context => // TODO: Make standalone object.
2122

@@ -33,7 +34,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
3334
/** Map a `C.this` type to the right prefix. If the prefix is unstable, and
3435
* the current variance is <= 0, return a range.
3536
*/
36-
def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = /*>|>*/ ctx.conditionalTraceIndented(TypeOps.track, s"toPrefix($pre, $cls, $thiscls)") /*<|<*/ {
37+
def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = /*>|>*/ trace.conditionally(TypeOps.track, s"toPrefix($pre, $cls, $thiscls)", show = true) /*<|<*/ {
3738
if ((pre eq NoType) || (pre eq NoPrefix) || (cls is PackageClass))
3839
tp
3940
else pre match {
@@ -49,7 +50,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
4950
}
5051
}
5152

52-
/*>|>*/ ctx.conditionalTraceIndented(TypeOps.track, s"asSeen ${tp.show} from (${pre.show}, ${cls.show})", show = true) /*<|<*/ { // !!! DEBUG
53+
/*>|>*/ trace.conditionally(TypeOps.track, s"asSeen ${tp.show} from (${pre.show}, ${cls.show})", show = true) /*<|<*/ { // !!! DEBUG
5354
// All cases except for ThisType are the same as in Map. Inlined for performance
5455
// TODO: generalize the inlining trick?
5556
tp match {

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ object Types {
830830
}
831831

832832
/** The basetype of this type with given class symbol, NoType if `base` is not a class. */
833-
final def baseType(base: Symbol)(implicit ctx: Context): Type = /*ctx.traceIndented(s"$this baseType $base")*/ /*>|>*/ track("base type") /*<|<*/ {
833+
final def baseType(base: Symbol)(implicit ctx: Context): Type = /*trace(s"$this baseType $base")*/ /*>|>*/ track("base type") /*<|<*/ {
834834
base.denot match {
835835
case classd: ClassDenotation => classd.baseTypeOf(this)
836836
case _ => NoType

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import classfile.ClassfileParser
2828
import scala.collection.{ mutable, immutable }
2929
import scala.collection.mutable.ListBuffer
3030
import scala.annotation.switch
31+
import reporting.trace
3132

3233
object Scala2Unpickler {
3334

@@ -571,7 +572,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
571572
} else {
572573
assert(denot.is(ParamAccessor) || denot.isSuperAccessor, denot)
573574
def disambiguate(alt: Symbol) = { // !!! DEBUG
574-
ctx.debugTraceIndented(s"disambiguating ${denot.info} =:= ${denot.owner.thisType.memberInfo(alt)} ${denot.owner}") {
575+
trace.onDebug(s"disambiguating ${denot.info} =:= ${denot.owner.thisType.memberInfo(alt)} ${denot.owner}") {
575576
denot.info matches denot.owner.thisType.memberInfo(alt)
576577
}
577578
}

compiler/src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import core.Contexts._
66
import util.{SourcePosition, NoSourcePosition}
77
import core.Decorators.PhaseListDecorator
88
import collection.mutable
9-
import config.Printers
109
import java.lang.System.currentTimeMillis
1110
import core.Mode
1211
import dotty.tools.dotc.core.Symbols.Symbol
@@ -118,63 +117,13 @@ trait Reporting { this: Context =>
118117
def informProgress(msg: => String) =
119118
inform("[" + msg + "]")
120119

121-
def trace[T](msg: => String)(value: T) = {
120+
def logWith[T](msg: => String)(value: T) = {
122121
log(msg + " " + value)
123122
value
124123
}
125124

126125
def debugwarn(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
127126
if (this.settings.debug.value) warning(msg, pos)
128-
129-
@inline
130-
def debugTraceIndented[TD](question: => String, printer: Printers.Printer = Printers.default, show: Boolean = false)(op: => TD): TD =
131-
conditionalTraceIndented(this.settings.debugTrace.value, question, printer, show)(op)
132-
133-
@inline
134-
def conditionalTraceIndented[TC](cond: Boolean, question: => String, printer: Printers.Printer = Printers.default, show: Boolean = false)(op: => TC): TC =
135-
if (cond) traceIndented[TC](question, printer, show)(op)
136-
else op
137-
138-
@inline
139-
def traceIndented[T](question: => String, printer: Printers.Printer = Printers.default, show: Boolean = false)(op: => T): T =
140-
if (printer eq config.Printers.noPrinter) op
141-
else doTraceIndented[T](question, printer, show)(op)
142-
143-
private def doTraceIndented[T](question: => String, printer: Printers.Printer = Printers.default, show: Boolean = false)(op: => T): T = {
144-
def resStr(res: Any): String = res match {
145-
case res: printing.Showable if show => res.show
146-
case _ => String.valueOf(res)
147-
}
148-
// Avoid evaluating question multiple time, since each evaluation
149-
// may cause some extra logging output.
150-
lazy val q: String = question
151-
doTraceIndented[T](s"==> $q?", (res: Any) => s"<== $q = ${resStr(res)}")(op)
152-
}
153-
154-
def doTraceIndented[T](leading: => String, trailing: Any => String)(op: => T): T =
155-
if (ctx.mode.is(Mode.Printing)) op
156-
else {
157-
var finalized = false
158-
var logctx = this
159-
while (logctx.reporter.isInstanceOf[StoreReporter]) logctx = logctx.outer
160-
def finalize(result: Any, note: String) =
161-
if (!finalized) {
162-
base.indent -= 1
163-
logctx.log(s"${base.indentTab * base.indent}${trailing(result)}$note")
164-
finalized = true
165-
}
166-
try {
167-
logctx.log(s"${base.indentTab * base.indent}$leading")
168-
base.indent += 1
169-
val res = op
170-
finalize(res, "")
171-
res
172-
} catch {
173-
case ex: Throwable =>
174-
finalize("<missing>", s" (with exception $ex)")
175-
throw ex
176-
}
177-
}
178127
}
179128

180129
/**

0 commit comments

Comments
 (0)