summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-06-15 23:20:35 +0000
committerPaul Phillips <paulp@improving.org>2011-06-15 23:20:35 +0000
commit5de317f769c2e9bead1cadceafbf87cb4223065f (patch)
tree55779903d663169b12a3a23732e682d8117d2466 /src
parent8b66af0cfe29ab6026215e44f4d4b148316c159d (diff)
downloadscala-5de317f769c2e9bead1cadceafbf87cb4223065f.tar.gz
scala-5de317f769c2e9bead1cadceafbf87cb4223065f.tar.bz2
scala-5de317f769c2e9bead1cadceafbf87cb4223065f.zip
Bytecode inspection reveals the pattern matcher...
Bytecode inspection reveals the pattern matcher leaving a lot more redundancy in generated trees than is necessary. Added more inteligence to the process. Review by dragos.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala21
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchSupport.scala4
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala52
3 files changed, 42 insertions, 35 deletions
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index 059a95f271..2ccd122a6c 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -367,8 +367,9 @@ abstract class TreeInfo {
case _ => false
}
- /** Some handy extractors for spotting true and false expressions
- * through the haze of braces.
+ /** Some handy extractors for spotting trees through the
+ * the haze of irrelevant braces: i.e. Block(Nil, SomeTree)
+ * should not keep us from seeing SomeTree.
*/
abstract class SeeThroughBlocks[T] {
protected def unapplyImpl(x: Tree): T
@@ -378,9 +379,21 @@ abstract class TreeInfo {
}
}
object IsTrue extends SeeThroughBlocks[Boolean] {
- protected def unapplyImpl(x: Tree): Boolean = x equalsStructure Literal(Constant(true))
+ protected def unapplyImpl(x: Tree): Boolean = x match {
+ case Literal(Constant(true)) => true
+ case _ => false
+ }
}
object IsFalse extends SeeThroughBlocks[Boolean] {
- protected def unapplyImpl(x: Tree): Boolean = x equalsStructure Literal(Constant(false))
+ protected def unapplyImpl(x: Tree): Boolean = x match {
+ case Literal(Constant(false)) => true
+ case _ => false
+ }
+ }
+ object IsIf extends SeeThroughBlocks[Option[(Tree, Tree, Tree)]] {
+ protected def unapplyImpl(x: Tree) = x match {
+ case If(cond, thenp, elsep) => Some(cond, thenp, elsep)
+ case _ => None
+ }
}
}
diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
index c5673fced7..beaf63106d 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
@@ -113,6 +113,10 @@ trait MatchSupport extends ast.TreeDSL { self: ParallelMatching =>
x
}
+ private[nsc] def printing[T](fmt: String, xs: Any*)(x: T): T = {
+ println(fmt.format(xs: _*) + " == " + x)
+ x
+ }
def indent(s: Any) = s.toString() split "\n" map (" " + _) mkString "\n"
def indentAll(s: Seq[Any]) = s map (" " + _.toString() + "\n") mkString
diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
index d75670fd38..24d3c38e74 100644
--- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
@@ -19,7 +19,7 @@ trait MatrixAdditions extends ast.TreeDSL {
import symtab.Flags
import CODE._
import Debug._
- import treeInfo.{ IsTrue, IsFalse }
+ import treeInfo._
import definitions.{ isValueClass }
/** The Squeezer, responsible for all the squeezing.
@@ -53,17 +53,6 @@ trait MatrixAdditions extends ast.TreeDSL {
super.traverse(tree)
}
}
- class Subst(vd: ValDef) extends Transformer {
- private var stop = false
- override def transform(tree: Tree): Tree = tree match {
- case t: Ident if t.symbol == vd.symbol =>
- stop = true
- vd.rhs
- case _ =>
- if (stop) tree
- else super.transform(tree)
- }
- }
/** Compresses multiple Blocks. */
private def combineBlocks(stats: List[Tree], expr: Tree): Tree = expr match {
@@ -87,9 +76,12 @@ trait MatrixAdditions extends ast.TreeDSL {
val rt = new RefTraverser(vd)
rt.atOwner(owner)(rt traverse squeezedTail)
- if (rt.canDrop) squeezedTail
- else if (rt.canInline) new Subst(vd) transform squeezedTail
- else default
+ if (rt.canDrop)
+ squeezedTail
+ else if (isConstantType(vd.symbol.tpe) || rt.canInline)
+ new TreeSubstituter(List(vd.symbol), List(vd.rhs)) transform squeezedTail
+ else
+ default
case _ => default
}
}
@@ -103,26 +95,24 @@ trait MatrixAdditions extends ast.TreeDSL {
import self.context._
final def optimize(tree: Tree): Tree = {
+ // Uses treeInfo extractors rather than looking at trees directly
+ // because the many Blocks obscure our vision.
object lxtt extends Transformer {
override def transform(tree: Tree): Tree = tree match {
- case blck @ Block(vdefs, ld @ LabelDef(name, params, body)) =>
- if (targets exists (_ shouldInline ld.symbol)) squeezedBlock(vdefs, body)
- else blck
-
- case t =>
- super.transform(t match {
- // note - it is too early for any other true/false related optimizations
- case If(cond, IsTrue(), IsFalse()) => cond
-
- case If(cond1, If(cond2, thenp, elsep1), elsep2) if (elsep1 equalsStructure elsep2) =>
- IF (cond1 AND cond2) THEN thenp ELSE elsep1
- case If(cond1, If(cond2, thenp, Apply(jmp, Nil)), ld: LabelDef) if jmp.symbol eq ld.symbol =>
- IF (cond1 AND cond2) THEN thenp ELSE ld
- case t => t
- })
+ case Block(stats, ld @ LabelDef(_, _, body)) if targets exists (_ shouldInline ld.symbol) =>
+ squeezedBlock(transformStats(stats, currentOwner), body)
+ case IsIf(cond, IsTrue(), IsFalse()) =>
+ transform(cond)
+ case IsIf(cond1, IsIf(cond2, thenp, elsep1), elsep2) if elsep1 equalsStructure elsep2 =>
+ transform(typer typed If(gen.mkAnd(cond1, cond2), thenp, elsep2))
+ case If(cond1, IsIf(cond2, thenp, Apply(jmp, Nil)), ld: LabelDef) if jmp.symbol eq ld.symbol =>
+ transform(typer typed If(gen.mkAnd(cond1, cond2), thenp, ld))
+ case _ =>
+ super.transform(tree)
}
}
- returning(lxtt transform tree)(_ => clearSyntheticSyms())
+ try lxtt transform tree
+ finally clearSyntheticSyms()
}
}