diff options
author | Burak Emir <emir@epfl.ch> | 2007-06-22 10:12:55 +0000 |
---|---|---|
committer | Burak Emir <emir@epfl.ch> | 2007-06-22 10:12:55 +0000 |
commit | ed3f1d101d6008629a2645e5887ba2485932acea (patch) | |
tree | 2c564676ca9d68adcfe9551c9cd9694dcd4e606e /src | |
parent | 30f41d643a482d21f1518abe0af39a182d54cf20 (diff) | |
download | scala-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
Diffstat (limited to 'src')
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); |