From ff059919a798a02a5792111be3e5d4bf1de8058e Mon Sep 17 00:00:00 2001 From: Alexey Andreev <Alexey.Andreev@jetbrains.com> Date: Sun, 8 Jan 2017 22:04:24 +0300 Subject: [PATCH] Eliminate exception joint in favour of phi functions with multiple inputs per source basic block --- .../org/teavm/ast/optimization/Optimizer.java | 1 - .../optimization/ReadWriteStatsBuilder.java | 8 - .../main/java/org/teavm/cache/ProgramIO.java | 19 -- .../dependency/DataFlowGraphBuilder.java | 14 - .../dependency/DependencyGraphBuilder.java | 14 - core/src/main/java/org/teavm/model/Phi.java | 4 - .../main/java/org/teavm/model/Program.java | 29 ++ .../java/org/teavm/model/TryCatchBlock.java | 66 ---- .../org/teavm/model/TryCatchBlockReader.java | 4 - .../java/org/teavm/model/TryCatchJoint.java | 52 --- .../org/teavm/model/TryCatchJointReader.java | 26 -- .../model/analysis/NullnessInformation.java | 18 +- .../analysis/NullnessInformationBuilder.java | 9 - .../lowlevel/ClassInitializerEliminator.java | 2 - ...ceptionHandlingShadowStackContributor.java | 53 ++- .../optimization/GlobalValueNumbering.java | 10 - .../model/optimization/LoopInversionImpl.java | 8 - .../UnusedVariableElimination.java | 11 - .../VariableUsageGraphBuilder.java | 123 ++----- .../org/teavm/model/text/ListingBuilder.java | 18 +- .../org/teavm/model/text/ListingParser.java | 32 +- .../model/util/InstructionVariableMapper.java | 66 ++-- .../model/util/InterferenceGraphBuilder.java | 9 - .../teavm/model/util/LivenessAnalyzer.java | 19 +- .../java/org/teavm/model/util/PhiUpdater.java | 304 +++++------------- .../org/teavm/model/util/ProgramUtils.java | 41 +-- .../teavm/model/util/RegisterAllocator.java | 51 --- .../org/teavm/model/util/TypeInferer.java | 8 - .../nullness/tryCatchJoint.extended.txt | 6 +- .../nullness/tryCatchJoint.original.txt | 4 +- .../test/resources/model/text/exceptions.txt | 4 +- .../phi-updater/exceptionPhi.expected.txt | 2 +- .../exceptionPhiMultiple.expected.txt | 10 +- .../existingExceptionPhi.expected.txt | 12 +- .../existingExceptionPhi.original.txt | 12 +- .../metaprogramming/impl/AliasFinder.java | 12 - .../impl/optimization/BoxingElimination.java | 9 - 37 files changed, 246 insertions(+), 844 deletions(-) delete mode 100644 core/src/main/java/org/teavm/model/TryCatchJoint.java delete mode 100644 core/src/main/java/org/teavm/model/TryCatchJointReader.java diff --git a/core/src/main/java/org/teavm/ast/optimization/Optimizer.java b/core/src/main/java/org/teavm/ast/optimization/Optimizer.java index d42e96421..98ff2ff09 100644 --- a/core/src/main/java/org/teavm/ast/optimization/Optimizer.java +++ b/core/src/main/java/org/teavm/ast/optimization/Optimizer.java @@ -16,7 +16,6 @@ package org.teavm.ast.optimization; import java.util.BitSet; -import java.util.List; import org.teavm.ast.AsyncMethodNode; import org.teavm.ast.AsyncMethodPart; import org.teavm.ast.RegularMethodNode; diff --git a/core/src/main/java/org/teavm/ast/optimization/ReadWriteStatsBuilder.java b/core/src/main/java/org/teavm/ast/optimization/ReadWriteStatsBuilder.java index 1b29da3a5..5a685a198 100644 --- a/core/src/main/java/org/teavm/ast/optimization/ReadWriteStatsBuilder.java +++ b/core/src/main/java/org/teavm/ast/optimization/ReadWriteStatsBuilder.java @@ -78,14 +78,6 @@ class ReadWriteStatsBuilder { } } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - writes[joint.getReceiver().getIndex()] += joint.getSourceVariables().size(); - for (Variable var : joint.getSourceVariables()) { - reads[var.getIndex()]++; - } - } - } for (int succ : dom.outgoingEdges(node)) { stack.push(succ); diff --git a/core/src/main/java/org/teavm/cache/ProgramIO.java b/core/src/main/java/org/teavm/cache/ProgramIO.java index eccdb63fe..8a3045cd5 100644 --- a/core/src/main/java/org/teavm/cache/ProgramIO.java +++ b/core/src/main/java/org/teavm/cache/ProgramIO.java @@ -63,14 +63,6 @@ public class ProgramIO { data.writeInt(tryCatch.getExceptionType() != null ? symbolTable.lookup( tryCatch.getExceptionType()) : -1); data.writeShort(tryCatch.getHandler().getIndex()); - data.writeShort(tryCatch.getJoints().size()); - for (TryCatchJoint joint : tryCatch.getJoints()) { - data.writeShort(joint.getReceiver().getIndex()); - data.writeShort(joint.getSourceVariables().size()); - for (Variable sourceVar : joint.getSourceVariables()) { - data.writeShort(sourceVar.getIndex()); - } - } } TextLocation location = null; InstructionWriter insnWriter = new InstructionWriter(data); @@ -141,17 +133,6 @@ public class ProgramIO { } tryCatch.setHandler(program.basicBlockAt(data.readShort())); - int jointCount = data.readShort(); - for (int k = 0; k < jointCount; ++k) { - TryCatchJoint joint = new TryCatchJoint(); - joint.setReceiver(program.variableAt(data.readShort())); - int jointSourceCount = data.readShort(); - for (int m = 0; m < jointSourceCount; ++m) { - joint.getSourceVariables().add(program.variableAt(data.readShort())); - } - tryCatch.getJoints().add(joint); - } - block.getTryCatchBlocks().add(tryCatch); } diff --git a/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index 044b6f612..1e043241e 100644 --- a/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -64,13 +64,6 @@ public class DataFlowGraphBuilder extends AbstractInstructionReader { builder.addEdge(from, to); } } - for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { - for (TryCatchJointReader joint : tryCatch.readJoints()) { - for (VariableReader sourceVar : joint.readSourceVariables()) { - builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex()); - } - } - } block.readAllInstructions(this); } Graph graph = builder.build(); @@ -221,13 +214,6 @@ public class DataFlowGraphBuilder extends AbstractInstructionReader { } } - @Override - public void invokeDynamic(VariableReader receiver, VariableReader instance, MethodDescriptor method, - List<? extends VariableReader> arguments, MethodHandle bootstrapMethod, - List<RuntimeConstant> bootstrapArguments) { - // Should be eliminated by bootstrap method substitutor - } - @Override public void nullCheck(VariableReader receiver, VariableReader value) { connect(value.getIndex(), receiver.getIndex()); diff --git a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index 309d2ca2b..78b069b82 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -44,7 +44,6 @@ import org.teavm.model.Program; import org.teavm.model.RuntimeConstant; import org.teavm.model.TextLocation; import org.teavm.model.TryCatchBlockReader; -import org.teavm.model.TryCatchJointReader; import org.teavm.model.ValueType; import org.teavm.model.VariableReader; import org.teavm.model.emit.ProgramEmitter; @@ -142,19 +141,6 @@ class DependencyGraphBuilder { if (tryCatch.getExceptionType() != null) { dependencyChecker.linkClass(tryCatch.getExceptionType(), new CallLocation(caller.getMethod())); } - - for (TryCatchJointReader joint : tryCatch.readJoints()) { - DependencyNode receiverNode = nodes[joint.getReceiver().getIndex()]; - if (receiverNode == null) { - continue; - } - for (VariableReader source : joint.readSourceVariables()) { - DependencyNode sourceNode = nodes[source.getIndex()]; - if (sourceNode != null) { - sourceNode.connect(receiverNode); - } - } - } } } diff --git a/core/src/main/java/org/teavm/model/Phi.java b/core/src/main/java/org/teavm/model/Phi.java index 00f715882..40db6ddaf 100644 --- a/core/src/main/java/org/teavm/model/Phi.java +++ b/core/src/main/java/org/teavm/model/Phi.java @@ -20,10 +20,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -/** - * - * @author Alexey Andreev - */ public class Phi implements PhiReader { private BasicBlock basicBlock; private Variable receiver; diff --git a/core/src/main/java/org/teavm/model/Program.java b/core/src/main/java/org/teavm/model/Program.java index 2274586ca..ba6b0b57d 100644 --- a/core/src/main/java/org/teavm/model/Program.java +++ b/core/src/main/java/org/teavm/model/Program.java @@ -65,6 +65,35 @@ public class Program implements ProgramReader { return basicBlocks; } + public void rearrangeBasicBlocks(List<BasicBlock> basicBlocks) { + if (!isPacked()) { + throw new IllegalStateException("This operation is not supported on unpacked programs"); + } + + if (basicBlocks.size() != this.basicBlocks.size()) { + throw new IllegalArgumentException("New list of basic blocks has wrong size (" + + basicBlocks.size() + ", expected " + basicBlockCount() + ")"); + } + + boolean[] indexes = new boolean[basicBlocks.size()]; + for (BasicBlock block : basicBlocks) { + if (block.getProgram() != this) { + throw new IllegalArgumentException("The list of basic blocks contains a basic block from " + + "another program"); + } + if (indexes[block.getIndex()]) { + throw new IllegalArgumentException("The list of basic blocks contains same basic block twice"); + } + indexes[block.getIndex()] = true; + } + + this.basicBlocks.clear(); + this.basicBlocks.addAll(basicBlocks); + for (int i = 0; i < this.basicBlocks.size(); ++i) { + this.basicBlocks.get(i).setIndex(i); + } + } + public void deleteVariable(int index) { Variable variable = variables.get(index); if (variable == null) { diff --git a/core/src/main/java/org/teavm/model/TryCatchBlock.java b/core/src/main/java/org/teavm/model/TryCatchBlock.java index 9a5846dc1..2b020c103 100644 --- a/core/src/main/java/org/teavm/model/TryCatchBlock.java +++ b/core/src/main/java/org/teavm/model/TryCatchBlock.java @@ -15,64 +15,10 @@ */ package org.teavm.model; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - public class TryCatchBlock implements TryCatchBlockReader { BasicBlock protectedBlock; private BasicBlock handler; private String exceptionType; - private List<TryCatchJoint> joints = new ArrayList<>(); - private List<TryCatchJointReader> immutableJoints; - - private List<TryCatchJoint> safeJoints = new AbstractList<TryCatchJoint>() { - @Override - public TryCatchJoint get(int index) { - return joints.get(index); - } - - @Override - public int size() { - return joints.size(); - } - - @Override - public void add(int index, TryCatchJoint e) { - if (e.getBlock() != null) { - throw new IllegalArgumentException("This joint is already in some basic block"); - } - e.block = TryCatchBlock.this; - joints.add(index, e); - } - - @Override - public TryCatchJoint set(int index, TryCatchJoint element) { - if (element.block != null) { - throw new IllegalArgumentException("This phi is already in some basic block"); - } - TryCatchJoint oldJoint = joints.get(index); - oldJoint.block = null; - element.block = TryCatchBlock.this; - return joints.set(index, element); - } - - @Override - public TryCatchJoint remove(int index) { - TryCatchJoint joint = joints.remove(index); - joint.block = null; - return joint; - } - - @Override - public void clear() { - for (TryCatchJoint joint : joints) { - joint.block = null; - } - joints.clear(); - } - }; @Override public BasicBlock getHandler() { @@ -96,16 +42,4 @@ public class TryCatchBlock implements TryCatchBlockReader { public BasicBlock getProtectedBlock() { return protectedBlock; } - - public List<TryCatchJoint> getJoints() { - return safeJoints; - } - - @Override - public List<TryCatchJointReader> readJoints() { - if (immutableJoints == null) { - immutableJoints = Collections.unmodifiableList(safeJoints); - } - return immutableJoints; - } } diff --git a/core/src/main/java/org/teavm/model/TryCatchBlockReader.java b/core/src/main/java/org/teavm/model/TryCatchBlockReader.java index a49344476..a710db5ca 100644 --- a/core/src/main/java/org/teavm/model/TryCatchBlockReader.java +++ b/core/src/main/java/org/teavm/model/TryCatchBlockReader.java @@ -15,14 +15,10 @@ */ package org.teavm.model; -import java.util.List; - public interface TryCatchBlockReader { BasicBlockReader getProtectedBlock(); BasicBlockReader getHandler(); String getExceptionType(); - - List<TryCatchJointReader> readJoints(); } diff --git a/core/src/main/java/org/teavm/model/TryCatchJoint.java b/core/src/main/java/org/teavm/model/TryCatchJoint.java deleted file mode 100644 index 919d876f6..000000000 --- a/core/src/main/java/org/teavm/model/TryCatchJoint.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2016 Alexey Andreev. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.teavm.model; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class TryCatchJoint implements TryCatchJointReader { - private List<Variable> sourceVariables = new ArrayList<>(); - private List<VariableReader> readonlySourceVariables; - private Variable receiver; - TryCatchBlock block; - - @Override - public List<VariableReader> readSourceVariables() { - if (readonlySourceVariables == null) { - readonlySourceVariables = Collections.unmodifiableList(sourceVariables); - } - return readonlySourceVariables; - } - - public List<Variable> getSourceVariables() { - return sourceVariables; - } - - @Override - public Variable getReceiver() { - return receiver; - } - - public void setReceiver(Variable receiver) { - this.receiver = receiver; - } - - public TryCatchBlock getBlock() { - return block; - } -} diff --git a/core/src/main/java/org/teavm/model/TryCatchJointReader.java b/core/src/main/java/org/teavm/model/TryCatchJointReader.java deleted file mode 100644 index 2045d7529..000000000 --- a/core/src/main/java/org/teavm/model/TryCatchJointReader.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2016 Alexey Andreev. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.teavm.model; - -import java.util.List; - -public interface TryCatchJointReader { - List<VariableReader> readSourceVariables(); - - VariableReader getReceiver(); - - TryCatchBlockReader getBlock(); -} diff --git a/core/src/main/java/org/teavm/model/analysis/NullnessInformation.java b/core/src/main/java/org/teavm/model/analysis/NullnessInformation.java index 1769b52f1..d82be9666 100644 --- a/core/src/main/java/org/teavm/model/analysis/NullnessInformation.java +++ b/core/src/main/java/org/teavm/model/analysis/NullnessInformation.java @@ -24,8 +24,6 @@ import org.teavm.model.Instruction; import org.teavm.model.MethodDescriptor; import org.teavm.model.Phi; import org.teavm.model.Program; -import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; import org.teavm.model.util.DefinitionExtractor; import org.teavm.model.util.InstructionVariableMapper; @@ -57,7 +55,6 @@ public class NullnessInformation { public void dispose() { Set<Phi> phisToRemove = new HashSet<>(phiUpdater.getSynthesizedPhis()); - Set<TryCatchJoint> jointsToRemove = new HashSet<>(phiUpdater.getSynthesizedJoints()); DefinitionExtractor defExtractor = new DefinitionExtractor(); InstructionVariableMapper variableMapper = new InstructionVariableMapper(var -> { int source = phiUpdater.getSourceVariable(var.getIndex()); @@ -65,9 +62,6 @@ public class NullnessInformation { }); for (BasicBlock block : program.getBasicBlocks()) { block.getPhis().removeIf(phisToRemove::contains); - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - tryCatch.getJoints().removeIf(jointsToRemove::contains); - } for (Instruction insn : block) { insn.acceptVisitor(defExtractor); if (Arrays.stream(defExtractor.getDefinedVariables()) @@ -78,8 +72,18 @@ public class NullnessInformation { } } variableMapper.applyToPhis(block); - variableMapper.applyToTryCatchBlocks(block); + if (block.getExceptionVariable() != null) { + block.setExceptionVariable(variableMapper.map(block.getExceptionVariable())); + } } + + for (int i = 0; i < program.variableCount(); ++i) { + int sourceVar = phiUpdater.getSourceVariable(i); + if (sourceVar >= 0 && sourceVar != i) { + program.deleteVariable(i); + } + } + program.pack(); } public static NullnessInformation build(Program program, MethodDescriptor methodDescriptor) { diff --git a/core/src/main/java/org/teavm/model/analysis/NullnessInformationBuilder.java b/core/src/main/java/org/teavm/model/analysis/NullnessInformationBuilder.java index 90f53c718..8927339eb 100644 --- a/core/src/main/java/org/teavm/model/analysis/NullnessInformationBuilder.java +++ b/core/src/main/java/org/teavm/model/analysis/NullnessInformationBuilder.java @@ -33,8 +33,6 @@ import org.teavm.model.Instruction; import org.teavm.model.MethodDescriptor; import org.teavm.model.Phi; import org.teavm.model.Program; -import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; import org.teavm.model.instructions.AbstractInstructionVisitor; import org.teavm.model.instructions.ArrayLengthInstruction; @@ -126,13 +124,6 @@ class NullnessInformationBuilder { builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (Variable sourceVar : joint.getSourceVariables()) { - builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex()); - } - } - } for (Instruction instruction : block) { if (instruction instanceof AssignInstruction) { diff --git a/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerEliminator.java b/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerEliminator.java index 7c72a2836..fab5328f0 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerEliminator.java +++ b/core/src/main/java/org/teavm/model/lowlevel/ClassInitializerEliminator.java @@ -16,7 +16,6 @@ package org.teavm.model.lowlevel; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.teavm.interop.StaticInit; import org.teavm.interop.Structure; @@ -26,7 +25,6 @@ import org.teavm.model.ClassReaderSource; import org.teavm.model.Instruction; import org.teavm.model.MethodDescriptor; import org.teavm.model.Program; -import org.teavm.model.instructions.EmptyInstruction; import org.teavm.model.instructions.InitClassInstruction; public class ClassInitializerEliminator { diff --git a/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java b/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java index 3ac9ba48b..8ca3a67f5 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java +++ b/core/src/main/java/org/teavm/model/lowlevel/ExceptionHandlingShadowStackContributor.java @@ -18,6 +18,7 @@ package org.teavm.model.lowlevel; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import org.teavm.common.DominatorTree; import org.teavm.common.Graph; import org.teavm.common.GraphUtils; @@ -29,7 +30,6 @@ import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.TextLocation; import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.ValueType; import org.teavm.model.Variable; import org.teavm.model.instructions.BinaryBranchingCondition; @@ -64,7 +64,6 @@ public class ExceptionHandlingShadowStackContributor { private Program program; private DominatorTree dom; private BasicBlock[] variableDefinitionPlaces; - private Phi[] jointPhis; private boolean hasExceptionHandlers; public ExceptionHandlingShadowStackContributor(ManagedMethodRepository managedMethodRepository, @@ -77,7 +76,6 @@ public class ExceptionHandlingShadowStackContributor { Graph cfg = ProgramUtils.buildControlFlowGraph(program); dom = GraphUtils.buildDominatorTree(cfg); variableDefinitionPlaces = ProgramUtils.getVariableDefinitionPlaces(program); - jointPhis = new Phi[program.variableCount()]; } public boolean contribute() { @@ -126,17 +124,26 @@ public class ExceptionHandlingShadowStackContributor { int[] currentJointSources = new int[program.variableCount()]; int[] jointReceiverMap = new int[program.variableCount()]; Arrays.fill(currentJointSources, -1); + for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (Variable sourceVar : joint.getSourceVariables()) { + for (Phi phi : tryCatch.getHandler().getPhis()) { + List<Variable> sourceVariables = phi.getIncomings().stream() + .filter(incoming -> incoming.getSource() == tryCatch.getProtectedBlock()) + .map(incoming -> incoming.getValue()) + .collect(Collectors.toList()); + if (sourceVariables.isEmpty()) { + continue; + } + + for (Variable sourceVar : sourceVariables) { BasicBlock sourceVarDefinedAt = variableDefinitionPlaces[sourceVar.getIndex()]; if (dom.dominates(sourceVarDefinedAt.getIndex(), block.getIndex())) { - currentJointSources[joint.getReceiver().getIndex()] = sourceVar.getIndex(); + currentJointSources[phi.getReceiver().getIndex()] = sourceVar.getIndex(); break; } } - for (Variable sourceVar : joint.getSourceVariables()) { - jointReceiverMap[sourceVar.getIndex()] = joint.getReceiver().getIndex(); + for (Variable sourceVar : sourceVariables) { + jointReceiverMap[sourceVar.getIndex()] = phi.getReceiver().getIndex(); } } } @@ -281,13 +288,17 @@ public class ExceptionHandlingShadowStackContributor { switchInsn.getEntries().add(catchEntry); } - for (TryCatchJoint joint : tryCatch.getJoints()) { - Phi phi = getJointPhi(joint); - Incoming incoming = new Incoming(); - incoming.setSource(block); - int value = currentJointSources[joint.getReceiver().getIndex()]; - incoming.setValue(program.variableAt(value)); - phi.getIncomings().add(incoming); + for (Phi phi : tryCatch.getHandler().getPhis()) { + int value = currentJointSources[phi.getReceiver().getIndex()]; + if (value < 0) { + continue; + } + for (Incoming incoming : phi.getIncomings()) { + if (incoming.getValue().getIndex() == value) { + incoming.setSource(block); + break; + } + } } } @@ -327,18 +338,6 @@ public class ExceptionHandlingShadowStackContributor { return defaultExceptionHandler; } - private Phi getJointPhi(TryCatchJoint joint) { - Phi phi = jointPhis[joint.getReceiver().getIndex()]; - if (phi == null) { - phi = new Phi(); - phi.setReceiver(joint.getReceiver()); - BasicBlock handler = program.basicBlockAt(joint.getBlock().getHandler().getIndex()); - handler.getPhis().add(phi); - jointPhis[joint.getReceiver().getIndex()] = phi; - } - return phi; - } - private Variable createReturnValueInstructions(BasicBlock block) { ValueType returnType = method.getReturnType(); if (returnType == ValueType.VOID) { diff --git a/core/src/main/java/org/teavm/model/optimization/GlobalValueNumbering.java b/core/src/main/java/org/teavm/model/optimization/GlobalValueNumbering.java index 029106f26..c9714fdd4 100644 --- a/core/src/main/java/org/teavm/model/optimization/GlobalValueNumbering.java +++ b/core/src/main/java/org/teavm/model/optimization/GlobalValueNumbering.java @@ -28,8 +28,6 @@ import org.teavm.model.Incoming; import org.teavm.model.Instruction; import org.teavm.model.InvokeDynamicInstruction; import org.teavm.model.Program; -import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; import org.teavm.model.instructions.ArrayLengthInstruction; import org.teavm.model.instructions.AssignInstruction; @@ -164,14 +162,6 @@ public class GlobalValueNumbering implements MethodOptimization { } } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (int i = 0; i < joint.getSourceVariables().size(); ++i) { - int sourceVar = map[joint.getSourceVariables().get(i).getIndex()]; - joint.getSourceVariables().set(i, program.variableAt(sourceVar)); - } - } - } for (Incoming incoming : outgoings.get(v)) { int value = map[incoming.getValue().getIndex()]; incoming.setValue(program.variableAt(value)); diff --git a/core/src/main/java/org/teavm/model/optimization/LoopInversionImpl.java b/core/src/main/java/org/teavm/model/optimization/LoopInversionImpl.java index 7947e2e0a..0642d232d 100644 --- a/core/src/main/java/org/teavm/model/optimization/LoopInversionImpl.java +++ b/core/src/main/java/org/teavm/model/optimization/LoopInversionImpl.java @@ -39,7 +39,6 @@ import org.teavm.model.MethodReference; import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; import org.teavm.model.analysis.NullnessInformation; import org.teavm.model.util.BasicBlockMapper; @@ -345,13 +344,6 @@ class LoopInversionImpl { tryCatchCopy.setExceptionType(tryCatch.getExceptionType()); tryCatchCopy.setHandler(program.basicBlockAt(copiedNodes.getOrDefault(handler, handler))); targetBlock.getTryCatchBlocks().add(tryCatchCopy); - - for (TryCatchJoint joint : tryCatch.getJoints()) { - TryCatchJoint jointCopy = new TryCatchJoint(); - jointCopy.setReceiver(joint.getReceiver()); - jointCopy.getSourceVariables().addAll(joint.getSourceVariables()); - tryCatchCopy.getJoints().add(jointCopy); - } } } diff --git a/core/src/main/java/org/teavm/model/optimization/UnusedVariableElimination.java b/core/src/main/java/org/teavm/model/optimization/UnusedVariableElimination.java index 34e82f5e9..42d3319d9 100644 --- a/core/src/main/java/org/teavm/model/optimization/UnusedVariableElimination.java +++ b/core/src/main/java/org/teavm/model/optimization/UnusedVariableElimination.java @@ -22,8 +22,6 @@ import org.teavm.model.InvokeDynamicInstruction; import org.teavm.model.MethodReader; import org.teavm.model.Phi; import org.teavm.model.Program; -import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; import org.teavm.model.instructions.AbstractInstructionVisitor; import org.teavm.model.instructions.ArrayLengthInstruction; @@ -105,15 +103,6 @@ public class UnusedVariableElimination implements MethodOptimization { } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (int j = 0; j < tryCatch.getJoints().size(); ++j) { - TryCatchJoint joint = tryCatch.getJoints().get(j); - if (!used[joint.getReceiver().getIndex()]) { - tryCatch.getJoints().remove(j--); - } - } - } - for (int j = 0; j < block.getPhis().size(); ++j) { Phi phi = block.getPhis().get(j); if (!used[phi.getReceiver().getIndex()]) { diff --git a/core/src/main/java/org/teavm/model/optimization/VariableUsageGraphBuilder.java b/core/src/main/java/org/teavm/model/optimization/VariableUsageGraphBuilder.java index 3fad34ec0..56d69cbe5 100644 --- a/core/src/main/java/org/teavm/model/optimization/VariableUsageGraphBuilder.java +++ b/core/src/main/java/org/teavm/model/optimization/VariableUsageGraphBuilder.java @@ -17,8 +17,28 @@ package org.teavm.model.optimization; import org.teavm.common.Graph; import org.teavm.common.GraphBuilder; -import org.teavm.model.*; -import org.teavm.model.instructions.*; +import org.teavm.model.BasicBlock; +import org.teavm.model.Incoming; +import org.teavm.model.Instruction; +import org.teavm.model.Phi; +import org.teavm.model.Program; +import org.teavm.model.Variable; +import org.teavm.model.instructions.AbstractInstructionVisitor; +import org.teavm.model.instructions.ArrayLengthInstruction; +import org.teavm.model.instructions.AssignInstruction; +import org.teavm.model.instructions.BinaryInstruction; +import org.teavm.model.instructions.CastInstruction; +import org.teavm.model.instructions.CastIntegerInstruction; +import org.teavm.model.instructions.CastNumberInstruction; +import org.teavm.model.instructions.CloneArrayInstruction; +import org.teavm.model.instructions.ConstructArrayInstruction; +import org.teavm.model.instructions.ConstructMultiArrayInstruction; +import org.teavm.model.instructions.GetElementInstruction; +import org.teavm.model.instructions.GetFieldInstruction; +import org.teavm.model.instructions.IsInstanceInstruction; +import org.teavm.model.instructions.NegateInstruction; +import org.teavm.model.instructions.NullCheckInstruction; +import org.teavm.model.instructions.UnwrapArrayInstruction; public final class VariableUsageGraphBuilder { private VariableUsageGraphBuilder() { @@ -37,18 +57,11 @@ public final class VariableUsageGraphBuilder { builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (Variable sourceVar : joint.getSourceVariables()) { - builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex()); - } - } - } } return builder.build(); } - private static class InstructionAnalyzer implements InstructionVisitor { + private static class InstructionAnalyzer extends AbstractInstructionVisitor { private GraphBuilder builder; public InstructionAnalyzer(GraphBuilder builder) { @@ -61,38 +74,6 @@ public final class VariableUsageGraphBuilder { } } - @Override - public void visit(EmptyInstruction insn) { - } - - @Override - public void visit(ClassConstantInstruction insn) { - } - - @Override - public void visit(NullConstantInstruction insn) { - } - - @Override - public void visit(IntegerConstantInstruction insn) { - } - - @Override - public void visit(LongConstantInstruction insn) { - } - - @Override - public void visit(FloatConstantInstruction insn) { - } - - @Override - public void visit(DoubleConstantInstruction insn) { - } - - @Override - public void visit(StringConstantInstruction insn) { - } - @Override public void visit(BinaryInstruction insn) { use(insn.getReceiver(), insn.getFirstOperand(), insn.getSecondOperand()); @@ -123,39 +104,11 @@ public final class VariableUsageGraphBuilder { use(insn.getReceiver(), insn.getValue()); } - @Override - public void visit(BranchingInstruction insn) { - } - - @Override - public void visit(BinaryBranchingInstruction insn) { - } - - @Override - public void visit(JumpInstruction insn) { - } - - @Override - public void visit(SwitchInstruction insn) { - } - - @Override - public void visit(ExitInstruction insn) { - } - - @Override - public void visit(RaiseInstruction insn) { - } - @Override public void visit(ConstructArrayInstruction insn) { use(insn.getReceiver(), insn.getSize()); } - @Override - public void visit(ConstructInstruction insn) { - } - @Override public void visit(ConstructMultiArrayInstruction insn) { use(insn.getReceiver(), insn.getDimensions().toArray(new Variable[0])); @@ -168,10 +121,6 @@ public final class VariableUsageGraphBuilder { } } - @Override - public void visit(PutFieldInstruction insn) { - } - @Override public void visit(ArrayLengthInstruction insn) { use(insn.getReceiver(), insn.getArray()); @@ -192,40 +141,14 @@ public final class VariableUsageGraphBuilder { use(insn.getReceiver(), insn.getArray(), insn.getIndex()); } - @Override - public void visit(PutElementInstruction insn) { - } - - @Override - public void visit(InvokeInstruction insn) { - } - - @Override - public void visit(InvokeDynamicInstruction insn) { - } - @Override public void visit(IsInstanceInstruction insn) { use(insn.getReceiver(), insn.getValue()); } - @Override - public void visit(InitClassInstruction insn) { - } - @Override public void visit(NullCheckInstruction insn) { use(insn.getReceiver(), insn.getValue()); } - - @Override - public void visit(MonitorEnterInstruction insn) { - - } - - @Override - public void visit(MonitorExitInstruction insn) { - - } } } diff --git a/core/src/main/java/org/teavm/model/text/ListingBuilder.java b/core/src/main/java/org/teavm/model/text/ListingBuilder.java index 7ee31b1c5..59bc02a03 100644 --- a/core/src/main/java/org/teavm/model/text/ListingBuilder.java +++ b/core/src/main/java/org/teavm/model/text/ListingBuilder.java @@ -17,8 +17,14 @@ package org.teavm.model.text; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; -import org.teavm.model.*; +import org.teavm.model.BasicBlockReader; +import org.teavm.model.IncomingReader; +import org.teavm.model.InstructionIterator; +import org.teavm.model.PhiReader; +import org.teavm.model.ProgramReader; +import org.teavm.model.TextLocation; +import org.teavm.model.TryCatchBlockReader; +import org.teavm.model.VariableReader; public class ListingBuilder { public String buildListing(ProgramReader program, String prefix) { @@ -87,14 +93,6 @@ public class ListingBuilder { } sb.append(" goto $").append(tryCatch.getHandler().getIndex()); sb.append("\n"); - for (TryCatchJointReader joint : tryCatch.readJoints()) { - sb.append(" @").append(stringifier.getVariableLabel(joint.getReceiver().getIndex())) - .append(" := ephi "); - sb.append(joint.readSourceVariables().stream() - .map(sourceVar -> "@" + stringifier.getVariableLabel(sourceVar.getIndex())) - .collect(Collectors.joining(", "))); - sb.append("\n"); - } } } return sb.toString(); diff --git a/core/src/main/java/org/teavm/model/text/ListingParser.java b/core/src/main/java/org/teavm/model/text/ListingParser.java index 88d85db5f..a6bbf0b13 100644 --- a/core/src/main/java/org/teavm/model/text/ListingParser.java +++ b/core/src/main/java/org/teavm/model/text/ListingParser.java @@ -34,7 +34,6 @@ import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.TextLocation; import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.ValueType; import org.teavm.model.Variable; import org.teavm.model.instructions.ArrayElementType; @@ -89,9 +88,9 @@ public class ListingParser { private Map<String, BasicBlock> blockMap; private Map<String, Integer> blockFirstOccurrence; private Set<String> declaredBlocks = new HashSet<>(); + private List<BasicBlock> orderedBlocks = new ArrayList<>(); private TextLocation currentLocation; private BasicBlock currentBlock; - private TryCatchBlock currentTryCatch; public Program parse(Reader reader) throws IOException, ListingParseException { try { @@ -114,6 +113,9 @@ public class ListingParser { throw new ListingParseException("Block not defined: " + blockName, blockIndex); } + program.pack(); + program.rearrangeBasicBlocks(orderedBlocks); + return program; } finally { program = null; @@ -177,7 +179,7 @@ public class ListingParser { b.setLabel(k); return b; }); - currentTryCatch = null; + orderedBlocks.add(currentBlock); currentLocation = null; do { @@ -361,10 +363,6 @@ public class ListingParser { lexer.nextToken(); parsePhi(receiver); break; - case "ephi": - lexer.nextToken(); - parseExceptionPhi(receiver); - break; case "classOf": lexer.nextToken(); parseClassLiteral(receiver); @@ -593,24 +591,6 @@ public class ListingParser { currentBlock.getPhis().add(phi); } - private void parseExceptionPhi(Variable receiver) throws IOException, ListingParseException { - int phiStart = lexer.getIndex(); - - TryCatchJoint joint = new TryCatchJoint(); - joint.setReceiver(receiver); - joint.getSourceVariables().add(expectVariable()); - while (lexer.getToken() == ListingToken.COMMA) { - lexer.nextToken(); - joint.getSourceVariables().add(expectVariable()); - } - - if (currentTryCatch == null) { - throw new ListingParseException("Exception phi must appear right after catch block", phiStart); - } - - currentTryCatch.getJoints().add(joint); - } - private void parseClassLiteral(Variable receiver) throws IOException, ListingParseException { ValueType type = expectValueType(); ClassConstantInstruction insn = new ClassConstantInstruction(); @@ -792,7 +772,6 @@ public class ListingParser { } expectKeyword("goto"); tryCatch.setHandler(expectBlock()); - currentTryCatch = tryCatch; currentBlock.getTryCatchBlocks().add(tryCatch); } @@ -1170,7 +1149,6 @@ public class ListingParser { } private void addInstruction(Instruction instruction) throws ListingParseException { - currentTryCatch = null; instruction.setLocation(currentLocation); currentBlock.add(instruction); } diff --git a/core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java b/core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java index 528963c3a..277866939 100644 --- a/core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java +++ b/core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java @@ -21,12 +21,43 @@ import org.teavm.model.Incoming; import org.teavm.model.Instruction; import org.teavm.model.InvokeDynamicInstruction; import org.teavm.model.Phi; -import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; -import org.teavm.model.instructions.*; +import org.teavm.model.instructions.AbstractInstructionVisitor; +import org.teavm.model.instructions.ArrayLengthInstruction; +import org.teavm.model.instructions.AssignInstruction; +import org.teavm.model.instructions.BinaryBranchingInstruction; +import org.teavm.model.instructions.BinaryInstruction; +import org.teavm.model.instructions.BranchingInstruction; +import org.teavm.model.instructions.CastInstruction; +import org.teavm.model.instructions.CastIntegerInstruction; +import org.teavm.model.instructions.CastNumberInstruction; +import org.teavm.model.instructions.ClassConstantInstruction; +import org.teavm.model.instructions.CloneArrayInstruction; +import org.teavm.model.instructions.ConstructArrayInstruction; +import org.teavm.model.instructions.ConstructInstruction; +import org.teavm.model.instructions.ConstructMultiArrayInstruction; +import org.teavm.model.instructions.DoubleConstantInstruction; +import org.teavm.model.instructions.ExitInstruction; +import org.teavm.model.instructions.FloatConstantInstruction; +import org.teavm.model.instructions.GetElementInstruction; +import org.teavm.model.instructions.GetFieldInstruction; +import org.teavm.model.instructions.IntegerConstantInstruction; +import org.teavm.model.instructions.InvokeInstruction; +import org.teavm.model.instructions.IsInstanceInstruction; +import org.teavm.model.instructions.LongConstantInstruction; +import org.teavm.model.instructions.MonitorEnterInstruction; +import org.teavm.model.instructions.MonitorExitInstruction; +import org.teavm.model.instructions.NegateInstruction; +import org.teavm.model.instructions.NullCheckInstruction; +import org.teavm.model.instructions.NullConstantInstruction; +import org.teavm.model.instructions.PutElementInstruction; +import org.teavm.model.instructions.PutFieldInstruction; +import org.teavm.model.instructions.RaiseInstruction; +import org.teavm.model.instructions.StringConstantInstruction; +import org.teavm.model.instructions.SwitchInstruction; +import org.teavm.model.instructions.UnwrapArrayInstruction; -public class InstructionVariableMapper implements InstructionVisitor { +public class InstructionVariableMapper extends AbstractInstructionVisitor { private final Function<Variable, Variable> f; public InstructionVariableMapper(Function<Variable, Variable> f) { @@ -40,7 +71,6 @@ public class InstructionVariableMapper implements InstructionVisitor { applyToInstructions(block); applyToPhis(block); - applyToTryCatchBlocks(block); } public void applyToInstructions(BasicBlock block) { @@ -58,26 +88,10 @@ public class InstructionVariableMapper implements InstructionVisitor { } } - public void applyToTryCatchBlocks(BasicBlock block) { - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - joint.setReceiver(map(joint.getReceiver())); - for (int i = 0; i < joint.getSourceVariables().size(); ++i) { - Variable var = joint.getSourceVariables().get(i); - joint.getSourceVariables().set(i, map(var)); - } - } - } - } - - private Variable map(Variable var) { + public Variable map(Variable var) { return f.apply(var); } - @Override - public void visit(EmptyInstruction insn) { - } - @Override public void visit(ClassConstantInstruction insn) { insn.setReceiver(map(insn.getReceiver())); @@ -161,10 +175,6 @@ public class InstructionVariableMapper implements InstructionVisitor { insn.setSecondOperand(map(insn.getSecondOperand())); } - @Override - public void visit(JumpInstruction insn) { - } - @Override public void visit(SwitchInstruction insn) { insn.setCondition(map(insn.getCondition())); @@ -281,10 +291,6 @@ public class InstructionVariableMapper implements InstructionVisitor { insn.setValue(map(insn.getValue())); } - @Override - public void visit(InitClassInstruction insn) { - } - @Override public void visit(NullCheckInstruction insn) { insn.setReceiver(map(insn.getReceiver())); diff --git a/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java b/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java index 3fab77af1..3929bf8fb 100644 --- a/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java +++ b/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java @@ -52,15 +52,6 @@ class InterferenceGraphBuilder { live.add(nodes.get(outgoing.getValue().getIndex())); } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (Variable sourceVar : joint.getSourceVariables()) { - live.add(nodes.get(sourceVar.getIndex())); - } - live.remove(nodes.get(joint.getReceiver().getIndex())); - } - } - for (Instruction insn = block.getLastInstruction(); insn != null; insn = insn.getPrevious()) { insn.acceptVisitor(useExtractor); insn.acceptVisitor(defExtractor); diff --git a/core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java b/core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java index cff039973..1d852dd70 100644 --- a/core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java +++ b/core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java @@ -21,7 +21,12 @@ import java.util.ArrayDeque; import java.util.BitSet; import java.util.Deque; import org.teavm.common.Graph; -import org.teavm.model.*; +import org.teavm.model.BasicBlock; +import org.teavm.model.Incoming; +import org.teavm.model.Instruction; +import org.teavm.model.Phi; +import org.teavm.model.Program; +import org.teavm.model.Variable; public class LivenessAnalyzer { private BitSet[] liveVars; @@ -70,18 +75,6 @@ public class LivenessAnalyzer { } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - definitions[joint.getReceiver().getIndex()] = i; - for (Variable sourceVar : joint.getSourceVariables()) { - Task task = new Task(); - task.block = i; - task.var = sourceVar.getIndex(); - stack.push(task); - } - } - } - for (Phi phi : block.getPhis()) { definitions[phi.getReceiver().getIndex()] = i; for (Incoming incoming : phi.getIncomings()) { 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 fb5e16b82..3a8d99323 100644 --- a/core/src/main/java/org/teavm/model/util/PhiUpdater.java +++ b/core/src/main/java/org/teavm/model/util/PhiUpdater.java @@ -27,12 +27,7 @@ import java.util.Arrays; import java.util.BitSet; import java.util.Collections; import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; import org.teavm.common.DominatorTree; import org.teavm.common.Graph; import org.teavm.common.GraphUtils; @@ -44,7 +39,6 @@ import org.teavm.model.InvokeDynamicInstruction; import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; import org.teavm.model.instructions.ArrayLengthInstruction; import org.teavm.model.instructions.AssignInstruction; @@ -92,21 +86,17 @@ public class PhiUpdater { private int[][] domFrontiers; private Variable[] variableMap; private boolean[] variableDefined; + private List<List<Variable>> definedVersions = new ArrayList<>(); private BasicBlock currentBlock; - private TryCatchBlock currentTryCatch; private Phi[][] phiMap; private int[][] phiIndexMap; - private Map<TryCatchBlock, Map<Variable, TryCatchJoint>> jointMap = new HashMap<>(); private List<List<Phi>> synthesizedPhisByBlock = new ArrayList<>(); private IntObjectMap<Phi> phisByReceiver = new IntObjectOpenHashMap<>(); - private IntObjectMap<TryCatchJoint> jointsByReceiver = new IntObjectOpenHashMap<>(); private BitSet usedPhis = new BitSet(); - private List<List<List<TryCatchJoint>>> synthesizedJointsByBlock = new ArrayList<>(); private Variable[] originalExceptionVariables; private boolean[] usedDefinitions; private IntegerArray variableToSourceMap = new IntegerArray(10); private List<Phi> synthesizedPhis = new ArrayList<>(); - private List<TryCatchJoint> synthesizedJoints = new ArrayList<>(); public int getSourceVariable(int var) { if (var >= variableToSourceMap.size()) { @@ -119,17 +109,12 @@ public class PhiUpdater { return synthesizedPhis; } - public List<TryCatchJoint> getSynthesizedJoints() { - return synthesizedJoints; - } - public void updatePhis(Program program, Variable[] arguments) { if (program.basicBlockCount() == 0) { return; } this.program = program; phisByReceiver.clear(); - jointsByReceiver.clear(); cfg = ProgramUtils.buildControlFlowGraph(program); domTree = GraphUtils.buildDominatorTree(cfg); domFrontiers = new int[cfg.size()][]; @@ -141,12 +126,14 @@ public class PhiUpdater { variableMap[i] = arguments[i]; usedDefinitions[i] = true; } + for (int i = 0; i < program.variableCount(); ++i) { variableToSourceMap.add(-1); } + definedVersions.addAll(Collections.nCopies(program.variableCount(), null)); + phiMap = new Phi[program.basicBlockCount()][]; phiIndexMap = new int[program.basicBlockCount()][]; - jointMap.clear(); for (int i = 0; i < phiMap.length; ++i) { phiMap[i] = new Phi[program.variableCount()]; phiIndexMap[i] = new int[program.variableCount()]; @@ -154,15 +141,9 @@ public class PhiUpdater { domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree); synthesizedPhisByBlock.clear(); - synthesizedJointsByBlock.clear(); for (int i = 0; i < program.basicBlockCount(); ++i) { synthesizedPhisByBlock.add(new ArrayList<>()); - synthesizedJointsByBlock.add(new ArrayList<>()); - int catchCount = program.basicBlockAt(i).getTryCatchBlocks().size(); - for (int j = 0; j < catchCount; ++j) { - synthesizedJointsByBlock.get(i).add(new ArrayList<>()); - } } originalExceptionVariables = new Variable[program.basicBlockCount()]; @@ -176,7 +157,6 @@ public class PhiUpdater { private void estimatePhis() { DefinitionExtractor definitionExtractor = new DefinitionExtractor(); - List<List<TryCatchJoint>> inputJoints = getInputJoints(program); variableDefined = new boolean[program.variableCount()]; IntDeque stack = new IntArrayDeque(); @@ -189,10 +169,6 @@ public class PhiUpdater { markAssignment(currentBlock.getExceptionVariable()); } - for (TryCatchJoint joint : inputJoints.get(currentBlock.getIndex())) { - markAssignment(joint.getReceiver()); - } - for (Phi phi : currentBlock.getPhis()) { markAssignment(phi.getReceiver()); } @@ -200,20 +176,8 @@ public class PhiUpdater { for (Instruction insn : currentBlock) { currentBlock = program.basicBlockAt(i); insn.acceptVisitor(definitionExtractor); - Set<Variable> definedVariables = new HashSet<>(); for (Variable var : definitionExtractor.getDefinedVariables()) { markAssignment(var); - definedVariables.add(var); - } - - Set<BasicBlock> handlers = currentBlock.getTryCatchBlocks().stream() - .map(tryCatch -> tryCatch.getHandler()) - .collect(Collectors.toSet()); - for (BasicBlock handler : handlers) { - currentBlock = handler; - for (Variable var : definedVariables) { - markAssignment(var); - } } } @@ -226,8 +190,6 @@ public class PhiUpdater { private static class Task { Variable[] variables; BasicBlock block; - TryCatchBlock tryCatch; - int tryCatchIndex; } private void renameVariables() { @@ -244,69 +206,35 @@ public class PhiUpdater { List<List<Incoming>> phiOutputs = ProgramUtils.getPhiOutputs(program); while (!stack.isEmpty()) { + Collections.fill(definedVersions, null); Task task = stack.pop(); currentBlock = task.block; - currentTryCatch = task.tryCatch; int index = currentBlock.getIndex(); variableMap = task.variables.clone(); - if (currentTryCatch == null) { - if (currentBlock.getExceptionVariable() != null) { - currentBlock.setExceptionVariable(define(currentBlock.getExceptionVariable())); - } - - for (Phi phi : synthesizedPhisByBlock.get(index)) { - Variable var = program.createVariable(); - var.setDebugName(phi.getReceiver().getDebugName()); - var.setLabel(phi.getReceiver().getLabel()); - mapVariable(phi.getReceiver().getIndex(), var); - phisByReceiver.put(var.getIndex(), phi); - phi.setReceiver(var); - } - for (Phi phi : currentBlock.getPhis()) { - phi.setReceiver(define(phi.getReceiver())); - } - - for (Instruction insn : currentBlock) { - insn.acceptVisitor(consumer); - } - } else { - for (TryCatchJoint joint : currentTryCatch.getJoints()) { - joint.setReceiver(define(joint.getReceiver())); - } + if (currentBlock.getExceptionVariable() != null) { + currentBlock.setExceptionVariable(define(currentBlock.getExceptionVariable())); } - boolean tryCatchIsSuccessor = currentTryCatch != null - && domTree.immediateDominatorOf(currentTryCatch.getHandler().getIndex()) == index; - if (currentTryCatch != null) { - for (TryCatchJoint joint : synthesizedJointsByBlock.get(index).get(task.tryCatchIndex)) { - Variable var = program.createVariable(); - var.setDebugName(joint.getReceiver().getDebugName()); - var.setLabel(joint.getReceiver().getLabel()); - mapVariable(joint.getReceiver().getIndex(), var); - joint.setReceiver(var); - jointsByReceiver.put(var.getIndex(), joint); - } + for (Phi phi : synthesizedPhisByBlock.get(index)) { + Variable var = program.createVariable(); + var.setDebugName(phi.getReceiver().getDebugName()); + var.setLabel(phi.getReceiver().getLabel()); + mapVariable(phi.getReceiver().getIndex(), var); + phisByReceiver.put(var.getIndex(), phi); + phi.setReceiver(var); + } + for (Phi phi : currentBlock.getPhis()) { + phi.setReceiver(define(phi.getReceiver())); } - int[] successors; - List<TryCatchBlock> tryCatchBlockSuccessors = new ArrayList<>(); - IntSet tryCatchSuccessors = new IntOpenHashSet(); - if (currentTryCatch != null) { - successors = tryCatchIsSuccessor ? new int[] { currentTryCatch.getHandler().getIndex() } : new int[0]; - } else { - List<TryCatchBlock> tryCatchBlocks = currentBlock.getTryCatchBlocks(); - for (int i = 0; i < tryCatchBlocks.size(); i++) { - TryCatchBlock tryCatch = tryCatchBlocks.get(i); - tryCatchSuccessors.add(tryCatch.getHandler().getIndex()); - tryCatchBlockSuccessors.add(tryCatch); - } - successors = Arrays.stream(domGraph.outgoingEdges(index)) - .filter(successor -> !tryCatchSuccessors.contains(successor)) - .toArray(); + for (Instruction insn : currentBlock) { + insn.acceptVisitor(consumer); } + int[] successors = domGraph.outgoingEdges(index); + IntSet successorSet = IntOpenHashSet.from(successors); for (Incoming output : phiOutputs.get(index)) { if (successorSet.contains(output.getPhi().getBasicBlock().getIndex())) { @@ -314,13 +242,6 @@ public class PhiUpdater { output.setValue(use(var)); } } - if (tryCatchIsSuccessor) { - for (TryCatchJoint joint : currentTryCatch.getJoints()) { - for (int i = 0; i < joint.getSourceVariables().size(); ++i) { - joint.getSourceVariables().set(i, use(joint.getSourceVariables().get(i))); - } - } - } for (int j = successors.length - 1; j >= 0; --j) { int successor = successors[j]; @@ -330,24 +251,13 @@ public class PhiUpdater { stack.push(next); } - for (int j = tryCatchBlockSuccessors.size() - 1; j >= 0; --j) { - TryCatchBlock tryCatch = tryCatchBlockSuccessors.get(j); - Task next = new Task(); - next.variables = variableMap.clone(); - next.block = currentBlock; - next.tryCatch = tryCatch; - next.tryCatchIndex = j; - stack.push(next); + IntSet exceptionHandlingSuccessors = new IntOpenHashSet(); + for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { + exceptionHandlingSuccessors.add(tryCatch.getHandler().getIndex()); } - if (currentTryCatch == null) { - for (int successor : cfg.outgoingEdges(index)) { - if (!tryCatchSuccessors.contains(successor)) { - renameOutgoingPhis(successor); - } - } - } else { - renameOutgoingPhis(currentTryCatch.getHandler().getIndex()); + for (int successor : cfg.outgoingEdges(index)) { + renameOutgoingPhis(successor, exceptionHandlingSuccessors.contains(successor)); } } } @@ -363,21 +273,6 @@ public class PhiUpdater { synthesizedPhis.add(phi); } } - - List<List<TryCatchJoint>> joints = synthesizedJointsByBlock.get(i); - for (int j = 0; j < joints.size(); ++j) { - List<TryCatchJoint> jointList = joints.get(j); - TryCatchBlock targetTryCatch = program.basicBlockAt(i).getTryCatchBlocks().get(j); - for (TryCatchJoint joint : jointList) { - if (!usedPhis.get(joint.getReceiver().getIndex())) { - continue; - } - if (!joint.getSourceVariables().isEmpty()) { - targetTryCatch.getJoints().add(joint); - synthesizedJoints.add(joint); - } - } - } } } @@ -388,11 +283,6 @@ public class PhiUpdater { worklist.addLast(receiverIndex); } } - for (int receiverIndex : jointsByReceiver.keys().toArray()) { - if (usedPhis.get(receiverIndex)) { - worklist.addLast(receiverIndex); - } - } IntSet visited = new IntOpenHashSet(); while (!worklist.isEmpty()) { @@ -410,19 +300,10 @@ public class PhiUpdater { } } } - - TryCatchJoint joint = jointsByReceiver.get(varIndex); - if (joint != null) { - for (Variable sourceVar : joint.getSourceVariables()) { - if (!visited.contains(sourceVar.getIndex())) { - worklist.addLast(sourceVar.getIndex()); - } - } - } } } - private void renameOutgoingPhis(int successor) { + private void renameOutgoingPhis(int successor, boolean allVersions) { int[] phiIndexes = phiIndexMap[successor]; List<Phi> phis = synthesizedPhisByBlock.get(successor); @@ -430,6 +311,16 @@ public class PhiUpdater { Phi phi = phis.get(j); Variable var = variableMap[phiIndexes[j]]; if (var != null) { + List<Variable> versions = definedVersions.get(phiIndexes[j]); + if (versions != null && allVersions) { + for (Variable version : versions) { + Incoming incoming = new Incoming(); + incoming.setSource(currentBlock); + incoming.setValue(version); + phi.getIncomings().add(incoming); + } + } + Incoming incoming = new Incoming(); incoming.setSource(currentBlock); incoming.setValue(var); @@ -440,91 +331,66 @@ public class PhiUpdater { } private void markAssignment(Variable var) { - BasicBlock[] worklist = new BasicBlock[program.basicBlockCount() * 4]; - int head = 0; - worklist[head++] = currentBlock; + Deque<BasicBlock> worklist = new ArrayDeque<>(); + worklist.push(currentBlock); if (variableDefined[var.getIndex()]) { - BasicBlock startBlock = currentBlock; - List<TryCatchBlock> tryCatchBlocks = startBlock.getTryCatchBlocks(); - for (int i = 0; i < tryCatchBlocks.size(); i++) { - TryCatchBlock tryCatch = tryCatchBlocks.get(i); - TryCatchJoint joint = jointMap.computeIfAbsent(tryCatch, k -> new HashMap<>()).get(var); - if (joint == null) { - joint = new TryCatchJoint(); - joint.setReceiver(var); - synthesizedJointsByBlock.get(startBlock.getIndex()).get(i).add(joint); - jointMap.get(tryCatch).put(var, joint); - worklist[head++] = tryCatch.getHandler(); - } + for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { + placePhi(tryCatch.getHandler().getIndex(), var, currentBlock, worklist); } } else { variableDefined[var.getIndex()] = true; } - while (head > 0) { - BasicBlock block = worklist[--head]; + while (!worklist.isEmpty()) { + BasicBlock block = worklist.pop(); int[] frontiers = domFrontiers[block.getIndex()]; if (frontiers != null) { for (int frontier : frontiers) { - BasicBlock frontierBlock = program.basicBlockAt(frontier); - if (frontierBlock.getExceptionVariable() == var) { - continue; - } - - boolean exists = frontierBlock.getPhis().stream() - .flatMap(phi -> phi.getIncomings().stream()) - .anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var); - if (exists) { - continue; - } - - Phi phi = phiMap[frontier][var.getIndex()]; - if (phi == null) { - phi = new Phi(); - phi.setReceiver(var); - phiIndexMap[frontier][synthesizedPhisByBlock.get(frontier).size()] = var.getIndex(); - synthesizedPhisByBlock.get(frontier).add(phi); - phiMap[frontier][var.getIndex()] = phi; - worklist[head++] = frontierBlock; - } + placePhi(frontier, var, block, worklist); } } } } - private Variable define(Variable var) { - Variable old = variableMap[var.getIndex()]; - Variable original = var; - var = introduce(var); - propagateToTryCatch(original, var, old); - mapVariable(original.getIndex(), var); - return var; + private void placePhi(int frontier, Variable var, BasicBlock block, Deque<BasicBlock> worklist) { + BasicBlock frontierBlock = program.basicBlockAt(frontier); + if (frontierBlock.getExceptionVariable() == var) { + return; + } + + boolean exists = frontierBlock.getPhis().stream() + .flatMap(phi -> phi.getIncomings().stream()) + .anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var); + if (exists) { + return; + } + + Phi phi = phiMap[frontier][var.getIndex()]; + if (phi == null) { + phi = new Phi(); + phi.setReceiver(var); + phiIndexMap[frontier][synthesizedPhisByBlock.get(frontier).size()] = var.getIndex(); + synthesizedPhisByBlock.get(frontier).add(phi); + phiMap[frontier][var.getIndex()] = phi; + worklist.push(frontierBlock); + } } - private void propagateToTryCatch(Variable original, Variable var, Variable old) { - for (int i = 0; i < currentBlock.getTryCatchBlocks().size(); ++i) { - TryCatchBlock tryCatch = currentBlock.getTryCatchBlocks().get(i); - if (originalExceptionVariables[tryCatch.getHandler().getIndex()] == original) { - continue; + private Variable define(Variable var) { + Variable old = variableMap[var.getIndex()]; + if (old != null) { + if (definedVersions.get(var.getIndex()) == null) { + definedVersions.set(var.getIndex(), new ArrayList<>()); } - - Map<Variable, TryCatchJoint> joints = jointMap.get(tryCatch); - if (joints == null) { - continue; - } - - TryCatchJoint joint = joints.get(original); - if (joint == null) { - continue; - } - - if (joint.getSourceVariables().isEmpty() && old != null) { - joint.getSourceVariables().add(old); - } - joint.getSourceVariables().add(var); + definedVersions.get(var.getIndex()).add(old); } + + Variable original = var; + var = introduce(var); + mapVariable(original.getIndex(), var); + return var; } private void mapVariable(int index, Variable var) { @@ -551,25 +417,13 @@ public class PhiUpdater { private Variable use(Variable var) { Variable mappedVar = variableMap[var.getIndex()]; if (mappedVar == null) { - throw new AssertionError("Variable used before definition: " + var.getDisplayLabel()); + throw new AssertionError("Variable used before definition: @" + var.getDisplayLabel() + + " at $" + currentBlock.getIndex()); } usedPhis.set(mappedVar.getIndex()); return mappedVar; } - private static List<List<TryCatchJoint>> getInputJoints(Program program) { - List<List<TryCatchJoint>> inputJoints = new ArrayList<>(Collections.nCopies(program.basicBlockCount(), null)); - for (int i = 0; i < program.basicBlockCount(); ++i) { - inputJoints.set(i, new ArrayList<>()); - } - for (BasicBlock block : program.getBasicBlocks()) { - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - inputJoints.get(tryCatch.getHandler().getIndex()).addAll(tryCatch.getJoints()); - } - } - return inputJoints; - } - private InstructionVisitor consumer = new InstructionVisitor() { @Override public void visit(EmptyInstruction insn) { diff --git a/core/src/main/java/org/teavm/model/util/ProgramUtils.java b/core/src/main/java/org/teavm/model/util/ProgramUtils.java index 8e54a0c2d..d7bc95c30 100644 --- a/core/src/main/java/org/teavm/model/util/ProgramUtils.java +++ b/core/src/main/java/org/teavm/model/util/ProgramUtils.java @@ -36,10 +36,7 @@ import org.teavm.model.ProgramReader; import org.teavm.model.TextLocation; import org.teavm.model.TryCatchBlock; import org.teavm.model.TryCatchBlockReader; -import org.teavm.model.TryCatchJoint; -import org.teavm.model.TryCatchJointReader; import org.teavm.model.Variable; -import org.teavm.model.VariableReader; public final class ProgramUtils { private ProgramUtils() { @@ -110,6 +107,7 @@ public final class ProgramUtils { InstructionReadVisitor visitor = new InstructionReadVisitor(copyReader); while (from != to) { from.acceptVisitor(visitor); + copyReader.getCopy().setLocation(from.getLocation()); result.add(copyReader.getCopy()); from = from.getNext(); } @@ -138,25 +136,11 @@ public final class ProgramUtils { TryCatchBlock tryCatchCopy = new TryCatchBlock(); tryCatchCopy.setExceptionType(tryCatch.getExceptionType()); tryCatchCopy.setHandler(target.basicBlockAt(tryCatch.getHandler().getIndex())); - tryCatchCopy.getJoints().addAll(copyTryCatchJoints(tryCatch, target)); result.add(tryCatchCopy); } return result; } - public static List<TryCatchJoint> copyTryCatchJoints(TryCatchBlockReader block, Program target) { - List<TryCatchJoint> result = new ArrayList<>(); - for (TryCatchJointReader joint : block.readJoints()) { - TryCatchJoint jointCopy = new TryCatchJoint(); - jointCopy.setReceiver(target.variableAt(joint.getReceiver().getIndex())); - for (VariableReader sourceVar : joint.readSourceVariables()) { - jointCopy.getSourceVariables().add(target.variableAt(sourceVar.getIndex())); - } - result.add(jointCopy); - } - return result; - } - public static List<List<Incoming>> getPhiOutputs(Program program) { List<List<Incoming>> outputs = new ArrayList<>(program.basicBlockCount()); for (int i = 0; i < program.basicBlockCount(); ++i) { @@ -175,23 +159,6 @@ public final class ProgramUtils { return outputs; } - public static List<List<Incoming>> getPhiOutputsByVariable(Program program) { - List<List<Incoming>> outputs = new ArrayList<>(program.variableCount()); - for (int i = 0; i < program.variableCount(); ++i) { - outputs.add(new ArrayList<>()); - } - - for (BasicBlock block : program.getBasicBlocks()) { - for (Phi phi : block.getPhis()) { - for (Incoming incoming : phi.getIncomings()) { - outputs.get(incoming.getValue().getIndex()).add(incoming); - } - } - } - - return outputs; - } - public static BasicBlock[] getVariableDefinitionPlaces(Program program) { BasicBlock[] places = new BasicBlock[program.variableCount()]; DefinitionExtractor defExtractor = new DefinitionExtractor(); @@ -213,12 +180,6 @@ public final class ProgramUtils { places[var.getIndex()] = block; } } - - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - places[joint.getReceiver().getIndex()] = block; - } - } } return places; } diff --git a/core/src/main/java/org/teavm/model/util/RegisterAllocator.java b/core/src/main/java/org/teavm/model/util/RegisterAllocator.java index ca4a4ddf4..4126615d7 100644 --- a/core/src/main/java/org/teavm/model/util/RegisterAllocator.java +++ b/core/src/main/java/org/teavm/model/util/RegisterAllocator.java @@ -18,10 +18,8 @@ package org.teavm.model.util; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import org.teavm.common.DisjointSet; import org.teavm.common.MutableGraphEdge; import org.teavm.common.MutableGraphNode; @@ -33,15 +31,12 @@ import org.teavm.model.MethodReference; import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.ProgramReader; -import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.Variable; import org.teavm.model.instructions.AssignInstruction; import org.teavm.model.instructions.JumpInstruction; public class RegisterAllocator { public void allocateRegisters(MethodReader method, Program program) { - insertJointArgumentsCopies(program); insertPhiArgumentsCopies(program); InterferenceGraphBuilder interferenceBuilder = new InterferenceGraphBuilder(); LivenessAnalyzer liveness = new LivenessAnalyzer(); @@ -91,9 +86,6 @@ public class RegisterAllocator { for (int i = 0; i < program.basicBlockCount(); ++i) { program.basicBlockAt(i).getPhis().clear(); - for (TryCatchBlock tryCatch : program.basicBlockAt(i).getTryCatchBlocks()) { - tryCatch.getJoints().clear(); - } } } @@ -137,42 +129,6 @@ public class RegisterAllocator { } } - private void insertJointArgumentsCopies(Program program) { - for (int i = 0; i < program.basicBlockCount(); ++i) { - BasicBlock block = program.basicBlockAt(i); - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - tryCatch.getJoints().forEach(this::insertCopy); - } - } - } - - private void insertCopy(TryCatchJoint joint) { - Set<Variable> variableSet = new HashSet<>(joint.getSourceVariables()); - - BasicBlock block = joint.getBlock().getProtectedBlock(); - DefinitionExtractor defExtractor = new DefinitionExtractor(); - Instruction nextInsn; - for (Instruction insn = block.getFirstInstruction(); insn != null; insn = nextInsn) { - nextInsn = insn.getNext(); - insn.acceptVisitor(defExtractor); - for (Variable definedVar : defExtractor.getDefinedVariables()) { - if (variableSet.remove(definedVar)) { - AssignInstruction copyInsn = new AssignInstruction(); - copyInsn.setReceiver(joint.getReceiver()); - copyInsn.setAssignee(definedVar); - insn.insertNext(copyInsn); - } - } - } - - for (Variable enteringVar : variableSet) { - AssignInstruction copyInsn = new AssignInstruction(); - copyInsn.setReceiver(joint.getReceiver()); - copyInsn.setAssignee(enteringVar); - block.addFirst(copyInsn); - } - } - private void insertPhiArgumentsCopies(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { Map<BasicBlock, BasicBlock> blockMap = new HashMap<>(); @@ -321,13 +277,6 @@ public class RegisterAllocator { classes.union(phi.getReceiver().getIndex(), incoming.getValue().getIndex()); } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (Variable sourceVar : joint.getSourceVariables()) { - classes.union(sourceVar.getIndex(), joint.getReceiver().getIndex()); - } - } - } } return classes; } diff --git a/core/src/main/java/org/teavm/model/util/TypeInferer.java b/core/src/main/java/org/teavm/model/util/TypeInferer.java index 36db9b292..0c97a6803 100644 --- a/core/src/main/java/org/teavm/model/util/TypeInferer.java +++ b/core/src/main/java/org/teavm/model/util/TypeInferer.java @@ -52,14 +52,6 @@ public class TypeInferer { builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); } } - - for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { - for (TryCatchJointReader joint : tryCatch.readJoints()) { - for (VariableReader sourceVar : joint.readSourceVariables()) { - builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex()); - } - } - } } IntegerStack stack = new IntegerStack(sz); diff --git a/core/src/test/resources/model/analysis/nullness/tryCatchJoint.extended.txt b/core/src/test/resources/model/analysis/nullness/tryCatchJoint.extended.txt index a8bad3c1e..68a7faa48 100644 --- a/core/src/test/resources/model/analysis/nullness/tryCatchJoint.extended.txt +++ b/core/src/test/resources/model/analysis/nullness/tryCatchJoint.extended.txt @@ -8,9 +8,9 @@ $if0 invokeVirtual `Bar.baz()LBar;` @bar @bar_1 := nullCheck @bar goto $join -catch java.lang.RuntimeException goto $if0Handler - @bar_2 := ephi @bar, @bar_1 + catch java.lang.RuntimeException goto $if0Handler $if0Handler + @bar_2 := phi @bar from $if0, @bar_1 from $if0 goto $join $else invokeVirtual `Bar.baz()LBar;` @bar @@ -19,7 +19,7 @@ $else $else1 invokeVirtual `Bar.baz2()LBar;` @bar_3 goto $join -catch java.lang.RuntimeException goto $elseHandler + catch java.lang.RuntimeException goto $elseHandler $elseHandler goto $join $join diff --git a/core/src/test/resources/model/analysis/nullness/tryCatchJoint.original.txt b/core/src/test/resources/model/analysis/nullness/tryCatchJoint.original.txt index 20a724067..c445b0701 100644 --- a/core/src/test/resources/model/analysis/nullness/tryCatchJoint.original.txt +++ b/core/src/test/resources/model/analysis/nullness/tryCatchJoint.original.txt @@ -7,7 +7,7 @@ $start $if0 invokeVirtual `Bar.baz()LBar;` @bar goto $join -catch java.lang.RuntimeException goto $if0Handler + catch java.lang.RuntimeException goto $if0Handler $if0Handler goto $join $else @@ -16,7 +16,7 @@ $else $else1 invokeVirtual `Bar.baz2()LBar;` @bar goto $join -catch java.lang.RuntimeException goto $elseHandler + catch java.lang.RuntimeException goto $elseHandler $elseHandler goto $join $join diff --git a/core/src/test/resources/model/text/exceptions.txt b/core/src/test/resources/model/text/exceptions.txt index 08112a485..4a2506737 100644 --- a/core/src/test/resources/model/text/exceptions.txt +++ b/core/src/test/resources/model/text/exceptions.txt @@ -5,9 +5,9 @@ $start invokeStatic `foo.Bar.baz()I` @a_3 := 2 return @a_3 -catch java.lang.Exception goto $handler - @a_h := ephi @a_1, @a_2, @a_3 + catch java.lang.Exception goto $handler $handler + @a_h := phi @a_1 from $start, @a_2 from $start, @a_3 from $start @e := exception @out := field `java.lang.String.out` as `Ljava/io/PrintStream;` invokeVirtual `java.io.PrintStream.println(Ljava/lang/Object;)V` @out, @e diff --git a/core/src/test/resources/model/util/phi-updater/exceptionPhi.expected.txt b/core/src/test/resources/model/util/phi-updater/exceptionPhi.expected.txt index 8b6075ec5..76c1ec367 100644 --- a/core/src/test/resources/model/util/phi-updater/exceptionPhi.expected.txt +++ b/core/src/test/resources/model/util/phi-updater/exceptionPhi.expected.txt @@ -3,8 +3,8 @@ $start @a_1 := invokeStatic `Foo.baz()I` goto $end catch java.lang.RuntimeException goto $catch - @a_2 := ephi @a, @a_1 $catch + @a_2 := phi @a from $start, @a_1 from $start @b := 1 @a_3 := @a_2 + @b as int goto $end diff --git a/core/src/test/resources/model/util/phi-updater/exceptionPhiMultiple.expected.txt b/core/src/test/resources/model/util/phi-updater/exceptionPhiMultiple.expected.txt index f0051945a..ff34589a1 100644 --- a/core/src/test/resources/model/util/phi-updater/exceptionPhiMultiple.expected.txt +++ b/core/src/test/resources/model/util/phi-updater/exceptionPhiMultiple.expected.txt @@ -3,17 +3,15 @@ $start @a_1 := invokeStatic `Foo.baz()I` goto $second catch java.lang.RuntimeException goto $catch - @a_2 := ephi @a, @a_1 $second - @a_5 := invokeStatic `Foo.boo()I` + @a_2 := invokeStatic `Foo.boo()I` goto $end catch java.lang.RuntimeException goto $catch - @a_6 := ephi @a_1, @a_5 $catch - @a_3 := phi @a_2 from $start, @a_6 from $second + @a_3 := phi @a from $start, @a_1 from $start, @a_1 from $second, @a_2 from $second @b := 1 @a_4 := @a_3 + @b as int goto $end $end - @a_7 := phi @a_4 from $catch, @a_5 from $second - return @a_7 \ No newline at end of file + @a_5 := phi @a_2 from $second, @a_4 from $catch + return @a_5 \ No newline at end of file diff --git a/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.expected.txt b/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.expected.txt index b5225b749..ca72443eb 100644 --- a/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.expected.txt +++ b/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.expected.txt @@ -3,16 +3,14 @@ $start @a_1 := invokeStatic `Foo.baz()I` goto $second catch goto $catch - @a_2 := ephi @a, @a_1 $second - @a_3 := invokeStatic `Foo.bar2()I` - @a_4 := invokeStatic `Foo.baz2()I` + @a_2 := invokeStatic `Foo.bar2()I` + @a_3 := invokeStatic `Foo.baz2()I` goto $end catch goto $catch - @a_5 := ephi @a_1, @a_3, @a_4 $catch - @a_6 := phi @a_2 from $start, @a_5 from $second + @a_4 := phi @a from $start, @a_1 from $start, @a_2 from $second, @a_3 from $second goto $end $end - @a_7 := phi @a_4 from $second, @a_6 from $catch - return @a_7 + @a_5 := phi @a_3 from $second, @a_4 from $catch + return @a_5 diff --git a/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.original.txt b/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.original.txt index b5225b749..ca72443eb 100644 --- a/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.original.txt +++ b/core/src/test/resources/model/util/phi-updater/existingExceptionPhi.original.txt @@ -3,16 +3,14 @@ $start @a_1 := invokeStatic `Foo.baz()I` goto $second catch goto $catch - @a_2 := ephi @a, @a_1 $second - @a_3 := invokeStatic `Foo.bar2()I` - @a_4 := invokeStatic `Foo.baz2()I` + @a_2 := invokeStatic `Foo.bar2()I` + @a_3 := invokeStatic `Foo.baz2()I` goto $end catch goto $catch - @a_5 := ephi @a_1, @a_3, @a_4 $catch - @a_6 := phi @a_2 from $start, @a_5 from $second + @a_4 := phi @a from $start, @a_1 from $start, @a_2 from $second, @a_3 from $second goto $end $end - @a_7 := phi @a_4 from $second, @a_6 from $catch - return @a_7 + @a_5 := phi @a_3 from $second, @a_4 from $catch + return @a_5 diff --git a/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/AliasFinder.java b/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/AliasFinder.java index 13e87a876..7d0650af1 100644 --- a/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/AliasFinder.java +++ b/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/AliasFinder.java @@ -22,8 +22,6 @@ import org.teavm.common.DisjointSet; import org.teavm.model.BasicBlockReader; import org.teavm.model.PhiReader; import org.teavm.model.ProgramReader; -import org.teavm.model.TryCatchBlockReader; -import org.teavm.model.TryCatchJointReader; import org.teavm.model.ValueType; import org.teavm.model.VariableReader; import org.teavm.model.instructions.AbstractInstructionReader; @@ -51,16 +49,6 @@ class AliasFinder { set.union(inputs.iterator().next(), phi.getReceiver().getIndex()); } } - for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { - for (TryCatchJointReader joint : tryCatch.readJoints()) { - Set<Integer> inputs = joint.readSourceVariables().stream() - .map(sourceVar -> sourceVar.getIndex()) - .collect(Collectors.toSet()); - if (inputs.size() == 1) { - set.union(inputs.iterator().next(), joint.getReceiver().getIndex()); - } - } - } } int[] map = new int[set.size()]; diff --git a/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/optimization/BoxingElimination.java b/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/optimization/BoxingElimination.java index ccb21bb16..d86e41924 100644 --- a/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/optimization/BoxingElimination.java +++ b/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/optimization/BoxingElimination.java @@ -29,8 +29,6 @@ import org.teavm.model.MethodReference; import org.teavm.model.Phi; import org.teavm.model.PrimitiveType; import org.teavm.model.Program; -import org.teavm.model.TryCatchBlock; -import org.teavm.model.TryCatchJoint; import org.teavm.model.ValueType; import org.teavm.model.Variable; import org.teavm.model.instructions.AssignInstruction; @@ -112,13 +110,6 @@ public class BoxingElimination { union(phi.getReceiver().getIndex(), incoming.getValue().getIndex()); } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (Variable sourceVar : joint.getSourceVariables()) { - union(sourceVar.getIndex(), joint.getReceiver().getIndex()); - } - } - } } }