Skip to content

Commit

Permalink
Assemble phases for -Vphases
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Nov 12, 2024
1 parent eea62ba commit 392a2cf
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 30 deletions.
27 changes: 3 additions & 24 deletions compiler/src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import typer.Typer
import typer.ImportInfo.withRootImports
import Decorators.*
import io.AbstractFile
import Phases.{unfusedPhases, Phase}
import Phases.{assemblePhases, unfusedPhases, Phase}

import sbt.interfaces.ProgressCallback

Expand Down Expand Up @@ -270,19 +270,12 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
report.echo(this.enrichErrorMessage(s"exception occurred while compiling ${files1.map(_.path)}"))
throw ex

/** TODO: There's a fundamental design problem here: We assemble phases using `fusePhases`
* when we first build the compiler. But we modify them with -Yskip, -Ystop
* on each run. That modification needs to either transform the tree structure,
* or we need to assemble phases on each run, and take -Yskip, -Ystop into
* account. I think the latter would be preferable.
*/
def compileSources(sources: List[SourceFile]): Unit =
if (sources forall (_.exists)) {
units = sources.map(CompilationUnit(_))
compileUnits()
}


def compileUnits(us: List[CompilationUnit]): Unit = {
units = us
compileUnits()
Expand All @@ -308,23 +301,9 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
then ActiveProfile(ctx.settings.VprofileDetails.value.max(0).min(1000))
else NoProfile

// If testing pickler, make sure to stop after pickling phase:
val stopAfter =
if (ctx.settings.YtestPickler.value) List("pickler")
else ctx.settings.YstopAfter.value

val runCtx = ctx.fresh
val runCtx = assemblePhases()
runCtx.setProfiler(Profiler())

val pluginPlan = ctx.base.addPluginPhases(ctx.base.phasePlan)
val phases = ctx.base.fusePhases(pluginPlan,
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
ctx.base.usePhases(phases, runCtx)
val phasesSettings = List("-Vphases", "-Vprint")
for phasesSetting <- ctx.settings.allSettings if phasesSettings.contains(phasesSetting.name) do
for case vs: List[String] <- phasesSetting.userValue; p <- vs do
if !phases.exists(List(p).containsPhase) then report.warning(s"'$p' specifies no phase")

if ctx.settings.YnoDoubleBindings.value then
ctx.base.checkNoDoubleBindings = true

Expand All @@ -334,7 +313,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
var phasesWereAdjusted = false

var forceReachPhaseMaybe =
if (ctx.isBestEffort && phases.exists(_.phaseName == "typer")) Some("typer")
if (ctx.isBestEffort && allPhases.exists(_.phaseName == "typer")) Some("typer")
else None

for phase <- allPhases do
Expand Down
14 changes: 12 additions & 2 deletions compiler/src/dotty/tools/dotc/config/CliCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import scala.language.unsafeNulls

import Settings.*
import core.Contexts.*
import core.Phases.assemblePhases
import printing.Highlighting
import transform.MegaPhase

import scala.util.chaining.given
import scala.PartialFunction.cond
Expand Down Expand Up @@ -117,9 +119,17 @@ trait CliCommand:

/** Used for the formatted output of -Xshow-phases */
protected def phasesMessage(using Context): String =
val phases = new Compiler().phases
val compiler = Compiler()
ctx.initialize()
ctx.base.setPhasePlan(compiler.phases)
val runCtx = assemblePhases()
val phases = runCtx.base.allPhases
val texts = phases.iterator.map {
case mp: MegaPhase => mp.miniPhases.iterator.map(p => (p.phaseName, p.description)).toList
case p => (p.phaseName, p.description) :: Nil
}.toList
val formatter = Columnator("phase name", "description", maxField = 25)
formatter(phases.map(mega => mega.map(p => (p.phaseName, p.description))))
formatter(texts)

/** Provide usage feedback on argument summary, assuming that all settings
* are already applied in context.
Expand Down
28 changes: 24 additions & 4 deletions compiler/src/dotty/tools/dotc/core/Phases.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,12 @@ object Phases {
*/
final def usePhases(phasess: List[Phase], runCtx: FreshContext, fuse: Boolean = true): Unit = {

val flatPhases = collection.mutable.ListBuffer[Phase]()
val flatPhases = ListBuffer.empty[Phase]

phasess.foreach(p => p match {
phasess.foreach {
case p: MegaPhase => flatPhases ++= p.miniPhases
case _ => flatPhases += p
})
case p => flatPhases += p
}

phases = (NoPhase :: flatPhases.toList ::: new TerminalPhase :: Nil).toArray
setSpecificPhases()
Expand Down Expand Up @@ -561,4 +561,24 @@ object Phases {
private def replace(oldPhaseClass: Class[? <: Phase], newPhases: Phase => List[Phase], current: List[List[Phase]]): List[List[Phase]] =
current.map(_.flatMap(phase =>
if (oldPhaseClass.isInstance(phase)) newPhases(phase) else phase :: Nil))

def assemblePhases()(using Context): FreshContext =
val runCtx = ctx.fresh

// If testing pickler, make sure to stop after pickling phase:
val stopAfter =
if (ctx.settings.YtestPickler.value) List("pickler")
else ctx.settings.YstopAfter.value

val pluginPlan = ctx.base.addPluginPhases(ctx.base.phasePlan)
val phases = ctx.base.fusePhases(pluginPlan,
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
ctx.base.usePhases(phases, runCtx)

val phasesSettings = List("-Vphases", "-Vprint")
for phasesSetting <- ctx.settings.allSettings if phasesSettings.contains(phasesSetting.name) do
for case vs: List[String] <- phasesSetting.userValue; p <- vs do
if !phases.exists(List(p).containsPhase) then report.warning(s"'$p' specifies no phase")
runCtx
end assemblePhases
}

0 comments on commit 392a2cf

Please sign in to comment.