@@ -176,13 +176,13 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
176
176
if local != null then
177
177
op(using ctx)(local)
178
178
179
- def doBeginUnit (unit : CompilationUnit )(using Context ): Unit =
179
+ def doBeginUnit ()(using Context ): Unit =
180
180
trackProgress : progress =>
181
- progress.informUnitStarting(unit )
181
+ progress.informUnitStarting(ctx.compilationUnit )
182
182
183
183
def doAdvanceUnit ()(using Context ): Unit =
184
184
trackProgress : progress =>
185
- progress.unitc += 1 // trace that we completed a unit in the current phase
185
+ progress.unitc += 1 // trace that we completed a unit in the current (sub) phase
186
186
progress.refreshProgress()
187
187
188
188
def doAdvanceLate ()(using Context ): Unit =
@@ -196,14 +196,23 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
196
196
197
197
private def doAdvancePhase (currentPhase : Phase , wasRan : Boolean )(using Context ): Unit =
198
198
trackProgress : progress =>
199
- progress.unitc = 0 // reset unit count in current phase
200
- progress.seen += 1 // trace that we've seen a phase
199
+ progress.unitc = 0 // reset unit count in current (sub)phase
200
+ progress.subtraversalc = 0 // reset subphase index to initial
201
+ progress.seen += 1 // trace that we've seen a (sub)phase
201
202
if wasRan then
202
- // add an extra traversal now that we completed a phase
203
+ // add an extra traversal now that we completed a (sub) phase
203
204
progress.traversalc += 1
204
205
else
205
- // no phase was ran, remove a traversal from expected total
206
- progress.runnablePhases -= 1
206
+ // no subphases were ran, remove traversals from expected total
207
+ progress.totalTraversals -= currentPhase.traversals
208
+
209
+ private def doAdvanceSubPhase ()(using Context ): Unit =
210
+ trackProgress : progress =>
211
+ progress.unitc = 0 // reset unit count in current (sub)phase
212
+ progress.seen += 1 // trace that we've seen a (sub)phase
213
+ progress.traversalc += 1 // add an extra traversal now that we completed a (sub)phase
214
+ progress.subtraversalc += 1 // record that we've seen a subphase
215
+ progress.tickSubphase()
207
216
208
217
/** Will be set to true if any of the compiled compilation units contains
209
218
* a pureFunctions language import.
@@ -318,7 +327,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
318
327
unfusedPhases.foreach(_.initContext(runCtx))
319
328
val fusedPhases = runCtx.base.allPhases
320
329
runCtx.withProgressCallback: cb =>
321
- _progress = Progress (cb, this , fusedPhases.length )
330
+ _progress = Progress (cb, this , fusedPhases.map(_.traversals).sum )
322
331
runPhases(allPhases = fusedPhases)(using runCtx)
323
332
if (! ctx.reporter.hasErrors)
324
333
Rewrites .writeBack()
@@ -451,31 +460,52 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
451
460
452
461
object Run {
453
462
454
- /** Computes the next MegaPhase for the given phase.*/
455
- def nextMegaPhase (phase : Phase )(using Context ): Phase = phase.megaPhase.next.megaPhase
463
+ class SubPhases (val phase : Phase ):
464
+ require(phase.exists)
465
+
466
+ val all = IArray .from(phase.subPhases.map(sub => s " ${phase.phaseName} ( $sub) " ))
467
+
468
+ def next (using Context ): Option [SubPhases ] =
469
+ val next0 = phase.megaPhase.next.megaPhase
470
+ if next0.exists then Some (SubPhases (next0))
471
+ else None
456
472
457
- private class Progress (cb : ProgressCallback , private val run : Run , val initialPhases : Int ):
458
- private [Run ] var runnablePhases : Int = initialPhases // track how many phases we expect to run
459
- private [Run ] var unitc : Int = 0 // current unit count in the current phase
473
+ def subPhase (index : Int ) =
474
+ if index < all.size then all(index)
475
+ else phase.phaseName
476
+
477
+ private class Progress (cb : ProgressCallback , private val run : Run , val initialTraversals : Int ):
478
+ private [Run ] var totalTraversals : Int = initialTraversals // track how many phases we expect to run
479
+ private [Run ] var unitc : Int = 0 // current unit count in the current (sub)phase
460
480
private [Run ] var latec : Int = 0 // current late unit count
461
481
private [Run ] var traversalc : Int = 0 // completed traversals over all files
482
+ private [Run ] var subtraversalc : Int = 0 // completed subphases in the current phase
462
483
private [Run ] var seen : Int = 0 // how many phases we've seen so far
463
484
464
485
private var currPhase : Phase = uninitialized // initialized by enterPhase
486
+ private var subPhases : SubPhases = uninitialized // initialized by enterPhase
465
487
private var currPhaseName : String = uninitialized // initialized by enterPhase
466
488
private var nextPhaseName : String = uninitialized // initialized by enterPhase
467
489
468
- private def phaseNameFor (phase : Phase ): String =
469
- if phase.exists then phase.phaseName
470
- else " <end>"
471
-
490
+ /** Enter into a new real phase, setting the current and next (sub)phases */
472
491
private [Run ] def enterPhase (newPhase : Phase )(using Context ): Unit =
473
492
if newPhase ne currPhase then
474
493
currPhase = newPhase
475
- currPhaseName = phaseNameFor(newPhase)
476
- nextPhaseName = phaseNameFor(Run .nextMegaPhase(newPhase))
477
- if seen > 0 then
478
- refreshProgress()
494
+ subPhases = SubPhases (newPhase)
495
+ tickSubphase()
496
+
497
+ /** Compute the current (sub)phase name and next (sub)phase name */
498
+ private [Run ] def tickSubphase ()(using Context ): Unit =
499
+ val index = subtraversalc
500
+ val s = subPhases
501
+ currPhaseName = s.subPhase(index)
502
+ nextPhaseName =
503
+ if index + 1 < s.all.size then s.subPhase(index + 1 )
504
+ else s.next match
505
+ case None => " <end>"
506
+ case Some (next0) => next0.subPhase(0 )
507
+ if seen > 0 then
508
+ refreshProgress()
479
509
480
510
481
511
/** Counts the number of completed full traversals over files, plus the number of units in the current phase */
@@ -487,26 +517,35 @@ object Run {
487
517
* - the number of late compilations
488
518
*/
489
519
private def totalProgress ()(using Context ): Int =
490
- runnablePhases * run.files.size + run.lateFiles.size
520
+ totalTraversals * run.files.size + run.lateFiles.size
491
521
492
522
private def requireInitialized (): Unit =
493
523
require((currPhase : Phase | Null ) != null , " enterPhase was not called" )
494
524
525
+ /** trace that we are beginning a unit in the current (sub)phase */
495
526
private [Run ] def informUnitStarting (unit : CompilationUnit )(using Context ): Unit =
496
527
requireInitialized()
497
528
cb.informUnitStarting(currPhaseName, unit)
498
529
530
+ /** trace the current progress out of the total, in the current (sub)phase, reporting the next (sub)phase */
499
531
private [Run ] def refreshProgress ()(using Context ): Unit =
500
532
requireInitialized()
501
533
cb.progress(currentProgress(), totalProgress(), currPhaseName, nextPhaseName)
502
534
503
535
extension (run : Run | Null )
504
- def beginUnit (unit : CompilationUnit )(using Context ): Unit =
505
- if run != null then run.doBeginUnit(unit)
506
536
537
+ /** record that the current phase has begun for the compilation unit of the current Context */
538
+ def beginUnit ()(using Context ): Unit =
539
+ if run != null then run.doBeginUnit()
540
+
541
+ /** advance the unit count and record progress in the current phase */
507
542
def advanceUnit ()(using Context ): Unit =
508
543
if run != null then run.doAdvanceUnit()
509
544
545
+ def advanceSubPhase ()(using Context ): Unit =
546
+ if run != null then run.doAdvanceSubPhase()
547
+
548
+ /** advance the late count and record progress in the current phase */
510
549
def advanceLate ()(using Context ): Unit =
511
550
if run != null then run.doAdvanceLate()
512
551
0 commit comments