From d2f5815113e5cbe7312e576950886959db4dbc0c Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 2 Sep 2024 21:06:43 +0200 Subject: [PATCH] Fix issues related to sigma nodes in phi updater --- .../java/org/teavm/model/util/PhiUpdater.java | 108 +++++++----------- .../analysis/test/NullnessAnalysisTest.java | 3 - 2 files changed, 39 insertions(+), 72 deletions(-) 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 30d8cf48f..9d78a59db 100644 --- a/core/src/main/java/org/teavm/model/util/PhiUpdater.java +++ b/core/src/main/java/org/teavm/model/util/PhiUpdater.java @@ -101,6 +101,7 @@ public class PhiUpdater { private Sigma[][] sigmas; private Predicate sigmaPredicate = instruction -> false; private int[][][] frontierVariableCache; + private Variable[][] pendingVariableMap; public int getSourceVariable(int var) { if (var >= variableToSourceMap.size()) { @@ -141,6 +142,7 @@ public void updatePhis(Program program, Variable[] parameters) { domTree = GraphUtils.buildDominatorTree(cfg); domFrontiers = new int[cfg.size()][]; domGraph = GraphUtils.buildDominatorGraph(domTree, program.basicBlockCount()); + pendingVariableMap = new Variable[program.basicBlockCount()][]; variableMap = new Variable[program.variableCount()]; usedDefinitions = new boolean[program.variableCount()]; @@ -207,11 +209,7 @@ private void estimateSigmas() { Sigma sigma = new Sigma(block, variables[j]); sigmasInBlock[j] = sigma; for (BasicBlock target : targets) { - Variable outgoingVar = program.createVariable(); - variableToSourceMap.add(sigma.getValue().getIndex()); - outgoingVar.setDebugName(sigma.getValue().getDebugName()); - outgoingVar.setLabel(sigma.getValue().getLabel()); - Outgoing outgoing = new Outgoing(outgoingVar, target); + Outgoing outgoing = new Outgoing(variables[j], target); sigma.getOutgoings().add(outgoing); } } @@ -264,12 +262,6 @@ private void estimatePhis() { } } - if (sigmas[i] != null) { - for (Sigma sigma : sigmas[i]) { - markAssignment(sigma.getValue()); - } - } - for (int successor : domGraph.outgoingEdges(i)) { stack.addLast(successor); } @@ -307,31 +299,22 @@ private void increaseDefinitionCount(Variable var) { } } - private static class Task { - Variable[] variables; - BasicBlock block; - } - private void renameVariables() { - Deque stack = new ArrayDeque<>(); + Deque stack = new ArrayDeque<>(); for (int i = 0; i < program.basicBlockCount(); ++i) { if (domGraph.incomingEdgesCount(i) == 0) { - Task task = new Task(); - task.block = program.basicBlockAt(i); - task.variables = variableMap.clone(); - stack.push(task); + stack.push(program.basicBlockAt(i)); + pendingVariableMap[i] = variableMap.clone(); } } - List> phiOutputs = ProgramUtils.getPhiOutputs(program); - while (!stack.isEmpty()) { Collections.fill(definedVersions, null); - Task task = stack.pop(); - currentBlock = task.block; + currentBlock = stack.pop(); int index = currentBlock.getIndex(); - variableMap = task.variables.clone(); + variableMap = pendingVariableMap[index]; + pendingVariableMap[index] = null; if (currentBlock.getExceptionVariable() != null) { currentBlock.setExceptionVariable(define(currentBlock.getExceptionVariable())); @@ -355,30 +338,20 @@ private void renameVariables() { int[] successors = domGraph.outgoingEdges(index); - for (Incoming output : phiOutputs.get(index)) { - Variable var = output.getValue(); - Variable sigmaVar = applySigmaRename(output.getPhi().getBasicBlock(), var); - var = sigmaVar != var ? sigmaVar : use(var); - output.setValue(var); + Sigma[] nextSigmas = sigmas[index]; + if (nextSigmas != null) { + for (Sigma sigma : sigmas[index]) { + sigma.setValue(use(sigma.getValue())); + } } - Sigma[] nextSigmas = sigmas[index]; + var oldVariableMap = variableMap; for (int j = successors.length - 1; j >= 0; --j) { int successor = successors[j]; - Task next = new Task(); - next.variables = variableMap.clone(); - next.block = program.basicBlockAt(successor); - if (nextSigmas != null) { - for (Sigma sigma : nextSigmas) { - for (Outgoing outgoing : sigma.getOutgoings()) { - if (outgoing.getTarget().getIndex() == successor) { - next.variables[sigma.getValue().getIndex()] = outgoing.getValue(); - break; - } - } - } - } - stack.push(next); + var variables = oldVariableMap.clone(); + pendingVariableMap[successor] = variables; + stack.push(program.basicBlockAt(successor)); + variableMap = variables; } IntSet exceptionHandlingSuccessors = new IntHashSet(); @@ -387,13 +360,19 @@ private void renameVariables() { } for (int successor : cfg.outgoingEdges(index)) { - renameOutgoingPhis(successor, exceptionHandlingSuccessors.contains(successor)); - } - - if (sigmas[index] != null) { - for (Sigma sigma : sigmas[index]) { - sigma.setValue(use(sigma.getValue())); + variableMap = domTree.directlyDominates(currentBlock.getIndex(), successor) + ? pendingVariableMap[successor] + : oldVariableMap.clone(); + if (nextSigmas != null) { + for (var sigma : nextSigmas) { + for (var outgoing : sigma.getOutgoings()) { + if (outgoing.getTarget().getIndex() == successor) { + outgoing.setValue(define(outgoing.getValue())); + } + } + } } + renameOutgoingPhis(successor, exceptionHandlingSuccessors.contains(successor)); } } } @@ -445,7 +424,6 @@ private void renameOutgoingPhis(int successor, boolean allVersions) { for (int j = 0; j < phis.size(); ++j) { Phi phi = phis.get(j); - Variable originalVar = program.variableAt(phiIndexes[j]); Variable var = variableMap[phiIndexes[j]]; if (var != null) { List versions = definedVersions.get(phiIndexes[j]); @@ -458,32 +436,24 @@ private void renameOutgoingPhis(int successor, boolean allVersions) { } } - Variable sigmaVar = applySigmaRename(program.basicBlockAt(successor), originalVar); Incoming incoming = new Incoming(); incoming.setSource(currentBlock); - incoming.setValue(sigmaVar != originalVar ? sigmaVar : var); + incoming.setValue(var); phi.getIncomings().add(incoming); phi.getReceiver().setDebugName(var.getDebugName()); } } - } - private Variable applySigmaRename(BasicBlock target, Variable var) { - Sigma[] blockSigmas = sigmas[currentBlock.getIndex()]; - if (blockSigmas == null) { - return var; - } - for (Sigma sigma : blockSigmas) { - if (sigma.getValue() != var) { - continue; - } - for (Outgoing outgoing : sigma.getOutgoings()) { - if (outgoing.getTarget() == target) { - return outgoing.getValue(); + for (var phi : program.basicBlockAt(successor).getPhis()) { + for (var incoming : phi.getIncomings()) { + if (incoming.getSource() == currentBlock) { + var value = variableMap[incoming.getValue().getIndex()]; + if (value != null) { + incoming.setValue(value); + } } } } - return var; } private void markAssignment(Variable var) { diff --git a/core/src/test/java/org/teavm/model/analysis/test/NullnessAnalysisTest.java b/core/src/test/java/org/teavm/model/analysis/test/NullnessAnalysisTest.java index b3c2b3771..03e510ef3 100644 --- a/core/src/test/java/org/teavm/model/analysis/test/NullnessAnalysisTest.java +++ b/core/src/test/java/org/teavm/model/analysis/test/NullnessAnalysisTest.java @@ -86,9 +86,6 @@ public void nonDominatedBranch() { } @Test - @Ignore - // Fix this issue and un-ignore - // Also, un-ignore TestYear.test_isLeap public void nonDominatedBranch2() { test(); }