From 5239ab477c7f81b768ce1896c2078bece41b33c7 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Wed, 3 Jun 2020 15:54:53 +0300 Subject: [PATCH] Lowerings apply to a list of modules --- .../jetbrains/kotlin/backend/common/Lower.kt | 8 +++ .../kotlin/ir/backend/js/JsLoweringPhases.kt | 51 ++++++++++++------- .../kotlin/ir/backend/js/compiler.kt | 4 +- .../kotlin/benchmarks/GenerateIrRuntime.kt | 2 +- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Lower.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Lower.kt index 8bfc79d116a..5f85f3b494f 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Lower.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/Lower.kt @@ -67,6 +67,14 @@ interface BodyLoweringPass : FileLoweringPass { fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) } +//fun FileLoweringPass.lower(modules: Iterable) { +// modules.forEach { module -> +// module.files.forEach { +// lower(it) +// } +// } +//} + fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) { irFile.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index 0df9d2e568d..f8b56aef7fc 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering import org.jetbrains.kotlin.backend.common.lower.optimizations.FoldConstantLowering import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering import org.jetbrains.kotlin.backend.common.phaser.* +import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.backend.js.lower.* import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering import org.jetbrains.kotlin.ir.backend.js.lower.cleanup.CleanupLowering @@ -34,7 +35,7 @@ private fun makeJsModulePhase( description: String, prerequisite: Set = emptySet() ) = makeCustomJsModulePhase( - op = { context, moduleFragment -> lowering(context).lower(moduleFragment) }, + op = { context, modules -> lowering(context).lower(modules) }, name = name, description = description, prerequisite = prerequisite @@ -49,27 +50,36 @@ private fun makeCustomJsModulePhase( name = name, description = description, prerequisite = prerequisite, - lower = object : SameTypeCompilerPhase { + lower = object : SameTypeCompilerPhase> { override fun invoke( phaseConfig: PhaseConfig, - phaserState: PhaserState, + phaserState: PhaserState>, context: JsIrBackendContext, - input: IrModuleFragment - ): IrModuleFragment { - op(context, input) + input: Iterable + ): Iterable { + input.forEach { module -> + op(context, module) + } return input } }, preconditions = emptySet(), postconditions = emptySet(), stickyPostconditions = emptySet(), - actions = setOf(defaultDumper, validationAction), + actions = setOf(defaultDumper.toMultiModuleAction(), validationAction.toMultiModuleAction()), nlevels = 0 ) -sealed class Lowering(val name: String) { +private fun Action.toMultiModuleAction(): Action, C> { + return { state, modules, context -> + modules.forEach { module -> + this(state, module, context) + } + } +} - abstract val modulePhase: SameTypeNamedPhaseWrapper +sealed class Lowering(val name: String) { + abstract val modulePhase: SameTypeNamedPhaseWrapper> } class DeclarationLowering( @@ -100,7 +110,7 @@ class BodyLowering( class ModuleLowering( name: String, - override val modulePhase: SameTypeNamedPhaseWrapper + override val modulePhase: SameTypeNamedPhaseWrapper> ) : Lowering(name) private fun makeDeclarationTransformerPhase( @@ -117,7 +127,7 @@ private fun makeBodyLoweringPhase( prerequisite: Set = emptySet() ) = BodyLowering(name, description, prerequisite.map { it.modulePhase }.toSet(), lowering) -fun SameTypeNamedPhaseWrapper.toModuleLowering() = ModuleLowering(this.name, this) +fun SameTypeNamedPhaseWrapper>.toModuleLowering() = ModuleLowering(this.name, this) private val validateIrBeforeLowering = makeCustomJsModulePhase( { context, module -> validationCallback(context, module) }, @@ -131,7 +141,7 @@ private val validateIrAfterLowering = makeCustomJsModulePhase( description = "Validate IR after lowering" ).toModuleLowering() -val scriptRemoveReceiverLowering = makeIrModulePhase( +val scriptRemoveReceiverLowering = makeJsModulePhase( ::ScriptRemoveReceiverLowering, name = "ScriptRemoveReceiver", description = "Remove receivers for declarations in script" @@ -515,7 +525,7 @@ private val bridgesConstructionPhase = makeDeclarationTransformerPhase( prerequisite = setOf(suspendFunctionsLoweringPhase) ) -private val singleAbstractMethodPhase = makeIrModulePhase( +private val singleAbstractMethodPhase = makeJsModulePhase( ::JsSingleAbstractMethodLowering, name = "SingleAbstractMethod", description = "Replace SAM conversions with instances of interface-implementing classes" @@ -726,14 +736,19 @@ val loweringList = listOf( validateIrAfterLowering ) -// TODO comment? Eliminate MouduleLowering's? Don't filter them here? +// TODO comment? Eliminate ModuleLowering's? Don't filter them here? val pirLowerings = loweringList.filter { it is DeclarationLowering || it is BodyLowering } + staticMembersLoweringPhase // TODO `fold` -> `reduce` -val jsPhases = namedIrModulePhase( +val jsPhases = SameTypeNamedPhaseWrapper( name = "IrModuleLowering", description = "IR module lowering", - lower = loweringList.drop(1).fold(loweringList[0].modulePhase) { acc: CompilerPhase, lowering -> - acc.then(lowering.modulePhase) - } + prerequisite = emptySet(), + lower = loweringList.map { it.modulePhase as CompilerPhase, Iterable> } + .reduce { acc, lowering -> acc.then(lowering) }, + preconditions = emptySet(), + postconditions = emptySet(), + stickyPostconditions = emptySet(), + actions = setOf(defaultDumper.toMultiModuleAction(), validationAction.toMultiModuleAction()), + nlevels = 1 ) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index f0425dae54e..77fcd765f48 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -98,7 +98,7 @@ fun compile( val transformer = IrModuleToJsTransformer(context, mainFunction, mainArguments) return transformer.generateModule(moduleFragment, fullJs = true, dceJs = false) } else { - jsPhases.invokeToplevel(phaseConfig, context, moduleFragment) + jsPhases.invokeToplevel(phaseConfig, context, listOf(moduleFragment)) val transformer = IrModuleToJsTransformer(context, mainFunction, mainArguments) return transformer.generateModule(moduleFragment, generateFullJs, generateDceJs) } @@ -110,7 +110,7 @@ fun generateJsCode( nameTables: NameTables ): String { moveBodilessDeclarationsToSeparatePlace(context, moduleFragment) - jsPhases.invokeToplevel(PhaseConfig(jsPhases), context, moduleFragment) + jsPhases.invokeToplevel(PhaseConfig(jsPhases), context, listOf(moduleFragment)) val transformer = IrModuleToJsTransformer(context, null, null, true, nameTables) return transformer.generateModule(moduleFragment).jsCode!! diff --git a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt index 7048cca9ce0..a942eb6d42c 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt @@ -580,7 +580,7 @@ class GenerateIrRuntime { ExternalDependenciesGenerator(symbolTable, listOf(jsLinker), languageVersionSettings).generateUnboundSymbolsAsDependencies() - jsPhases.invokeToplevel(phaseConfig, context, module) + jsPhases.invokeToplevel(phaseConfig, context, listOf(module)) val transformer = IrModuleToJsTransformer(context, null, null)