Trying to preserve variable names after GVN

This commit is contained in:
Alexey Andreev 2016-08-26 00:29:12 +03:00
parent 1c1b0c69fa
commit ef5145d6fd
6 changed files with 43 additions and 27 deletions

View File

@ -140,13 +140,13 @@ public class WasmCRenderer {
line(functionDeclaration(function) + " {"); line(functionDeclaration(function) + " {");
indent(); indent();
WasmCRenderingVisitor visitor = new WasmCRenderingVisitor(function.getResult(), function.getModule());
List<WasmLocal> variables = function.getLocalVariables().subList(function.getParameters().size(), List<WasmLocal> variables = function.getLocalVariables().subList(function.getParameters().size(),
function.getLocalVariables().size()); function.getLocalVariables().size());
for (WasmLocal variable : variables) { for (WasmLocal variable : variables) {
line(WasmCRenderingVisitor.mapType(variable.getType()) + " var_" + variable.getIndex() + ";"); line(WasmCRenderingVisitor.mapType(variable.getType()) + " " + visitor.getVariableName(variable) + ";");
} }
WasmCRenderingVisitor visitor = new WasmCRenderingVisitor(function.getResult(), function.getModule());
List<WasmExpression> body = function.getBody(); List<WasmExpression> body = function.getBody();
List<CLine> lines = new ArrayList<>(); List<CLine> lines = new ArrayList<>();
if (!body.isEmpty()) { if (!body.isEmpty()) {

View File

@ -42,6 +42,6 @@ public interface ClassHolderSource extends ClassReaderSource {
} }
default Stream<MethodHolder> mutableOverridenMethods(MethodReference method) { default Stream<MethodHolder> mutableOverridenMethods(MethodReference method) {
return overridenMethods(method).map(m -> (MethodHolder) m); return overriddenMethods(method).map(m -> (MethodHolder) m);
} }
} }

View File

@ -24,10 +24,6 @@ import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
/**
*
* @author Alexey Andreev
*/
public interface ClassReaderSource { public interface ClassReaderSource {
ClassReader get(String name); ClassReader get(String name);
@ -104,7 +100,7 @@ public interface ClassReaderSource {
.findFirst().orElse(null); .findFirst().orElse(null);
} }
default Stream<MethodReader> overridenMethods(MethodReference method) { default Stream<MethodReader> overriddenMethods(MethodReference method) {
return getAncestorClasses(method.getClassName()) return getAncestorClasses(method.getClassName())
.map(cls -> cls.getMethod(method.getDescriptor())) .map(cls -> cls.getMethod(method.getDescriptor()))
.filter(candidate -> candidate != null); .filter(candidate -> candidate != null);

View File

@ -150,12 +150,20 @@ public class GlobalValueNumbering implements MethodOptimization {
} }
} }
String[] debugNames = new String[program.variableCount()];
for (int i = 0; i < program.variableCount(); ++i) {
debugNames[i] = program.variableAt(i).getDebugName();
program.variableAt(i).setDebugName(null);
}
for (int i = 0; i < map.length; ++i) { for (int i = 0; i < map.length; ++i) {
if (map[i] != i) { if (map[i] != i) {
Variable var = program.variableAt(i);
Variable mapVar = program.variableAt(map[i]); Variable mapVar = program.variableAt(map[i]);
mapVar.setDebugName(var.getDebugName()); if (debugNames[i] != null && mapVar.getDebugName() == null) {
mapVar.setDebugName(debugNames[i]);
}
program.deleteVariable(i); program.deleteVariable(i);
} else {
program.variableAt(i).setDebugName(debugNames[i]);
} }
} }
@ -165,7 +173,7 @@ public class GlobalValueNumbering implements MethodOptimization {
} }
private void bind(int var, String value) { private void bind(int var, String value) {
String name = program.variableAt(var).getDebugName(); String name = program.variableAt(map[var]).getDebugName();
if (name == null) { if (name == null) {
name = ""; name = "";
} }

View File

@ -28,6 +28,7 @@ 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;
import org.teavm.common.IntegerArray;
import org.teavm.model.BasicBlock; import org.teavm.model.BasicBlock;
import org.teavm.model.Incoming; import org.teavm.model.Incoming;
import org.teavm.model.Instruction; import org.teavm.model.Instruction;
@ -88,6 +89,11 @@ public class PhiUpdater {
private List<List<List<TryCatchJoint>>> synthesizedJoints = new ArrayList<>(); private List<List<List<TryCatchJoint>>> synthesizedJoints = new ArrayList<>();
private Variable[] originalExceptionVariables; private Variable[] originalExceptionVariables;
private boolean[] usedDefinitions; private boolean[] usedDefinitions;
private IntegerArray variableToSourceMap = new IntegerArray(10);
public int getSourceVariable(int var) {
return variableToSourceMap.get(var);
}
public void updatePhis(Program program, Variable[] arguments) { public void updatePhis(Program program, Variable[] arguments) {
if (program.basicBlockCount() == 0) { if (program.basicBlockCount() == 0) {
@ -103,6 +109,9 @@ public class PhiUpdater {
variableMap[i] = arguments[i]; variableMap[i] = arguments[i];
usedDefinitions[i] = true; usedDefinitions[i] = true;
} }
for (int i = 0; i < program.variableCount(); ++i) {
variableToSourceMap.add(-1);
}
phiMap = new Phi[program.basicBlockCount()][]; phiMap = new Phi[program.basicBlockCount()][];
phiIndexMap = new int[program.basicBlockCount()][]; phiIndexMap = new int[program.basicBlockCount()][];
jointMap.clear(); jointMap.clear();
@ -201,7 +210,7 @@ public class PhiUpdater {
for (Phi phi : synthesizedPhis.get(index)) { for (Phi phi : synthesizedPhis.get(index)) {
Variable var = program.createVariable(); Variable var = program.createVariable();
var.setDebugName(phi.getReceiver().getDebugName()); var.setDebugName(phi.getReceiver().getDebugName());
variableMap[phi.getReceiver().getIndex()] = var; mapVariable(phi.getReceiver().getIndex(), var);
phi.setReceiver(var); phi.setReceiver(var);
} }
for (Phi phi : currentBlock.getPhis()) { for (Phi phi : currentBlock.getPhis()) {
@ -334,7 +343,7 @@ public class PhiUpdater {
Variable original = var; Variable original = var;
var = introduce(var); var = introduce(var);
propagateToTryCatch(original, var, old); propagateToTryCatch(original, var, old);
variableMap[original.getIndex()] = var; mapVariable(original.getIndex(), var);
return var; return var;
} }
@ -368,6 +377,14 @@ public class PhiUpdater {
} }
} }
private void mapVariable(int index, Variable var) {
variableMap[index] = var;
while (variableToSourceMap.size() <= var.getIndex()) {
variableToSourceMap.add(-1);
}
variableToSourceMap.set(var.getIndex(), index);
}
private Variable introduce(Variable var) { private Variable introduce(Variable var) {
if (!usedDefinitions[var.getIndex()]) { if (!usedDefinitions[var.getIndex()]) {
usedDefinitions[var.getIndex()] = true; usedDefinitions[var.getIndex()] = true;

View File

@ -86,6 +86,8 @@ public class Parser {
applyDebugNames(program, phiUpdater, programParser, argumentMapping); applyDebugNames(program, phiUpdater, programParser, argumentMapping);
parseAnnotations(method.getAnnotations(), node.visibleAnnotations, node.invisibleAnnotations); parseAnnotations(method.getAnnotations(), node.visibleAnnotations, node.invisibleAnnotations);
applyDebugNames(program, phiUpdater, programParser,
applySignature(program, method.getDescriptor().getParameterTypes()));
while (program.variableCount() <= method.parameterCount()) { while (program.variableCount() <= method.parameterCount()) {
program.createVariable(); program.createVariable();
} }
@ -100,7 +102,7 @@ public class Parser {
return method; return method;
} }
private void applyDebugNames(Program program, PhiUpdater phiUpdater, ProgramParser parser, private static void applyDebugNames(Program program, PhiUpdater phiUpdater, ProgramParser parser,
Variable[] argumentMapping) { Variable[] argumentMapping) {
if (program.basicBlockCount() == 0) { if (program.basicBlockCount() == 0) {
return; return;
@ -130,14 +132,14 @@ public class Parser {
for (Map.Entry<Integer, String> debugName : debugNames.entrySet()) { for (Map.Entry<Integer, String> debugName : debugNames.entrySet()) {
int receiver = varMap.getOrDefault(debugName.getKey(), -1); int receiver = varMap.getOrDefault(debugName.getKey(), -1);
if (receiver >= 0) { if (receiver >= 0) {
program.variableAt(receiver).getDebugNames().add(debugName.getValue()); program.variableAt(receiver).setDebugName(debugName.getValue());
} }
} }
} }
} }
} }
private IntIntMap[] getBlockEntryVariableMappings(Program program, PhiUpdater phiUpdater, private static IntIntMap[] getBlockEntryVariableMappings(Program program, PhiUpdater phiUpdater,
Variable[] argumentMapping) { Variable[] argumentMapping) {
class Step { class Step {
int node; int node;
@ -171,36 +173,29 @@ public class Parser {
IntIntMap varMap = new IntIntOpenHashMap(step.varMap); IntIntMap varMap = new IntIntOpenHashMap(step.varMap);
BasicBlock block = program.basicBlockAt(node); BasicBlock block = program.basicBlockAt(node);
/*
for (TryCatchJoint joint : block.getTryCatchJoints()) {
int receiver = joint.getReceiver().getIndex();
int sourceVar = phiUpdater.getSourceVariable(receiver);
if (sourceVar >= 0) {
varMap.put(sourceVar, receiver);
}
}
for (Phi phi : block.getPhis()) { for (Phi phi : block.getPhis()) {
int receiver = phi.getReceiver().getIndex(); int receiver = phi.getReceiver().getIndex();
/*
int sourceVar = phiUpdater.getSourceVariable(receiver); int sourceVar = phiUpdater.getSourceVariable(receiver);
if (sourceVar >= 0) { if (sourceVar >= 0) {
varMap.put(sourceVar, receiver); varMap.put(sourceVar, receiver);
} }
*/
} }
*/
result[node] = new IntIntOpenHashMap(varMap); result[node] = new IntIntOpenHashMap(varMap);
/*
for (Instruction insn : block.getInstructions()) { for (Instruction insn : block.getInstructions()) {
insn.acceptVisitor(defExtractor); insn.acceptVisitor(defExtractor);
for (Variable definedVar : defExtractor.getDefinedVariables()) { for (Variable definedVar : defExtractor.getDefinedVariables()) {
/*
int sourceVar = phiUpdater.getSourceVariable(definedVar.getIndex()); int sourceVar = phiUpdater.getSourceVariable(definedVar.getIndex());
if (sourceVar >= 0) { if (sourceVar >= 0) {
varMap.put(sourceVar, definedVar.getIndex()); varMap.put(sourceVar, definedVar.getIndex());
} }
*/
} }
} }
*/
for (int successor : dom.outgoingEdges(node)) { for (int successor : dom.outgoingEdges(node)) {
stack[top++] = new Step(successor, new IntIntOpenHashMap(varMap)); stack[top++] = new Step(successor, new IntIntOpenHashMap(varMap));