mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
Further work on incremental phi updater
This commit is contained in:
parent
d196eb9864
commit
9fc6f02875
|
@ -139,11 +139,16 @@ 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()];
|
||||||
|
if (sourceNode != null) {
|
||||||
sourceNode.connect(receiverNode);
|
sourceNode.connect(receiverNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (PhiReader phi : block.readPhis()) {
|
for (PhiReader phi : block.readPhis()) {
|
||||||
DependencyNode receiverNode = nodes[phi.getReceiver().getIndex()];
|
DependencyNode receiverNode = nodes[phi.getReceiver().getIndex()];
|
||||||
for (IncomingReader incoming : phi.readIncomings()) {
|
for (IncomingReader incoming : phi.readIncomings()) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,11 +264,37 @@ 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)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean exists = frontierBlock.getPhis().stream()
|
||||||
|
.flatMap(phi -> phi.getIncomings().stream())
|
||||||
|
.anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var);
|
||||||
|
if (exists) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Phi phi = phiMap[frontier][var.getIndex()];
|
||||||
|
if (phi == null) {
|
||||||
|
phi = new Phi();
|
||||||
|
phi.setReceiver(var);
|
||||||
|
phiIndexMap[frontier][synthesizedPhis.get(frontier).size()] = var.getIndex();
|
||||||
|
synthesizedPhis.get(frontier).add(phi);
|
||||||
|
phiMap[frontier][var.getIndex()] = phi;
|
||||||
|
worklist[head++] = frontierBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
|
BasicBlock frontierBlock = tryCatch.getHandler();
|
||||||
|
int frontier = frontierBlock.getIndex();
|
||||||
boolean jointExists = frontierBlock.getTryCatchJoints().stream()
|
boolean jointExists = frontierBlock.getTryCatchJoints().stream()
|
||||||
.anyMatch(joint -> joint.getSourceVariables().contains(var) && joint.getSource() == block);
|
.anyMatch(joint -> joint.getSourceVariables().contains(var) && joint.getSource() == block);
|
||||||
if (!jointExists) {
|
if (jointExists) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Map<Variable, TryCatchJoint> jointSubmap = jointMap.get(frontier).get(block);
|
Map<Variable, TryCatchJoint> jointSubmap = jointMap.get(frontier).get(block);
|
||||||
if (jointSubmap == null) {
|
if (jointSubmap == null) {
|
||||||
jointSubmap = new HashMap<>();
|
jointSubmap = new HashMap<>();
|
||||||
|
@ -297,24 +310,6 @@ public class PhiUpdater {
|
||||||
worklist[head++] = frontierBlock;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(), ""));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user