Dotty Documentation


object TreeTransforms

[-] Constructors

[-] Members

A helper trait to transform annotations on MemberDefs

[+] trait MiniPhase

A phase that defines a TreeTransform to be used in a group

[+] abstract class MiniPhaseTransform

A mini phase that is its own tree transform

[+] class NXTransformations

This class maintains track of which methods are redefined in MiniPhases and creates execution plans for transformXXX and prepareXXX Thanks to Martin for this idea

[+] class TransformerInfo
[+] abstract class TreeTransform

The base class of tree transforms. For each kind of tree K, there are two methods which can be overridden:

prepareForK // return a new TreeTransform which gets applied to the K // node and its children transformK // transform node of type K

If a transform does not need to visit a node or any of its children, it signals this fact by returning a NoTransform from a prepare method.

If all transforms in a group are NoTransforms, the tree is no longer traversed.

      Performance analysis: Taking the dotty compiler frontend as a use case, we are aiming for a warm performance of
      about 4000 lines / sec. This means 6 seconds for a codebase of 24'000 lines. Of these the frontend consumes
      over 2.5 seconds, erasure and code generation will most likely consume over 1 second each. So we would have
      about 1 sec for all other transformations in our budget. Of this second, let's assume a maximum of 20% for
      the general dispatch overhead as opposed to the concrete work done in transformations. So that leaves us with
      0.2sec, or roughly 600M processor cycles.

      Now, to the amount of work that needs to be done. The codebase produces an average of about 250'000 trees after typechecking.
      Transformations are likely to make this bigger so let's assume 300K trees on average. We estimate to have about 100
      micro-transformations. Let's say 5 transformation groups of 20 micro-transformations each. (by comparison,
      scalac has in excess of 20 phases, and most phases do multiple transformations). There are then 30M visits
      of a node by a transformation. Each visit has a budget of 20 processor cycles.

      A more detailed breakdown: I assume that about one third of all transformations have real work to do for each node.
      This might look high, but keep in mind that the most common nodes are Idents and Selects, and most transformations
      touch these. By contrast the amount of work for generating new transformations should be negligible.

      So, in 400 clock cycles we need to (1) perform a pattern match according to the type of node, (2) generate new
      transformations if applicable, (3) reconstitute the tree node from the result of transforming the children, and
      (4) chain 7 out of 20 transformations over the resulting tree node. I believe the current algorithm is suitable
      for achieving this goal, but there can be no wasted cycles anywhere.
[+] abstract class TreeTransformer

A group of tree transforms that are applied in sequence during the same phase

[+] type Mutator = (TreeTransform, T, Context) => TreeTransform
[+] @sharable val NoTransform : TreeTransform