Skip to content

Commit 10aa8cb

Browse files
committed
Split Compiler.phases into smaller logical groups
1 parent 88d016c commit 10aa8cb

File tree

7 files changed

+144
-127
lines changed

7 files changed

+144
-127
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 92 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -39,78 +39,99 @@ class Compiler {
3939
* - after erasure, asSeenFrom is the identity, so every reference has a
4040
* plain SymDenotation, as opposed to a UniqueRefDenotation.
4141
*/
42-
def phases: List[List[Phase]] =
43-
List(
44-
List(new FrontEnd), // Compiler frontend: scanner, parser, namer, typer
45-
List(new sbt.ExtractDependencies), // Sends information on classes' dependencies to sbt via callbacks
46-
List(new PostTyper), // Additional checks and cleanups after type checking
47-
List(new sbt.ExtractAPI), // Sends a representation of the API of classes to sbt via callbacks
48-
List(new Pickler), // Generate TASTY info
49-
List(new LinkAll), // Reload compilation units from TASTY for library code (if needed)
50-
List(new FirstTransform, // Some transformations to put trees into a canonical form
51-
new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars
52-
new ElimJavaPackages), // Eliminate syntactic references to Java packages
53-
List(new CheckStatic, // Check restrictions that apply to @static members
54-
new ElimRepeated, // Rewrite vararg parameters and arguments
55-
new NormalizeFlags, // Rewrite some definition flags
56-
new ExtensionMethods, // Expand methods of value classes with extension methods
57-
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
58-
new TailRec, // Rewrite tail recursion to loops
59-
new ByNameClosures, // Expand arguments to by-name parameters to closures
60-
new LiftTry, // Put try expressions that might execute on non-empty stacks into their own methods
61-
new HoistSuperArgs, // Hoist complex arguments of supercalls to enclosing scope
62-
new ClassOf, // Expand `Predef.classOf` calls.
63-
new RefChecks), // Various checks mostly related to abstract members and overriding
64-
List(new TryCatchPatterns, // Compile cases in try/catch
65-
new PatternMatcher, // Compile pattern matches
66-
new ExplicitOuter, // Add accessors to outer classes from nested ones.
67-
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
68-
new ShortcutImplicits, // Allow implicit functions without creating closures
69-
new CrossCastAnd, // Normalize selections involving intersection types.
70-
new Splitter), // Expand selections involving union types into conditionals
71-
List(new PhantomArgLift, // Extracts the evaluation of phantom arguments placing them before the call.
72-
new VCInlineMethods, // Inlines calls to value class methods
73-
new SeqLiterals, // Express vararg arguments as arrays
74-
new InterceptedMethods, // Special handling of `==`, `|=`, `getClass` methods
75-
new Getters, // Replace non-private vals and vars with getter defs (fields are added later)
76-
new ElimByName, // Expand by-name parameter references
77-
new ElimOuterSelect, // Expand outer selections
78-
new AugmentScala2Traits, // Expand traits defined in Scala 2.x to simulate old-style rewritings
79-
new ResolveSuper, // Implement super accessors and add forwarders to trait methods
80-
new Simplify, // Perform local optimizations, simplified versions of what linker does.
81-
new PrimitiveForwarders, // Add forwarders to trait methods that have a mismatch between generic and primitives
82-
new FunctionXXLForwarders, // Add forwarders for FunctionXXL apply method
83-
new ArrayConstructors), // Intercept creation of (non-generic) arrays and intrinsify.
84-
List(new Erasure), // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
85-
List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types
86-
new VCElideAllocations, // Peep-hole optimization to eliminate unnecessary value class allocations
87-
new Mixin, // Expand trait fields and trait initializers
88-
new LazyVals, // Expand lazy vals
89-
new Memoize, // Add private fields to getters and setters
90-
new NonLocalReturns, // Expand non-local returns
91-
new CapturedVars), // Represent vars captured by closures as heap objects
92-
List(new Constructors, // Collect initialization code in primary constructors
93-
// Note: constructors changes decls in transformTemplate, no InfoTransformers should be added after it
94-
new FunctionalInterfaces, // Rewrites closures to implement @specialized types of Functions.
95-
new GetClass, // Rewrites getClass calls on primitive types.
96-
new Simplify), // Perform local optimizations, simplified versions of what linker does.
97-
List(new LinkScala2Impls, // Redirect calls to trait methods defined by Scala 2.x, so that they now go to their implementations
98-
new LambdaLift, // Lifts out nested functions to class scope, storing free variables in environments
42+
def phases: List[List[Phase]] = {
43+
val listBuilder = List.newBuilder[List[Phase]]
44+
listBuilder ++= frontendPhases
45+
listBuilder ++= picklerPhases
46+
listBuilder ++= transformPhases
47+
listBuilder ++= backendPhases
48+
listBuilder.result()
49+
}
50+
51+
/** Phases dealing with the the frontend up to trees ready for TASTY pickling */
52+
protected def frontendPhases: List[List[Phase]] =
53+
List(new FrontEnd) :: // Compiler frontend: scanner, parser, namer, typer
54+
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
55+
List(new PostTyper) :: // Additional checks and cleanups after type checking
56+
List(new sbt.ExtractAPI) :: // Sends a representation of the API of classes to sbt via callbacks
57+
Nil
58+
59+
/** Phases dealing with TASTY tree pickling and unpickling */
60+
protected def picklerPhases: List[List[Phase]] =
61+
List(new Pickler) :: // Generate TASTY info
62+
List(new LinkAll) :: // Reload compilation units from TASTY for library code (if needed)
63+
Nil
64+
65+
/** Phases dealing transforming from pickled trees to backend trees */
66+
protected def transformPhases: List[List[Phase]] =
67+
List(new FirstTransform, // Some transformations to put trees into a canonical form
68+
new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars
69+
new ElimJavaPackages) :: // Eliminate syntactic references to Java packages
70+
List(new CheckStatic, // Check restrictions that apply to @static members
71+
new ElimRepeated, // Rewrite vararg parameters and arguments
72+
new NormalizeFlags, // Rewrite some definition flags
73+
new ExtensionMethods, // Expand methods of value classes with extension methods
74+
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
75+
new TailRec, // Rewrite tail recursion to loops
76+
new ByNameClosures, // Expand arguments to by-name parameters to closures
77+
new LiftTry, // Put try expressions that might execute on non-empty stacks into their own methods
78+
new HoistSuperArgs, // Hoist complex arguments of supercalls to enclosing scope
79+
new ClassOf, // Expand `Predef.classOf` calls.
80+
new RefChecks) :: // Various checks mostly related to abstract members and overriding
81+
List(new TryCatchPatterns, // Compile cases in try/catch
82+
new PatternMatcher, // Compile pattern matches
83+
new ExplicitOuter, // Add accessors to outer classes from nested ones.
84+
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
85+
new ShortcutImplicits, // Allow implicit functions without creating closures
86+
new CrossCastAnd, // Normalize selections involving intersection types.
87+
new Splitter) :: // Expand selections involving union types into conditionals
88+
List(new PhantomArgLift, // Extracts the evaluation of phantom arguments placing them before the call.
89+
new VCInlineMethods, // Inlines calls to value class methods
90+
new SeqLiterals, // Express vararg arguments as arrays
91+
new InterceptedMethods, // Special handling of `==`, `|=`, `getClass` methods
92+
new Getters, // Replace non-private vals and vars with getter defs (fields are added later)
93+
new ElimByName, // Expand by-name parameter references
94+
new ElimOuterSelect, // Expand outer selections
95+
new AugmentScala2Traits, // Expand traits defined in Scala 2.x to simulate old-style rewritings
96+
new ResolveSuper, // Implement super accessors and add forwarders to trait methods
97+
new Simplify, // Perform local optimizations, simplified versions of what linker does.
98+
new PrimitiveForwarders, // Add forwarders to trait methods that have a mismatch between generic and primitives
99+
new FunctionXXLForwarders, // Add forwarders for FunctionXXL apply method
100+
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
101+
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
102+
List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types
103+
new VCElideAllocations, // Peep-hole optimization to eliminate unnecessary value class allocations
104+
new Mixin, // Expand trait fields and trait initializers
105+
new LazyVals, // Expand lazy vals
106+
new Memoize, // Add private fields to getters and setters
107+
new NonLocalReturns, // Expand non-local returns
108+
new CapturedVars) :: // Represent vars captured by closures as heap objects
109+
List(new Constructors, // Collect initialization code in primary constructors
110+
// Note: constructors changes decls in transformTemplate, no InfoTransformers should be added after it
111+
new FunctionalInterfaces, // Rewrites closures to implement @specialized types of Functions.
112+
new GetClass, // Rewrites getClass calls on primitive types.
113+
new Simplify) :: // Perform local optimizations, simplified versions of what linker does.
114+
List(new LinkScala2Impls, // Redirect calls to trait methods defined by Scala 2.x, so that they now go to their implementations
115+
new LambdaLift, // Lifts out nested functions to class scope, storing free variables in environments
99116
// Note: in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
100-
new ElimStaticThis), // Replace `this` references to static objects by global identifiers
101-
List(new Flatten, // Lift all inner classes to package scope
102-
new RestoreScopes, // Repair scopes rendered invalid by moving definitions in prior phases of the group
103-
new RenameLifted, // Renames lifted classes to local numbering scheme
104-
new TransformWildcards, // Replace wildcards with default values
105-
new MoveStatics, // Move static methods to companion classes
106-
new ExpandPrivate, // Widen private definitions accessed from nested classes
107-
new SelectStatic, // get rid of selects that would be compiled into GetStatic
108-
new CollectEntryPoints, // Find classes with main methods
109-
new CollectSuperCalls, // Find classes that are called with super
110-
new DropInlined, // Drop Inlined nodes, since backend has no use for them
111-
new LabelDefs), // Converts calls to labels to jumps
112-
List(new GenBCode) // Generate JVM bytecode
113-
)
117+
new ElimStaticThis) :: // Replace `this` references to static objects by global identifiers
118+
List(new Flatten, // Lift all inner classes to package scope
119+
new RestoreScopes, // Repair scopes rendered invalid by moving definitions in prior phases of the group
120+
new RenameLifted, // Renames lifted classes to local numbering scheme
121+
new TransformWildcards, // Replace wildcards with default values
122+
new MoveStatics, // Move static methods to companion classes
123+
new ExpandPrivate, // Widen private definitions accessed from nested classes
124+
new SelectStatic, // get rid of selects that would be compiled into GetStatic
125+
new CollectEntryPoints, // Find classes with main methods
126+
new CollectSuperCalls, // Find classes that are called with super
127+
new DropInlined, // Drop Inlined nodes, since backend has no use for them
128+
new LabelDefs) :: // Converts calls to labels to jumps
129+
Nil
130+
131+
/** Generate the output of the compilation */
132+
protected def backendPhases: List[List[Phase]] =
133+
List(new GenBCode) :: // Generate JVM bytecode
134+
Nil
114135

115136
var runId = 1
116137
def nextRunId = {

compiler/src/dotty/tools/dotc/decompiler/TASTYDecompiler.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ import dotty.tools.dotc.core.Phases.Phase
99
* @author Nicolas Stucki
1010
*/
1111
class TASTYDecompiler extends TASTYCompiler {
12-
override def phases: List[List[Phase]] = List(
13-
List(new ReadTastyTreesFromClasses), // Load classes from tasty
14-
List(new DecompilationPrinter) // Print all loaded classes
15-
)
12+
13+
override protected def frontendPhases: List[List[Phase]] =
14+
List(new ReadTastyTreesFromClasses) :: // Load classes from tasty
15+
Nil
16+
17+
override protected def picklerPhases: List[List[Phase]] = Nil
18+
override protected def transformPhases: List[List[Phase]] = Nil
19+
20+
override protected def backendPhases: List[List[Phase]] =
21+
List(new DecompilationPrinter) :: // Print all loaded classes
22+
Nil
1623
}

compiler/src/dotty/tools/dotc/fromtasty/TASTYCompiler.scala

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@ package fromtasty
55
import core._
66
import Contexts._
77
import Phases.Phase
8-
import dotty.tools.dotc.transform.Pickler
8+
import dotty.tools.dotc.transform._
99

1010
class TASTYCompiler extends Compiler {
1111

12-
override def phases: List[List[Phase]] = {
13-
val backendPhases = super.phases.dropWhile {
14-
case List(_: Pickler) => false
15-
case _ => true
16-
}.tail
17-
List(new ReadTastyTreesFromClasses) :: backendPhases
18-
}
12+
override protected def frontendPhases: List[List[Phase]] =
13+
List(new ReadTastyTreesFromClasses) :: Nil
14+
15+
override protected def picklerPhases: List[List[Phase]] =
16+
super.picklerPhases.map(_.filterNot(_.isInstanceOf[Pickler])) // No need to repickle
1917

2018
override def newRun(implicit ctx: Context): Run = {
2119
reset()

compiler/src/dotty/tools/repl/ReplCompiler.scala

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
package dotty.tools
22
package repl
33

4-
import java.io.{ File => JFile }
5-
64
import dotc.ast.Trees._
75
import dotc.ast.{ untpd, tpd }
86
import dotc.{ Run, CompilationUnit, Compiler }
9-
import dotc.core.Decorators._, dotc.core.Flags._, dotc.core.Phases
7+
import dotc.core.Decorators._, dotc.core.Flags._, dotc.core.Phases, Phases.Phase
108
import dotc.core.Names._, dotc.core.Contexts._, dotc.core.StdNames._
119
import dotc.core.Constants.Constant
1210
import dotc.util.SourceFile
1311
import dotc.typer.{ ImportInfo, FrontEnd }
1412
import backend.jvm.GenBCode
1513
import dotc.core.NameOps._
1614
import dotc.util.Positions._
17-
import dotc.reporting.diagnostic.{ messages, MessageContainer }
18-
import dotc.reporting._
15+
import dotc.reporting.diagnostic.messages
1916
import io._
2017

2118
import results._
@@ -37,19 +34,11 @@ class ReplCompiler(val directory: AbstractFile) extends Compiler {
3734
override def outputDir(implicit ctx: Context) = directory
3835
}
3936

40-
override def phases = {
41-
val replacedFrontend = Phases.replace(
42-
classOf[FrontEnd],
43-
_ => new REPLFrontEnd :: Nil,
44-
super.phases
45-
)
37+
override protected def frontendPhases: List[List[Phase]] =
38+
Phases.replace(classOf[FrontEnd], _ => new REPLFrontEnd :: Nil, super.frontendPhases)
4639

47-
Phases.replace(
48-
classOf[GenBCode],
49-
_ => new REPLGenBCode :: Nil,
50-
replacedFrontend
51-
)
52-
}
40+
override protected def backendPhases: List[List[Phase]] =
41+
List(new REPLGenBCode) :: Nil
5342

5443
def newRun(initCtx: Context, objectIndex: Int) = new Run(this, initCtx) {
5544
override protected[this] def rootContext(implicit ctx: Context) =

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTest.scala

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,18 @@ trait DottyBytecodeTest extends DottyTest {
4545
val javaString = "java/lang/String"
4646
}
4747

48-
private def bCodeCheckingComp(phase: TestGenBCode)(check: Directory => Unit) =
48+
private def bCodeCheckingComp(testPhase: TestGenBCode)(check: Directory => Unit) = {
49+
class AssertionChecker extends Phase {
50+
def phaseName = "assertionChecker"
51+
def run(implicit ctx: Context): Unit = check(testPhase.virtualDir)
52+
}
4953
new Compiler {
50-
override def phases = {
51-
val updatedPhases = {
52-
def replacePhase: Phase => Phase =
53-
{ p => if (p.phaseName == "genBCode") phase else p }
54-
55-
for (phaseList <- super.phases) yield phaseList.map(replacePhase)
56-
}
57-
58-
val checkerPhase = List(List(new Phase {
59-
def phaseName = "assertionChecker"
60-
override def run(implicit ctx: Context): Unit =
61-
check(phase.virtualDir)
62-
}))
63-
64-
updatedPhases ::: checkerPhase
65-
}
54+
override protected def backendPhases: List[List[Phase]] =
55+
List(testPhase) ::
56+
List(new AssertionChecker) ::
57+
Nil
6658
}
59+
}
6760

6861
private def outPath(obj: Any) =
6962
"/genBCodeTest" + math.abs(obj.hashCode) + System.currentTimeMillis

doc-tool/src/dotty/tools/dottydoc/DocCompiler.scala

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ import dotc.Compiler
1919
* 3. Serialize to JS object
2020
*/
2121
class DocCompiler extends Compiler {
22-
override def phases: List[List[Phase]] = List(
23-
List(new DocFrontEnd),
24-
List(new DocImplicitsPhase),
25-
List(new DocASTPhase),
22+
23+
override protected def frontendPhases: List[List[Phase]] =
24+
List(new DocFrontEnd) :: Nil
25+
26+
override protected def picklerPhases: List[List[Phase]] =
27+
Nil
28+
29+
override protected def transformPhases: List[List[Phase]] =
30+
List(new DocImplicitsPhase) ::
31+
List(new DocASTPhase) ::
2632
List(DocMiniTransformations(new UsecasePhase,
2733
new DocstringPhase,
2834
new PackageObjectsPhase,
@@ -32,8 +38,11 @@ class DocCompiler extends Compiler {
3238
new LinkSuperTypes,
3339
new LinkCompanions,
3440
new AlternateConstructors,
35-
new SortMembers)),
36-
List(DocMiniTransformations(new RemoveEmptyPackages)),
37-
List(new StatisticsPhase)
38-
)
41+
new SortMembers)) ::
42+
List(DocMiniTransformations(new RemoveEmptyPackages)) ::
43+
Nil
44+
45+
override protected def backendPhases: List[List[Phase]] =
46+
List(new StatisticsPhase) :: Nil
47+
3948
}

doc-tool/test/DottyDocTest.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ trait DottyDocTest extends MessageRendering {
5252
}
5353
}) :: Nil
5454

55-
override def phases =
56-
super.phases ++ assertionPhase
55+
override protected def backendPhases: List[List[Phase]] =
56+
super.backendPhases ++ assertionPhase
5757
}
5858

5959
private def callingMethod: String =

0 commit comments

Comments
 (0)