Dotty Documentation

0.4.0-bin-SNAPSHOT

package dotty.tools.dotc.transform.localopt

[-] Constructors

[-] Members

[+] class BubbleUpNothing

If a block has a statement that evaluates to Nothing: - Every pure statement dirrectly preceding an expression that returns Nothing can be removed, - as every statement after an expression that returns Nothing can be removed

If an If condition evalutates to Nothing, the entire If can be replaced by condition If an argument evaluates to Nothing, the entire call can be replaced by evaluation of arguments.

This optimisation makes it rather tricky to write meaningful examples since the compiler will often be able to reduce them to a single main method with body = ???.

[+] class ConstantFold

Various constant folding.

  • Starts/ends with the constant folding implemented in typer (ConstFold).

  • Join branches if they are "similar"

  • regularize arithmetic and boolean expressions to have constants on the left, ie. 6 * 2 * a * 5 => 60 * a

  • (if) specific optimisation that propagate booleans, negation, and factor out (nested) if with equivalent branches wrt to isSimilar. For example:
    • if (b) exp else exp → b; exp
    • if (b1) e1 else if (b2) e1 else e2 → if (b1 || b2) e1 else e2
  • Constant propagation over pattern matching.
[+] class Devalify

Inline vals and remove vals that are aliases to other vals

Notion of alias is a by-value notion, so "good" casts are ignored.

This phase has to be careful not to eliminate vals that are parts of other types

[+] class DropGoodCasts

Eliminated casts and equality tests whose results can be locally determined at compile time:

  • a.asInstanceOf[T] → a when we know that a: T
  • Simplify (a == null) and (a != null) when the result is statically known
[+] class DropNoEffects

Removes side effect free statements in blocks and Defdef. Flattens blocks (except Closure-blocks) Note: BoxedUnit currently messes up this phase when run after erasure

Inline case class specific methods using desugarings assumptions.

Note: to run this optimisation after erasure one would need to specialize it for constructor with outer pointer and values classes. There is probably no need to run this more than once.

Inlines LabelDef which are used exactly once.

[+] class InlineLocalObjects

Rewrite fields of local instances as vals.

If a local instance does not escape the local scope, it will be removed later by DropNoEffects, thus implementing the equivalent of (local) multi parameter value classes. The main motivation for this transformation is to get ride of the intermediate tuples object somes created when pattern matching on Scala2 case classes.

[+] class InlineOptions

Inlines Option methods whose result is known statically.

[+] class Jumpjump

Rewrites pairs of consecutive LabelDef jumps by jumping directly to the target.

[+] trait Optimisation

Eliminated null checks based on the following observations:

  • (this) cannot be null
  • (new C) cannot be null
  • literal is either null itself or non null
  • fallsback to tpe.isNotNull, which will eventually be true for non nullable types.
  • in (a.call; a == null), the first call throws a NPE if a is null; the test can be removed.
[+] class Simplify

This phase consists of a series of small, simple, local optimisations applied as a fix point transformation over Dotty Trees.

The termination condition uses referential equality on Trees. Furthermore, termination relies of every optimisation to be shrinking transformations.

This phase is intended to be run multiple times in the compilation pipeline. This is due to several reasons: - running this phase early allows to reduce size of compilation unit, speeding up subsequent transformations. - running this phase late allows to eliminate inefficiencies created by previous phase - different patters are easier to optimize at different moments of pipeline

[+] object Simplify
[+] class Valify

Rewrite vars with exactly one assignment as vals.

[+] class Varify

Inline val with exactly one assignment to a var. For example:

{ val l = // code that may use l var r = l // code not using l }

becomes:

{ var r = // code that may use l // code not using l }