@@ -20,7 +20,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
20
20
override def phaseName : String = " simplify"
21
21
override val cpy = tpd.cpy
22
22
23
- def beforeErasure (implicit ctx : Context ): List [Optimisation ] =
23
+ private def beforeErasure (implicit ctx : Context ): List [Optimisation ] =
24
24
new InlineCaseIntrinsics ::
25
25
new RemoveUnnecessaryNullChecks ::
26
26
new InlineOptions ::
@@ -36,50 +36,73 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
36
36
new ConstantFold ::
37
37
Nil
38
38
39
- def afterErasure (implicit ctx : Context ): List [Optimisation ] =
40
- // new InlineCaseIntrinsics ::
41
- // new RemoveUnnecessaryNullChecks ::
42
- // new InlineOptions ::
43
- // new InlineLabelsCalledOnce ::
39
+ private def afterErasure (implicit ctx : Context ): List [Optimisation ] =
44
40
new Valify (this ) ::
45
41
new Devalify ::
46
42
new Jumpjump ::
47
43
new DropGoodCasts ::
48
- // new DropNoEffects(this) ::
49
- // new InlineLocalObjects :: // followCases needs to be fixed, see ./tests/pos/rbtree.scala
50
- // new Varify :: // varify could stop other transformations from being applied. postponed.
51
- // new BubbleUpNothing ::
52
44
new ConstantFold ::
53
45
Nil
54
46
47
+ /** Optimisation fuel, for debugging. Decremented every time Simplify
48
+ * applies an optimisation until fuel == 0. Original idea from Automatic
49
+ * Isolation of Compiler Errors by David Whalley. Unable with -Yopt-fuel.
50
+ *
51
+ * The fuel can be used to do a bisection on large test cases that fail
52
+ * -optimise. See compiler/test/bisect.sh for a shell script to automates
53
+ * the bisection search.
54
+ */
55
+ var fuel : Int = - 1
56
+
57
+ override def prepareForUnit (tree : Tree )(implicit ctx : Context ) = {
58
+ val maxFuel = ctx.settings.YoptFuel .value
59
+ if (fuel < 0 && maxFuel > 0 ) // Both defaults are at -1
60
+ fuel = maxFuel
61
+ this
62
+ }
63
+
55
64
// The entry point of local optimisation: DefDefs
56
65
override def transformDefDef (tree : DefDef )(implicit ctx : Context , info : TransformerInfo ): Tree = {
57
66
val ctx0 = ctx
58
67
if (ctx.settings.optimise.value && ! tree.symbol.is(Label )) {
59
68
implicit val ctx : Context = ctx0.withOwner(tree.symbol(ctx0))
60
- val optimisations = if (ctx.erasedTypes) afterErasure else beforeErasure
69
+ val optimisations = {
70
+ val o = if (ctx.erasedTypes) afterErasure else beforeErasure
71
+ val p = ctx.settings.YoptPhases .value
72
+ if (p.isEmpty) o else o.filter(x => p.contains(x.name))
73
+ }
61
74
62
75
var rhs0 = tree.rhs
63
76
var rhs1 : Tree = null
64
77
while (rhs1 ne rhs0) {
65
78
rhs1 = rhs0
66
79
val context = ctx.withOwner(tree.symbol)
67
- // TODO: fuse for performance
68
- optimisations.foreach { optimisation =>
80
+ optimisations.foreach { optimisation => // TODO: fuse for performance
81
+ // Visit
69
82
rhs0.foreachSubTree(optimisation.visitor)
70
83
71
- val rhst = new TreeMap () {
84
+ // Transform
85
+ rhs0 = new TreeMap () {
72
86
override def transform (tree : Tree )(implicit ctx : Context ): Tree = {
73
87
val innerCtx = if (tree.isDef && tree.symbol.exists) ctx.withOwner(tree.symbol) else ctx
74
- optimisation.transformer(ctx)(super .transform(tree)(innerCtx))
88
+ val childOptimizedTree = super .transform(tree)(innerCtx)
89
+
90
+ if (fuel == 0 )
91
+ childOptimizedTree
92
+ else {
93
+ val fullyOptimizedTree = optimisation.transformer(ctx)(childOptimizedTree)
94
+
95
+ if (tree ne fullyOptimizedTree) {
96
+ if (fuel > 0 ) fuel -= 1
97
+ if (fuel != - 1 && fuel < 10 ) {
98
+ println(s " ${tree.symbol} was simplified by ${optimisation.name} (fuel= $fuel): ${tree.show}" )
99
+ println(s " became after ${optimisation.name}: (fuel= $fuel) ${fullyOptimizedTree.show}" )
100
+ }
101
+ }
102
+ fullyOptimizedTree
103
+ }
75
104
}
76
105
}.transform(rhs0)
77
-
78
- if (rhst ne rhs0) {
79
- simplify.println(s " ${tree.symbol} was simplified by ${optimisation.name}: ${rhs0.show}" )
80
- simplify.println(s " became: ${rhst.show}" )
81
- }
82
- rhs0 = rhst
83
106
}
84
107
}
85
108
if (rhs0 ne tree.rhs) tpd.cpy.DefDef (tree)(rhs = rhs0)
0 commit comments