From 66931401a8286bd8060d4ad235223d9b0a2c84fd Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 5 Jun 2016 17:36:43 +0300 Subject: [PATCH] Further work on incremental phi updater --- .../main/java/org/teavm/cache/ProgramIO.java | 43 ++++--- .../dependency/DataFlowGraphBuilder.java | 9 +- .../dependency/DependencyGraphBuilder.java | 10 +- .../javascript/ReadWriteStatsBuilder.java | 11 +- .../main/java/org/teavm/model/BasicBlock.java | 26 +++- .../org/teavm/model/BasicBlockReader.java | 6 +- .../model/PreOptimizingClassHolderSource.java | 4 - .../java/org/teavm/model/TryCatchBlock.java | 18 --- .../org/teavm/model/TryCatchBlockReader.java | 4 - .../java/org/teavm/model/TryCatchJoint.java | 20 ++- .../org/teavm/model/TryCatchJointReader.java | 4 +- .../teavm/model/util/BasicBlockMapper.java | 7 +- .../model/util/InstructionVariableMapper.java | 16 ++- .../model/util/InterferenceGraphBuilder.java | 27 ++-- .../org/teavm/model/util/ListingBuilder.java | 16 +-- .../teavm/model/util/LivenessAnalyzer.java | 19 +-- .../java/org/teavm/model/util/PhiUpdater.java | 119 ++++++++++++------ .../org/teavm/model/util/ProgramUtils.java | 37 ++++-- .../teavm/model/util/RegisterAllocator.java | 75 +++++++++-- .../org/teavm/model/util/TypeInferer.java | 5 + .../optimization/EmptyBlockElimination.java | 4 +- .../optimization/GlobalValueNumbering.java | 36 ++---- .../optimization/LoopInvariantMotion.java | 16 +-- .../teavm/optimization/LoopInversionImpl.java | 15 ++- .../UnusedVariableElimination.java | 18 +-- .../VariableUsageGraphBuilder.java | 9 +- core/src/main/java/org/teavm/vm/TeaVM.java | 2 +- .../metaprogramming/impl/AliasFinder.java | 9 ++ .../impl/optimization/BoxingElimination.java | 6 + 29 files changed, 361 insertions(+), 230 deletions(-) diff --git a/core/src/main/java/org/teavm/cache/ProgramIO.java b/core/src/main/java/org/teavm/cache/ProgramIO.java index dcacdc86b..58be34add 100644 --- a/core/src/main/java/org/teavm/cache/ProgramIO.java +++ b/core/src/main/java/org/teavm/cache/ProgramIO.java @@ -20,10 +20,6 @@ import java.util.Objects; import org.teavm.model.*; import org.teavm.model.instructions.*; -/** - * - * @author Alexey Andreev - */ public class ProgramIO { private SymbolTable symbolTable; private SymbolTable fileTable; @@ -70,13 +66,14 @@ public class ProgramIO { data.writeShort(tryCatch.getExceptionVariable() != null ? tryCatch.getExceptionVariable().getIndex() : -1); data.writeShort(tryCatch.getHandler().getIndex()); - data.writeShort(tryCatch.getJoints().size()); - for (TryCatchJoint joint : tryCatch.getJoints()) { - data.writeShort(joint.getTargetVariable().getIndex()); - data.writeShort(joint.getSourceVariables().size()); - for (Variable sourceVar : joint.getSourceVariables()) { - data.writeShort(sourceVar.getIndex()); - } + } + data.writeShort(basicBlock.getTryCatchJoints().size()); + for (TryCatchJoint joint : basicBlock.getTryCatchJoints()) { + data.writeShort(joint.getSource().getIndex()); + data.writeShort(joint.getReceiver().getIndex()); + data.writeShort(joint.getSourceVariables().size()); + for (Variable sourceVar : joint.getSourceVariables()) { + data.writeShort(sourceVar.getIndex()); } } InstructionLocation location = null; @@ -146,18 +143,20 @@ public class ProgramIO { } tryCatch.setHandler(program.basicBlockAt(data.readShort())); block.getTryCatchBlocks().add(tryCatch); - - int jointCount = data.readShort(); - for (int k = 0; k < jointCount; ++k) { - TryCatchJoint joint = new TryCatchJoint(); - joint.setTargetVariable(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); - } } + + int jointCount = data.readShort(); + for (int j = 0; j < jointCount; ++j) { + TryCatchJoint joint = new TryCatchJoint(); + joint.setSource(program.basicBlockAt(data.readShort())); + joint.setReceiver(program.variableAt(data.readShort())); + int jointSourceCount = data.readShort(); + for (int k = 0; k < jointSourceCount; ++k) { + joint.getSourceVariables().add(program.variableAt(data.readShort())); + } + block.getTryCatchJoints().add(joint); + } + InstructionLocation location = null; insnLoop: while (true) { byte insnType = data.readByte(); diff --git a/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index 4eaec8708..84903dfc3 100644 --- a/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -26,10 +26,6 @@ import org.teavm.common.*; import org.teavm.model.*; import org.teavm.model.instructions.*; -/** - * - * @author Alexey Andreev - */ public class DataFlowGraphBuilder implements InstructionReader { private int lastIndex; private GraphBuilder builder = new GraphBuilder(); @@ -68,6 +64,11 @@ public class DataFlowGraphBuilder implements InstructionReader { builder.addEdge(from, to); } } + for (TryCatchJointReader joint : block.readTryCatchJoints()) { + for (VariableReader sourceVar : joint.readSourceVariables()) { + builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex()); + } + } block.readAllInstructions(this); } Graph graph = builder.build(); diff --git a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index c752a1c4b..ff4b3dfac 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -44,6 +44,7 @@ import org.teavm.model.PhiReader; import org.teavm.model.Program; import org.teavm.model.RuntimeConstant; 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; @@ -136,10 +137,17 @@ class DependencyGraphBuilder { BasicBlockReader block = program.basicBlockAt(i); currentExceptionConsumer = createExceptionConsumer(dep, block); block.readAllInstructions(reader); + for (TryCatchJointReader joint : block.readTryCatchJoints()) { + DependencyNode receiverNode = nodes[joint.getReceiver().getIndex()]; + for (VariableReader source : joint.readSourceVariables()) { + DependencyNode sourceNode = nodes[source.getIndex()]; + sourceNode.connect(receiverNode); + } + } for (PhiReader phi : block.readPhis()) { + DependencyNode receiverNode = nodes[phi.getReceiver().getIndex()]; for (IncomingReader incoming : phi.readIncomings()) { DependencyNode incomingNode = nodes[incoming.getValue().getIndex()]; - DependencyNode receiverNode = nodes[phi.getReceiver().getIndex()]; if (incomingNode != null && receiverNode != null) { incomingNode.connect(receiverNode); } diff --git a/core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java b/core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java index 17d7666fb..caf99a014 100644 --- a/core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java +++ b/core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java @@ -24,10 +24,6 @@ import org.teavm.model.util.DefinitionExtractor; import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.UsageExtractor; -/** - * - * @author Alexey Andreev - */ class ReadWriteStatsBuilder { public int[] reads; public int[] writes; @@ -67,6 +63,13 @@ class ReadWriteStatsBuilder { reads[var.getIndex()]++; } } + + for (TryCatchJoint joint : block.getTryCatchJoints()) { + writes[joint.getReceiver().getIndex()] += joint.getSourceVariables().size(); + for (Variable var : joint.getSourceVariables()) { + reads[var.getIndex()]++; + } + } for (Phi phi : block.getPhis()) { writes[phi.getReceiver().getIndex()] += phi.getIncomings().size(); for (Incoming incoming : phi.getIncomings()) { diff --git a/core/src/main/java/org/teavm/model/BasicBlock.java b/core/src/main/java/org/teavm/model/BasicBlock.java index 08248cfe7..3689bac8c 100644 --- a/core/src/main/java/org/teavm/model/BasicBlock.java +++ b/core/src/main/java/org/teavm/model/BasicBlock.java @@ -18,16 +18,14 @@ package org.teavm.model; import java.util.*; import org.teavm.model.instructions.InstructionReader; -/** - * - * @author Alexey Andreev - */ public class BasicBlock implements BasicBlockReader { private Program program; private int index; private List phis = new ArrayList<>(); private List instructions = new ArrayList<>(); - List tryCatchBlocks = new ArrayList<>(); + private List tryCatchBlocks = new ArrayList<>(); + private List joints = new ArrayList<>(); + private List immutableJoints = new ArrayList<>(); BasicBlock(Program program, int index) { this.program = program; @@ -199,6 +197,12 @@ public class BasicBlock implements BasicBlockReader { } } } + for (int i = 0; i < joints.size(); ++i) { + TryCatchJoint joint = joints.get(i); + if (joint.getSource() == predecessor) { + joints.remove(i--); + } + } } private List immutableTryCatchBlocks = Collections.unmodifiableList(tryCatchBlocks); @@ -251,4 +255,16 @@ public class BasicBlock implements BasicBlockReader { public List getTryCatchBlocks() { return safeTryCatchBlocks; } + + public List getTryCatchJoints() { + return joints; + } + + @Override + public List readTryCatchJoints() { + if (immutableJoints == null) { + immutableJoints = Collections.unmodifiableList(joints); + } + return immutableJoints; + } } diff --git a/core/src/main/java/org/teavm/model/BasicBlockReader.java b/core/src/main/java/org/teavm/model/BasicBlockReader.java index 7f3333fe6..8a7f9c09b 100644 --- a/core/src/main/java/org/teavm/model/BasicBlockReader.java +++ b/core/src/main/java/org/teavm/model/BasicBlockReader.java @@ -18,10 +18,6 @@ package org.teavm.model; import java.util.List; import org.teavm.model.instructions.InstructionReader; -/** - * - * @author Alexey Andreev - */ public interface BasicBlockReader { ProgramReader getProgram(); @@ -36,4 +32,6 @@ public interface BasicBlockReader { void readAllInstructions(InstructionReader reader); List readTryCatchBlocks(); + + List readTryCatchJoints(); } diff --git a/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java b/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java index ac52dd71e..99538be98 100644 --- a/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java +++ b/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java @@ -20,10 +20,6 @@ import java.util.Map; import org.teavm.optimization.GlobalValueNumbering; import org.teavm.optimization.UnusedVariableElimination; -/** - * - * @author Alexey Andreev - */ public class PreOptimizingClassHolderSource implements ClassHolderSource { private ClassHolderSource innerClassSource; private Map cache = new HashMap<>(); diff --git a/core/src/main/java/org/teavm/model/TryCatchBlock.java b/core/src/main/java/org/teavm/model/TryCatchBlock.java index ad549c910..58bba408a 100644 --- a/core/src/main/java/org/teavm/model/TryCatchBlock.java +++ b/core/src/main/java/org/teavm/model/TryCatchBlock.java @@ -15,17 +15,11 @@ */ package org.teavm.model; -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 Variable exceptionVariable; - private List joints = new ArrayList<>(); - private List immutableJoints = new ArrayList<>(); @Override public BasicBlock getHandler() { @@ -58,16 +52,4 @@ public class TryCatchBlock implements TryCatchBlockReader { public BasicBlock getProtectedBlock() { return protectedBlock; } - - public List getJoints() { - return joints; - } - - @Override - public List readJoints() { - if (immutableJoints == null) { - immutableJoints = Collections.unmodifiableList(joints); - } - 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 226a2c87e..125358947 100644 --- a/core/src/main/java/org/teavm/model/TryCatchBlockReader.java +++ b/core/src/main/java/org/teavm/model/TryCatchBlockReader.java @@ -15,8 +15,6 @@ */ package org.teavm.model; -import java.util.List; - public interface TryCatchBlockReader { BasicBlockReader getProtectedBlock(); @@ -25,6 +23,4 @@ public interface TryCatchBlockReader { String getExceptionType(); VariableReader getExceptionVariable(); - - List readJoints(); } diff --git a/core/src/main/java/org/teavm/model/TryCatchJoint.java b/core/src/main/java/org/teavm/model/TryCatchJoint.java index 7737a7c02..7096acd61 100644 --- a/core/src/main/java/org/teavm/model/TryCatchJoint.java +++ b/core/src/main/java/org/teavm/model/TryCatchJoint.java @@ -20,9 +20,10 @@ import java.util.Collections; import java.util.List; public class TryCatchJoint implements TryCatchJointReader { + private BasicBlock source; private List sourceVariables = new ArrayList<>(); private List readonlySourceVariables; - private Variable targetVariable; + private Variable receiver; @Override public List readSourceVariables() { @@ -37,11 +38,20 @@ public class TryCatchJoint implements TryCatchJointReader { } @Override - public Variable getTargetVariable() { - return targetVariable; + public Variable getReceiver() { + return receiver; } - public void setTargetVariable(Variable targetVariable) { - this.targetVariable = targetVariable; + public void setReceiver(Variable receiver) { + this.receiver = receiver; + } + + @Override + public BasicBlock getSource() { + return source; + } + + public void setSource(BasicBlock source) { + this.source = source; } } diff --git a/core/src/main/java/org/teavm/model/TryCatchJointReader.java b/core/src/main/java/org/teavm/model/TryCatchJointReader.java index 3c20024c0..55456fa0a 100644 --- a/core/src/main/java/org/teavm/model/TryCatchJointReader.java +++ b/core/src/main/java/org/teavm/model/TryCatchJointReader.java @@ -20,5 +20,7 @@ import java.util.List; public interface TryCatchJointReader { List readSourceVariables(); - VariableReader getTargetVariable(); + VariableReader getReceiver(); + + BasicBlockReader getSource(); } diff --git a/core/src/main/java/org/teavm/model/util/BasicBlockMapper.java b/core/src/main/java/org/teavm/model/util/BasicBlockMapper.java index a422221e8..732b9f796 100644 --- a/core/src/main/java/org/teavm/model/util/BasicBlockMapper.java +++ b/core/src/main/java/org/teavm/model/util/BasicBlockMapper.java @@ -19,10 +19,6 @@ import java.util.function.IntUnaryOperator; import org.teavm.model.*; import org.teavm.model.instructions.*; -/** - * - * @author Alexey Andreev - */ public class BasicBlockMapper implements InstructionVisitor { private IntUnaryOperator mapFunction; @@ -47,6 +43,9 @@ public class BasicBlockMapper implements InstructionVisitor { return; } lastInsn.acceptVisitor(this); + for (TryCatchJoint joint : block.getTryCatchJoints()) { + joint.setSource(map(joint.getSource())); + } for (Phi phi : block.getPhis()) { for (Incoming incoming : phi.getIncomings()) { incoming.setSource(map(incoming.getSource())); 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 568d537b0..b417daa0d 100644 --- a/core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java +++ b/core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java @@ -37,6 +37,7 @@ public class InstructionVariableMapper implements InstructionVisitor { applyToInstructions(block); applyToPhis(block); applyToTryCatchBlocks(block); + applyToTryCatchJoints(block); } public void applyToInstructions(BasicBlock block) { @@ -59,12 +60,15 @@ public class InstructionVariableMapper implements InstructionVisitor { if (tryCatch.getExceptionVariable() != null) { tryCatch.setExceptionVariable(map(tryCatch.getExceptionVariable())); } - for (TryCatchJoint joint : tryCatch.getJoints()) { - joint.setTargetVariable(map(joint.getTargetVariable())); - for (int i = 0; i < joint.getSourceVariables().size(); ++i) { - Variable var = joint.getSourceVariables().get(i); - joint.getSourceVariables().set(i, map(var)); - } + } + } + + public void applyToTryCatchJoints(BasicBlock block) { + for (TryCatchJoint joint : block.getTryCatchJoints()) { + 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)); } } } 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 ba1026e75..5687d3cf2 100644 --- a/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java +++ b/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java @@ -29,6 +29,7 @@ class InterferenceGraphBuilder { DefinitionExtractor defExtractor = new DefinitionExtractor(); InstructionTransitionExtractor succExtractor = new InstructionTransitionExtractor(); List> outgoings = ProgramUtils.getPhiOutputs(program); + List> outputJoints = ProgramUtils.getOutputJoints(program); Set live = new HashSet<>(128); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); @@ -46,6 +47,11 @@ class InterferenceGraphBuilder { live.add(nodes.get(j)); } } + for (TryCatchJoint joint : outputJoints.get(i)) { + for (Variable outputVar : joint.getSourceVariables()) { + live.add(nodes.get(outputVar.getIndex())); + } + } for (Incoming outgoing : outgoings.get(i)) { live.add(nodes.get(outgoing.getValue().getIndex())); } @@ -53,24 +59,11 @@ class InterferenceGraphBuilder { if (tryCatch.getExceptionVariable() != null) { nodes.get(tryCatch.getExceptionVariable().getIndex()).connectAll(live); } - for (TryCatchJoint joint : tryCatch.getJoints()) { - nodes.get(joint.getTargetVariable().getIndex()).connectAll(live); - } } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { if (tryCatch.getExceptionVariable() != null) { live.remove(nodes.get(tryCatch.getExceptionVariable().getIndex())); } - for (TryCatchJoint joint : tryCatch.getJoints()) { - nodes.get(joint.getTargetVariable().getIndex()).connectAll(live); - } - } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - for (Variable var : joint.getSourceVariables()) { - live.add(nodes.get(var.getIndex())); - } - } } for (int j = block.getInstructions().size() - 1; j >= 0; --j) { Instruction insn = block.getInstructions().get(j); @@ -98,9 +91,17 @@ class InterferenceGraphBuilder { live.add(nodes.get(j)); } } + + for (TryCatchJoint joint : block.getTryCatchJoints()) { + live.add(nodes.get(joint.getReceiver().getIndex())); + } for (Phi phi : block.getPhis()) { live.add(nodes.get(phi.getReceiver().getIndex())); } + + for (TryCatchJoint joint : block.getTryCatchJoints()) { + nodes.get(joint.getReceiver().getIndex()).connectAll(live); + } for (Phi phi : block.getPhis()) { nodes.get(phi.getReceiver().getIndex()).connectAll(live); } diff --git a/core/src/main/java/org/teavm/model/util/ListingBuilder.java b/core/src/main/java/org/teavm/model/util/ListingBuilder.java index 9fe19aeea..e1c7fd7e8 100644 --- a/core/src/main/java/org/teavm/model/util/ListingBuilder.java +++ b/core/src/main/java/org/teavm/model/util/ListingBuilder.java @@ -47,6 +47,13 @@ public class ListingBuilder { if (block == null) { continue; } + + for (TryCatchJointReader joint : block.readTryCatchJoints()) { + sb.append("@").append(joint.getReceiver().getIndex()).append(" := e-phi("); + sb.append(joint.readSourceVariables().stream().map(sourceVar -> "@" + sourceVar.getIndex()) + .collect(Collectors.joining(", "))); + sb.append(") from $").append(joint.getSource().getIndex()).append("\n"); + } for (PhiReader phi : block.readPhis()) { sb.append(prefix).append(" "); sb.append("@").append(phi.getReceiver().getIndex()).append(" := "); @@ -61,6 +68,7 @@ public class ListingBuilder { } sb.append("\n"); } + InstructionLocation location = null; for (int j = 0; j < block.instructionCount(); ++j) { insnSb.setLength(0); @@ -76,14 +84,6 @@ public class ListingBuilder { sb.append(prefix).append(" catch ").append(tryCatch.getExceptionType()).append(" @") .append(tryCatch.getExceptionVariable().getIndex()) .append(" -> $").append(tryCatch.getHandler().getIndex()); - if (!tryCatch.readJoints().isEmpty()) { - sb.append(" with "); - for (TryCatchJointReader joint : tryCatch.readJoints()) { - sb.append(" @").append(joint.getTargetVariable().getIndex()).append(" := "); - sb.append(joint.readSourceVariables().stream().map(sourceVar -> "@" + sourceVar.getIndex()) - .collect(Collectors.joining("|"))); - } - } sb.append("\n"); } } 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 4f3297215..e73af3fd2 100644 --- a/core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java +++ b/core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java @@ -65,19 +65,20 @@ public class LivenessAnalyzer { } } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - definitions[joint.getTargetVariable().getIndex()] = i; - for (Variable sourceVar : joint.getSourceVariables()) { - Task task = new Task(); - task.block = i; - task.var = sourceVar.getIndex(); - stack.push(task); - } - } if (tryCatch.getExceptionVariable() != null) { definitions[tryCatch.getExceptionVariable().getIndex()] = i; } } + + for (TryCatchJoint joint : block.getTryCatchJoints()) { + definitions[joint.getReceiver().getIndex()] = i; + for (Variable sourceVar : joint.getSourceVariables()) { + Task task = new Task(); + task.block = joint.getSource().getIndex(); + 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 0fbd01dc3..05896e2b8 100644 --- a/core/src/main/java/org/teavm/model/util/PhiUpdater.java +++ b/core/src/main/java/org/teavm/model/util/PhiUpdater.java @@ -22,7 +22,9 @@ import java.nio.CharBuffer; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.teavm.common.DominatorTree; import org.teavm.common.Graph; import org.teavm.common.GraphUtils; @@ -86,8 +88,9 @@ public class PhiUpdater { private BasicBlock currentBlock; private Phi[][] phiMap; private int[][] phiIndexMap; + private List>> jointMap = new ArrayList<>(); private List> synthesizedPhis = new ArrayList<>(); - private List> outputJoints = new ArrayList<>(); + private List> synthesizedJoints = new ArrayList<>(); private boolean[] usedDefinitions; public void updatePhis(Program program, Variable[] arguments) { @@ -106,15 +109,19 @@ public class PhiUpdater { } phiMap = new Phi[program.basicBlockCount()][]; phiIndexMap = new int[program.basicBlockCount()][]; + jointMap = new ArrayList<>(); for (int i = 0; i < phiMap.length; ++i) { phiMap[i] = new Phi[program.variableCount()]; phiIndexMap[i] = new int[program.variableCount()]; + jointMap.add(new HashMap<>()); } domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree); synthesizedPhis.clear(); + synthesizedJoints.clear(); for (int i = 0; i < program.basicBlockCount(); ++i) { synthesizedPhis.add(new ArrayList<>()); + synthesizedJoints.add(new ArrayList<>()); } estimatePhis(); renameVariables(); @@ -127,6 +134,9 @@ public class PhiUpdater { for (Phi phi : currentBlock.getPhis()) { markAssignment(phi.getReceiver()); } + for (TryCatchJoint joint : currentBlock.getTryCatchJoints()) { + markAssignment(joint.getReceiver()); + } for (Instruction insn : currentBlock.getInstructions()) { insn.acceptVisitor(definitionExtractor); for (Variable var : definitionExtractor.getDefinedVariables()) { @@ -159,6 +169,7 @@ public class PhiUpdater { } List> phiOutputs = ProgramUtils.getPhiOutputs(program); + List> existingOutputJoints = ProgramUtils.getOutputJoints(program); boolean[] processed = new boolean[program.basicBlockCount()]; while (head > 0) { @@ -170,10 +181,6 @@ public class PhiUpdater { } processed[index] = true; variableMap = Arrays.copyOf(task.variables, task.variables.length); - outputJoints.clear(); - for (int i = 0; i < currentBlock.getTryCatchBlocks().size(); ++i) { - outputJoints.add(new IntObjectOpenHashMap<>()); - } for (Phi phi : synthesizedPhis.get(index)) { Variable var = program.createVariable(); @@ -181,18 +188,22 @@ public class PhiUpdater { variableMap[phi.getReceiver().getIndex()] = var; phi.setReceiver(var); } + for (TryCatchJoint joint : synthesizedJoints.get(index)) { + Variable var = program.createVariable(); + var.getDebugNames().addAll(joint.getReceiver().getDebugNames()); + variableMap[joint.getReceiver().getIndex()] = var; + joint.setReceiver(var); + } for (Phi phi : currentBlock.getPhis()) { phi.setReceiver(define(phi.getReceiver())); } + for (TryCatchJoint joint : currentBlock.getTryCatchJoints()) { + joint.setReceiver(define(joint.getReceiver())); + } for (Instruction insn : currentBlock.getInstructions()) { insn.acceptVisitor(consumer); } - for (IntObjectMap joints : outputJoints) { - for (int jointVar : joints.keys().toArray()) { - joints.get(jointVar).setTargetVariable(introduce(program.variableAt(jointVar))); - } - } IntObjectMap> exceptionVariableMap = new IntObjectOpenHashMap<>(); for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { @@ -205,9 +216,16 @@ public class PhiUpdater { tryCatchVariableMap.put(var.getIndex(), newVar); } } + for (Incoming output : phiOutputs.get(index)) { output.setValue(use(output.getValue())); } + for (TryCatchJoint joint : existingOutputJoints.get(index)) { + for (int i = 0; i < joint.getSourceVariables().size(); ++i) { + Variable var = joint.getSourceVariables().get(i); + joint.getSourceVariables().set(i, use(var)); + } + } int[] successors = domGraph.outgoingEdges(index); for (int successor : successors) { @@ -243,6 +261,7 @@ public class PhiUpdater { for (int i = 0; i < program.basicBlockCount(); ++i) { program.basicBlockAt(i).getPhis().addAll(synthesizedPhis.get(i)); + program.basicBlockAt(i).getTryCatchJoints().addAll(synthesizedJoints.get(i)); } } @@ -258,25 +277,51 @@ public class PhiUpdater { } for (int frontier : frontiers) { BasicBlock frontierBlock = program.basicBlockAt(frontier); - 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][synthesizedPhis.get(frontier).size()] = var.getIndex(); - synthesizedPhis.get(frontier).add(phi); - phiMap[frontier][var.getIndex()] = phi; - worklist[head++] = frontierBlock; + + if (isExceptionHandler(block, frontierBlock)) { + boolean jointExists = frontierBlock.getTryCatchJoints().stream() + .anyMatch(joint -> joint.getSourceVariables().contains(var) && joint.getSource() == block); + if (!jointExists) { + Map jointSubmap = jointMap.get(frontier).get(block); + if (jointSubmap == null) { + jointSubmap = new HashMap<>(); + jointMap.get(frontier).put(block, jointSubmap); + } + TryCatchJoint joint = jointSubmap.get(var); + if (joint == null) { + joint = new TryCatchJoint(); + joint.setSource(block); + joint.setReceiver(var); + synthesizedJoints.get(frontier).add(joint); + jointSubmap.put(var, joint); + worklist[head++] = frontierBlock; + } + } + } else { + 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][synthesizedPhis.get(frontier).size()] = var.getIndex(); + synthesizedPhis.get(frontier).add(phi); + phiMap[frontier][var.getIndex()] = phi; + worklist[head++] = frontierBlock; + } } } } } + private boolean isExceptionHandler(BasicBlock source, BasicBlock target) { + return source.getTryCatchBlocks().stream().anyMatch(tryCatch -> tryCatch.getHandler() == target); + } + private Variable define(Variable var) { Variable original = var; Variable old = variableMap[var.getIndex()]; @@ -285,24 +330,22 @@ public class PhiUpdater { } var = introduce(var); - if (original != var) { - List tryCatches = currentBlock.getTryCatchBlocks(); - for (int i = 0; i < tryCatches.size(); ++i) { - TryCatchBlock tryCatch = tryCatches.get(i); - IntObjectMap jointMap = outputJoints.get(i); - TryCatchJoint joint = jointMap.get(original.getIndex()); - if (joint == null) { - joint = new TryCatchJoint(); - joint.getSourceVariables().add(old); - tryCatch.getJoints().add(joint); - jointMap.put(original.getIndex(), joint); - } - joint.getSourceVariables().add(var); + for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { + Map joints = jointMap.get(tryCatch.getHandler().getIndex()).get(currentBlock); + if (joints == null) { + continue; } + TryCatchJoint joint = joints.get(original); + if (joint == null) { + continue; + } + if (joint.getSourceVariables().isEmpty()) { + joint.getSourceVariables().add(original); + } + joint.getSourceVariables().add(var); } variableMap[original.getIndex()] = var; - return var; } 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 27e6a47af..4d87590d3 100644 --- a/core/src/main/java/org/teavm/model/util/ProgramUtils.java +++ b/core/src/main/java/org/teavm/model/util/ProgramUtils.java @@ -81,6 +81,7 @@ public final class ProgramUtils { blockCopy.getInstructions().addAll(copyInstructions(block, 0, block.instructionCount(), copy)); blockCopy.getPhis().addAll(copyPhis(block, copy)); blockCopy.getTryCatchBlocks().addAll(copyTryCatches(block, copy)); + blockCopy.getTryCatchJoints().addAll(copyTryCatchJoints(block, copy)); } return copy; } @@ -119,14 +120,20 @@ public final class ProgramUtils { tryCatchCopy.setExceptionVariable(target.variableAt(tryCatch.getExceptionVariable().getIndex())); tryCatchCopy.setHandler(target.basicBlockAt(tryCatch.getHandler().getIndex())); result.add(tryCatchCopy); - for (TryCatchJointReader joint : tryCatch.readJoints()) { - TryCatchJoint jointCopy = new TryCatchJoint(); - jointCopy.setTargetVariable(target.variableAt(joint.getTargetVariable().getIndex())); - for (VariableReader jointSourceVar : joint.readSourceVariables()) { - jointCopy.getSourceVariables().add(target.variableAt(jointSourceVar.getIndex())); - } - tryCatchCopy.getJoints().add(jointCopy); + } + return result; + } + + public static List copyTryCatchJoints(BasicBlockReader block, Program target) { + List result = new ArrayList<>(); + for (TryCatchJointReader joint : block.readTryCatchJoints()) { + TryCatchJoint jointCopy = new TryCatchJoint(); + jointCopy.setSource(target.basicBlockAt(joint.getSource().getIndex())); + jointCopy.setReceiver(target.variableAt(joint.getReceiver().getIndex())); + for (VariableReader sourceVar : jointCopy.getSourceVariables()) { + jointCopy.getSourceVariables().add(target.variableAt(sourceVar.getIndex())); } + result.add(jointCopy); } return result; } @@ -148,4 +155,20 @@ public final class ProgramUtils { return outputs; } + + public static List> getOutputJoints(Program program) { + List> outputs = new ArrayList<>(program.basicBlockCount()); + for (int i = 0; i < program.basicBlockCount(); ++i) { + outputs.add(new ArrayList<>()); + } + + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlock block = program.basicBlockAt(i); + for (TryCatchJoint joint : block.getTryCatchJoints()) { + outputs.get(joint.getSource().getIndex()).add(joint); + } + } + + return outputs; + } } 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 4f41d2b12..833da95ee 100644 --- a/core/src/main/java/org/teavm/model/util/RegisterAllocator.java +++ b/core/src/main/java/org/teavm/model/util/RegisterAllocator.java @@ -15,19 +15,33 @@ */ package org.teavm.model.util; -import java.util.*; -import org.teavm.common.*; -import org.teavm.model.*; +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; +import org.teavm.model.BasicBlock; +import org.teavm.model.Incoming; +import org.teavm.model.Instruction; +import org.teavm.model.MethodReader; +import org.teavm.model.MethodReference; +import org.teavm.model.Phi; +import org.teavm.model.Program; +import org.teavm.model.ProgramReader; +import org.teavm.model.TryCatchJoint; +import org.teavm.model.Variable; import org.teavm.model.instructions.AssignInstruction; import org.teavm.model.instructions.EmptyInstruction; import org.teavm.model.instructions.JumpInstruction; -/** - * - * @author Alexey Andreev - */ public class RegisterAllocator { public void allocateRegisters(MethodReader method, Program program) { + insertJointArgumentsCopies(program); insertPhiArgumentsCopies(program); InterferenceGraphBuilder interferenceBuilder = new InterferenceGraphBuilder(); LivenessAnalyzer liveness = new LivenessAnalyzer(); @@ -63,6 +77,7 @@ public class RegisterAllocator { for (int i = 0; i < program.basicBlockCount(); ++i) { program.basicBlockAt(i).getPhis().clear(); + program.basicBlockAt(i).getTryCatchJoints().clear(); } } @@ -98,6 +113,39 @@ public class RegisterAllocator { } } + private void insertJointArgumentsCopies(Program program) { + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlock block = program.basicBlockAt(i); + block.getTryCatchJoints().forEach(this::insertCopy); + } + } + + private void insertCopy(TryCatchJoint joint) { + Set variableSet = new HashSet<>(joint.getSourceVariables()); + + BasicBlock block = joint.getSource(); + DefinitionExtractor defExtractor = new DefinitionExtractor(); + for (int i = block.getInstructions().size() - 1; i >= 0; --i) { + Instruction insn = block.getInstructions().get(i); + insn.acceptVisitor(defExtractor); + for (Variable definedVar : defExtractor.getDefinedVariables()) { + if (variableSet.remove(definedVar)) { + AssignInstruction copyInsn = new AssignInstruction(); + copyInsn.setReceiver(joint.getReceiver()); + copyInsn.setAssignee(definedVar); + block.getInstructions().add(i, copyInsn); + } + } + } + + for (Variable enteringVar : variableSet) { + AssignInstruction copyInsn = new AssignInstruction(); + copyInsn.setReceiver(joint.getReceiver()); + copyInsn.setAssignee(enteringVar); + block.getInstructions().add(0, copyInsn); + } + } + private void insertPhiArgumentsCopies(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { Map blockMap = new HashMap<>(); @@ -147,12 +195,8 @@ public class RegisterAllocator { } private boolean isExceptionHandler(Incoming incoming) { - for (TryCatchBlock tryCatch : incoming.getSource().getTryCatchBlocks()) { - if (tryCatch.getExceptionVariable() == incoming.getValue()) { - return true; - } - } - return false; + return incoming.getSource().getTryCatchJoints().stream().anyMatch( + joint -> joint.getReceiver() == incoming.getValue()); } private void removeRedundantCopies(Program program, List interferenceGraph, @@ -257,6 +301,11 @@ public class RegisterAllocator { classes.union(phi.getReceiver().getIndex(), incoming.getValue().getIndex()); } } + for (TryCatchJoint joint : block.getTryCatchJoints()) { + 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 7f36e819f..0c79aa76a 100644 --- a/core/src/main/java/org/teavm/model/util/TypeInferer.java +++ b/core/src/main/java/org/teavm/model/util/TypeInferer.java @@ -51,6 +51,11 @@ public class TypeInferer { builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); } } + for (TryCatchJointReader joint : block.readTryCatchJoints()) { + for (VariableReader sourceVar : joint.readSourceVariables()) { + builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex()); + } + } for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { if (tryCatch.getExceptionVariable() != null) { types[tryCatch.getExceptionVariable().getIndex()] = VariableType.OBJECT; diff --git a/core/src/main/java/org/teavm/optimization/EmptyBlockElimination.java b/core/src/main/java/org/teavm/optimization/EmptyBlockElimination.java index 27dd8ff2b..8150dc788 100644 --- a/core/src/main/java/org/teavm/optimization/EmptyBlockElimination.java +++ b/core/src/main/java/org/teavm/optimization/EmptyBlockElimination.java @@ -35,8 +35,8 @@ public class EmptyBlockElimination implements MethodOptimization { int lastNonEmpty = program.basicBlockCount() - 1; for (int i = program.basicBlockCount() - 2; i > 0; --i) { BasicBlock block = program.basicBlockAt(i); - if (block.getPhis().isEmpty() && block.getInstructions().size() == 1 - && block.getLastInstruction() instanceof JumpInstruction) { + if (block.getPhis().isEmpty() && block.getTryCatchJoints().isEmpty() + && block.getInstructions().size() == 1 && block.getLastInstruction() instanceof JumpInstruction) { JumpInstruction insn = (JumpInstruction) block.getLastInstruction(); if (insn.getTarget().getIndex() == i + 1) { blockMapping[i] = lastNonEmpty; diff --git a/core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java b/core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java index a49106e95..b618b0cfe 100644 --- a/core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java +++ b/core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java @@ -24,10 +24,6 @@ import org.teavm.model.*; import org.teavm.model.instructions.*; import org.teavm.model.util.ProgramUtils; -/** - * - * @author Alexey Andreev - */ public class GlobalValueNumbering implements MethodOptimization { private Map knownValues = new HashMap<>(); private boolean eliminate; @@ -52,7 +48,8 @@ public class GlobalValueNumbering implements MethodOptimization { for (int i = 0; i < map.length; ++i) { map[i] = i; } - List> outgoings = findOutgoings(program); + List> outgoings = ProgramUtils.getPhiOutputs(program); + List> outputJoints = ProgramUtils.getOutputJoints(program); int[] stack = new int[cfg.size() * 2]; int top = 0; @@ -95,19 +92,17 @@ public class GlobalValueNumbering implements MethodOptimization { eliminate = false; } } + for (TryCatchJoint joint : outputJoints.get(v)) { + 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)); } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (TryCatchJoint joint : tryCatch.getJoints()) { - joint.setTargetVariable(program.variableAt(map[joint.getTargetVariable().getIndex()])); - for (int i = 0; i < joint.getSourceVariables().size(); ++i) { - int var = joint.getSourceVariables().get(i).getIndex(); - var = map[var]; - joint.getSourceVariables().set(i, program.variableAt(var)); - } - } if (tryCatch.getExceptionVariable() != null) { int var = map[tryCatch.getExceptionVariable().getIndex()]; tryCatch.setExceptionVariable(program.variableAt(var)); @@ -131,21 +126,6 @@ public class GlobalValueNumbering implements MethodOptimization { this.program = null; } - private List> findOutgoings(Program program) { - List> outgoings = new ArrayList<>(); - for (int i = 0; i < program.basicBlockCount(); ++i) { - outgoings.add(new ArrayList<>()); - } - for (int i = 0; i < program.basicBlockCount(); ++i) { - for (Phi phi : program.basicBlockAt(i).getPhis()) { - for (Incoming incoming : phi.getIncomings()) { - outgoings.get(incoming.getSource().getIndex()).add(incoming); - } - } - } - return outgoings; - } - private void bind(int var, String value) { KnownValue known = knownValues.get(value); if (known != null && domTree.dominates(known.location, currentBlockIndex) && known.value != var) { diff --git a/core/src/main/java/org/teavm/optimization/LoopInvariantMotion.java b/core/src/main/java/org/teavm/optimization/LoopInvariantMotion.java index 9032a237f..4f868651f 100644 --- a/core/src/main/java/org/teavm/optimization/LoopInvariantMotion.java +++ b/core/src/main/java/org/teavm/optimization/LoopInvariantMotion.java @@ -165,18 +165,18 @@ public class LoopInvariantMotion implements MethodOptimization { } private int insertPreheader(int headerIndex) { - final BasicBlock preheader = program.createBasicBlock(); + BasicBlock preheader = program.createBasicBlock(); JumpInstruction escapeInsn = new JumpInstruction(); - final BasicBlock header = program.basicBlockAt(headerIndex); + BasicBlock header = program.basicBlockAt(headerIndex); escapeInsn.setTarget(header); preheader.getInstructions().add(escapeInsn); - for (int i = 0; i < header.getPhis().size(); ++i) { - Phi phi = header.getPhis().get(i); + + for (Phi phi : header.getPhis()) { Phi preheaderPhi = null; - for (int j = 0; j < phi.getIncomings().size(); ++j) { - Incoming incoming = phi.getIncomings().get(j); + for (int i = 0; i < phi.getIncomings().size(); ++i) { + Incoming incoming = phi.getIncomings().get(i); if (!dom.dominates(headerIndex, incoming.getSource().getIndex())) { - phi.getIncomings().remove(j--); + phi.getIncomings().remove(i--); if (preheaderPhi == null) { preheaderPhi = new Phi(); preheaderPhi.setReceiver(program.createVariable()); @@ -192,6 +192,7 @@ public class LoopInvariantMotion implements MethodOptimization { phi.getIncomings().add(incoming); } } + for (int predIndex : graph.incomingEdges(headerIndex)) { if (!dom.dominates(headerIndex, predIndex)) { BasicBlock pred = program.basicBlockAt(predIndex); @@ -199,6 +200,7 @@ public class LoopInvariantMotion implements MethodOptimization { block -> block == header.getIndex() ? preheader.getIndex() : block)); } } + return preheader.getIndex(); } diff --git a/core/src/main/java/org/teavm/optimization/LoopInversionImpl.java b/core/src/main/java/org/teavm/optimization/LoopInversionImpl.java index b5ad75474..20de56b2d 100644 --- a/core/src/main/java/org/teavm/optimization/LoopInversionImpl.java +++ b/core/src/main/java/org/teavm/optimization/LoopInversionImpl.java @@ -277,12 +277,15 @@ class LoopInversionImpl { tryCatchCopy.setExceptionVariable(tryCatch.getExceptionVariable()); tryCatchCopy.setHandler(program.basicBlockAt(copiedNodes.getOrDefault(handler, handler))); targetBlock.getTryCatchBlocks().add(tryCatchCopy); - for (TryCatchJoint joint : tryCatch.getJoints()) { - TryCatchJoint jointCopy = new TryCatchJoint(); - jointCopy.setTargetVariable(joint.getTargetVariable()); - jointCopy.getSourceVariables().addAll(joint.getSourceVariables()); - tryCatchCopy.getJoints().add(joint); - } + } + + for (TryCatchJoint joint : sourceBlock.getTryCatchJoints()) { + TryCatchJoint jointCopy = new TryCatchJoint(); + jointCopy.setReceiver(joint.getReceiver()); + jointCopy.getSourceVariables().addAll(joint.getSourceVariables()); + int source = joint.getSource().getIndex(); + jointCopy.setSource(program.basicBlockAt(copiedNodes.getOrDefault(source, source))); + targetBlock.getTryCatchJoints().add(joint); } } diff --git a/core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java b/core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java index 61fb411ed..a1a9c2c0f 100644 --- a/core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java +++ b/core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java @@ -19,10 +19,6 @@ import org.teavm.common.Graph; import org.teavm.model.*; import org.teavm.model.instructions.*; -/** - * - * @author Alexey Andreev - */ public class UnusedVariableElimination implements MethodOptimization { @Override public void optimize(MethodReader method, Program program) { @@ -64,20 +60,18 @@ public class UnusedVariableElimination implements MethodOptimization { block.getInstructions().remove(j--); } } + for (int j = 0; j < block.getTryCatchJoints().size(); ++j) { + TryCatchJoint joint = block.getTryCatchJoints().get(j); + if (!used[joint.getReceiver().getIndex()]) { + block.getTryCatchJoints().remove(j--); + } + } for (int j = 0; j < block.getPhis().size(); ++j) { Phi phi = block.getPhis().get(j); if (!used[phi.getReceiver().getIndex()]) { block.getPhis().remove(j--); } } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - for (int j = 0; j < tryCatch.getJoints().size(); ++j) { - TryCatchJoint joint = tryCatch.getJoints().get(j); - if (!used[joint.getTargetVariable().getIndex()]) { - tryCatch.getJoints().remove(j--); - } - } - } } } diff --git a/core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java b/core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java index 1fc0e5bc8..2d640a822 100644 --- a/core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java +++ b/core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java @@ -20,10 +20,6 @@ import org.teavm.common.GraphBuilder; import org.teavm.model.*; import org.teavm.model.instructions.*; -/** - * - * @author Alexey Andreev - */ public final class VariableUsageGraphBuilder { private VariableUsageGraphBuilder() { } @@ -41,6 +37,11 @@ public final class VariableUsageGraphBuilder { builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); } } + for (TryCatchJoint joint : block.getTryCatchJoints()) { + for (Variable sourceVar : joint.getSourceVariables()) { + builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex()); + } + } } return builder.build(); } diff --git a/core/src/main/java/org/teavm/vm/TeaVM.java b/core/src/main/java/org/teavm/vm/TeaVM.java index b724671a6..d76455cd5 100644 --- a/core/src/main/java/org/teavm/vm/TeaVM.java +++ b/core/src/main/java/org/teavm/vm/TeaVM.java @@ -712,7 +712,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { } private List getOptimizations() { - return Arrays.asList(new ArrayUnwrapMotion(), new LoopInversion(), new LoopInvariantMotion(), + return Arrays.asList(new ArrayUnwrapMotion(), /*new LoopInversion(),*/ new LoopInvariantMotion(), new GlobalValueNumbering(), new UnusedVariableElimination()); } 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 07f2beb81..1c14b2588 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 @@ -29,6 +29,7 @@ import org.teavm.model.MethodReference; import org.teavm.model.PhiReader; import org.teavm.model.ProgramReader; import org.teavm.model.RuntimeConstant; +import org.teavm.model.TryCatchJointReader; import org.teavm.model.ValueType; import org.teavm.model.VariableReader; import org.teavm.model.instructions.ArrayElementType; @@ -64,6 +65,14 @@ class AliasFinder { set.union(inputs.iterator().next(), phi.getReceiver().getIndex()); } } + for (TryCatchJointReader joint : block.readTryCatchJoints()) { + Set 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 d96b572a2..c0c8d4c07 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,6 +29,7 @@ import org.teavm.model.MethodReference; import org.teavm.model.Phi; import org.teavm.model.PrimitiveType; import org.teavm.model.Program; +import org.teavm.model.TryCatchJoint; import org.teavm.model.ValueType; import org.teavm.model.Variable; import org.teavm.model.instructions.AssignInstruction; @@ -110,6 +111,11 @@ public class BoxingElimination { union(phi.getReceiver().getIndex(), incoming.getValue().getIndex()); } } + for (TryCatchJoint joint : block.getTryCatchJoints()) { + for (Variable sourceVar : joint.getSourceVariables()) { + union(sourceVar.getIndex(), joint.getReceiver().getIndex()); + } + } } }