All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.backend.wasm.dce.Dce.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
Show newest version
/*
 * Copyright 2010-2020 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.backend.wasm.dce

import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
import org.jetbrains.kotlin.backend.wasm.ir2wasm.isExported
import org.jetbrains.kotlin.backend.wasm.utils.getWasmExportNameIfWasmExport
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.dce.DceDumpNameCache
import org.jetbrains.kotlin.ir.backend.js.utils.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.util.primaryConstructor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.js.config.JSConfigurationKeys

fun eliminateDeadDeclarations(modules: List, context: WasmBackendContext, dceDumpNameCache: DceDumpNameCache) {
    val printReachabilityInfo =
        context.configuration.getBoolean(JSConfigurationKeys.PRINT_REACHABILITY_INFO) ||
                java.lang.Boolean.getBoolean("kotlin.wasm.dce.print.reachability.info")

    val dumpReachabilityInfoToFile: String? =
        context.configuration.get(JSConfigurationKeys.DUMP_REACHABILITY_INFO_TO_FILE)
            ?: System.getProperty("kotlin.wasm.dce.dump.reachability.info.to.file")

    val usefulDeclarations = WasmUsefulDeclarationProcessor(
        context = context,
        printReachabilityInfo = printReachabilityInfo,
        dumpReachabilityInfoToFile
    ).collectDeclarations(rootDeclarations = buildRoots(modules, context), dceDumpNameCache)

    val remover = WasmUselessDeclarationsRemover(context, usefulDeclarations)
    modules.onAllFiles {
        acceptVoid(remover)
    }
}

private fun buildRoots(modules: List, context: WasmBackendContext): List = buildList {
    val declarationsCollector = object : IrElementVisitorVoid {
        override fun visitElement(element: IrElement): Unit = element.acceptChildrenVoid(this)
        override fun visitBody(body: IrBody): Unit = Unit // Skip

        override fun visitDeclaration(declaration: IrDeclarationBase) {
            super.visitDeclaration(declaration)
            add(declaration)
        }
    }

    modules.onAllFiles {
        declarations.forEach { declaration ->
            if (declaration is IrFunction && declaration.isExported()) {
                declaration.acceptVoid(declarationsCollector)
            }
        }
    }

    add(context.irBuiltIns.throwableClass.owner)
    add(context.mainCallsWrapperFunction)
    add(context.fieldInitFunction)
    add(context.findUnitInstanceField())
    add(context.irBuiltIns.unitClass.owner.primaryConstructor!!)
    if (context.isWasmJsTarget) {
        add(context.wasmSymbols.jsRelatedSymbols.throwJsException.owner)
    }

    // Remove all functions used to call a kotlin closure from JS side, reachable ones will be added back later.
    removeAll(context.closureCallExports.values)
}

private inline fun List.onAllFiles(body: IrFile.() -> Unit) {
    forEach { module ->
        module.files.forEach { file ->
            file.body()
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy