mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 10:44:47 +01:00
optimize the DUP instruction, only use a temp local variable if needed.
This commit is contained in:
parent
3d8f49c79a
commit
a4040a8d3b
@ -723,7 +723,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
||||
byteCode.skip( 4 - padding );
|
||||
}
|
||||
startPosition--;
|
||||
int switchValuestartPosition = findPushInstructionCodePosition( 1 );
|
||||
int switchValuestartPosition = findBlockStartCodePosition( 1 );
|
||||
|
||||
int defaultPosition = startPosition + byteCode.readInt();
|
||||
int[] keys;
|
||||
|
@ -18,6 +18,7 @@ package de.inetsoftware.jwebassembly.module;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnegative;
|
||||
@ -112,8 +113,8 @@ public abstract class WasmCodeBuilder {
|
||||
* the count of values on the stack back. 1 means the last value. 2 means the penultimate value.
|
||||
* @return the code position that push the last instruction
|
||||
*/
|
||||
int findPushInstructionCodePosition( int count ) {
|
||||
return findPushInstruction( count, true );
|
||||
int findBlockStartCodePosition( int count ) {
|
||||
return findBlockStart( count, true );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +127,7 @@ public abstract class WasmCodeBuilder {
|
||||
* true, get the code position; false, get the index in the instructions
|
||||
* @return the code position that push the last instruction
|
||||
*/
|
||||
private int findPushInstruction( int count, boolean codePosition ) {
|
||||
private int findBlockStart( int count, boolean codePosition ) {
|
||||
int valueCount = 0;
|
||||
List<WasmInstruction> instructions = this.instructions;
|
||||
for( int i = instructions.size() - 1; i >= 0; i-- ) {
|
||||
@ -152,6 +153,32 @@ public abstract class WasmCodeBuilder {
|
||||
*/
|
||||
@Nonnull
|
||||
AnyType findValueTypeFromStack( int count ) {
|
||||
return findInstructionThatPushValue( count, (idx,instr ) -> instr.getPushValueType() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the instruction that push the x-th value to the stack.
|
||||
*
|
||||
* @param count
|
||||
* the count of values on the stack back. 1 means the last value. 2 means the penultimate value.
|
||||
* @return the instruction
|
||||
*/
|
||||
private WasmInstruction findInstructionThatPushValue( int count ) {
|
||||
return findInstructionThatPushValue( count, (index,instruction) -> instruction );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the instruction that push the x-th value to the stack.
|
||||
*
|
||||
* @param <T>
|
||||
* the return type
|
||||
* @param count
|
||||
* the count of values on the stack back. 1 means the last value. 2 means the penultimate value.
|
||||
* @param funct
|
||||
* the return value from the instruction
|
||||
* @return the function value
|
||||
*/
|
||||
<T> T findInstructionThatPushValue( int count, BiFunction<Integer, WasmInstruction, T> funct ) {
|
||||
int valueCount = 0;
|
||||
List<WasmInstruction> instructions = this.instructions;
|
||||
for( int i = instructions.size() - 1; i >= 0; i-- ) {
|
||||
@ -159,12 +186,12 @@ public abstract class WasmCodeBuilder {
|
||||
AnyType valueType = instr.getPushValueType();
|
||||
if( valueType != null ) {
|
||||
if( ++valueCount == count ) {
|
||||
return valueType;
|
||||
return funct.apply( i, instr );
|
||||
}
|
||||
}
|
||||
valueCount -= instr.getPopCount();
|
||||
}
|
||||
throw new WasmException( "Push Value not found", -1 ); // should never occur
|
||||
throw new WasmException( "Push instruction not found", -1 ); // should never occur
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,7 +298,7 @@ public abstract class WasmCodeBuilder {
|
||||
AnyType valueType = findValueTypeFromStack( 1 );
|
||||
localVariables.useIndex( valueType, wasmIdx );
|
||||
}
|
||||
instructions.add( new WasmLocalInstruction( op, wasmIdx, javaCodePos, lineNumber ) );
|
||||
instructions.add( new WasmLocalInstruction( op, wasmIdx, localVariables, javaCodePos, lineNumber ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -283,11 +310,25 @@ public abstract class WasmCodeBuilder {
|
||||
* the line number in the Java source code
|
||||
*/
|
||||
protected void addDupInstruction( int javaCodePos, int lineNumber ) {
|
||||
AnyType type = findValueTypeFromStack( 1 );
|
||||
int idx = getTempVariable( type, javaCodePos, javaCodePos + 1 );
|
||||
instructions.add( new WasmDupInstruction( idx, type, localVariables, javaCodePos, lineNumber ) );
|
||||
// an alternative solution can be a function call with multiple return values but this seems to be slower
|
||||
// new SyntheticFunctionName( "dup" + storeType, "local.get 0 local.get 0 return", storeType, null, storeType, storeType ), codePos, lineNumber )
|
||||
WasmInstruction instr = findInstructionThatPushValue( 1 );
|
||||
AnyType type = instr.getPushValueType();
|
||||
int varIndex = -1;
|
||||
// if it is a GET to a local variable then we can use it
|
||||
if( instr.getType() == Type.Local ) {
|
||||
WasmLocalInstruction local1 = (WasmLocalInstruction)instr;
|
||||
if( local1.getOperator() == VariableOperator.get ) {
|
||||
varIndex = local1.getIndex();
|
||||
}
|
||||
}
|
||||
//alternate we need to create a new locale variable
|
||||
if( varIndex < 0 ) {
|
||||
varIndex = getTempVariable( type, javaCodePos, javaCodePos + 1 );
|
||||
instructions.add( new WasmDupInstruction( varIndex, type, localVariables, javaCodePos, lineNumber ) );
|
||||
// an alternative solution can be a function call with multiple return values but this seems to be slower
|
||||
// new SyntheticFunctionName( "dup" + storeType, "local.get 0 local.get 0 return", storeType, null, storeType, storeType ), codePos, lineNumber )
|
||||
} else {
|
||||
instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex, localVariables, javaCodePos, lineNumber ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -473,8 +514,7 @@ public abstract class WasmCodeBuilder {
|
||||
|
||||
// find the instruction that this push on stack
|
||||
int count = indirectCall.getPopCount();
|
||||
int idx = findPushInstruction( count, false );
|
||||
WasmInstruction instr = instructions.get( idx );
|
||||
WasmInstruction instr = findInstructionThatPushValue( count );
|
||||
int varIndex = -1;
|
||||
// if it is a GET to a local variable then we can use it
|
||||
if( instr.getType() == Type.Local ) {
|
||||
@ -487,7 +527,7 @@ public abstract class WasmCodeBuilder {
|
||||
if( varIndex < 0 ) {
|
||||
int javaCodePos = indirectCall.getCodePosition();
|
||||
varIndex = getTempVariable( indirectCall.getThisType(), instr.getCodePosition(), javaCodePos + 1 );
|
||||
idx = count == 1 ? instructions.size() : findPushInstruction( count - 1, false );
|
||||
int idx = count == 1 ? instructions.size() : findBlockStart( count - 1, false );
|
||||
instructions.add( idx, new DupThis( indirectCall, varIndex, javaCodePos ) );
|
||||
}
|
||||
indirectCall.setVariableIndexOfThis( varIndex );
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 - 2019 Volker Berlin (i-net software)
|
||||
Copyright 2018 - 2020 Volker Berlin (i-net software)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -31,8 +31,6 @@ import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
*/
|
||||
class WasmLoadStoreInstruction extends WasmLocalInstruction {
|
||||
|
||||
private LocaleVariableManager localVariables;
|
||||
|
||||
/**
|
||||
* Create an instance of a load/store instruction
|
||||
*
|
||||
@ -48,8 +46,7 @@ class WasmLoadStoreInstruction extends WasmLocalInstruction {
|
||||
* the line number in the Java source code
|
||||
*/
|
||||
WasmLoadStoreInstruction( boolean load, @Nonnegative int idx, LocaleVariableManager localVariables, int javaCodePos, int lineNumber ) {
|
||||
super( load ? get : set, idx, javaCodePos, lineNumber );
|
||||
this.localVariables = localVariables;
|
||||
super( load ? get : set, idx, localVariables, javaCodePos, lineNumber );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,11 +56,4 @@ class WasmLoadStoreInstruction extends WasmLocalInstruction {
|
||||
int getIndex() {
|
||||
return localVariables.get( super.getIndex(), getCodePosition() ); // translate slot index to position index
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
AnyType getPushValueType() {
|
||||
return getPopCount() == 0 ? localVariables.getValueType( getIndex() ) : null;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 - 2019 Volker Berlin (i-net software)
|
||||
Copyright 2018 - 2020 Volker Berlin (i-net software)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -38,6 +38,8 @@ class WasmLocalInstruction extends WasmInstruction {
|
||||
|
||||
private int idx;
|
||||
|
||||
final LocaleVariableManager localVariables;
|
||||
|
||||
/**
|
||||
* Create an instance of a load/store instruction for a local variable.
|
||||
*
|
||||
@ -45,15 +47,18 @@ class WasmLocalInstruction extends WasmInstruction {
|
||||
* the operation
|
||||
* @param idx
|
||||
* the memory/slot idx of the variable
|
||||
* @param localVariables
|
||||
* the manager for local variables
|
||||
* @param javaCodePos
|
||||
* the code position/offset in the Java method
|
||||
* @param lineNumber
|
||||
* the line number in the Java source code
|
||||
*/
|
||||
WasmLocalInstruction( VariableOperator op, @Nonnegative int idx, int javaCodePos, int lineNumber ) {
|
||||
WasmLocalInstruction( VariableOperator op, @Nonnegative int idx, LocaleVariableManager localVariables, int javaCodePos, int lineNumber ) {
|
||||
super( javaCodePos, lineNumber );
|
||||
this.op = op;
|
||||
this.idx = idx;
|
||||
this.localVariables = localVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,7 +91,7 @@ class WasmLocalInstruction extends WasmInstruction {
|
||||
/**
|
||||
* Get the number of the locals
|
||||
*
|
||||
* @return the index
|
||||
* @return the index, mostly the Wasm Index
|
||||
*/
|
||||
@Nonnegative
|
||||
int getIndex() {
|
||||
@ -107,7 +112,7 @@ class WasmLocalInstruction extends WasmInstruction {
|
||||
*/
|
||||
@Override
|
||||
AnyType getPushValueType() {
|
||||
return null;
|
||||
return op == get ? localVariables.getValueType( getIndex() ) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user