@@ -33,6 +33,7 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
3333 private var reporter : Reporter = _
3434
3535 implicit val executor = ExecutionContext .fromExecutor(new java.util.concurrent.ForkJoinPool (parallelism))
36+ val fileManager = ToolProvider .getSystemJavaCompiler.getStandardFileManager(null , null , null )
3637
3738 private class PickleClassPath [G <: Global ](data : mutable.AnyRefMap [G # Symbol , PickleBuffer ]) {
3839 val dir = new VirtualDirectory (" fakes" , None )
@@ -102,6 +103,34 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
102103 val timer = new Timer
103104 timer.start()
104105 strategy match {
106+ case OutlineTypeOnly =>
107+ val futures = projects.map { p =>
108+ val f1 = Future .sequence[Unit , List ](dependsOn.getOrElse(p, Nil ).map(_.outlineDone.future))
109+ p.shouldOutlineType = true
110+ f1.map { _ =>
111+ p.outlineCompile()
112+ p.javaCompile()
113+ }
114+ }
115+
116+ val toWait : Future [List [Unit ]] = Future .sequence(futures).flatMap(_ => Future .sequence(projects.flatMap(p => p.javaDone.future :: p.outlineDone.future :: Nil ) ))
117+ Await .result(toWait, Duration .Inf )
118+ timer.stop()
119+
120+ for (p <- projects) {
121+ val dependencies = dependsOn(p)
122+ def maxByOrZero [A ](as : List [A ])(f : A => Double ): Double = if (as.isEmpty) 0d else as.map(f).max
123+ val maxOutlineCriticalPathMs = maxByOrZero(dependencies)(_.outlineCriticalPathMs)
124+ p.outlineCriticalPathMs = maxOutlineCriticalPathMs + p.outlineTimer.durationMs
125+ p.regularCriticalPathMs = maxOutlineCriticalPathMs + maxByOrZero(p.groups)(_.timer.durationMs)
126+ p.fullCriticalPathMs = maxByOrZero(dependencies)(_.fullCriticalPathMs) + p.groups.map(_.timer.durationMs).sum
127+ }
128+
129+ if (parallelism == 1 ) {
130+ val criticalPath = projects.maxBy(_.regularCriticalPathMs)
131+ println(f " Critical path: ${criticalPath.regularCriticalPathMs}%.0f ms. Wall Clock: ${timer.durationMs}%.0f ms " )
132+ } else
133+ println(f " Wall Clock: ${timer.durationMs}%.0f ms " )
105134 case OutlineTypePipeline =>
106135 val futures = projects.map { p =>
107136 val f1 = Future .sequence[Unit , List ](dependsOn.getOrElse(p, Nil ).map(_.outlineDone.future))
@@ -202,7 +231,8 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
202231 events += durationEvent(p.label, " outline-type" , p.outlineTimer)
203232 }
204233 for ((g, ix) <- p.groups.zipWithIndex) {
205- events += durationEvent(p.label, " compile-" + ix, g.timer)
234+ if (g.timer.durationMicros > 0d )
235+ events += durationEvent(p.label, " compile-" + ix, g.timer)
206236 }
207237 events.result()
208238 }
@@ -229,8 +259,8 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
229259 } else {
230260 command.settings.classpath.value = command.settings.outputDirs.getSingleOutput.get.toString + File .pathSeparator + command.settings.classpath.value
231261 val length = files.length
232- val groups = (length.toDouble / 64 ).toInt.max(1 )
233- files.grouped((length.toDouble / groups).ceil.toInt).toList.map(Group (_))
262+ val groups = (length.toDouble / 128 ).toInt.max(1 )
263+ files.grouped((length.toDouble / groups).ceil.toInt.max( 1 ) ).toList.map(Group (_))
234264 }
235265 }
236266 command.settings.outputDirs.getSingleOutput.get.file.mkdirs()
@@ -260,6 +290,7 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
260290 outlineTimer.start()
261291 command.settings.Youtline .value = true
262292 command.settings.stopAfter.value = List (" pickler" )
293+ command.settings.Ymacroexpand .value = command.settings.MacroExpand .None
263294 val run1 = new compiler.Run ()
264295 run1 compile files
265296 allPickleData.put(command.settings.outputDirs.getSingleOutput.get.file.toPath.toRealPath().normalize(), new PickleClassPath (run1.symData))
@@ -274,6 +305,7 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
274305 def fullCompile (): Unit = {
275306 command.settings.Youtline .value = false
276307 command.settings.stopAfter.value = Nil
308+ command.settings.Ymacroexpand .value = command.settings.MacroExpand .Normal
277309
278310 for (group <- groups) {
279311 group.done.completeWith {
@@ -324,7 +356,6 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
324356 val javaSources = files.filter(_.endsWith(" .java" ))
325357 if (javaSources.nonEmpty) {
326358 javaDone.completeWith(Future {
327- val fileManager = ToolProvider .getSystemJavaCompiler.getStandardFileManager(null , null , null )
328359 val opts = java.util.Arrays .asList(" -d" , command.settings.outdir.value, " -cp" , command.settings.outdir.value + File .pathSeparator + command.settings.classpath.value)
329360 val compileTask = ToolProvider .getSystemJavaCompiler.getTask(null , null , null , opts, null , fileManager.getJavaFileObjects(javaSources.toArray: _* ))
330361 compileTask.call()
@@ -391,6 +422,7 @@ class PipelineMainClass(label: String, parallelism: Int, strategy: BuildStrategy
391422}
392423
393424sealed abstract class BuildStrategy
425+ case object OutlineTypeOnly extends BuildStrategy
394426/** Outline type check to compute type signatures as pickles as an input to downstream compilation. */
395427case object OutlineTypePipeline extends BuildStrategy
396428case object Pipeline extends BuildStrategy
@@ -401,7 +433,7 @@ object PipelineMain {
401433 def main (args : Array [String ]): Unit = {
402434 var i = 0
403435 // for (_ <- 1 to 10; n <- List(parallel.availableProcessors, 1); strat <- List(Pipeline, OutlineTypePipeline, Traditional)) {
404- for (_ <- 1 to 10 ; n <- List (parallel.availableProcessors); strat <- List (Pipeline , OutlineTypePipeline , Traditional )) {
436+ for (_ <- 1 to 20 ; n <- List (parallel.availableProcessors); strat <- List (OutlineTypeOnly )) {
405437 i += 1
406438 val main = new PipelineMainClass (i.toString, n, strat)
407439 println(s " ====== ITERATION $i======= " )
0 commit comments