@@ -573,129 +573,6 @@ object PatternMatcher {
573
573
new MergeTests ()(plan)
574
574
}
575
575
576
- /** Eliminate tests that are redundant (known to be true or false).
577
- * Two parts:
578
- *
579
- * - If we know at some point that a test is true or false skip it and continue
580
- * diretcly with the test's onSuccess or onFailure continuation.
581
- * - If a label of a call points to a test that is known to be true or false
582
- * at the point of call, let the label point instead to the test's onSuccess
583
- * or onFailure continuation.
584
- *
585
- * We use some tricks to identify a let pointing to an unapply and the
586
- * NonEmptyTest that follows it as a single `UnappTest` test.
587
- */
588
- /*
589
- def elimRedundantTests(plan: Plan): Plan = {
590
- type SeenTests = Map[TestPlan, Boolean] // Map from tests to their outcomes
591
-
592
- def isUnapply(sym: Symbol) = sym.name == nme.unapply || sym.name == nme.unapplySeq
593
-
594
- /** A locally used test value that represents combos of
595
- *
596
- * let x = X.unapply(...) in if !x.isEmpty then ... else ...
597
- */
598
- case object UnappTest extends Test
599
-
600
- /** If `plan` is the NonEmptyTest part of an unapply, the corresponding UnappTest
601
- * otherwise the original plan
602
- */
603
- def normalize(plan: TestPlan): TestPlan = plan.scrutinee match {
604
- case id: Ident
605
- if plan.test == NonEmptyTest &&
606
- isPatmatGenerated(id.symbol) &&
607
- isUnapply(initializer(id.symbol).symbol) =>
608
- TestPlan(UnappTest, initializer(id.symbol), plan.pos, plan.onSuccess, plan.onFailure)
609
- case _ =>
610
- plan
611
- }
612
-
613
- /** Extractor for Let/NonEmptyTest combos that represent unapplies */
614
- object UnappTestPlan {
615
- def unapply(plan: Plan): Option[TestPlan] = plan match {
616
- case LetPlan(sym, body: TestPlan) =>
617
- val RHS = initializer(sym)
618
- normalize(body) match {
619
- case normPlan @ TestPlan(UnappTest, RHS, _, _, _) => Some(normPlan)
620
- case _ => None
621
- }
622
- case _ => None
623
- }
624
- }
625
-
626
- def intersect(tests1: SeenTests, tests2: SeenTests) =
627
- tests1.filter { case(test, outcome) => tests2.get(test) == Some(outcome) }
628
-
629
- /** The tests with known outcomes valid at entry to label */
630
- val seenAtLabel = newMutableSymbolMap[SeenTests]
631
-
632
- class ElimRedundant(seenTests: SeenTests) extends PlanTransform {
633
- override def apply(plan: TestPlan): Plan = {
634
- val normPlan = normalize(plan)
635
- seenTests.get(normPlan) match {
636
- case Some(outcome) =>
637
- apply(if (outcome) plan.onSuccess else plan.onFailure)
638
- case None =>
639
- plan.onSuccess = new ElimRedundant(seenTests + (normPlan -> true))(plan.onSuccess)
640
- plan.onFailure = new ElimRedundant(seenTests + (normPlan -> false))(plan.onFailure)
641
- plan
642
- }
643
- }
644
- override def apply(plan: LabelledPlan): Plan = {
645
- plan.body = apply(plan.body)
646
- for (seenTests1 <- seenAtLabel.get(plan.sym))
647
- labelled(plan.sym) = new ElimRedundant(seenTests1)(labelled(plan.sym))
648
- plan
649
- }
650
- override def apply(plan: CallPlan): Plan = {
651
- val label = plan.label
652
- def redirect(target: Plan): Plan = {
653
- def forward(tst: TestPlan) = seenTests.get(tst) match {
654
- case Some(true) => redirect(tst.onSuccess)
655
- case Some(false) => redirect(tst.onFailure)
656
- case none => target
657
- }
658
- target match {
659
- case tst: TestPlan => forward(tst)
660
- case UnappTestPlan(tst) => forward(tst)
661
- case _ => target
662
- }
663
- }
664
- redirect(labelled(label)) match {
665
- case target: CallPlan =>
666
- apply(target)
667
- case _ =>
668
- seenAtLabel(label) = seenAtLabel.get(label) match {
669
- case Some(seenTests1) => intersect(seenTests1, seenTests)
670
- case none => seenTests
671
- }
672
- plan
673
- }
674
- }
675
- }
676
- new ElimRedundant(Map())(plan)
677
- }
678
- */
679
-
680
- /** Inline labelled blocks that are referenced only once.
681
- * Drop all labels that are not referenced anymore after this.
682
- */
683
- /*
684
- private def inlineLabelled(plan: Plan) = {
685
- val refCount = labelRefCount(plan)
686
- def toDrop(sym: Symbol) = labelled.contains(sym) && refCount(sym) <= 1
687
- class Inliner extends PlanTransform {
688
- override def apply(plan: LabelledPlan): Plan =
689
- if (toDrop(plan.sym)) apply(plan.body) else super.apply(plan)
690
- override def apply(plan: CallPlan): Plan = {
691
- if (refCount(plan.label) == 1) apply(labelled(plan.label))
692
- else plan
693
- }
694
- }
695
- (new Inliner)(plan)
696
- }
697
- */
698
-
699
576
/** Merge variables that have the same right hand side.
700
577
* Propagate common variable bindings as parameters into case labels.
701
578
*/
@@ -788,7 +665,6 @@ object PatternMatcher {
788
665
/** Inline let-bound trees that are referenced only once.
789
666
* Drop all variables that are not referenced anymore after this.
790
667
*/
791
- /*
792
668
private def inlineVars (plan : Plan ): Plan = {
793
669
val refCount = varRefCount(plan)
794
670
val LetPlan (topSym, _) = plan
@@ -819,20 +695,9 @@ object PatternMatcher {
819
695
plan
820
696
}
821
697
}
822
- override def apply(plan: LabelledPlan): Plan = {
823
- plan.params = plan.params.filter(refCount(_) != 0)
824
- super.apply(plan)
825
- }
826
- override def apply(plan: CallPlan): Plan = {
827
- plan.args = plan.args
828
- .filter(formalActual => refCount(formalActual._1) != 0)
829
- .sortBy(_._1.name.toString)
830
- plan
831
- }
832
698
}
833
699
Inliner (plan)
834
700
}
835
- */
836
701
837
702
// ----- Generating trees from plans ---------------
838
703
@@ -1069,11 +934,9 @@ object PatternMatcher {
1069
934
}
1070
935
1071
936
val optimizations : List [(String , Plan => Plan )] = List (
1072
- " mergeTests" -> mergeTests
937
+ " mergeTests" -> mergeTests,
938
+ " inlineVars" -> inlineVars
1073
939
/*
1074
- "hoistLabels" -> hoistLabels,
1075
- "elimRedundantTests" -> elimRedundantTests,
1076
- "inlineLabelled" -> inlineLabelled,
1077
940
"mergeVars" -> mergeVars,
1078
941
"inlineVars" -> inlineVars
1079
942
*/
0 commit comments