summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2007-06-22 10:12:55 +0000
committerBurak Emir <emir@epfl.ch>2007-06-22 10:12:55 +0000
commited3f1d101d6008629a2645e5887ba2485932acea (patch)
tree2c564676ca9d68adcfe9551c9cd9694dcd4e606e
parent30f41d643a482d21f1518abe0af39a182d54cf20 (diff)
downloadscala-ed3f1d101d6008629a2645e5887ba2485932acea.tar.gz
scala-ed3f1d101d6008629a2645e5887ba2485932acea.tar.bz2
scala-ed3f1d101d6008629a2645e5887ba2485932acea.zip
added -Xsqueeze option, which optimizes valdefs...
added -Xsqueeze option, which optimizes valdefs generated by pattern matcher
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala5
-rw-r--r--src/compiler/scala/tools/nsc/matching/CodeFactory.scala9
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala14
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala71
4 files changed, 54 insertions, 45 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index b5dab7c2cf..7b9b6fa9f7 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -146,9 +146,12 @@ class Settings(error: String => Unit) {
//Xplugtypes.value = true // just while experimenting
// for benchmarking purposes
- val Xmatchalgo = ChoiceSetting("-Xmatchalgo", "which match algorithm to use", List("both","par","incr"),
+ val Xmatchalgo = ChoiceSetting("-Xmatchalgo", "which match algorithm to use", List("both","par","incr"),
/*default*/"both")
+ val Xsqueeze = ChoiceSetting("-Xsqueeze", "if on, creates compact code in matching", List("on","on","off"),
+ /*default*/"off")
+
/** scaladoc specific options */
val windowtitle = StringSetting("-windowtitle", "windowtitle",
"Specify window title of generated HTML documentation",
diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
index 13472a8d19..db04de42a5 100644
--- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
+++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
@@ -259,9 +259,12 @@ trait CodeFactory {
var nsubstituted = 0
var nstatic = 0
- def squeezedBlock(vds:List[Tree], exp:Tree)(implicit theOwner: Symbol): Tree = {
- Block(vds,exp)
- }
+ def squeezedBlock(vds:List[Tree], exp:Tree)(implicit theOwner: Symbol): Tree =
+ if(settings.Xsqueeze.value == "on")
+ squeezedBlock1(vds, exp)
+ else
+ Block(vds,exp)
+
def squeezedBlock1(vds:List[Tree], exp:Tree)(implicit theOwner: Symbol): Tree = {
val tpe = exp.tpe
class RefTraverser(sym:Symbol) extends Traverser {
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 3e42a896d2..b2355fc135 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -447,15 +447,15 @@ trait ParallelMatching {
/** converts given rep to a tree - performs recursive call to translation in the process to get sub reps
*/
- def repToTree(rep:Rep, typed:Tree => Tree, handleOuter: Tree => Tree)(implicit theOwner: Symbol, failTree: Tree, bodies: collection.mutable.Map[Tree,(Tree,Tree, Symbol)]): Tree = {
+ def repToTree(rep:Rep, typed:Tree => Tree, handleOuter: Tree => Tree)(implicit theOwner: Symbol, failTree: Tree, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = {
rep.applyRule match {
case VariableRule(subst, EmptyTree, b) => bodies.get(b) match {
- case Some(EmptyTree, b, theLabel) => //Console.println("H E L L O"+subst+" "+b)
+ case Some(EmptyTree, nb, theLabel) => //Console.println("H E L L O"+subst+" "+b)
if(b.isInstanceOf[Literal])
return b
// recover the order of the idents that is expected for the labeldef
- val args = b match { case Block(_, LabelDef(_, origs, _)) =>
+ val args = nb match { case Block(_, LabelDef(_, origs, _)) =>
origs.map { p => Ident(subst.find { q => q._1 == p.symbol }.get._2) } // wrong!
} // using this instead would not work: subst.map { p => Ident(p._2) }
// the order can be garbled, when default patterns are used... #bug 1163
@@ -476,7 +476,7 @@ trait ParallelMatching {
var nbody: Tree = b
val vrefs = vdefs.map { p:ValDef => Ident(p.symbol) }
- nbody = Block(vdefs:::List(Apply(Ident(theLabel), vrefs)), LabelDef(theLabel, subst.map(_._1), nbody))
+ nbody = squeezedBlock(vdefs:::List(Apply(Ident(theLabel), vrefs)), LabelDef(theLabel, subst.map(_._1), nbody))
bodies(b) = (EmptyTree, nbody, theLabel)
nbody
}
@@ -533,7 +533,7 @@ trait ParallelMatching {
}
vdefs = typed { ValDef(casted, gen.mkAsInstanceOf(typed{Ident(mm.scrutinee)}, casted.tpe))} :: vdefs
- typed { makeIf(cond, Block(vdefs,succ), fail) }
+ typed { makeIf(cond, squeezedBlock(vdefs,succ), fail) }
case mu: MixUnapply =>
val (uacall,vdefs,srep,frep) = mu.getTransition
@@ -541,7 +541,7 @@ trait ParallelMatching {
val succ = repToTree(srep, typed, handleOuter)
val fail = if(frep.isEmpty) failTree else repToTree(frep.get, typed, handleOuter)
val cond = typed { Not(Select(Ident(uacall.symbol),nme.isEmpty)) }
- typed { Block(List(uacall), makeIf(cond,Block(vdefs,succ),fail)) }
+ typed { squeezedBlock(List(uacall), makeIf(cond,squeezedBlock(vdefs,succ),fail)) }
}
}
@@ -569,7 +569,7 @@ object Rep {
}
def getAlternativeBranches(p:Tree): List[Tree] = {
def get_BIND(pctx:Tree => Tree, p:Tree):List[Tree] = p match {
- case b @ Bind(n,p) => get_BIND({ x:Tree => pctx(copy.Bind(b, n, x) setType x.tpe) }, p)
+ case b @ Bind(n,p) => get_BIND({ x:Tree => pctx(copy.Bind(b, n, x) setType x.tpe) }, p)
case Alternative(ps) => ps map pctx
}
get_BIND({x=>x}, p)
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 33b8385c26..3a98d9b450 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -154,42 +154,45 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
}
def constructParallel(cases: List[Tree]) {
- cases foreach { case CaseDef(pat,_,_) => hasUnapply.traverse(pat) }
- if(cases.forall{case CaseDef(_,x,_) => x == EmptyTree}) {
- val irep = initRep(selector, cases, doCheckExhaustive)
- val root = irep.temp.head
-
- implicit val fail: Tree = ThrowMatchError(selector.pos, Ident(root))
- val vdef = typed{ValDef(root, selector)}
-
- implicit val memo = new collection.mutable.HashMap[(Symbol,Symbol),Symbol]
- implicit val theCastMap = new collection.mutable.HashMap[(Symbol,Type),Symbol]
- implicit val bodies = new collection.mutable.HashMap[Tree, (Tree,Tree,Symbol)]
- val mch = typed{repToTree(irep, typed, handleOuter)}
- dfatree = typed{squeezedBlock(List(vdef), mch)}
-
- //DEBUG("**** finished\n"+dfatree.toString)
-
- val i = cases.findIndexOf { case CaseDef(_,_,b) => bodies.get(b).isEmpty}
- if(i != -1) {
- val CaseDef(_,_,b) = cases(i)
- //DEBUG("*** damn, unreachable!")
- //Console.println("damn, unreachable!")
- if(settings.debug.value) {
- Console.println("bodies:"+bodies.mkString("","\n",""))
- }
- cunit.error(b.pos, "unreachable code")
- }
+ var cases1 = cases; while(cases1 ne Nil) {
+ val c = cases1.head.asInstanceOf[CaseDef]
+ if(c.guard != EmptyTree)
+ throw CantHandleGuard
+ hasUnapply.traverse(c.pat)
+ cases1 = cases1.tail
+ }
- resetTrav.traverse(dfatree)
+ val irep = initRep(selector, cases, doCheckExhaustive)
+ val root = irep.temp.head
- //constructParallel(cases) // ZZZ
- nParallel = nParallel + 1
- } else {
- throw CantHandleGuard
+ implicit val fail: Tree = ThrowMatchError(selector.pos, Ident(root))
+ val vdef = typed{ValDef(root, selector)}
+
+ implicit val memo = new collection.mutable.HashMap[(Symbol,Symbol),Symbol]
+ implicit val theCastMap = new collection.mutable.HashMap[(Symbol,Type),Symbol]
+ implicit val bodies = new collection.mutable.HashMap[Tree, (Tree,Tree,Symbol)]
+ val mch = typed{repToTree(irep, typed, handleOuter)}
+
+ dfatree = typed{squeezedBlock(List(vdef), mch)}
+
+ //DEBUG("**** finished\n"+dfatree.toString)
+
+ val i = cases.findIndexOf { case CaseDef(_,_,b) => bodies.get(b).isEmpty}
+ if(i != -1) {
+ val CaseDef(_,_,b) = cases(i)
+ if(settings.debug.value) {
+ Console.println("bodies:"+bodies.mkString("","\n",""))
+ }
+ cunit.error(b.pos, "unreachable code")
}
+
+ resetTrav.traverse(dfatree)
+
+ //constructParallel(cases) // ZZZ
+ nParallel = nParallel + 1
}
+
/** constructs match-translation incrementally */
private def constructIncremental(cases:List[Tree]) {
doCheckExhaustive = false
@@ -882,7 +885,7 @@ print()
// changed to
nCases = CaseDef(Ident(nme.WILDCARD),defaultBody1) :: nCases;
- Block(List(ValDef(root.casted, selector)),Match(Ident(root.casted), nCases))
+ squeezedBlock(List(ValDef(root.casted, selector)),Match(Ident(root.casted), nCases))
}
@@ -952,7 +955,7 @@ print()
squeezedBlock(
List(
ValDef(temp, body(i)),
- Apply(Ident(exit), List(Ident(temp)) )
+ Apply(Ident(exit), List(Ident(temp).setType(temp.tpe)) )
),
Literal(Constant(true))
); // forward jump
@@ -1250,7 +1253,7 @@ print()
bindings = ValDef(casted, treeAsSeq.duplicate) :: bindings
- val succ = Block(bindings, toTree(node.and))
+ val succ = squeezedBlock(bindings, toTree(node.and))
val fail = toTree(node.or, selector.duplicate)
return Or(And(cond, succ), fail);