mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-21 01:00:54 +08:00
Improve inlining performance by caching method complexity
This commit is contained in:
parent
d4f98a57d0
commit
e48dfb27b0
@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.teavm.model.optimization;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.teavm.model.BasicBlockReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ProgramReader;
|
||||
@ -32,6 +34,7 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
||||
private final int totalComplexityThreshold;
|
||||
private final boolean onceUsedOnly;
|
||||
private int getComplexityDepth;
|
||||
private Map<MethodReference, Complexity> complexityCache = new HashMap<>();
|
||||
|
||||
public DefaultInliningStrategy(int complexityThreshold, int depthThreshold, int totalComplexityThreshold,
|
||||
boolean onceUsedOnly) {
|
||||
@ -53,6 +56,20 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
||||
return new InliningStepImpl(complexityHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void methodChanged(MethodReference method) {
|
||||
complexityCache.remove(method);
|
||||
}
|
||||
|
||||
private Complexity getComplexity(MethodReference methodRef, InliningContext context) {
|
||||
var result = complexityCache.get(methodRef);
|
||||
if (result == null) {
|
||||
result = getComplexity(context.getProgram(methodRef), context);
|
||||
complexityCache.put(methodRef, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Complexity getComplexity(ProgramReader program, InliningContext context) {
|
||||
int complexity = 0;
|
||||
ComplexityCounter counter = new ComplexityCounter(context);
|
||||
@ -81,7 +98,7 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
||||
return null;
|
||||
}
|
||||
|
||||
Complexity complexity = getComplexity(program, context);
|
||||
Complexity complexity = getComplexity(method, context);
|
||||
if (onceUsedOnly && !context.isUsedOnce(method)) {
|
||||
if (complexity.callsToUsedOnceMethods || complexity.score > 1) {
|
||||
return null;
|
||||
@ -125,19 +142,18 @@ 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)) {
|
||||
ProgramReader program = context.getProgram(method);
|
||||
if (!isTrivialCall(program)) {
|
||||
if (!isTrivialCall(method)) {
|
||||
callsToUsedOnceMethods = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTrivialCall(ProgramReader program) {
|
||||
if (program == null || getComplexityDepth > 10) {
|
||||
private boolean isTrivialCall(MethodReference methodRef) {
|
||||
if (context.getProgram(methodRef) == null || getComplexityDepth > 10) {
|
||||
return false;
|
||||
}
|
||||
getComplexityDepth++;
|
||||
Complexity complexity = getComplexity(program, context);
|
||||
Complexity complexity = getComplexity(methodRef, context);
|
||||
getComplexityDepth--;
|
||||
return complexity.score <= 1 && !complexity.callsToUsedOnceMethods;
|
||||
}
|
||||
|
@ -175,6 +175,7 @@ public class Inlining {
|
||||
instructionsToSkip = null;
|
||||
|
||||
new UnreachableBasicBlockEliminator().optimize(program);
|
||||
strategy.methodChanged(method);
|
||||
}
|
||||
|
||||
private boolean applyOnce(Program program, MethodReference method) {
|
||||
|
@ -20,4 +20,7 @@ import org.teavm.model.ProgramReader;
|
||||
|
||||
public interface InliningStrategy {
|
||||
InliningStep start(MethodReference method, ProgramReader program);
|
||||
|
||||
default void methodChanged(MethodReference method) {
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user