[K/JS, K/Wasm] Optimize simple objects declaration and usage ^Fixed KT-58797
This commit is contained in:
@@ -6,6 +6,8 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":core:util.runtime"))
|
||||
|
||||
implementation(kotlinStdlib())
|
||||
implementation(kotlinxCollectionsImmutable())
|
||||
testImplementation(commonDependency("junit:junit"))
|
||||
|
||||
@@ -386,9 +386,6 @@ enum class WasmOp(
|
||||
EXTERN_EXTERNALIZE("extern.externalize", 0xfb71), // anyref -> externref
|
||||
|
||||
// ============================================================
|
||||
// Pseudo-instruction, just alias for a normal call. It's used to easily spot get_unit on the wasm level.
|
||||
GET_UNIT("call", 0x10, FUNC_IDX),
|
||||
|
||||
PSEUDO_COMMENT_PREVIOUS_INSTR("<comment-single>", WASM_OP_PSEUDO_OPCODE),
|
||||
PSEUDO_COMMENT_GROUP_START("<comment-group-start>", WASM_OP_PSEUDO_OPCODE),
|
||||
PSEUDO_COMMENT_GROUP_END("<comment-group-end>", WASM_OP_PSEUDO_OPCODE),
|
||||
@@ -400,4 +397,4 @@ enum class WasmOp(
|
||||
const val WASM_OP_PSEUDO_OPCODE = 0xFFFF
|
||||
|
||||
val opcodesToOp: Map<Int, WasmOp> =
|
||||
enumValues<WasmOp>().associateBy { it.opcode }
|
||||
enumValues<WasmOp>().associateBy { it.opcode }
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.wasm.ir
|
||||
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.trimToSize
|
||||
import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
|
||||
|
||||
private fun WasmOp.isOutCfgNode() = when (this) {
|
||||
@@ -18,7 +19,7 @@ private fun WasmOp.isInCfgNode() = when (this) {
|
||||
}
|
||||
|
||||
private fun WasmOp.pureStacklessInstruction() = when (this) {
|
||||
WasmOp.GET_UNIT, WasmOp.REF_NULL, WasmOp.I32_CONST, WasmOp.I64_CONST, WasmOp.F32_CONST, WasmOp.F64_CONST, WasmOp.LOCAL_GET, WasmOp.GLOBAL_GET -> true
|
||||
WasmOp.REF_NULL, WasmOp.I32_CONST, WasmOp.I64_CONST, WasmOp.F32_CONST, WasmOp.F64_CONST, WasmOp.LOCAL_GET, WasmOp.GLOBAL_GET -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
@@ -30,13 +31,12 @@ class WasmIrExpressionBuilder(
|
||||
val expression: MutableList<WasmInstr>
|
||||
) : WasmExpressionBuilder() {
|
||||
|
||||
private val lastInstr: WasmInstr?
|
||||
get() = expression.lastOrNull()
|
||||
private var eatEverythingUntilLevel: Int? = null
|
||||
private var lastInstructionIndex: Int = expression.indexOfLast { !it.operator.isPseudoInstruction }
|
||||
|
||||
private fun addInstruction(op: WasmOp, location: SourceLocation, immediates: Array<out WasmImmediate>) {
|
||||
val newInstruction = WasmInstrWithLocation(op, immediates.toList(), location)
|
||||
expression.add(newInstruction)
|
||||
expression += WasmInstrWithLocation(op, immediates.toList(), location)
|
||||
if (!op.isPseudoInstruction) lastInstructionIndex = expression.lastIndex
|
||||
}
|
||||
|
||||
private fun getCurrentEatLevel(op: WasmOp): Int? {
|
||||
@@ -64,16 +64,17 @@ class WasmIrExpressionBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
val lastInstruction = lastInstr
|
||||
if (lastInstruction == null) {
|
||||
if (lastInstructionIndex == -1) {
|
||||
addInstruction(op, location, immediates)
|
||||
return
|
||||
}
|
||||
|
||||
val lastInstruction = expression[lastInstructionIndex]
|
||||
val lastOperator = lastInstruction.operator
|
||||
|
||||
// droppable instructions + drop/unreachable -> nothing
|
||||
if ((op == WasmOp.DROP || op == WasmOp.UNREACHABLE) && lastOperator.pureStacklessInstruction()) {
|
||||
expression.removeLast()
|
||||
trimInstructionsUntil(lastInstructionIndex)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -83,7 +84,7 @@ class WasmIrExpressionBuilder(
|
||||
if (localSetNumber != null) {
|
||||
val localGetNumber = (immediates.firstOrNull() as? WasmImmediate.LocalIdx)?.value
|
||||
if (localGetNumber == localSetNumber) {
|
||||
expression.removeLast()
|
||||
trimInstructionsUntil(lastInstructionIndex)
|
||||
addInstruction(WasmOp.LOCAL_TEE, location, immediates)
|
||||
return
|
||||
}
|
||||
@@ -93,11 +94,19 @@ class WasmIrExpressionBuilder(
|
||||
addInstruction(op, location, immediates)
|
||||
}
|
||||
|
||||
private fun trimInstructionsUntil(index: Int) {
|
||||
expression.trimToSize(index)
|
||||
lastInstructionIndex = index - 1
|
||||
}
|
||||
|
||||
override var numberOfNestedBlocks: Int = 0
|
||||
set(value) {
|
||||
assert(value >= 0) { "end without matching block" }
|
||||
field = value
|
||||
}
|
||||
|
||||
private val WasmOp.isPseudoInstruction: Boolean
|
||||
get() = opcode == WASM_OP_PSEUDO_OPCODE
|
||||
}
|
||||
|
||||
inline fun buildWasmExpression(body: WasmExpressionBuilder.() -> Unit): MutableList<WasmInstr> {
|
||||
|
||||
Generated
+5
@@ -31450,6 +31450,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/size/helloWorldDOM.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectsOptimization.kt")
|
||||
public void testObjectsOptimization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/size/objectsOptimization.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ok.kt")
|
||||
public void testOk() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/size/ok.kt");
|
||||
|
||||
Reference in New Issue
Block a user