Further work on incremental phi updater

This commit is contained in:
Alexey Andreev 2016-06-05 23:06:09 +03:00
parent d196eb9864
commit 9fc6f02875
6 changed files with 80 additions and 83 deletions

View File

@ -139,9 +139,14 @@ class DependencyGraphBuilder {
block.readAllInstructions(reader); block.readAllInstructions(reader);
for (TryCatchJointReader joint : block.readTryCatchJoints()) { for (TryCatchJointReader joint : block.readTryCatchJoints()) {
DependencyNode receiverNode = nodes[joint.getReceiver().getIndex()]; DependencyNode receiverNode = nodes[joint.getReceiver().getIndex()];
if (receiverNode == null) {
continue;
}
for (VariableReader source : joint.readSourceVariables()) { for (VariableReader source : joint.readSourceVariables()) {
DependencyNode sourceNode = nodes[source.getIndex()]; DependencyNode sourceNode = nodes[source.getIndex()];
sourceNode.connect(receiverNode); if (sourceNode != null) {
sourceNode.connect(receiverNode);
}
} }
} }
for (PhiReader phi : block.readPhis()) { for (PhiReader phi : block.readPhis()) {

View File

@ -25,7 +25,7 @@ public class BasicBlock implements BasicBlockReader {
private List<Instruction> instructions = new ArrayList<>(); private List<Instruction> instructions = new ArrayList<>();
private List<TryCatchBlock> tryCatchBlocks = new ArrayList<>(); private List<TryCatchBlock> tryCatchBlocks = new ArrayList<>();
private List<TryCatchJoint> joints = new ArrayList<>(); private List<TryCatchJoint> joints = new ArrayList<>();
private List<TryCatchJointReader> immutableJoints = new ArrayList<>(); private List<TryCatchJointReader> immutableJoints;
BasicBlock(Program program, int index) { BasicBlock(Program program, int index) {
this.program = program; this.program = program;

View File

@ -49,7 +49,7 @@ public class ListingBuilder {
} }
for (TryCatchJointReader joint : block.readTryCatchJoints()) { for (TryCatchJointReader joint : block.readTryCatchJoints()) {
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(", ")));
sb.append(") from $").append(joint.getSource().getIndex()).append("\n"); sb.append(") from $").append(joint.getSource().getIndex()).append("\n");

View File

@ -15,11 +15,6 @@
*/ */
package org.teavm.model.util; package org.teavm.model.util;
import com.carrotsearch.hppc.IntObjectMap;
import com.carrotsearch.hppc.IntObjectOpenHashMap;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -29,13 +24,9 @@ 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;
import org.teavm.model.BasicBlock; import org.teavm.model.BasicBlock;
import org.teavm.model.ClassHolder;
import org.teavm.model.ClassHolderSource;
import org.teavm.model.Incoming; import org.teavm.model.Incoming;
import org.teavm.model.Instruction; import org.teavm.model.Instruction;
import org.teavm.model.InvokeDynamicInstruction; import org.teavm.model.InvokeDynamicInstruction;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodHolder;
import org.teavm.model.Phi; import org.teavm.model.Phi;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.TryCatchBlock; import org.teavm.model.TryCatchBlock;
@ -78,7 +69,6 @@ import org.teavm.model.instructions.RaiseInstruction;
import org.teavm.model.instructions.StringConstantInstruction; import org.teavm.model.instructions.StringConstantInstruction;
import org.teavm.model.instructions.SwitchInstruction; import org.teavm.model.instructions.SwitchInstruction;
import org.teavm.model.instructions.UnwrapArrayInstruction; import org.teavm.model.instructions.UnwrapArrayInstruction;
import org.teavm.parsing.ClasspathClassHolderSource;
public class PhiUpdater { public class PhiUpdater {
private Program program; private Program program;
@ -205,15 +195,11 @@ public class PhiUpdater {
insn.acceptVisitor(consumer); insn.acceptVisitor(consumer);
} }
IntObjectMap<IntObjectMap<Variable>> exceptionVariableMap = new IntObjectOpenHashMap<>();
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
IntObjectMap<Variable> tryCatchVariableMap = new IntObjectOpenHashMap<>();
exceptionVariableMap.put(tryCatch.getHandler().getIndex(), tryCatchVariableMap);
Variable var = tryCatch.getExceptionVariable(); Variable var = tryCatch.getExceptionVariable();
if (var != null) { if (var != null) {
Variable newVar = introduce(var); Variable newVar = introduce(var, true);
tryCatch.setExceptionVariable(newVar); tryCatch.setExceptionVariable(newVar);
tryCatchVariableMap.put(var.getIndex(), newVar);
} }
} }
@ -236,18 +222,11 @@ public class PhiUpdater {
} }
successors = cfg.outgoingEdges(index); successors = cfg.outgoingEdges(index);
for (int successor : successors) { for (int successor : successors) {
IntObjectMap<Variable> tryCatchVariableMap = exceptionVariableMap.get(successor);
int[] phiIndexes = phiIndexMap[successor]; int[] phiIndexes = phiIndexMap[successor];
List<Phi> phis = synthesizedPhis.get(successor); List<Phi> phis = synthesizedPhis.get(successor);
for (int j = 0; j < phis.size(); ++j) { for (int j = 0; j < phis.size(); ++j) {
Phi phi = phis.get(j); Phi phi = phis.get(j);
Variable var = null; Variable var = variableMap[phiIndexes[j]];
if (tryCatchVariableMap != null) {
var = tryCatchVariableMap.get(phiIndexes[j]);
}
if (var == null) {
var = variableMap[phiIndexes[j]];
}
if (var != null) { if (var != null) {
Incoming incoming = new Incoming(); Incoming incoming = new Incoming();
incoming.setSource(currentBlock); incoming.setSource(currentBlock);
@ -260,8 +239,16 @@ public class PhiUpdater {
} }
for (int i = 0; i < program.basicBlockCount(); ++i) { for (int i = 0; i < program.basicBlockCount(); ++i) {
program.basicBlockAt(i).getPhis().addAll(synthesizedPhis.get(i)); for (Phi phi : synthesizedPhis.get(i)) {
program.basicBlockAt(i).getTryCatchJoints().addAll(synthesizedJoints.get(i)); if (!phi.getIncomings().isEmpty()) {
program.basicBlockAt(i).getPhis().add(phi);
}
}
for (TryCatchJoint joint : synthesizedJoints.get(i)) {
if (!joint.getSourceVariables().isEmpty()) {
program.basicBlockAt(i).getTryCatchJoints().add(joint);
}
}
} }
} }
@ -277,42 +264,50 @@ public class PhiUpdater {
} }
for (int frontier : frontiers) { for (int frontier : frontiers) {
BasicBlock frontierBlock = program.basicBlockAt(frontier); BasicBlock frontierBlock = program.basicBlockAt(frontier);
if (isExceptionHandler(block, frontierBlock)) { if (isExceptionHandler(block, frontierBlock)) {
boolean jointExists = frontierBlock.getTryCatchJoints().stream() continue;
.anyMatch(joint -> joint.getSourceVariables().contains(var) && joint.getSource() == block); }
if (!jointExists) {
Map<Variable, TryCatchJoint> jointSubmap = jointMap.get(frontier).get(block); boolean exists = frontierBlock.getPhis().stream()
if (jointSubmap == null) { .flatMap(phi -> phi.getIncomings().stream())
jointSubmap = new HashMap<>(); .anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var);
jointMap.get(frontier).put(block, jointSubmap); if (exists) {
} continue;
TryCatchJoint joint = jointSubmap.get(var); }
if (joint == null) {
joint = new TryCatchJoint(); Phi phi = phiMap[frontier][var.getIndex()];
joint.setSource(block); if (phi == null) {
joint.setReceiver(var); phi = new Phi();
synthesizedJoints.get(frontier).add(joint); phi.setReceiver(var);
jointSubmap.put(var, joint); phiIndexMap[frontier][synthesizedPhis.get(frontier).size()] = var.getIndex();
worklist[head++] = frontierBlock; synthesizedPhis.get(frontier).add(phi);
} phiMap[frontier][var.getIndex()] = phi;
} worklist[head++] = frontierBlock;
} else { }
boolean exists = frontierBlock.getPhis().stream() }
.flatMap(phi -> phi.getIncomings().stream())
.anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var); for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
if (exists) { BasicBlock frontierBlock = tryCatch.getHandler();
continue; int frontier = frontierBlock.getIndex();
} boolean jointExists = frontierBlock.getTryCatchJoints().stream()
Phi phi = phiMap[frontier][var.getIndex()]; .anyMatch(joint -> joint.getSourceVariables().contains(var) && joint.getSource() == block);
if (phi == null) { if (jointExists) {
phi = new Phi(); continue;
phi.setReceiver(var); }
phiIndexMap[frontier][synthesizedPhis.get(frontier).size()] = var.getIndex();
synthesizedPhis.get(frontier).add(phi); Map<Variable, TryCatchJoint> jointSubmap = jointMap.get(frontier).get(block);
phiMap[frontier][var.getIndex()] = phi; if (jointSubmap == null) {
worklist[head++] = frontierBlock; 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;
} }
} }
} }
@ -323,12 +318,24 @@ public class PhiUpdater {
} }
private Variable define(Variable var) { private Variable define(Variable var) {
Variable original = var;
var = introduce(var, false);
variableMap[original.getIndex()] = var;
return var;
}
private Variable introduce(Variable var, boolean clear) {
Variable original = var; Variable original = var;
Variable old = variableMap[var.getIndex()]; Variable old = variableMap[var.getIndex()];
if (old == null) { if (old == null) {
old = var; old = var;
} }
var = introduce(var);
if (!usedDefinitions[var.getIndex()]) {
usedDefinitions[var.getIndex()] = true;
} else {
var = program.createVariable();
}
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) { for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
Map<Variable, TryCatchJoint> joints = jointMap.get(tryCatch.getHandler().getIndex()).get(currentBlock); Map<Variable, TryCatchJoint> joints = jointMap.get(tryCatch.getHandler().getIndex()).get(currentBlock);
@ -342,19 +349,12 @@ public class PhiUpdater {
if (joint.getSourceVariables().isEmpty()) { if (joint.getSourceVariables().isEmpty()) {
joint.getSourceVariables().add(original); joint.getSourceVariables().add(original);
} }
if (clear) {
joint.getSourceVariables().clear();
}
joint.getSourceVariables().add(var); joint.getSourceVariables().add(var);
} }
variableMap[original.getIndex()] = var;
return var;
}
private Variable introduce(Variable var) {
if (!usedDefinitions[var.getIndex()]) {
usedDefinitions[var.getIndex()] = true;
} else {
var = program.createVariable();
}
return var; return var;
} }
@ -597,11 +597,4 @@ public class PhiUpdater {
insn.setObjectRef(use(insn.getObjectRef())); insn.setObjectRef(use(insn.getObjectRef()));
} }
}; };
public static void main(String[] args) {
ClassHolderSource classSource = new ClasspathClassHolderSource();
ClassHolder cls = classSource.get(Charset.class.getName());
MethodHolder method = cls.getMethod(new MethodDescriptor("decode", ByteBuffer.class, CharBuffer.class));
System.out.println(new ListingBuilder().buildListing(method.getProgram(), ""));
}
} }

View File

@ -130,7 +130,7 @@ public final class ProgramUtils {
TryCatchJoint jointCopy = new TryCatchJoint(); TryCatchJoint jointCopy = new TryCatchJoint();
jointCopy.setSource(target.basicBlockAt(joint.getSource().getIndex())); jointCopy.setSource(target.basicBlockAt(joint.getSource().getIndex()));
jointCopy.setReceiver(target.variableAt(joint.getReceiver().getIndex())); jointCopy.setReceiver(target.variableAt(joint.getReceiver().getIndex()));
for (VariableReader sourceVar : jointCopy.getSourceVariables()) { for (VariableReader sourceVar : joint.readSourceVariables()) {
jointCopy.getSourceVariables().add(target.variableAt(sourceVar.getIndex())); jointCopy.getSourceVariables().add(target.variableAt(sourceVar.getIndex()));
} }
result.add(jointCopy); result.add(jointCopy);

View File

@ -95,7 +95,6 @@ import org.teavm.optimization.ArrayUnwrapMotion;
import org.teavm.optimization.Devirtualization; import org.teavm.optimization.Devirtualization;
import org.teavm.optimization.GlobalValueNumbering; import org.teavm.optimization.GlobalValueNumbering;
import org.teavm.optimization.LoopInvariantMotion; import org.teavm.optimization.LoopInvariantMotion;
import org.teavm.optimization.LoopInversion;
import org.teavm.optimization.MethodOptimization; import org.teavm.optimization.MethodOptimization;
import org.teavm.optimization.UnusedVariableElimination; import org.teavm.optimization.UnusedVariableElimination;
import org.teavm.vm.spi.RendererListener; import org.teavm.vm.spi.RendererListener;