Improve inlining

This commit is contained in:
Alexey Andreev 2020-03-03 14:34:27 +03:00
parent 146776ff55
commit eb3490dba0
5 changed files with 36 additions and 6 deletions

View File

@ -408,7 +408,8 @@ public class Renderer implements RenderingManager {
if (clinit != null && context.isDynamicInitializer(cls.getName())) {
renderCallClinit(clinit, cls);
}
if (!cls.getClassHolder().getModifiers().contains(ElementModifier.INTERFACE)) {
if (!cls.getClassHolder().hasModifier(ElementModifier.INTERFACE)
&& !cls.getClassHolder().hasModifier(ElementModifier.ABSTRACT)) {
for (PreparedMethod method : cls.getMethods()) {
if (!method.methodHolder.getModifiers().contains(ElementModifier.STATIC)) {
if (method.reference.getName().equals("<init>")) {

View File

@ -124,26 +124,37 @@ public class DefaultInliningStrategy implements InliningStrategy {
public void invoke(VariableReader receiver, VariableReader instance, MethodReference method,
List<? extends VariableReader> arguments, InvocationType type) {
if (type == InvocationType.SPECIAL && context != null && context.isUsedOnce(method)) {
callsToUsedOnceMethods = true;
ProgramReader program = context.getProgram(method);
if (!isTrivialCall(program)) {
callsToUsedOnceMethods = true;
}
}
}
private boolean isTrivialCall(ProgramReader program) {
if (program == null) {
return false;
}
Complexity complexity = getComplexity(program, context);
return complexity.score <= 1 && !complexity.callsToUsedOnceMethods;
}
@Override
public void choose(VariableReader condition, List<? extends SwitchTableEntryReader> table,
BasicBlockReader defaultTarget) {
complexity += 3;
complexity += 2;
}
@Override
public void jumpIf(BranchingCondition cond, VariableReader operand, BasicBlockReader consequent,
BasicBlockReader alternative) {
complexity += 2;
complexity += 1;
}
@Override
public void jumpIf(BinaryBranchingCondition cond, VariableReader first, VariableReader second,
BasicBlockReader consequent, BasicBlockReader alternative) {
complexity += 2;
complexity += 1;
}
@Override
@ -155,6 +166,11 @@ public class DefaultInliningStrategy implements InliningStrategy {
public void exit(VariableReader valueToReturn) {
complexity--;
}
@Override
public void raise(VariableReader exception) {
complexity--;
}
}
static class Complexity {

View File

@ -500,6 +500,16 @@ public class Inlining {
return methodsUsedOnce.contains(method);
}
@Override
public ProgramReader getProgram(MethodReference method) {
ClassReader cls = dependencyInfo.getClassSource().get(method.getClassName());
if (cls == null) {
return null;
}
MethodReader methodReader = cls.getMethod(method.getDescriptor());
return methodReader != null ? methodReader.getProgram() : null;
}
@Override
public int getDepth() {
return depth;

View File

@ -16,9 +16,12 @@
package org.teavm.model.optimization;
import org.teavm.model.MethodReference;
import org.teavm.model.ProgramReader;
public interface InliningContext {
boolean isUsedOnce(MethodReference method);
ProgramReader getProgram(MethodReference method);
int getDepth();
}

View File

@ -837,7 +837,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
}
boolean isVirtual(MethodReference method) {
if (method.getName().equals("<init>") || method.getName().equals("<clinit>")) {
if (method.getName().equals("<clinit>")) {
return false;
}
return virtualMethods == null || virtualMethods.contains(method)