Use also local.tee instruction for reused with dup instructions

This commit is contained in:
Volker Berlin 2021-03-27 18:27:00 +01:00
parent 4e2f35a073
commit d480471e27
3 changed files with 37 additions and 8 deletions

View File

@ -359,6 +359,20 @@ class LocaleVariableManager {
return var.idx;
}
/**
* Expand code range for which the variable is valid
*
* @param slot
* the memory/slot index of the local variable
* @param javaCodePos
* the new end code position in the Java method
*/
void expandUse( int slot, int javaCodePos ) {
Variable var = variables[slot];
//TODO does we need to check for overlap with other slots?
var.endPos = Math.max( var.endPos, javaCodePos );
}
/**
* Get the WebAssembly variable index of the given Java Slot.
*

View File

@ -316,23 +316,28 @@ public abstract class WasmCodeBuilder {
protected void addDupInstruction( int javaCodePos, int lineNumber ) {
WasmInstruction instr = findInstructionThatPushValue( 1, javaCodePos );
AnyType type = instr.getPushValueType();
int varIndex = -1;
int slot = -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();
switch( local1.getOperator() ) {
case get:
case tee:
slot = local1.getSlot();
break;
default:
}
}
//alternate we need to create a new locale variable
if( varIndex < 0 ) {
varIndex = getTempVariable( type, javaCodePos, javaCodePos + 1 );
instructions.add( new WasmLoadStoreInstruction( VariableOperator.tee, varIndex, localVariables, javaCodePos, lineNumber ) );
instructions.add( new WasmLoadStoreInstruction( VariableOperator.get, varIndex, localVariables, javaCodePos, lineNumber ) );
if( slot < 0 ) {
slot = getTempVariable( type, javaCodePos, javaCodePos + 1 );
instructions.add( new WasmLoadStoreInstruction( VariableOperator.tee, slot, localVariables, javaCodePos, lineNumber ) );
instructions.add( new WasmLoadStoreInstruction( VariableOperator.get, slot, 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 ) );
instructions.add( new WasmLoadStoreInstruction( VariableOperator.get, slot, localVariables, javaCodePos, lineNumber ) );
localVariables.expandUse( slot, javaCodePos );
}
}

View File

@ -90,6 +90,16 @@ class WasmLocalInstruction extends WasmInstruction {
this.op = op;
}
/**
* Get the slot of the locals
*
* @return the Java slot for the variable
*/
@Nonnegative
int getSlot() {
return idx;
}
/**
* Get the number of the locals
*