[Wasm] Add an option to dump declaration IR sizes to file
This commit is contained in:
+14
@@ -308,6 +308,20 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
|||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xir-dump-declaration-ir-sizes-to-file",
|
||||||
|
valueDescription = "<path>",
|
||||||
|
description = "Dump the IR size of each declaration to a file. " +
|
||||||
|
"The format will be chosen automatically depending on the file extension. " +
|
||||||
|
"Supported output formats include JSON for .json, JS const initialized with a plain object containing information for .js, " +
|
||||||
|
"and plain text for all other file types."
|
||||||
|
)
|
||||||
|
var irDceDumpDeclarationIrSizesToFile: String? = null
|
||||||
|
set(value) {
|
||||||
|
checkFrozen()
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
@Argument(value = "-Xir-property-lazy-initialization", description = "Perform lazy initialization for properties")
|
@Argument(value = "-Xir-property-lazy-initialization", description = "Perform lazy initialization for properties")
|
||||||
var irPropertyLazyInitialization = true
|
var irPropertyLazyInitialization = true
|
||||||
set(value) {
|
set(value) {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker
|
|||||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||||
import org.jetbrains.kotlin.ir.backend.js.*
|
import org.jetbrains.kotlin.ir.backend.js.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.dce.dumpDeclarationIrSizesIfNeed
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
import org.jetbrains.kotlin.ir.backend.js.ic.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CompilationOutputsBuilt
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CompilationOutputsBuilt
|
||||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
|
||||||
@@ -354,6 +355,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
eliminateDeadDeclarations(allModules, backendContext)
|
eliminateDeadDeclarations(allModules, backendContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dumpDeclarationIrSizesIfNeed(arguments.irDceDumpDeclarationIrSizesToFile, allModules)
|
||||||
|
|
||||||
val generateSourceMaps = configuration.getBoolean(JSConfigurationKeys.SOURCE_MAP)
|
val generateSourceMaps = configuration.getBoolean(JSConfigurationKeys.SOURCE_MAP)
|
||||||
|
|
||||||
val res = compileWasm(
|
val res = compileWasm(
|
||||||
|
|||||||
+1
-3
@@ -299,11 +299,9 @@ private fun transformToStringBy(
|
|||||||
separator: String,
|
separator: String,
|
||||||
transformer: (sourceFqn: String, targetFqn: String, description: String, isTargetContagious: Boolean) -> String
|
transformer: (sourceFqn: String, targetFqn: String, description: String, isTargetContagious: Boolean) -> String
|
||||||
): String {
|
): String {
|
||||||
fun IrDeclaration.fqnOrUnknown() = (this as? IrDeclarationWithName)?.fqNameWhenAvailable?.asString() ?: "<unknown>"
|
|
||||||
|
|
||||||
return reachabilityInfos
|
return reachabilityInfos
|
||||||
.map {
|
.map {
|
||||||
transformer(it.source.fqnOrUnknown(), it.target.fqnOrUnknown(), it.description, it.isTargetContagious)
|
transformer(it.source.fqNameForDceDump(), it.target.fqNameForDceDump(), it.description, it.isTargetContagious)
|
||||||
}
|
}
|
||||||
.distinct()
|
.distinct()
|
||||||
.joinToString(separator)
|
.joinToString(separator)
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.ir.backend.js.dce
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.PrimaryConstructorLowering
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
|
||||||
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
internal fun IrDeclaration.fqNameForDceDump(): String {
|
||||||
|
// TODO: sanitize names
|
||||||
|
val fqn = (this as? IrDeclarationWithName)?.fqNameWhenAvailable?.asString() ?: "<unknown>"
|
||||||
|
val signature = when (this is IrFunction) {
|
||||||
|
true -> this.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.dumpKotlinLike() }
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
val synthetic = when (this.origin == PrimaryConstructorLowering.SYNTHETIC_PRIMARY_CONSTRUCTOR) {
|
||||||
|
true -> "[synthetic]"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fqn + signature + synthetic)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dumpDeclarationIrSizesIfNeed(path: String?, allModules: List<IrModuleFragment>) {
|
||||||
|
if (path == null) return
|
||||||
|
|
||||||
|
val declarations = linkedSetOf<IrDeclaration>()
|
||||||
|
|
||||||
|
allModules.forEach {
|
||||||
|
it.acceptChildrenVoid(object : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitDeclaration(declaration: IrDeclarationBase) {
|
||||||
|
when (declaration) {
|
||||||
|
is IrFunction,
|
||||||
|
is IrProperty,
|
||||||
|
is IrField,
|
||||||
|
is IrAnonymousInitializer -> {
|
||||||
|
declarations.add(declaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.visitDeclaration(declaration)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
val out = File(path)
|
||||||
|
val (prefix, postfix, separator, indent) = when (out.extension) {
|
||||||
|
"json" -> listOf("{\n", "\n}", ",\n", " ")
|
||||||
|
"js" -> listOf("const kotlinDeclarationsSize = {\n", "\n};\n", ",\n", " ")
|
||||||
|
else -> listOf("", "", "\n", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
val value = declarations.joinToString(separator, prefix, postfix) {
|
||||||
|
val fqn = it.fqNameForDceDump()
|
||||||
|
val size = it.dumpKotlinLike().length
|
||||||
|
"$indent\"$fqn\" : $size"
|
||||||
|
}
|
||||||
|
|
||||||
|
out.writeText(value)
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.dce.dumpDeclarationIrSizesIfNeed
|
||||||
import org.jetbrains.kotlin.ir.backend.js.prepareAnalyzedSourceModule
|
import org.jetbrains.kotlin.ir.backend.js.prepareAnalyzedSourceModule
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
@@ -37,7 +38,6 @@ import org.jetbrains.kotlin.test.*
|
|||||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.math.abs
|
|
||||||
|
|
||||||
abstract class BasicWasmBoxTest(
|
abstract class BasicWasmBoxTest(
|
||||||
private val pathToTestDir: String,
|
private val pathToTestDir: String,
|
||||||
@@ -167,6 +167,8 @@ abstract class BasicWasmBoxTest(
|
|||||||
|
|
||||||
eliminateDeadDeclarations(allModules, backendContext)
|
eliminateDeadDeclarations(allModules, backendContext)
|
||||||
|
|
||||||
|
dumpDeclarationIrSizesIfNeed(System.getProperty("kotlin.wasm.dump.declaration.ir.size.to.file"), allModules)
|
||||||
|
|
||||||
val compilerResultWithDCE = compileWasm(
|
val compilerResultWithDCE = compileWasm(
|
||||||
allModules = allModules,
|
allModules = allModules,
|
||||||
backendContext = backendContext,
|
backendContext = backendContext,
|
||||||
|
|||||||
Reference in New Issue
Block a user