Skip to content

Commit b61a193

Browse files
Merge pull request scala#3671 from dotty-staging/split-compiler-phases
Split Compiler.phases into smaller logical groups
2 parents f709c2c + d732ae4 commit b61a193

File tree

7 files changed

+139
-128
lines changed

7 files changed

+139
-128
lines changed

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

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

116131
var runId = 1
117132
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)