From 219de85e24831d59add44ec401c850a9c9bd93e3 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 27 Sep 2023 19:36:02 +0200 Subject: [PATCH] Improve performance of PhiUpdater --- .../java/org/teavm/model/util/PhiUpdater.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/core/src/main/java/org/teavm/model/util/PhiUpdater.java b/core/src/main/java/org/teavm/model/util/PhiUpdater.java index d25a2ac4c..30d8cf48f 100644 --- a/core/src/main/java/org/teavm/model/util/PhiUpdater.java +++ b/core/src/main/java/org/teavm/model/util/PhiUpdater.java @@ -87,6 +87,7 @@ public class PhiUpdater { private int[][] domFrontiers; private Variable[] variableMap; private boolean[] variableDefined; + private int[] variableDefinitionCount; private List> definedVersions = new ArrayList<>(); private BasicBlock currentBlock; private Phi[][] phiMap; @@ -143,9 +144,11 @@ public class PhiUpdater { variableMap = new Variable[program.variableCount()]; usedDefinitions = new boolean[program.variableCount()]; + variableDefinitionCount = new int[program.variableCount()]; for (int i = 0; i < parameters.length; ++i) { variableMap[i] = parameters[i]; usedDefinitions[i] = true; + variableDefinitionCount[i] = 1; } for (int i = 0; i < program.variableCount(); ++i) { @@ -217,6 +220,8 @@ public class PhiUpdater { } private void estimatePhis() { + calculateDefinitions(); + DefinitionExtractor definitionExtractor = new DefinitionExtractor(); variableDefined = new boolean[program.variableCount()]; @@ -271,6 +276,37 @@ public class PhiUpdater { } } + private void calculateDefinitions() { + var defExtractor = new DefinitionExtractor(); + for (var block : program.getBasicBlocks()) { + increaseDefinitionCount(block.getExceptionVariable()); + for (var phi : block.getPhis()) { + increaseDefinitionCount(phi.getReceiver()); + } + for (var instruction : block) { + instruction.acceptVisitor(defExtractor); + for (var definedVar : defExtractor.getDefinedVariables()) { + increaseDefinitionCount(definedVar); + } + } + var sigmas = getSigmasAt(block.getIndex()); + if (sigmas != null) { + for (var sigma : sigmas) { + increaseDefinitionCount(sigma.getValue()); + for (var i = 0; i < sigma.getOutgoings().size(); ++i) { + increaseDefinitionCount(sigma.getValue()); + } + } + } + } + } + + private void increaseDefinitionCount(Variable var) { + if (var != null) { + variableDefinitionCount[var.getIndex()]++; + } + } + private static class Task { Variable[] variables; BasicBlock block; @@ -451,6 +487,11 @@ public class PhiUpdater { } private void markAssignment(Variable var) { + if (variableDefinitionCount[var.getIndex()] < 2) { + variableDefined[var.getIndex()] = true; + return; + } + Deque worklist = new ArrayDeque<>(); worklist.push(currentBlock);