diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt index 6aabbe2906f..973c2f2bafc 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt @@ -21,7 +21,7 @@ class CodeAnalysisMeasurement(private val lines: Int?, val milliseconds: Long) : override fun render(): String = formatMeasurement("ANALYZE", milliseconds, lines) } -class CodeGenerationMeasurement(private val lines: Int?, private val milliseconds: Long) : PerformanceMeasurement { +class CodeGenerationMeasurement(private val lines: Int?, val milliseconds: Long) : PerformanceMeasurement { override fun render(): String = formatMeasurement("GENERATE", milliseconds, lines) } diff --git a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/AbstractFullPipelineModularizedTest.kt b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/AbstractFullPipelineModularizedTest.kt new file mode 100644 index 00000000000..226a349f51a --- /dev/null +++ b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/AbstractFullPipelineModularizedTest.kt @@ -0,0 +1,321 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir + +import com.intellij.util.io.delete +import org.jetbrains.kotlin.cli.common.* +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.messages.MessageRenderer +import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler +import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.util.PerformanceCounter +import java.io.FileOutputStream +import java.io.PrintStream +import java.nio.file.Files +import java.nio.file.Path + +abstract class AbstractFullPipelineModularizedTest : AbstractModularizedTest() { + + data class ModuleStatus(val data: ModuleData, val targetInfo: String) { + var compilationError: String? = null + var jvmInternalError: String? = null + var exceptionMessage: String = "NO MESSAGE" + } + + private val totalModules = mutableListOf() + private val okModules = mutableListOf() + private val errorModules = mutableListOf() + private val crashedModules = mutableListOf() + + protected data class CumulativeTime( + val gcInfo: Map, + val components: Map, + val files: Int, + val lines: Int + ) { + constructor() : this(emptyMap(), emptyMap(), 0, 0) + + operator fun plus(other: CumulativeTime): CumulativeTime { + return CumulativeTime( + (gcInfo.values + other.gcInfo.values).groupingBy { it.name }.reduce { key, accumulator, element -> + GCInfo(key, accumulator.gcTime + element.gcTime, accumulator.collections + element.collections) + }, + (components.toList() + other.components.toList()).groupingBy { (name, _) -> name }.fold(0L) { a, b -> a + b.second }, + files + other.files, + lines + other.lines + ) + } + + fun totalTime() = components.values.sum() + } + + protected lateinit var totalPassResult: CumulativeTime + + override fun beforePass(pass: Int) { + totalPassResult = CumulativeTime() + totalModules.clear() + okModules.clear() + errorModules.clear() + crashedModules.clear() + } + + override fun afterPass(pass: Int) { + createReport(finalReport = pass == PASSES - 1) + require(totalModules.isNotEmpty()) { "No modules were analyzed" } + require(okModules.isNotEmpty()) { "All of $totalModules is failed" } + } + + protected fun formatReportTable(stream: PrintStream) { + val total = totalPassResult + var totalGcTimeMs = 0L + var totalGcCount = 0L + printTable(stream) { + row("Name", "Time", "Count") + separator() + fun gcRow(name: String, timeMs: Long, count: Long) { + row { + cell(name, align = LEFT) + timeCell(timeMs, inputUnit = TableTimeUnit.MS) + cell(count.toString()) + } + } + for (measurement in total.gcInfo.values) { + totalGcTimeMs += measurement.gcTime + totalGcCount += measurement.collections + gcRow(measurement.name, measurement.gcTime, measurement.collections) + } + separator() + gcRow("Total", totalGcTimeMs, totalGcCount) + + } + + printTable(stream) { + row("Phase", "Time", "Files", "L/S") + separator() + + fun phase(name: String, timeMs: Long, files: Int, lines: Int) { + row { + cell(name, align = LEFT) + timeCell(timeMs, inputUnit = TableTimeUnit.MS) + cell(files.toString()) + linePerSecondCell(lines, timeMs, timeUnit = TableTimeUnit.MS) + } + } + for (component in total.components) { + phase(component.key, component.value, total.files, total.lines) + } + + separator() + phase("Total", total.totalTime(), total.files, total.lines) + } + + } + + private fun configureBaseArguments(args: K2JVMCompilerArguments, moduleData: ModuleData, tmp: Path) { + args.reportPerf = true + args.jvmTarget = "1.8" + args.classpath = moduleData.classpath.joinToString(separator = ":") { it.absolutePath } + args.javaSourceRoots = moduleData.javaSourceRoots.map { it.absolutePath }.toTypedArray() + args.allowKotlinPackage = true + args.freeArgs = moduleData.sources.map { it.absolutePath } + args.destination = tmp.toAbsolutePath().toFile().toString() + args.friendPaths = moduleData.friendDirs.map { it.canonicalPath }.toTypedArray() + } + + abstract fun configureArguments(args: K2JVMCompilerArguments, moduleData: ModuleData) + + protected open fun handleResult(result: ExitCode, moduleData: ModuleData, collector: TestMessageCollector, targetInfo: String): ProcessorAction { + val status = ModuleStatus(moduleData, targetInfo) + totalModules += status + + return when (result) { + ExitCode.OK -> { + okModules += status + ProcessorAction.NEXT + } + ExitCode.COMPILATION_ERROR -> { + errorModules += status + status.compilationError = collector.messages.firstOrNull { + it.severity == CompilerMessageSeverity.ERROR + }?.message + status.jvmInternalError = collector.messages.firstOrNull { + it.severity == CompilerMessageSeverity.EXCEPTION + }?.message + ProcessorAction.NEXT + } + ExitCode.INTERNAL_ERROR -> { + crashedModules += status + status.exceptionMessage = collector.messages.firstOrNull { + it.severity == CompilerMessageSeverity.EXCEPTION + }?.message?.split("\n")?.let { exceptionLines -> + exceptionLines.lastOrNull { it.startsWith("Caused by: ") } ?: exceptionLines.firstOrNull() + } ?: "NO MESSAGE" + ProcessorAction.NEXT + } + else -> ProcessorAction.NEXT + } + } + + + private fun String.shorten(): String { + val split = split("\n") + return split.mapIndexedNotNull { index, s -> + if (index < 4 || index >= split.size - 6) s else null + }.joinToString("\n") + } + + open fun formatReport(stream: PrintStream, finalReport: Boolean) { + stream.println("TOTAL MODULES: ${totalModules.size}") + stream.println("OK MODULES: ${okModules.size}") + + formatReportTable(stream) + + if (finalReport) { + with(stream) { + println() + println("SUCCESSFUL MODULES") + println("------------------") + println() + for (okModule in okModules) { + println("${okModule.data.qualifiedName}: ${okModule.targetInfo}") + } + println() + println("COMPILATION ERRORS") + println("------------------") + println() + for (errorModule in errorModules.filter { it.jvmInternalError == null }) { + println("${errorModule.data.qualifiedName}: ${errorModule.targetInfo}") + println(" 1st error: ${errorModule.compilationError}") + } + println() + println("JVM INTERNAL ERRORS") + println("------------------") + println() + for (errorModule in errorModules.filter { it.jvmInternalError != null }) { + println("${errorModule.data.qualifiedName}: ${errorModule.targetInfo}") + println(" 1st error: ${errorModule.jvmInternalError?.shorten()}") + } + val crashedModuleGroups = crashedModules.groupBy { it.exceptionMessage.take(60) } + for (modules in crashedModuleGroups.values) { + println() + println(modules.first().exceptionMessage) + println("--------------------------------------------------------") + println() + for (module in modules) { + println("${module.data.qualifiedName}: ${module.targetInfo}") + println(" ${module.exceptionMessage}") + } + } + } + } + } + + override fun processModule(moduleData: ModuleData): ProcessorAction { + val compiler = K2JVMCompiler() + val args = compiler.createArguments() + val tmp = Files.createTempDirectory("compile-output") + configureBaseArguments(args, moduleData, tmp) + configureArguments(args, moduleData) + + val manager = CompilerPerformanceManager() + val services = Services.Builder().register(CommonCompilerPerformanceManager::class.java, manager).build() + val collector = TestMessageCollector() + val result = try { + compiler.exec(collector, services, args) + } catch (e: Exception) { + e.printStackTrace() + ExitCode.INTERNAL_ERROR + } + val resultTime = manager.reportCumulativeTime() + PerformanceCounter.resetAllCounters() + + tmp.delete(recursively = true) + if (result == ExitCode.OK) { + totalPassResult += resultTime + } + + return handleResult(result, moduleData, collector, manager.getTargetInfo()) + } + + protected fun createReport(finalReport: Boolean) { + formatReport(System.out, finalReport) + + PrintStream( + FileOutputStream( + reportDir().resolve("report-$reportDateStr.log"), + true + ) + ).use { stream -> + formatReport(stream, finalReport) + stream.println() + stream.println() + } + } + + + private inner class CompilerPerformanceManager : CommonCompilerPerformanceManager("Modularized test performance manager") { + + fun reportCumulativeTime(): CumulativeTime { + val gcInfo = measurements.filterIsInstance() + .associate { it.garbageCollectionKind to GCInfo(it.garbageCollectionKind, it.milliseconds, it.count) } + + val analysisMeasurement = measurements.filterIsInstance().firstOrNull() + val initMeasurement = measurements.filterIsInstance().firstOrNull() + val irMeasurements = measurements.filterIsInstance() + + @OptIn(ExperimentalStdlibApi::class) + val components = buildMap { + put("Init", initMeasurement?.milliseconds ?: 0) + put("Analysis", analysisMeasurement?.milliseconds ?: 0) + + irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.TRANSLATION }?.milliseconds?.let { put("Translation", it) } + irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.LOWERING }?.milliseconds?.let { put("Lowering", it) } + + val generationTime = + irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.GENERATION }?.milliseconds ?: + measurements.filterIsInstance().firstOrNull()?.milliseconds + + if (generationTime != null) { + put("Generation", generationTime) + } + } + + return CumulativeTime( + gcInfo, + components, + files ?: 0, + lines ?: 0 + ) + } + } + + protected class TestMessageCollector : MessageCollector { + + data class Message(val severity: CompilerMessageSeverity, val message: String, val location: CompilerMessageSourceLocation?) + + val messages = arrayListOf() + + override fun clear() { + messages.clear() + } + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) { + messages.add(Message(severity, message, location)) + if (severity in CompilerMessageSeverity.VERBOSE) return + println(MessageRenderer.GRADLE_STYLE.render(severity, message, location)) + } + + override fun hasErrors(): Boolean = messages.any { + it.severity == CompilerMessageSeverity.EXCEPTION || it.severity == CompilerMessageSeverity.ERROR + } + } + + +} \ No newline at end of file diff --git a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/AbstractModularizedTest.kt b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/AbstractModularizedTest.kt index 3df9dfe621d..1bc74bd3846 100644 --- a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/AbstractModularizedTest.kt +++ b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/AbstractModularizedTest.kt @@ -38,10 +38,6 @@ data class ModuleData( val sources = rawSources.map { it.fixPath() } val javaSourceRoots = rawJavaSourceRoots.map { it.fixPath() } val friendDirs = rawFriendDirs.map { it.fixPath() } - lateinit var targetInfo: String - var compilationError: String? = null - var jvmInternalError: String? = null - var exceptionMessage: String = "NO MESSAGE" } private fun String.fixPath(): File = File(ROOT_PATH_PREFIX, this.removePrefix("/")) diff --git a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FE1FullPipelineModularizedTest.kt b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FE1FullPipelineModularizedTest.kt new file mode 100644 index 00000000000..d45a0b1433f --- /dev/null +++ b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FE1FullPipelineModularizedTest.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir + +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.toBooleanLenient + + +private val USE_BE_IR = System.getProperty("fir.bench.fe1.useIR", "false").toBooleanLenient()!! + +class FE1FullPipelineModularizedTest : AbstractFullPipelineModularizedTest() { + override fun configureArguments(args: K2JVMCompilerArguments, moduleData: ModuleData) { + args.useIR = USE_BE_IR + args.useOldBackend = !USE_BE_IR + args.useFir = false + args.jvmDefault = "compatibility" + args.optIn = arrayOf("kotlin.RequiresOptIn") + } + + fun testTotalKotlin() { + for (i in 0 until PASSES) { + println("Pass $i") + runTestOnce(i) + } + } +} \ No newline at end of file diff --git a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt index 09cf29c4b0e..c6e51234eef 100644 --- a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt +++ b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt @@ -5,280 +5,13 @@ package org.jetbrains.kotlin.fir -import com.intellij.util.io.delete -import org.jetbrains.kotlin.cli.common.* -import org.jetbrains.kotlin.cli.common.messages.* -import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -import org.jetbrains.kotlin.config.Services -import org.jetbrains.kotlin.fir.TableTimeUnit.MS -import org.jetbrains.kotlin.fir.scopes.ProcessorAction -import org.jetbrains.kotlin.util.PerformanceCounter -import java.io.FileOutputStream -import java.io.PrintStream -import java.nio.file.Files +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -class FullPipelineModularizedTest : AbstractModularizedTest() { - override fun beforePass(pass: Int) { - totalPassResult = CumulativeTime() - totalModules.clear() - okModules.clear() - errorModules.clear() - crashedModules.clear() - } +class FullPipelineModularizedTest : AbstractFullPipelineModularizedTest() { - private data class CumulativeTime( - val gcInfo: Map, - val init: Long, - val analysis: Long, - val translation: Long, - val lowering: Long, - val generation: Long, - val files: Int, - val lines: Int - ) { - constructor() : this(emptyMap(), 0, 0, 0, 0, 0, 0, 0) - - operator fun plus(other: CumulativeTime): CumulativeTime { - return CumulativeTime( - (gcInfo.values + other.gcInfo.values).groupingBy { it.name }.reduce { key, accumulator, element -> - GCInfo(key, accumulator.gcTime + element.gcTime, accumulator.collections + element.collections) - }, - init + other.init, - analysis + other.analysis, - translation + other.translation, - lowering + other.lowering, - generation + other.generation, - files + other.files, - lines + other.lines - ) - } - - fun totalTime() = init + analysis + translation + lowering + generation - } - - private lateinit var totalPassResult: CumulativeTime - private val totalModules = mutableListOf() - private val okModules = mutableListOf() - private val errorModules = mutableListOf() - private val crashedModules = mutableListOf() - - override fun afterPass(pass: Int) { - createReport(finalReport = pass == PASSES - 1) - require(totalModules.isNotEmpty()) { "No modules were analyzed" } - require(okModules.isNotEmpty()) { "All of $totalModules is failed" } - } - - private fun createReport(finalReport: Boolean) { - formatReport(System.out, finalReport) - - PrintStream( - FileOutputStream( - reportDir().resolve("report-$reportDateStr.log"), - true - ) - ).use { stream -> - formatReport(stream, finalReport) - stream.println() - stream.println() - } - } - - private fun String.shorten(): String { - val split = split("\n") - return split.mapIndexedNotNull { index, s -> - if (index < 4 || index >= split.size - 6) s else null - }.joinToString("\n") - } - - private fun formatReport(stream: PrintStream, finalReport: Boolean) { - stream.println("TOTAL MODULES: ${totalModules.size}") - stream.println("OK MODULES: ${okModules.size}") - val total = totalPassResult - var totalGcTimeMs = 0L - var totalGcCount = 0L - printTable(stream) { - row("Name", "Time", "Count") - separator() - fun gcRow(name: String, timeMs: Long, count: Long) { - row { - cell(name, align = LEFT) - timeCell(timeMs, inputUnit = MS) - cell(count.toString()) - } - } - for (measurement in total.gcInfo.values) { - totalGcTimeMs += measurement.gcTime - totalGcCount += measurement.collections - gcRow(measurement.name, measurement.gcTime, measurement.collections) - } - separator() - gcRow("Total", totalGcTimeMs, totalGcCount) - - } - - printTable(stream) { - row("Phase", "Time", "Files", "L/S") - separator() - - fun phase(name: String, timeMs: Long, files: Int, lines: Int) { - row { - cell(name, align = LEFT) - timeCell(timeMs, inputUnit = MS) - cell(files.toString()) - linePerSecondCell(lines, timeMs, timeUnit = MS) - } - } - phase("Init", total.init, total.files, total.lines) - phase("Analysis", total.analysis, total.files, total.lines) - phase("Translation", total.translation, total.files, total.lines) - phase("Lowering", total.lowering, total.files, total.lines) - phase("Generation", total.generation, total.files, total.lines) - - separator() - phase("Total", total.totalTime(), total.files, total.lines) - } - - if (finalReport) { - with(stream) { - println() - println("SUCCESSFUL MODULES") - println("------------------") - println() - for (okModule in okModules) { - println("${okModule.qualifiedName}: ${okModule.targetInfo}") - } - println() - println("COMPILATION ERRORS") - println("------------------") - println() - for (errorModule in errorModules.filter { it.jvmInternalError == null }) { - println("${errorModule.qualifiedName}: ${errorModule.targetInfo}") - println(" 1st error: ${errorModule.compilationError}") - } - println() - println("JVM INTERNAL ERRORS") - println("------------------") - println() - for (errorModule in errorModules.filter { it.jvmInternalError != null }) { - println("${errorModule.qualifiedName}: ${errorModule.targetInfo}") - println(" 1st error: ${errorModule.jvmInternalError?.shorten()}") - } - val crashedModuleGroups = crashedModules.groupBy { it.exceptionMessage.take(60) } - for (modules in crashedModuleGroups.values) { - println() - println(modules.first().exceptionMessage) - println("--------------------------------------------------------") - println() - for (module in modules) { - println("${module.qualifiedName}: ${module.targetInfo}") - println(" ${module.exceptionMessage}") - } - } - } - } - } - - private class TestMessageCollector : MessageCollector { - - data class Message(val severity: CompilerMessageSeverity, val message: String, val location: CompilerMessageSourceLocation?) - - val messages = arrayListOf() - - override fun clear() { - messages.clear() - } - - override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) { - messages.add(Message(severity, message, location)) - if (severity in CompilerMessageSeverity.VERBOSE) return - println(MessageRenderer.GRADLE_STYLE.render(severity, message, location)) - } - - override fun hasErrors(): Boolean = messages.any { - it.severity == CompilerMessageSeverity.EXCEPTION || it.severity == CompilerMessageSeverity.ERROR - } - } - - override fun processModule(moduleData: ModuleData): ProcessorAction { - val compiler = K2JVMCompiler() - val args = compiler.createArguments() - args.reportPerf = true - args.jvmTarget = "1.8" + override fun configureArguments(args: K2JVMCompilerArguments, moduleData: ModuleData) { args.useFir = true - args.classpath = moduleData.classpath.joinToString(separator = ":") { it.absolutePath } - args.javaSourceRoots = moduleData.javaSourceRoots.map { it.absolutePath }.toTypedArray() - args.allowKotlinPackage = true - args.freeArgs = moduleData.sources.map { it.absolutePath } - val tmp = Files.createTempDirectory("compile-output") - args.destination = tmp.toAbsolutePath().toFile().toString() - args.friendPaths = moduleData.friendDirs.map { it.canonicalPath }.toTypedArray() - val manager = CompilerPerformanceManager() - val services = Services.Builder().register(CommonCompilerPerformanceManager::class.java, manager).build() - val collector = TestMessageCollector() - val result = try { - compiler.exec(collector, services, args) - } catch (e: Exception) { - e.printStackTrace() - ExitCode.INTERNAL_ERROR - } - val resultTime = manager.reportCumulativeTime() - - PerformanceCounter.resetAllCounters() - - tmp.delete(recursively = true) - totalModules += moduleData - moduleData.targetInfo = manager.getTargetInfo() - - return when (result) { - ExitCode.OK -> { - totalPassResult += resultTime - okModules += moduleData - ProcessorAction.NEXT - } - ExitCode.COMPILATION_ERROR -> { - errorModules += moduleData - moduleData.compilationError = collector.messages.firstOrNull { - it.severity == CompilerMessageSeverity.ERROR - }?.message - moduleData.jvmInternalError = collector.messages.firstOrNull { - it.severity == CompilerMessageSeverity.EXCEPTION - }?.message - ProcessorAction.NEXT - } - ExitCode.INTERNAL_ERROR -> { - crashedModules += moduleData - moduleData.exceptionMessage = collector.messages.firstOrNull { - it.severity == CompilerMessageSeverity.EXCEPTION - }?.message?.split("\n")?.let { exceptionLines -> - exceptionLines.lastOrNull { it.startsWith("Caused by: ") } ?: exceptionLines.firstOrNull() - } ?: "NO MESSAGE" - ProcessorAction.NEXT - } - else -> ProcessorAction.NEXT - } - } - - - private inner class CompilerPerformanceManager : CommonCompilerPerformanceManager("Modularized test performance manager") { - fun reportCumulativeTime(): CumulativeTime { - val gcInfo = measurements.filterIsInstance() - .associate { it.garbageCollectionKind to GCInfo(it.garbageCollectionKind, it.milliseconds, it.count) } - - val analysisMeasurement = measurements.filterIsInstance().firstOrNull() - val initMeasurement = measurements.filterIsInstance().firstOrNull() - val irMeasurements = measurements.filterIsInstance() - - return CumulativeTime( - gcInfo, - initMeasurement?.milliseconds ?: 0, - analysisMeasurement?.milliseconds ?: 0, - irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.TRANSLATION }?.milliseconds ?: 0, - irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.LOWERING }?.milliseconds ?: 0, - irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.GENERATION }?.milliseconds ?: 0, - files ?: 0, - lines ?: 0 - ) - } + args.useIR = true } fun testTotalKotlin() {