mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 00:14:10 -08:00
Further refactoring of exception handling
This commit is contained in:
parent
a26eed7c51
commit
e82518b88f
|
@ -66,8 +66,8 @@ public class ProgramIO {
|
||||||
data.writeInt(tryCatch.getExceptionType() != null ? symbolTable.lookup(
|
data.writeInt(tryCatch.getExceptionType() != null ? symbolTable.lookup(
|
||||||
tryCatch.getExceptionType()) : -1);
|
tryCatch.getExceptionType()) : -1);
|
||||||
data.writeShort(tryCatch.getHandler().getIndex());
|
data.writeShort(tryCatch.getHandler().getIndex());
|
||||||
data.writeShort(tryCatch.getTryCatchJoints().size());
|
data.writeShort(tryCatch.getJoints().size());
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
data.writeShort(joint.getReceiver().getIndex());
|
data.writeShort(joint.getReceiver().getIndex());
|
||||||
data.writeShort(joint.getSourceVariables().size());
|
data.writeShort(joint.getSourceVariables().size());
|
||||||
for (Variable sourceVar : joint.getSourceVariables()) {
|
for (Variable sourceVar : joint.getSourceVariables()) {
|
||||||
|
@ -152,7 +152,7 @@ public class ProgramIO {
|
||||||
for (int m = 0; m < jointSourceCount; ++m) {
|
for (int m = 0; m < jointSourceCount; ++m) {
|
||||||
joint.getSourceVariables().add(program.variableAt(data.readShort()));
|
joint.getSourceVariables().add(program.variableAt(data.readShort()));
|
||||||
}
|
}
|
||||||
tryCatch.getTryCatchJoints().add(joint);
|
tryCatch.getJoints().add(joint);
|
||||||
}
|
}
|
||||||
|
|
||||||
block.getTryCatchBlocks().add(tryCatch);
|
block.getTryCatchBlocks().add(tryCatch);
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class DataFlowGraphBuilder implements InstructionReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
||||||
for (TryCatchJointReader joint : tryCatch.readTryCatchJoints()) {
|
for (TryCatchJointReader joint : tryCatch.readJoints()) {
|
||||||
for (VariableReader sourceVar : joint.readSourceVariables()) {
|
for (VariableReader sourceVar : joint.readSourceVariables()) {
|
||||||
builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ class DependencyGraphBuilder {
|
||||||
dependencyChecker.linkClass(tryCatch.getExceptionType(), new CallLocation(caller.getMethod()));
|
dependencyChecker.linkClass(tryCatch.getExceptionType(), new CallLocation(caller.getMethod()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TryCatchJointReader joint : tryCatch.readTryCatchJoints()) {
|
for (TryCatchJointReader joint : tryCatch.readJoints()) {
|
||||||
DependencyNode receiverNode = nodes[joint.getReceiver().getIndex()];
|
DependencyNode receiverNode = nodes[joint.getReceiver().getIndex()];
|
||||||
if (receiverNode == null) {
|
if (receiverNode == null) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -289,7 +289,9 @@ class DependencyGraphBuilder {
|
||||||
if (tryCatch.getExceptionType() != null) {
|
if (tryCatch.getExceptionType() != null) {
|
||||||
exceptions[i] = dependencyChecker.getClassSource().get(tryCatch.getExceptionType());
|
exceptions[i] = dependencyChecker.getClassSource().get(tryCatch.getExceptionType());
|
||||||
}
|
}
|
||||||
vars[i] = methodDep.getVariable(tryCatch.getHandler().getExceptionVariable().getIndex());
|
if (tryCatch.getHandler().getExceptionVariable() != null) {
|
||||||
|
vars[i] = methodDep.getVariable(tryCatch.getHandler().getExceptionVariable().getIndex());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new ExceptionConsumer(dependencyChecker, exceptions, vars, methodDep);
|
return new ExceptionConsumer(dependencyChecker, exceptions, vars, methodDep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ class ReadWriteStatsBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
writes[joint.getReceiver().getIndex()] += joint.getSourceVariables().size();
|
writes[joint.getReceiver().getIndex()] += joint.getSourceVariables().size();
|
||||||
for (Variable var : joint.getSourceVariables()) {
|
for (Variable var : joint.getSourceVariables()) {
|
||||||
reads[var.getIndex()]++;
|
reads[var.getIndex()]++;
|
||||||
|
|
|
@ -111,6 +111,9 @@ public class Program implements ProgramReader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Variable variableAt(int index) {
|
public Variable variableAt(int index) {
|
||||||
|
if (index < 0) {
|
||||||
|
throw new IllegalArgumentException("Index " + index + " is negative");
|
||||||
|
}
|
||||||
return variables.get(index);
|
return variables.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,12 +97,12 @@ public class TryCatchBlock implements TryCatchBlockReader {
|
||||||
return protectedBlock;
|
return protectedBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TryCatchJoint> getTryCatchJoints() {
|
public List<TryCatchJoint> getJoints() {
|
||||||
return safeJoints;
|
return safeJoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TryCatchJointReader> readTryCatchJoints() {
|
public List<TryCatchJointReader> readJoints() {
|
||||||
if (immutableJoints == null) {
|
if (immutableJoints == null) {
|
||||||
immutableJoints = Collections.unmodifiableList(safeJoints);
|
immutableJoints = Collections.unmodifiableList(safeJoints);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,5 @@ public interface TryCatchBlockReader {
|
||||||
|
|
||||||
String getExceptionType();
|
String getExceptionType();
|
||||||
|
|
||||||
List<TryCatchJointReader> readTryCatchJoints();
|
List<TryCatchJointReader> readJoints();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class InstructionVariableMapper implements InstructionVisitor {
|
||||||
|
|
||||||
public void applyToTryCatchBlocks(BasicBlock block) {
|
public void applyToTryCatchBlocks(BasicBlock block) {
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
joint.setReceiver(map(joint.getReceiver()));
|
joint.setReceiver(map(joint.getReceiver()));
|
||||||
for (int i = 0; i < joint.getSourceVariables().size(); ++i) {
|
for (int i = 0; i < joint.getSourceVariables().size(); ++i) {
|
||||||
Variable var = joint.getSourceVariables().get(i);
|
Variable var = joint.getSourceVariables().get(i);
|
||||||
|
|
|
@ -53,7 +53,7 @@ class InterferenceGraphBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
for (Variable sourceVar : joint.getSourceVariables()) {
|
for (Variable sourceVar : joint.getSourceVariables()) {
|
||||||
live.add(nodes.get(sourceVar.getIndex()));
|
live.add(nodes.get(sourceVar.getIndex()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class ListingBuilder {
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
sb.append(prefix).append("var @").append(i);
|
sb.append(prefix).append("var @").append(i);
|
||||||
VariableReader var = program.variableAt(i);
|
VariableReader var = program.variableAt(i);
|
||||||
if (!var.readDebugNames().isEmpty()) {
|
if (var != null && !var.readDebugNames().isEmpty()) {
|
||||||
sb.append(" as ");
|
sb.append(" as ");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String debugName : var.readDebugNames()) {
|
for (String debugName : var.readDebugNames()) {
|
||||||
|
@ -49,7 +49,7 @@ public class ListingBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block.getExceptionVariable() != null) {
|
if (block.getExceptionVariable() != null) {
|
||||||
sb.append("@").append(block.getExceptionVariable().getIndex()).append(" = exception");
|
sb.append(" @").append(block.getExceptionVariable().getIndex()).append(" = exception\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PhiReader phi : block.readPhis()) {
|
for (PhiReader phi : block.readPhis()) {
|
||||||
|
@ -82,7 +82,7 @@ public class ListingBuilder {
|
||||||
sb.append(prefix).append(" catch ").append(tryCatch.getExceptionType())
|
sb.append(prefix).append(" catch ").append(tryCatch.getExceptionType())
|
||||||
.append(" -> $").append(tryCatch.getHandler().getIndex());
|
.append(" -> $").append(tryCatch.getHandler().getIndex());
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
for (TryCatchJointReader joint : tryCatch.readTryCatchJoints()) {
|
for (TryCatchJointReader joint : tryCatch.readJoints()) {
|
||||||
sb.append(" @").append(joint.getReceiver().getIndex()).append(" := e-phi(");
|
sb.append(" @").append(joint.getReceiver().getIndex()).append(" := e-phi(");
|
||||||
sb.append(joint.readSourceVariables().stream().map(sourceVar -> "@" + sourceVar.getIndex())
|
sb.append(joint.readSourceVariables().stream().map(sourceVar -> "@" + sourceVar.getIndex())
|
||||||
.collect(Collectors.joining(", ")));
|
.collect(Collectors.joining(", ")));
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class LivenessAnalyzer {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
definitions[joint.getReceiver().getIndex()] = i;
|
definitions[joint.getReceiver().getIndex()] = i;
|
||||||
for (Variable sourceVar : joint.getSourceVariables()) {
|
for (Variable sourceVar : joint.getSourceVariables()) {
|
||||||
Task task = new Task();
|
Task task = new Task();
|
||||||
|
|
|
@ -15,11 +15,16 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.util;
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.IntOpenHashSet;
|
||||||
|
import com.carrotsearch.hppc.IntSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.teavm.common.DominatorTree;
|
import org.teavm.common.DominatorTree;
|
||||||
import org.teavm.common.Graph;
|
import org.teavm.common.Graph;
|
||||||
import org.teavm.common.GraphUtils;
|
import org.teavm.common.GraphUtils;
|
||||||
|
@ -78,8 +83,10 @@ public class PhiUpdater {
|
||||||
private BasicBlock currentBlock;
|
private BasicBlock currentBlock;
|
||||||
private Phi[][] phiMap;
|
private Phi[][] phiMap;
|
||||||
private int[][] phiIndexMap;
|
private int[][] phiIndexMap;
|
||||||
private List<Map<BasicBlock, Map<Variable, TryCatchJoint>>> jointMap = new ArrayList<>();
|
private Map<TryCatchBlock, Map<Variable, TryCatchJoint>> jointMap = new HashMap<>();
|
||||||
private List<List<Phi>> synthesizedPhis = new ArrayList<>();
|
private List<List<Phi>> synthesizedPhis = new ArrayList<>();
|
||||||
|
private List<List<List<TryCatchJoint>>> synthesizedJoints = new ArrayList<>();
|
||||||
|
private Variable[] originalExceptionVariables;
|
||||||
private boolean[] usedDefinitions;
|
private boolean[] usedDefinitions;
|
||||||
|
|
||||||
public void updatePhis(Program program, Variable[] arguments) {
|
public void updatePhis(Program program, Variable[] arguments) {
|
||||||
|
@ -98,18 +105,28 @@ public class PhiUpdater {
|
||||||
}
|
}
|
||||||
phiMap = new Phi[program.basicBlockCount()][];
|
phiMap = new Phi[program.basicBlockCount()][];
|
||||||
phiIndexMap = new int[program.basicBlockCount()][];
|
phiIndexMap = new int[program.basicBlockCount()][];
|
||||||
jointMap = new ArrayList<>();
|
jointMap.clear();
|
||||||
for (int i = 0; i < phiMap.length; ++i) {
|
for (int i = 0; i < phiMap.length; ++i) {
|
||||||
phiMap[i] = new Phi[program.variableCount()];
|
phiMap[i] = new Phi[program.variableCount()];
|
||||||
phiIndexMap[i] = new int[program.variableCount()];
|
phiIndexMap[i] = new int[program.variableCount()];
|
||||||
jointMap.add(new HashMap<>());
|
|
||||||
}
|
}
|
||||||
domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree);
|
domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree);
|
||||||
|
|
||||||
synthesizedPhis.clear();
|
synthesizedPhis.clear();
|
||||||
|
synthesizedJoints.clear();
|
||||||
|
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
synthesizedPhis.add(new ArrayList<>());
|
synthesizedPhis.add(new ArrayList<>());
|
||||||
|
synthesizedJoints.add(new ArrayList<>());
|
||||||
|
int catchCount = program.basicBlockAt(i).getTryCatchBlocks().size();
|
||||||
|
for (int j = 0; j < catchCount; ++j) {
|
||||||
|
synthesizedJoints.get(i).add(new ArrayList<>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
originalExceptionVariables = new Variable[program.basicBlockCount()];
|
||||||
|
Arrays.setAll(originalExceptionVariables, i -> program.basicBlockAt(i).getExceptionVariable());
|
||||||
|
|
||||||
estimatePhis();
|
estimatePhis();
|
||||||
renameVariables();
|
renameVariables();
|
||||||
}
|
}
|
||||||
|
@ -128,14 +145,22 @@ public class PhiUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Instruction insn : currentBlock.getInstructions()) {
|
for (Instruction insn : currentBlock.getInstructions()) {
|
||||||
|
currentBlock = program.basicBlockAt(i);
|
||||||
insn.acceptVisitor(definitionExtractor);
|
insn.acceptVisitor(definitionExtractor);
|
||||||
|
Set<Variable> definedVariables = new HashSet<>();
|
||||||
for (Variable var : definitionExtractor.getDefinedVariables()) {
|
for (Variable var : definitionExtractor.getDefinedVariables()) {
|
||||||
markAssignment(var);
|
markAssignment(var);
|
||||||
|
definedVariables.add(var);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
|
Set<BasicBlock> handlers = currentBlock.getTryCatchBlocks().stream()
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
.map(tryCatch -> tryCatch.getHandler())
|
||||||
markAssignment(joint.getReceiver());
|
.collect(Collectors.toSet());
|
||||||
|
for (BasicBlock handler : handlers) {
|
||||||
|
currentBlock = handler;
|
||||||
|
for (Variable var : definedVariables) {
|
||||||
|
markAssignment(var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +169,6 @@ public class PhiUpdater {
|
||||||
private static class Task {
|
private static class Task {
|
||||||
Variable[] variables;
|
Variable[] variables;
|
||||||
BasicBlock block;
|
BasicBlock block;
|
||||||
TryCatchBlock tryCatch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renameVariables() {
|
private void renameVariables() {
|
||||||
|
@ -156,7 +180,7 @@ public class PhiUpdater {
|
||||||
if (domGraph.incomingEdgesCount(i) == 0) {
|
if (domGraph.incomingEdgesCount(i) == 0) {
|
||||||
Task task = new Task();
|
Task task = new Task();
|
||||||
task.block = program.basicBlockAt(i);
|
task.block = program.basicBlockAt(i);
|
||||||
task.variables = Arrays.copyOf(variableMap, variableMap.length);
|
task.variables = variableMap.clone();
|
||||||
stack[head++] = task;
|
stack[head++] = task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,63 +190,68 @@ public class PhiUpdater {
|
||||||
while (head > 0) {
|
while (head > 0) {
|
||||||
Task task = stack[--head];
|
Task task = stack[--head];
|
||||||
|
|
||||||
if (task.tryCatch != null) {
|
currentBlock = task.block;
|
||||||
TryCatchBlock tryCatch = task.tryCatch;
|
int index = currentBlock.getIndex();
|
||||||
if (domTree.dominates(tryCatch.getProtectedBlock().getIndex(), tryCatch.getHandler().getIndex())) {
|
variableMap = task.variables.clone();
|
||||||
Task next = new Task();
|
|
||||||
next.block = tryCatch.getProtectedBlock();
|
if (currentBlock.getExceptionVariable() != null) {
|
||||||
next.variables = Arrays.copyOf(variableMap, variableMap.length);
|
currentBlock.setExceptionVariable(define(currentBlock.getExceptionVariable()));
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
}
|
||||||
Variable mappedReceiver = introduce(joint.getReceiver());
|
|
||||||
for (Variable sourceVariable : joint.getSourceVariables()) {
|
for (Phi phi : synthesizedPhis.get(index)) {
|
||||||
next.variables[sourceVariable.getIndex()] = mappedReceiver;
|
Variable var = program.createVariable();
|
||||||
}
|
var.getDebugNames().addAll(phi.getReceiver().getDebugNames());
|
||||||
next.variables[joint.getReceiver().getIndex()] = mappedReceiver;
|
variableMap[phi.getReceiver().getIndex()] = var;
|
||||||
for (int i = 0; i < joint.getSourceVariables().size(); ++i) {
|
phi.setReceiver(var);
|
||||||
Variable var = joint.getSourceVariables().get(i);
|
}
|
||||||
joint.getSourceVariables().set(i, use(var));
|
for (Phi phi : currentBlock.getPhis()) {
|
||||||
}
|
phi.setReceiver(define(phi.getReceiver()));
|
||||||
joint.setReceiver(mappedReceiver);
|
}
|
||||||
|
|
||||||
|
for (Instruction insn : currentBlock.getInstructions()) {
|
||||||
|
insn.acceptVisitor(consumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Incoming output : phiOutputs.get(index)) {
|
||||||
|
Variable var = output.getValue();
|
||||||
|
output.setValue(use(var));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
|
||||||
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
|
for (int i = 0; i < joint.getSourceVariables().size(); ++i) {
|
||||||
|
joint.getSourceVariables().set(i, use(joint.getSourceVariables().get(i)));
|
||||||
}
|
}
|
||||||
stack[head++] = next;
|
joint.setReceiver(define(joint.getReceiver()));
|
||||||
}
|
}
|
||||||
renameOutgoingPhis(tryCatch.getHandler().getIndex());
|
}
|
||||||
} else {
|
|
||||||
currentBlock = task.block;
|
|
||||||
int index = currentBlock.getIndex();
|
|
||||||
variableMap = Arrays.copyOf(task.variables, task.variables.length);
|
|
||||||
|
|
||||||
for (Phi phi : synthesizedPhis.get(index)) {
|
IntSet catchSuccessors = new IntOpenHashSet();
|
||||||
Variable var = program.createVariable();
|
Variable[] regularVariableMap = variableMap;
|
||||||
var.getDebugNames().addAll(phi.getReceiver().getDebugNames());
|
Variable[] catchVariableMap = variableMap.clone();
|
||||||
propagateToTryCatch(phi.getReceiver(), var, null);
|
|
||||||
variableMap[phi.getReceiver().getIndex()] = var;
|
|
||||||
phi.setReceiver(var);
|
|
||||||
}
|
|
||||||
for (Phi phi : currentBlock.getPhis()) {
|
|
||||||
phi.setReceiver(define(phi.getReceiver()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Instruction insn : currentBlock.getInstructions()) {
|
variableMap = catchVariableMap;
|
||||||
insn.acceptVisitor(consumer);
|
for (int i = 0; i < currentBlock.getTryCatchBlocks().size(); ++i) {
|
||||||
|
TryCatchBlock tryCatch = currentBlock.getTryCatchBlocks().get(i);
|
||||||
|
catchSuccessors.add(tryCatch.getHandler().getIndex());
|
||||||
|
for (TryCatchJoint joint : synthesizedJoints.get(index).get(i)) {
|
||||||
|
joint.setReceiver(define(joint.getReceiver()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
variableMap = regularVariableMap;
|
||||||
|
|
||||||
for (Incoming output : phiOutputs.get(index)) {
|
int[] successors = domGraph.outgoingEdges(index);
|
||||||
Variable var = output.getValue();
|
for (int successor : successors) {
|
||||||
output.setValue(use(var));
|
Task next = new Task();
|
||||||
}
|
next.variables = (catchSuccessors.contains(successor) ? catchVariableMap : variableMap).clone();
|
||||||
|
next.block = program.basicBlockAt(successor);
|
||||||
|
stack[head++] = next;
|
||||||
|
}
|
||||||
|
|
||||||
int[] successors = domGraph.outgoingEdges(index);
|
successors = cfg.outgoingEdges(index);
|
||||||
for (int successor : successors) {
|
for (int successor : successors) {
|
||||||
Task next = new Task();
|
variableMap = catchSuccessors.contains(successor) ? catchVariableMap : variableMap;
|
||||||
next.variables = Arrays.copyOf(variableMap, variableMap.length);
|
renameOutgoingPhis(successor);
|
||||||
next.block = program.basicBlockAt(successor);
|
|
||||||
stack[head++] = next;
|
|
||||||
}
|
|
||||||
successors = cfg.outgoingEdges(index);
|
|
||||||
for (int successor : successors) {
|
|
||||||
renameOutgoingPhis(successor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,6 +261,17 @@ public class PhiUpdater {
|
||||||
program.basicBlockAt(i).getPhis().add(phi);
|
program.basicBlockAt(i).getPhis().add(phi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<List<TryCatchJoint>> joints = synthesizedJoints.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 (!joint.getSourceVariables().isEmpty()) {
|
||||||
|
targetTryCatch.getJoints().add(joint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,19 +336,28 @@ public class PhiUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void propagateToTryCatch(Variable original, Variable var, Variable old) {
|
private void propagateToTryCatch(Variable original, Variable var, Variable old) {
|
||||||
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
|
for (int i = 0; i < currentBlock.getTryCatchBlocks().size(); ++i) {
|
||||||
if (tryCatch.getHandler().getExceptionVariable() == original) {
|
TryCatchBlock tryCatch = currentBlock.getTryCatchBlocks().get(i);
|
||||||
|
if (originalExceptionVariables[tryCatch.getHandler().getIndex()] == original) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Variable, TryCatchJoint> joints = jointMap.get(tryCatch.getHandler().getIndex()).get(currentBlock);
|
Map<Variable, TryCatchJoint> joints = jointMap.get(tryCatch);
|
||||||
if (joints == null) {
|
if (joints == null) {
|
||||||
continue;
|
joints = new HashMap<>();
|
||||||
|
jointMap.put(tryCatch, joints);
|
||||||
}
|
}
|
||||||
TryCatchJoint joint = joints.get(original);
|
TryCatchJoint joint = joints.get(original);
|
||||||
if (joint == null) {
|
if (joint == null) {
|
||||||
|
joint = new TryCatchJoint();
|
||||||
|
joint.setReceiver(original);
|
||||||
|
joints.put(original, joint);
|
||||||
|
synthesizedJoints.get(currentBlock.getIndex()).get(i).add(joint);
|
||||||
|
}
|
||||||
|
if (joint.getReceiver() == var) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (joint.getSourceVariables().isEmpty() && old != null) {
|
if (joint.getSourceVariables().isEmpty() && old != null) {
|
||||||
joint.getSourceVariables().add(old);
|
joint.getSourceVariables().add(old);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ public final class ProgramUtils {
|
||||||
TryCatchBlock tryCatchCopy = new TryCatchBlock();
|
TryCatchBlock tryCatchCopy = new TryCatchBlock();
|
||||||
tryCatchCopy.setExceptionType(tryCatch.getExceptionType());
|
tryCatchCopy.setExceptionType(tryCatch.getExceptionType());
|
||||||
tryCatchCopy.setHandler(target.basicBlockAt(tryCatch.getHandler().getIndex()));
|
tryCatchCopy.setHandler(target.basicBlockAt(tryCatch.getHandler().getIndex()));
|
||||||
tryCatchCopy.getTryCatchJoints().addAll(copyTryCatchJoints(tryCatch, target));
|
tryCatchCopy.getJoints().addAll(copyTryCatchJoints(tryCatch, target));
|
||||||
result.add(tryCatchCopy);
|
result.add(tryCatchCopy);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -128,7 +128,7 @@ public final class ProgramUtils {
|
||||||
|
|
||||||
public static List<TryCatchJoint> copyTryCatchJoints(TryCatchBlockReader block, Program target) {
|
public static List<TryCatchJoint> copyTryCatchJoints(TryCatchBlockReader block, Program target) {
|
||||||
List<TryCatchJoint> result = new ArrayList<>();
|
List<TryCatchJoint> result = new ArrayList<>();
|
||||||
for (TryCatchJointReader joint : block.readTryCatchJoints()) {
|
for (TryCatchJointReader joint : block.readJoints()) {
|
||||||
TryCatchJoint jointCopy = new TryCatchJoint();
|
TryCatchJoint jointCopy = new TryCatchJoint();
|
||||||
jointCopy.setReceiver(target.variableAt(joint.getReceiver().getIndex()));
|
jointCopy.setReceiver(target.variableAt(joint.getReceiver().getIndex()));
|
||||||
for (VariableReader sourceVar : joint.readSourceVariables()) {
|
for (VariableReader sourceVar : joint.readSourceVariables()) {
|
||||||
|
@ -180,7 +180,7 @@ public final class ProgramUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
places[joint.getReceiver().getIndex()] = block;
|
places[joint.getReceiver().getIndex()] = block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class RegisterAllocator {
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
program.basicBlockAt(i).getPhis().clear();
|
program.basicBlockAt(i).getPhis().clear();
|
||||||
for (TryCatchBlock tryCatch : program.basicBlockAt(i).getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : program.basicBlockAt(i).getTryCatchBlocks()) {
|
||||||
tryCatch.getTryCatchJoints().clear();
|
tryCatch.getJoints().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ public class RegisterAllocator {
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
tryCatch.getTryCatchJoints().forEach(this::insertCopy);
|
tryCatch.getJoints().forEach(this::insertCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ public class RegisterAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
for (Variable sourceVar : joint.getSourceVariables()) {
|
for (Variable sourceVar : joint.getSourceVariables()) {
|
||||||
classes.union(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
classes.union(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class TypeInferer {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
||||||
for (TryCatchJointReader joint : tryCatch.readTryCatchJoints()) {
|
for (TryCatchJointReader joint : tryCatch.readJoints()) {
|
||||||
for (VariableReader sourceVar : joint.readSourceVariables()) {
|
for (VariableReader sourceVar : joint.readSourceVariables()) {
|
||||||
builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
for (int i = 0; i < joint.getSourceVariables().size(); ++i) {
|
for (int i = 0; i < joint.getSourceVariables().size(); ++i) {
|
||||||
int sourceVar = map[joint.getSourceVariables().get(i).getIndex()];
|
int sourceVar = map[joint.getSourceVariables().get(i).getIndex()];
|
||||||
joint.getSourceVariables().set(i, program.variableAt(sourceVar));
|
joint.getSourceVariables().set(i, program.variableAt(sourceVar));
|
||||||
|
|
|
@ -197,11 +197,11 @@ public class Inlining {
|
||||||
tryCatchCopy.setHandler(target.getProgram().basicBlockAt(handler));
|
tryCatchCopy.setHandler(target.getProgram().basicBlockAt(handler));
|
||||||
target.getTryCatchBlocks().add(tryCatchCopy);
|
target.getTryCatchBlocks().add(tryCatchCopy);
|
||||||
|
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
TryCatchJoint jointCopy = new TryCatchJoint();
|
TryCatchJoint jointCopy = new TryCatchJoint();
|
||||||
jointCopy.setReceiver(joint.getReceiver());
|
jointCopy.setReceiver(joint.getReceiver());
|
||||||
jointCopy.getSourceVariables().addAll(joint.getSourceVariables());
|
jointCopy.getSourceVariables().addAll(joint.getSourceVariables());
|
||||||
tryCatchCopy.getTryCatchJoints().add(joint);
|
tryCatchCopy.getJoints().add(joint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,11 +348,11 @@ class LoopInversionImpl {
|
||||||
tryCatchCopy.setHandler(program.basicBlockAt(copiedNodes.getOrDefault(handler, handler)));
|
tryCatchCopy.setHandler(program.basicBlockAt(copiedNodes.getOrDefault(handler, handler)));
|
||||||
targetBlock.getTryCatchBlocks().add(tryCatchCopy);
|
targetBlock.getTryCatchBlocks().add(tryCatchCopy);
|
||||||
|
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
TryCatchJoint jointCopy = new TryCatchJoint();
|
TryCatchJoint jointCopy = new TryCatchJoint();
|
||||||
jointCopy.setReceiver(joint.getReceiver());
|
jointCopy.setReceiver(joint.getReceiver());
|
||||||
jointCopy.getSourceVariables().addAll(joint.getSourceVariables());
|
jointCopy.getSourceVariables().addAll(joint.getSourceVariables());
|
||||||
tryCatchCopy.getTryCatchJoints().add(joint);
|
tryCatchCopy.getJoints().add(joint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ public class UnusedVariableElimination implements MethodOptimization {
|
||||||
InstructionOptimizer insnOptimizer = new InstructionOptimizer(used);
|
InstructionOptimizer insnOptimizer = new InstructionOptimizer(used);
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
if (block.getExceptionVariable() != null && !used[block.getExceptionVariable().getIndex()]) {
|
||||||
|
block.setExceptionVariable(null);
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < block.getInstructions().size(); ++j) {
|
for (int j = 0; j < block.getInstructions().size(); ++j) {
|
||||||
insnOptimizer.eliminate = false;
|
insnOptimizer.eliminate = false;
|
||||||
block.getInstructions().get(j).acceptVisitor(insnOptimizer);
|
block.getInstructions().get(j).acceptVisitor(insnOptimizer);
|
||||||
|
@ -62,10 +66,10 @@ public class UnusedVariableElimination implements MethodOptimization {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (int j = 0; j < tryCatch.getTryCatchJoints().size(); ++j) {
|
for (int j = 0; j < tryCatch.getJoints().size(); ++j) {
|
||||||
TryCatchJoint joint = tryCatch.getTryCatchJoints().get(j);
|
TryCatchJoint joint = tryCatch.getJoints().get(j);
|
||||||
if (!used[joint.getReceiver().getIndex()]) {
|
if (!used[joint.getReceiver().getIndex()]) {
|
||||||
tryCatch.getTryCatchJoints().remove(j--);
|
tryCatch.getJoints().remove(j--);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public final class VariableUsageGraphBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
for (Variable sourceVar : joint.getSourceVariables()) {
|
for (Variable sourceVar : joint.getSourceVariables()) {
|
||||||
builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
builder.addEdge(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ class AliasFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
||||||
for (TryCatchJointReader joint : tryCatch.readTryCatchJoints()) {
|
for (TryCatchJointReader joint : tryCatch.readJoints()) {
|
||||||
Set<Integer> inputs = joint.readSourceVariables().stream()
|
Set<Integer> inputs = joint.readSourceVariables().stream()
|
||||||
.map(sourceVar -> sourceVar.getIndex())
|
.map(sourceVar -> sourceVar.getIndex())
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
|
@ -113,7 +113,7 @@ public class BoxingElimination {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
for (TryCatchJoint joint : tryCatch.getTryCatchJoints()) {
|
for (TryCatchJoint joint : tryCatch.getJoints()) {
|
||||||
for (Variable sourceVar : joint.getSourceVariables()) {
|
for (Variable sourceVar : joint.getSourceVariables()) {
|
||||||
union(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
union(sourceVar.getIndex(), joint.getReceiver().getIndex());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user