Permalink
Browse files

Reduce time spent in lubs

Reduce time spent in lubs by making depth more adaptive. It now takes into account separately the depth of the lub types and the maximal depth of theior base type sequences. It cuts depth more aggressively if it is the base types  instead of the types themselves that grow deep.

The old truncation behavior is retained under option -Xfull-lubs

Another change is that we now track depth more precisely, which should also help or at least allow better statistics.

Also added statistics that measure #lubs and time spent in them.
  • Loading branch information...
odersky authored and adriaanm committed Jun 8, 2012
1 parent abc1c0b commit 1dd02bdd72707e0f39bd1d8e381908b25ff7c5d7
@@ -109,6 +109,7 @@ trait ScalaSettings extends AbsScalaSettings
val XoldPatmat = BooleanSetting ("-Xoldpatmat", "Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10.")
val XnoPatmatAnalysis = BooleanSetting ("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.")
val XfullLubs = BooleanSetting ("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.")
/** Compatibility stubs for options whose value name did
* not previously match the option name.
@@ -138,6 +138,8 @@ abstract class StatisticsInfo {
inform(" of which in app impl : " + subtypeAppInfos)
inform(" of which in improv : " + subtypeImprovCount)
inform("#sametype : " + sametypeCount)
inform("#toplevel lub : " + lubCount)
inform("#all lub : " + nestedLubCount)
inform("ms type-flow-analysis: " + analysis.timer.millis)
if (phase.name == "typer") {
@@ -155,6 +157,7 @@ abstract class StatisticsInfo {
inform(" failed apply : " + showRelTyper(failedApplyNanos))
inform(" failed op= : " + showRelTyper(failedOpEqNanos))
inform("time spent ref scanning : " + showRelTyper(isReferencedNanos))
inform("time spent in lubs : " + showRelTyper(lubNanos))
inform("micros by tree node : " + showCounts(microsByType))
inform("#visits by tree node : " + showCounts(visitsByType))
val average = new ClassCounts
@@ -127,38 +127,11 @@ trait BaseTypeSeqs {
def exists(p: Type => Boolean): Boolean = elems exists p
lazy val maxDepth: Int = maxDepthOfElems
lazy val maxDepth = maxDepthOfElems
protected def maxDepthOfElems = {
protected def maxDepthOfElems: Int = {
var d = 0
for (i <- 0 until length) d = max(d, maxDpth(elems(i)))
d
}
/** The maximum depth of type `tp` */
protected def maxDpth(tp: Type): Int = tp match {
case TypeRef(pre, sym, args) =>
max(maxDpth(pre), maxDpth(args) + 1)
case RefinedType(parents, decls) =>
max(maxDpth(parents), maxDpth(decls.toList.map(_.info)) + 1)
case TypeBounds(lo, hi) =>
max(maxDpth(lo), maxDpth(hi))
case MethodType(paramtypes, result) =>
maxDpth(result)
case NullaryMethodType(result) =>
maxDpth(result)
case PolyType(tparams, result) =>
max(maxDpth(result), maxDpth(tparams map (_.info)) + 1)
case ExistentialType(tparams, result) =>
max(maxDpth(result), maxDpth(tparams map (_.info)) + 1)
case _ =>
1
}
/** The maximum depth of all types `tps` */
private def maxDpth(tps: Seq[Type]): Int = {
var d = 0
for (tp <- tps) d = max(d, maxDpth(tp))
for (i <- 1 until length) d = max(d, typeDepth(elems(i)))
d
}
@@ -252,7 +225,7 @@ trait BaseTypeSeqs {
override def map(g: Type => Type) = lateMap(g)
override def lateMap(g: Type => Type) = orig.lateMap(x => g(f(x)))
override def exists(p: Type => Boolean) = elems exists (x => p(f(x)))
override protected def maxDepthOfElems: Int = (elems map (x => maxDpth(f(x)))).max
override protected def maxDepthOfElems: Int = elems map (x => typeDepth(f(x))) max
override def toString = elems.mkString("MBTS(", ",", ")")
}
Oops, something went wrong.

0 comments on commit 1dd02bd

Please sign in to comment.