Skip to content

Commit d69cd13

Browse files
DarkDimiusOlivierBlanvillain
authored andcommitted
Improve Simplify's documentation
1 parent f6e4632 commit d69cd13

File tree

9 files changed

+44
-5
lines changed

9 files changed

+44
-5
lines changed

compiler/src/dotty/tools/dotc/transform/localopt/BubbleUpNothing.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@ import core.Contexts.Context
55
import core.Symbols._
66
import ast.Trees._
77

8-
/** Every pure statement preceding a ??? can be removed.
8+
/**
9+
* If a block has a statement that evaluates to Nothing:
10+
* - Every pure statement dirrectly preceding an expression that returns Nothing can be removed,
11+
* - as every statement after an expression that returns Nothing can be removed
12+
*
13+
* If an If condition evalutates to Nothing, the entire If can be replaced by condition
14+
* If an argument evaluates to Nothing, the entire call can be replaced by evaluation of arguments.
915
*
1016
* This optimisation makes it rather tricky to write meaningful examples
1117
* since the compiler will often be able to reduce them to a single main
1218
* method with body = ???.
19+
*
20+
* @author DarkDimius, OlivierBlanvillain
1321
*/
1422
class BubbleUpNothing(implicit val ctx: Context) extends Optimisation {
1523
import ast.tpd._

compiler/src/dotty/tools/dotc/transform/localopt/ConstantFold.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ import Simplify.desugarIdent
1111
/** Various constant folding.
1212
*
1313
* - Starts/ends with the constant folding implemented in typer (ConstFold).
14-
*
14+
* - Join branches if they are "similar"
15+
* - regularize arithmetic and boolean expressions to have constants on the left, ie. 6 * 2 * a * 5 => 60 * a
1516
* - (if) specific optimisation that propagate booleans, negation, and factor
16-
* out (nested) if with equivalent branches wrt to isSimilar (using &&,||).
17+
* out (nested) if with equivalent branches wrt to isSimilar (using &&,||). Dark: ping @OlivierBlanvillain, I didn't understand this
1718
*
1819
* - Constant propagation over pattern matching.
20+
*
21+
* @author DarkDimius, OlivierBlanvillain
1922
*/
2023
class ConstantFold(implicit val ctx: Context) extends Optimisation {
2124
import ast.tpd._

compiler/src/dotty/tools/dotc/transform/localopt/Devalify.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ import config.Printers.simplify
1313
import Simplify.desugarIdent
1414
import transform.SymUtils._
1515

16-
/** Inline vals */
16+
/** Inline vals and remove vals that are aliases to other vals
17+
*
18+
* Notion of alias is a by-value notion, so "good" casts are ignored.
19+
*
20+
* This phase has to be careful not to eliminate vals that are parts of other types
21+
* @author DarkDimius, OlivierBlanvillain
22+
* */
1723
class Devalify(implicit val ctx: Context) extends Optimisation {
1824
import ast.tpd._
1925

compiler/src/dotty/tools/dotc/transform/localopt/DropGoodCasts.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import transform.SymUtils._
1616
*
1717
* - a.asInstanceOf[T] → a when we know that a: T
1818
* - Simplify (a == null) and (a != null) when the result is statically known
19+
*
20+
* @author DarkDimius, OlivierBlanvillain
1921
*/
2022
class DropGoodCasts(implicit val ctx: Context) extends Optimisation {
2123
import ast.tpd._

compiler/src/dotty/tools/dotc/transform/localopt/DropNoEffects.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import ast.Trees._
1111
import Simplify.desugarIdent
1212

1313
/** Removes side effect free statements in blocks and Defdef.
14+
* Flattens blocks(except Closure-blocks)
1415
* Note: BoxedUnit currently messes up this phase when run after erasure
16+
*
17+
* @author DarkDimius, OlivierBlanvillain
1518
*/
1619
class DropNoEffects(val simplifyPhase: Simplify)(implicit val ctx: Context) extends Optimisation {
1720
import ast.tpd._

compiler/src/dotty/tools/dotc/transform/localopt/InlineCaseIntrinsics.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ import core.Flags._
1010
import ast.Trees._
1111
import transform.SymUtils._
1212
import Simplify.desugarIdent
13+
import dotty.tools.dotc.ast.tpd
1314

1415
/** Inline case class specific methods using desugarings assumptions.
1516
*
1617
* Note: to run this optimisation after erasure one would need to specialize
1718
* it for constructor with outer pointer and values classes. There is
1819
* probably no need to run this more than once.
20+
*
21+
* @author DarkDimius, OlivierBlanvillain
1922
*/
2023
class InlineCaseIntrinsics(implicit val ctx: Context) extends Optimisation {
2124
import ast.tpd._

compiler/src/dotty/tools/dotc/transform/localopt/RemoveUnnecessaryNullChecks.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import scala.collection.mutable
4040
val visitor: Tree => Unit = {
4141
case vd: ValDef =>
4242
val rhs = vd.rhs
43-
val rhsName = rhs.symbol.name
4443
if (!vd.symbol.is(Mutable) && !rhs.isEmpty) {
4544
def checkNonNull(t: Tree, target: Symbol): Boolean = t match {
4645
case Block(_ , expr) =>

compiler/src/dotty/tools/dotc/transform/localopt/Simplify.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,24 @@ import ast.tpd
1414
*
1515
* The termination condition uses referential equality on Trees. Furthermore,
1616
* termination relies of every optimisation to be shrinking transformations.
17+
*
18+
* This phase is intended to be run multiple times in the compilation pipeline.
19+
* This is due to several reasons:
20+
* - running this phase early allows to reduce size of compilation unit, speeding up subsequent transformations.
21+
* - running this phase late allows to eliminate inefficiencies created by previous phase
22+
* - different patters are easier to optimize at different moments of pipeline
1723
*/
1824
class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
1925
import tpd._
2026
override def phaseName: String = "simplify"
2127
override val cpy = tpd.cpy
2228

29+
/** The original intention is to run most optimizations both before and after erasure.
30+
* Erasure creates new inefficiencies as well as new optimization opportunities.
31+
*
32+
* The order of optimizations is tuned to converge faster.
33+
* Reordering them may require quadratically more rounds to finish.
34+
*/
2335
private def beforeErasure(implicit ctx: Context): List[Optimisation] =
2436
new InlineCaseIntrinsics ::
2537
new RemoveUnnecessaryNullChecks ::
@@ -36,6 +48,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
3648
new ConstantFold ::
3749
Nil
3850

51+
/** see comment on beforeErasure */
3952
private def afterErasure(implicit ctx: Context): List[Optimisation] =
4053
new Valify(this) ::
4154
new Devalify ::

compiler/src/dotty/tools/dotc/transform/localopt/Varify.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import scala.collection.mutable
1111
*
1212
* {
1313
* val l = <expr>
14+
* // code that may use l
1415
* var r = l
1516
* // code not using l
1617
* }
@@ -19,6 +20,7 @@ import scala.collection.mutable
1920
*
2021
* {
2122
* var r = <expr>
23+
* // code that may use l
2224
* // code not using l
2325
* }
2426
*/

0 commit comments

Comments
 (0)