From e48dfb27b0dda2db3874604f5a570d1c80bee336 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 29 Apr 2024 16:32:16 +0200 Subject: [PATCH] Improve inlining performance by caching method complexity --- .../optimization/DefaultInliningStrategy.java | 28 +++++++++++++++---- .../teavm/model/optimization/Inlining.java | 1 + .../model/optimization/InliningStrategy.java | 3 ++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/teavm/model/optimization/DefaultInliningStrategy.java b/core/src/main/java/org/teavm/model/optimization/DefaultInliningStrategy.java index b93924f60..d2de45b5b 100644 --- a/core/src/main/java/org/teavm/model/optimization/DefaultInliningStrategy.java +++ b/core/src/main/java/org/teavm/model/optimization/DefaultInliningStrategy.java @@ -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 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 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; } diff --git a/core/src/main/java/org/teavm/model/optimization/Inlining.java b/core/src/main/java/org/teavm/model/optimization/Inlining.java index c360aad73..6f5cd6eb1 100644 --- a/core/src/main/java/org/teavm/model/optimization/Inlining.java +++ b/core/src/main/java/org/teavm/model/optimization/Inlining.java @@ -175,6 +175,7 @@ public class Inlining { instructionsToSkip = null; new UnreachableBasicBlockEliminator().optimize(program); + strategy.methodChanged(method); } private boolean applyOnce(Program program, MethodReference method) { diff --git a/core/src/main/java/org/teavm/model/optimization/InliningStrategy.java b/core/src/main/java/org/teavm/model/optimization/InliningStrategy.java index 93dc18dc0..961272f43 100644 --- a/core/src/main/java/org/teavm/model/optimization/InliningStrategy.java +++ b/core/src/main/java/org/teavm/model/optimization/InliningStrategy.java @@ -20,4 +20,7 @@ import org.teavm.model.ProgramReader; public interface InliningStrategy { InliningStep start(MethodReference method, ProgramReader program); + + default void methodChanged(MethodReference method) { + } }