Permalink
Browse files

A simpler and faster implementation of assignUniqueSymbols

  • Loading branch information...
szeiger committed Sep 1, 2015
1 parent e933ed3 commit bc90afe3e533512664eea6a557d499f13427d48a
@@ -30,6 +30,8 @@ object CompilerBenchmark {
}
}
var compileMS: Double = 0.0
for(i <- 1 to RUNS) {
val (queries, t1) = time("Creating queries", COUNT_CREATE)(allQueries)
val (asts, t2) = time("Creating ASTs", COUNT_TONODE)(queries.map(_.toNode))
@@ -45,10 +47,15 @@ object CompilerBenchmark {
Console.readLine()
}*/
println(String.format("Creating: %1$7.3f ms, toNode: %2$7.3f ms, compiling: %3$7.3f ms", t1.asInstanceOf[AnyRef], t2.asInstanceOf[AnyRef], t3.asInstanceOf[AnyRef]))
compileMS = t3
}
println("Last run by phase:")
phases.foreach(p => println(String.format("Phase %1$25s: %2$7.3f ms", p.name, (phaseNanos(p.name)(0)/1000000.0/COUNT_COMPILE).asInstanceOf[AnyRef])))
phases.foreach { p =>
val pms = (phaseNanos(p.name)(0)/1000000.0/COUNT_COMPILE)
val percentage = pms / compileMS * 100.0
println(String.format("Phase %1$25s: %2$7.3f ms, %3$7.3f %%", p.name, pms.asInstanceOf[AnyRef], percentage.asInstanceOf[AnyRef]))
}
}
def time[T](name: String, count: Int)(f: => T): (T, Double) = {
@@ -101,14 +101,8 @@ object Library {
/** A Symbol that represents a library function or operator */
class FunctionSymbol(val name: String) extends TermSymbol {
/** Create an untyped Apply of this Symbol */
//def apply(ch: Node*): Apply = Apply(this, ch)
/** Match an Apply of this Symbol */
def unapplySeq(n: Node) = n match {
case Apply(sym, ch) if sym eq this => Some(ch.toSeq)
case _ => None
}
def unapplySeq(a: Apply) = if(a.sym eq this) Some(a.children.toSeq) else None
/** Create a typed Apply of this Symbol */
def typed(tpe: Type, ch: Node*): Apply = Apply(this, ConstArray.from(ch))(tpe)
@@ -1,6 +1,6 @@
package slick.compiler
import scala.collection.mutable.HashSet
import scala.collection.mutable.{HashSet, HashMap}
import slick.SlickException
import slick.ast._
import TypeUtil._
@@ -15,41 +15,30 @@ class AssignUniqueSymbols extends Phase {
val name = "assignUniqueSymbols"
def apply(state: CompilerState) = state.map { tree =>
val seen = new HashSet[AnonSymbol]
def tr(n: Node, replace: Map[AnonSymbol, AnonSymbol]): Node = {
val n2 = n match { // Give TableNode, GroupBy and Pure nodes a unique TypeSymbol
val replace = new HashMap[TermSymbol, AnonSymbol]
def tr(n: Node): Node = {
val n3 = n match {
case Select(in, s) => Select(tr(in), s) :@ n.nodeType
case r @ Ref(a: AnonSymbol) =>
val s = replace.getOrElse(a, a)
if(s eq a) r else Ref(s)
case t: TableNode => t.copy(identity = new AnonTableIdentitySymbol)(t.driverTable)
case Pure(value, _) => Pure(value)
case g: GroupBy => g.copy(identity = new AnonTypeSymbol)
case n => n
}
val n3 = n2 match {
case r @ Ref(a: AnonSymbol) => replace.get(a) match {
case Some(s) => if(s eq a) r else Ref(s)
case None => r
}
case Pure(value, _) => Pure(tr(value))
case g: GroupBy =>
val d = g.copy(identity = new AnonTypeSymbol)
val a = new AnonSymbol
replace += g.fromGen -> a
g.copy(fromGen = a, tr(g.from), tr(g.by), identity = new AnonTypeSymbol)
case n: StructNode => n.mapChildren(tr)
case d: DefNode =>
var defs = replace
d.mapScopedChildren { (symO, ch) =>
val r = tr(ch, defs)
symO match {
case Some(a: AnonSymbol) =>
if(seen.contains(a)) defs += a -> new AnonSymbol
else seen += a
case _ =>
}
r
}.mapSymbols {
case a: AnonSymbol => defs.getOrElse(a, a)
case s => s
}
case n: Select => n.mapChildren(tr(_, replace)) :@ n.nodeType
case n => n.mapChildren(tr(_, replace))
replace ++= d.generators.iterator.map(_._1 -> new AnonSymbol)
d.mapSymbols(s => replace.getOrElse(s, s)).mapChildren(tr)
case n => n.mapChildren(tr)
}
// Remove all NominalTypes (which might have changed)
if(n3.hasType && hasNominalType(n3.nodeType)) n3.untyped else n3
}
tr(tree, Map())
tr(tree)
}
def hasNominalType(t: Type): Boolean = t match {

0 comments on commit bc90afe

Please sign in to comment.