[WASM] Fold redundant patterns with drop instruction on a wasm level
This commit is contained in:
committed by
teamcityserver
parent
1db45faba2
commit
9685695769
+8
-2
@@ -35,7 +35,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
|
|
||||||
private val unitGetInstance by lazy { backendContext.findUnitGetInstanceFunction() }
|
private val unitGetInstance by lazy { backendContext.findUnitGetInstanceFunction() }
|
||||||
fun WasmExpressionBuilder.buildGetUnit() {
|
fun WasmExpressionBuilder.buildGetUnit() {
|
||||||
buildCall(context.referenceFunction(unitGetInstance.symbol))
|
buildInstr(WasmOp.GET_UNIT, WasmImmediate.FuncIdx(context.referenceFunction(unitGetInstance.symbol)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates code for the given IR element and *always* leaves something on the stack
|
// Generates code for the given IR element and *always* leaves something on the stack
|
||||||
@@ -264,6 +264,12 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get unit is a special case because it is the only function which returns the real unit instance.
|
||||||
|
if (call.symbol == unitGetInstance.symbol) {
|
||||||
|
body.buildGetUnit()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
call.dispatchReceiver?.let { generateExpression(it) }
|
call.dispatchReceiver?.let { generateExpression(it) }
|
||||||
call.extensionReceiver?.let { generateExpression(it) }
|
call.extensionReceiver?.let { generateExpression(it) }
|
||||||
for (i in 0 until call.valueArgumentsCount) {
|
for (i in 0 until call.valueArgumentsCount) {
|
||||||
@@ -319,7 +325,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unit types don't cross function boundaries
|
// Unit types don't cross function boundaries
|
||||||
if (function.returnType == irBuiltIns.unitType && function.symbol != unitGetInstance.symbol)
|
if (function.returnType == irBuiltIns.unitType)
|
||||||
body.buildGetUnit()
|
body.buildGetUnit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -367,6 +367,9 @@ enum class WasmOp(
|
|||||||
REF_CAST("ref.cast", 0xFB_41),
|
REF_CAST("ref.cast", 0xFB_41),
|
||||||
|
|
||||||
BR_ON_CAST("br_on_cast", 0xFB_42, listOf(LABEL_IDX)),
|
BR_ON_CAST("br_on_cast", 0xFB_42, listOf(LABEL_IDX)),
|
||||||
|
|
||||||
|
// 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)
|
||||||
;
|
;
|
||||||
|
|
||||||
constructor(mnemonic: String, opcode: Int, vararg immediates: WasmImmediateKind) : this(mnemonic, opcode, immediates.toList())
|
constructor(mnemonic: String, opcode: Int, vararg immediates: WasmImmediateKind) : this(mnemonic, opcode, immediates.toList())
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ fun foldWasmInstructions(prev: WasmInstr?, next: WasmInstr): List<WasmInstr>? {
|
|||||||
if (next.operator == WasmOp.UNREACHABLE && prev.operator in listOf(WasmOp.UNREACHABLE, WasmOp.RETURN))
|
if (next.operator == WasmOp.UNREACHABLE && prev.operator in listOf(WasmOp.UNREACHABLE, WasmOp.RETURN))
|
||||||
return listOf(prev)
|
return listOf(prev)
|
||||||
|
|
||||||
|
if (next.operator == WasmOp.DROP) {
|
||||||
|
// simple pure instruction + drop -> nothing
|
||||||
|
if (prev.operator == WasmOp.GET_UNIT || prev.operator == WasmOp.REF_NULL)
|
||||||
|
return listOf()
|
||||||
|
|
||||||
|
// return + drop -> return
|
||||||
|
if (prev.operator == WasmOp.RETURN)
|
||||||
|
return listOf(prev)
|
||||||
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user