@@ -40,75 +40,6 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
4040 this
4141 }
4242
43- private def desugarIdent (i : Ident )(implicit ctx : Context ): Option [Select ] = {
44- i.tpe match {
45- case TermRef (prefix : TermRef , name) =>
46- Some (ref(prefix).select(i.symbol))
47- case TermRef (prefix : ThisType , name) =>
48- Some (This (prefix.cls).select(i.symbol))
49- case _ => None
50- }
51- }
52-
53- private def dropCasts (t : Tree )(implicit ctx : Context ): Tree = t match {
54- // case TypeApply(aio@Select(rec, nm), _) if aio.symbol == defn.Any_asInstanceOf => dropCasts(rec)
55- case Typed (t, tpe) => t
56- case _ => t
57- }
58-
59- private def readingOnlyVals (t : Tree )(implicit ctx : Context ): Boolean = dropCasts(t) match {
60- case Typed (exp, _) => readingOnlyVals(exp)
61- case TypeApply (fun @ Select (rec, _), List (tp)) =>
62- if ((fun.symbol eq defn.Any_asInstanceOf ) && rec.tpe.derivesFrom(tp.tpe.classSymbol))
63- readingOnlyVals(rec)
64- else false
65- case Apply (Select (rec, _), Nil ) =>
66- def isGetterOfAImmutableField = t.symbol.isGetter && ! t.symbol.is(Flags .Mutable )
67- def isCaseClassWithVar = t.symbol.info.decls.exists(_.is(Flags .Mutable ))
68- def isAccessingProductField = t.symbol.exists &&
69- t.symbol.owner.derivesFrom(defn.ProductClass ) &&
70- t.symbol.owner.is(Flags .CaseClass ) &&
71- t.symbol.name.isSelectorName &&
72- ! isCaseClassWithVar // Conservative Covers case class A(var x: Int)
73- def isImmutableCaseAccessor = t.symbol.is(Flags .CaseAccessor ) && ! t.symbol.is(Flags .Mutable )
74- if (isGetterOfAImmutableField || isAccessingProductField || isImmutableCaseAccessor)
75- readingOnlyVals(rec)
76- else false
77- case Select (rec, _) if t.symbol.is(Flags .Method ) =>
78- if (t.symbol.isGetter && ! t.symbol.is(Flags .Mutable )) readingOnlyVals(rec) // getter of a immutable field
79- else if (t.symbol.owner.derivesFrom(defn.ProductClass ) && t.symbol.owner.is(Flags .CaseClass ) && t.symbol.name.isSelectorName) {
80- def isImmutableField = {
81- val fieldId = t.symbol.name.toString.drop(1 ).toInt - 1
82- ! t.symbol.owner.caseAccessors(ctx)(fieldId).is(Flags .Mutable )
83- }
84- if (isImmutableField) readingOnlyVals(rec) // accessing a field of a product
85- else false
86- } else if (t.symbol.is(Flags .CaseAccessor ) && ! t.symbol.is(Flags .Mutable ))
87- readingOnlyVals(rec)
88- else false
89- case Select (qual, _) if ! t.symbol.is(Flags .Mutable ) =>
90- readingOnlyVals(qual)
91- case t : Ident if ! t.symbol.is(Flags .Mutable ) && ! t.symbol.is(Flags .Method ) && ! t.symbol.info.dealias.isInstanceOf [ExprType ] =>
92- desugarIdent(t) match {
93- case Some (t) => readingOnlyVals(t)
94- case None => true
95- }
96- case t : This => true
97- // null => false, or the following fails devalify:
98- // trait I {
99- // def foo: Any = null
100- // }
101- // object Main {
102- // def main = {
103- // val s: I = null
104- // s.foo
105- // }
106- // }
107- case Literal (Constant (null )) => false
108- case t : Literal => true
109- case _ => false
110- }
111-
11243 type Visitor = Tree => Unit
11344 type ErasureCompatibility = Int
11445 val BeforeErasure : ErasureCompatibility = 1
@@ -134,14 +65,8 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
13465
13566 private lazy val _optimizations : Seq [Optimization ] =
13667 inlineCaseIntrinsics ::
137- removeUnnecessaryNullChecks :: // Doesn't seams to work AfterErasure
68+ removeUnnecessaryNullChecks ::
13869 inlineOptions ::
139- // Tests that fail when enabled AfterErasure, to be investigated?
140- // ../tests/run/Course-2002-04.scala failed
141- // ../tests/run/t2005.scala failed
142- // ../tests/run/optimizer-array-load.scala failed
143- // ../tests/pos/virtpatmat_exist1.scala failed
144- // ../tests/pos/t1133.scala failed
14570 inlineLabelsCalledOnce ::
14671 valify ::
14772 devalify ::
@@ -151,11 +76,6 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
15176 // inlineLocalObjects :: // followCases needs to be fixed, see ./tests/pos/rbtree.scala
15277 // varify :: // varify could stop other transformations from being applied. postponed.
15378 // bubbleUpNothing ::
154- // Still need to import the tailRec thing
155- // t2429.scala
156- // constraining-lub.scala
157- // t8933c.scala
158- // t348plus.scala
15979 constantFold ::
16080 Nil
16181
@@ -170,7 +90,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
17090 while (rhs1 ne rhs0) {
17191 rhs1 = rhs0
17292 val initialized = _optimizations.map(x => x(ctx.withOwner(tree.symbol)))
173- var (names, erasureSupport, visitors, transformers) = unzip4(initialized)
93+ var (names, erasureSupport , visitors, transformers) = unzip4(initialized)
17494 // TODO: fuse for performance
17595 while (names.nonEmpty) {
17696 val nextVisitor = visitors.head
@@ -202,6 +122,75 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
202122 } else tree
203123 }
204124
125+ private def desugarIdent (i : Ident )(implicit ctx : Context ): Option [Select ] = {
126+ i.tpe match {
127+ case TermRef (prefix : TermRef , name) =>
128+ Some (ref(prefix).select(i.symbol))
129+ case TermRef (prefix : ThisType , name) =>
130+ Some (This (prefix.cls).select(i.symbol))
131+ case _ => None
132+ }
133+ }
134+
135+ private def dropCasts (t : Tree )(implicit ctx : Context ): Tree = t match {
136+ // case TypeApply(aio@Select(rec, nm), _) if aio.symbol == defn.Any_asInstanceOf => dropCasts(rec)
137+ case Typed (t, tpe) => t
138+ case _ => t
139+ }
140+
141+ private def readingOnlyVals (t : Tree )(implicit ctx : Context ): Boolean = dropCasts(t) match {
142+ case Typed (exp, _) => readingOnlyVals(exp)
143+ case TypeApply (fun @ Select (rec, _), List (tp)) =>
144+ if ((fun.symbol eq defn.Any_asInstanceOf ) && rec.tpe.derivesFrom(tp.tpe.classSymbol))
145+ readingOnlyVals(rec)
146+ else false
147+ case Apply (Select (rec, _), Nil ) =>
148+ def isGetterOfAImmutableField = t.symbol.isGetter && ! t.symbol.is(Flags .Mutable )
149+ def isCaseClassWithVar = t.symbol.info.decls.exists(_.is(Flags .Mutable ))
150+ def isAccessingProductField = t.symbol.exists &&
151+ t.symbol.owner.derivesFrom(defn.ProductClass ) &&
152+ t.symbol.owner.is(Flags .CaseClass ) &&
153+ t.symbol.name.isSelectorName &&
154+ ! isCaseClassWithVar // Conservative Covers case class A(var x: Int)
155+ def isImmutableCaseAccessor = t.symbol.is(Flags .CaseAccessor ) && ! t.symbol.is(Flags .Mutable )
156+ if (isGetterOfAImmutableField || isAccessingProductField || isImmutableCaseAccessor)
157+ readingOnlyVals(rec)
158+ else false
159+ case Select (rec, _) if t.symbol.is(Flags .Method ) =>
160+ if (t.symbol.isGetter && ! t.symbol.is(Flags .Mutable )) readingOnlyVals(rec) // getter of a immutable field
161+ else if (t.symbol.owner.derivesFrom(defn.ProductClass ) && t.symbol.owner.is(Flags .CaseClass ) && t.symbol.name.isSelectorName) {
162+ def isImmutableField = {
163+ val fieldId = t.symbol.name.toString.drop(1 ).toInt - 1
164+ ! t.symbol.owner.caseAccessors(ctx)(fieldId).is(Flags .Mutable )
165+ }
166+ if (isImmutableField) readingOnlyVals(rec) // accessing a field of a product
167+ else false
168+ } else if (t.symbol.is(Flags .CaseAccessor ) && ! t.symbol.is(Flags .Mutable ))
169+ readingOnlyVals(rec)
170+ else false
171+ case Select (qual, _) if ! t.symbol.is(Flags .Mutable ) =>
172+ readingOnlyVals(qual)
173+ case t : Ident if ! t.symbol.is(Flags .Mutable ) && ! t.symbol.is(Flags .Method ) && ! t.symbol.info.dealias.isInstanceOf [ExprType ] =>
174+ desugarIdent(t) match {
175+ case Some (t) => readingOnlyVals(t)
176+ case None => true
177+ }
178+ case t : This => true
179+ // null => false, or the following fails devalify:
180+ // trait I {
181+ // def foo: Any = null
182+ // }
183+ // object Main {
184+ // def main = {
185+ // val s: I = null
186+ // s.foo
187+ // }
188+ // }
189+ case Literal (Constant (null )) => false
190+ case t : Literal => true
191+ case _ => false
192+ }
193+
205194 /** Inline case class specific methods using desugarings assumptions.
206195 *
207196 * - CC.apply(args) → new CC(args)
@@ -374,17 +363,17 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
374363 // case ift @ If(cond, thenp, elsep :Literal) if ift.tpe.derivesFrom(defn.BooleanClass) && !elsep.const.booleanValue =>
375364 // cond.select(defn.Boolean_&&).appliedTo(elsep)
376365 // // the other case ins't handled intentionally. See previous case for explanation
377- case If (t@ Select (recv, _), thenp, elsep) if t.symbol eq defn.Boolean_! =>
366+ case If (t @ Select (recv, _), thenp, elsep) if t.symbol eq defn.Boolean_! =>
378367 If (recv, elsep, thenp)
379- case If (t@ Apply (Select (recv, _), Nil ), thenp, elsep) if t.symbol eq defn.Boolean_! =>
368+ case If (t @ Apply (Select (recv, _), Nil ), thenp, elsep) if t.symbol eq defn.Boolean_! =>
380369 If (recv, elsep, thenp)
381370 // TODO: similar trick for comparisons.
382371 // TODO: handle comparison with min\max values
383372 case Apply (meth1 @ Select (Apply (meth2 @ Select (rec, _), Nil ), _), Nil ) if meth1.symbol == defn.Boolean_! && meth2.symbol == defn.Boolean_! =>
384373 rec
385374 case meth1 @ Select (meth2 @ Select (rec, _), _) if meth1.symbol == defn.Boolean_! && meth2.symbol == defn.Boolean_! && ! ctx.erasedTypes =>
386375 rec
387- case t@ Apply (Select (lhs, _), List (rhs)) =>
376+ case t @ Apply (Select (lhs, _), List (rhs)) =>
388377 val sym = t.symbol
389378 (lhs, rhs) match {
390379 case (lhs, Literal (_)) if ! lhs.isInstanceOf [Literal ] && symmetricOperations.contains(sym) =>
@@ -441,6 +430,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
441430 case t if ! isPureExpr(t) =>
442431 t
443432 case t =>
433+ // TODO: did not manage to trigger this in tests
444434 val s = ConstFold .apply(t)
445435 if ((s ne null ) && s.tpe.isInstanceOf [ConstantType ]) {
446436 val constant = s.tpe.asInstanceOf [ConstantType ].value
@@ -798,7 +788,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
798788
799789 private def keepOnlySideEffects (t : Tree )(implicit ctx : Context ): Tree = {
800790 t match {
801- case t : Literal =>
791+ case l : Literal =>
802792 EmptyTree
803793 case t : This =>
804794 EmptyTree
@@ -889,8 +879,8 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
889879 case Block (Nil , expr) => expr
890880 case a : Block =>
891881 val newStats0 = a.stats.mapConserve(keepOnlySideEffects)
892- val newStats1 = if (newStats0 eq a.stats) newStats0 else newStats0.flatMap{
893- case x : Block => x.stats ::: List (x.expr)
882+ val newStats1 = if (newStats0 eq a.stats) newStats0 else newStats0.flatMap {
883+ case x : Block => x.stats ::: List (x.expr)
894884 case EmptyTree => Nil
895885 case t => t :: Nil
896886 }
@@ -1037,7 +1027,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
10371027 if (nw ne old) nw
10381028 else tree
10391029 }
1040- (" inlineLabelsCalledOnce " , BeforeErasure , visitor, transformer)
1030+ (" inlineOptions " , BeforeErasure , visitor, transformer)
10411031 }
10421032
10431033 /** Rewrite vars with exactly one assignment as vals. */
0 commit comments