From 6e6df180d46774651bea43a443f9d074020f68df Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 Sep 2017 15:42:18 +0200 Subject: [PATCH] Avoid creating most trees in GenBCode GenBCode generates trees when it desugars Idents based on their type. We now cache the generated tree, avoiding generating the same tree several times. In the Dotty bootstrap, this reduced generated trees in backend from 606K (about 20% of total) to 49K. --- .../backend/jvm/DottyBackendInterface.scala | 28 +++++++++++-------- compiler/src/dotty/tools/dotc/Run.scala | 6 ++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 297f7e0f8934..40b8412308a4 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -424,18 +424,26 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma }.bits def isQualifierSafeToElide(qual: Tree): Boolean = tpd.isIdempotentExpr(qual) + + private val desugared = new java.util.IdentityHashMap[Type, tpd.Select] + def desugarIdent(i: Ident): Option[tpd.Select] = { - i.tpe match { - case TermRef(prefix: TermRef, name) => - Some(tpd.ref(prefix).select(i.symbol)) - case TermRef(prefix: ThisType, name) => - Some(tpd.This(prefix.cls).select(i.symbol)) - case TermRef(NoPrefix, name) => - if (i.symbol is Flags.Method) Some(This(i.symbol.topLevelClass).select(i.symbol)) // workaround #342 todo: remove after fixed - else None - case _ => None + var found = desugared.get(i.tpe) + if (found == null) { + i.tpe match { + case TermRef(prefix: TermRef, name) => + found = tpd.ref(prefix).select(i.symbol) + case TermRef(prefix: ThisType, name) => + found = tpd.This(prefix.cls).select(i.symbol) + case TermRef(NoPrefix, name) => + if (i.symbol is Flags.Method) found = This(i.symbol.topLevelClass).select(i.symbol) // workaround #342 todo: remove after fixed + case _ => + } + if (found != null) desugared.put(i.tpe, found) } + if (found == null) None else Some(found) } + def getLabelDefOwners(tree: Tree): Map[Tree, List[LabelDef]] = { // for each rhs of a defdef returns LabelDefs inside this DefDef val res = new collection.mutable.HashMap[Tree, List[LabelDef]]() @@ -892,8 +900,6 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def parents: List[Type] = tp.parents } - - object Assign extends AssignDeconstructor { def _1: Tree = field.lhs def _2: Tree = field.rhs diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index f8e7967e89d8..10ccc59a3e5f 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -128,11 +128,11 @@ class Run(comp: Compiler, ictx: Context) { } } ctx.informTime(s"$phase ", start) + Stats.record(s"total trees at end of $phase", ast.Trees.ntrees) + for (unit <- units) + Stats.record(s"retained typed trees at end of $phase", unit.tpdTree.treeSize) } if (!ctx.reporter.hasErrors) Rewrites.writeBack() - for (unit <- units) - Stats.record("retained typed trees at end", unit.tpdTree.treeSize) - Stats.record("total trees at end", ast.Trees.ntrees) } private sealed trait PrintedTree