mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Always eliminate constant variables in AST optimizer
This commit is contained in:
parent
5593a2c557
commit
973cdf045b
|
@ -74,14 +74,11 @@ public class Decompiler {
|
||||||
private Deque<Block> stack;
|
private Deque<Block> stack;
|
||||||
private Program program;
|
private Program program;
|
||||||
private boolean friendlyToDebugger;
|
private boolean friendlyToDebugger;
|
||||||
private boolean moveConstants;
|
|
||||||
|
|
||||||
public Decompiler(ClassHolderSource classSource, Set<MethodReference> splitMethods, boolean friendlyToDebugger,
|
public Decompiler(ClassHolderSource classSource, Set<MethodReference> splitMethods, boolean friendlyToDebugger) {
|
||||||
boolean moveConstants) {
|
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
this.splitMethods = splitMethods;
|
this.splitMethods = splitMethods;
|
||||||
this.friendlyToDebugger = friendlyToDebugger;
|
this.friendlyToDebugger = friendlyToDebugger;
|
||||||
this.moveConstants = moveConstants;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Block {
|
static class Block {
|
||||||
|
@ -152,7 +149,7 @@ public class Decompiler {
|
||||||
methodNode.getVariables().add(variable);
|
methodNode.getVariables().add(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optimizer optimizer = new Optimizer(moveConstants);
|
Optimizer optimizer = new Optimizer();
|
||||||
optimizer.optimize(methodNode, method.getProgram(), friendlyToDebugger);
|
optimizer.optimize(methodNode, method.getProgram(), friendlyToDebugger);
|
||||||
methodNode.getModifiers().addAll(method.getModifiers());
|
methodNode.getModifiers().addAll(method.getModifiers());
|
||||||
|
|
||||||
|
@ -185,7 +182,7 @@ public class Decompiler {
|
||||||
node.getVariables().add(variable);
|
node.getVariables().add(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optimizer optimizer = new Optimizer(moveConstants);
|
Optimizer optimizer = new Optimizer();
|
||||||
optimizer.optimize(node, splitter, friendlyToDebugger);
|
optimizer.optimize(node, splitter, friendlyToDebugger);
|
||||||
node.getModifiers().addAll(method.getModifiers());
|
node.getModifiers().addAll(method.getModifiers());
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,6 @@ import org.teavm.model.util.ProgramUtils;
|
||||||
import org.teavm.model.util.UsageExtractor;
|
import org.teavm.model.util.UsageExtractor;
|
||||||
|
|
||||||
public class Optimizer {
|
public class Optimizer {
|
||||||
private boolean moveConstants;
|
|
||||||
|
|
||||||
public Optimizer(boolean moveConstants) {
|
|
||||||
this.moveConstants = moveConstants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void optimize(RegularMethodNode method, Program program, boolean friendlyToDebugger) {
|
public void optimize(RegularMethodNode method, Program program, boolean friendlyToDebugger) {
|
||||||
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
|
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
|
||||||
stats.analyze(program);
|
stats.analyze(program);
|
||||||
|
@ -54,7 +48,7 @@ public class Optimizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.writes, stats.reads,
|
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.writes, stats.reads,
|
||||||
moveConstants ? stats.constants : new Object[stats.constants.length], friendlyToDebugger);
|
stats.constants, friendlyToDebugger);
|
||||||
method.getBody().acceptVisitor(optimizer);
|
method.getBody().acceptVisitor(optimizer);
|
||||||
method.setBody(optimizer.resultStmt);
|
method.setBody(optimizer.resultStmt);
|
||||||
int paramCount = method.getReference().parameterCount();
|
int paramCount = method.getReference().parameterCount();
|
||||||
|
@ -89,7 +83,7 @@ public class Optimizer {
|
||||||
breakEliminator.eliminate(part.getStatement());
|
breakEliminator.eliminate(part.getStatement());
|
||||||
findEscapingLiveVars(liveness, cfg, splitter, i, preservedVars);
|
findEscapingLiveVars(liveness, cfg, splitter, i, preservedVars);
|
||||||
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.writes, stats.reads,
|
OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.writes, stats.reads,
|
||||||
moveConstants ? stats.constants : new Object[stats.constants.length], friendlyToDebugger);
|
stats.constants, friendlyToDebugger);
|
||||||
part.getStatement().acceptVisitor(optimizer);
|
part.getStatement().acceptVisitor(optimizer);
|
||||||
part.setStatement(optimizer.resultStmt);
|
part.setStatement(optimizer.resultStmt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
Statement resultStmt;
|
Statement resultStmt;
|
||||||
private final boolean[] preservedVars;
|
private final boolean[] preservedVars;
|
||||||
private final int[] writeFrequencies;
|
private final int[] writeFrequencies;
|
||||||
private final int[] initialWriteFrequences;
|
private final int[] initialWriteFrequencies;
|
||||||
private final int[] readFrequencies;
|
private final int[] readFrequencies;
|
||||||
private final Object[] constants;
|
private final Object[] constants;
|
||||||
private List<Statement> resultSequence;
|
private List<Statement> resultSequence;
|
||||||
|
@ -82,7 +82,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
boolean friendlyToDebugger) {
|
boolean friendlyToDebugger) {
|
||||||
this.preservedVars = preservedVars;
|
this.preservedVars = preservedVars;
|
||||||
this.writeFrequencies = writeFrequencies;
|
this.writeFrequencies = writeFrequencies;
|
||||||
this.initialWriteFrequences = writeFrequencies.clone();
|
this.initialWriteFrequencies = writeFrequencies.clone();
|
||||||
this.readFrequencies = readFrequencies;
|
this.readFrequencies = readFrequencies;
|
||||||
this.constants = constants;
|
this.constants = constants;
|
||||||
this.friendlyToDebugger = friendlyToDebugger;
|
this.friendlyToDebugger = friendlyToDebugger;
|
||||||
|
@ -279,7 +279,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!preservedVars[index] && initialWriteFrequences[index] == 1 && constants[index] != null) {
|
if (!preservedVars[index] && initialWriteFrequencies[index] == 1 && constants[index] != null) {
|
||||||
ConstantExpr constantExpr = new ConstantExpr();
|
ConstantExpr constantExpr = new ConstantExpr();
|
||||||
constantExpr.setValue(constants[index]);
|
constantExpr.setValue(constants[index]);
|
||||||
constantExpr.setLocation(expr.getLocation());
|
constantExpr.setLocation(expr.getLocation());
|
||||||
|
@ -561,7 +561,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
left = resultExpr;
|
left = resultExpr;
|
||||||
} else {
|
} else {
|
||||||
int varIndex = ((VariableExpr) statement.getLeftValue()).getIndex();
|
int varIndex = ((VariableExpr) statement.getLeftValue()).getIndex();
|
||||||
if (!preservedVars[varIndex] && initialWriteFrequences[varIndex] == 1
|
if (!preservedVars[varIndex] && initialWriteFrequencies[varIndex] == 1
|
||||||
&& constants[varIndex] != null) {
|
&& constants[varIndex] != null) {
|
||||||
resultStmt = new SequentialStatement();
|
resultStmt = new SequentialStatement();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -20,7 +20,12 @@ import org.teavm.common.Graph;
|
||||||
import org.teavm.common.GraphUtils;
|
import org.teavm.common.GraphUtils;
|
||||||
import org.teavm.common.IntegerStack;
|
import org.teavm.common.IntegerStack;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
import org.teavm.model.instructions.AbstractInstructionVisitor;
|
||||||
import org.teavm.model.instructions.ClassConstantInstruction;
|
import org.teavm.model.instructions.ClassConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.DoubleConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.FloatConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.IntegerConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.LongConstantInstruction;
|
||||||
import org.teavm.model.instructions.StringConstantInstruction;
|
import org.teavm.model.instructions.StringConstantInstruction;
|
||||||
import org.teavm.model.util.DefinitionExtractor;
|
import org.teavm.model.util.DefinitionExtractor;
|
||||||
import org.teavm.model.util.ProgramUtils;
|
import org.teavm.model.util.ProgramUtils;
|
||||||
|
@ -54,6 +59,7 @@ class ReadWriteStatsBuilder {
|
||||||
UsageExtractor useExtractor = new UsageExtractor();
|
UsageExtractor useExtractor = new UsageExtractor();
|
||||||
IntegerStack stack = new IntegerStack(program.basicBlockCount());
|
IntegerStack stack = new IntegerStack(program.basicBlockCount());
|
||||||
stack.push(0);
|
stack.push(0);
|
||||||
|
ConstantExtractor constantExtractor = new ConstantExtractor(constants);
|
||||||
while (!stack.isEmpty()) {
|
while (!stack.isEmpty()) {
|
||||||
int node = stack.pop();
|
int node = stack.pop();
|
||||||
BasicBlock block = program.basicBlockAt(node);
|
BasicBlock block = program.basicBlockAt(node);
|
||||||
|
@ -73,13 +79,7 @@ class ReadWriteStatsBuilder {
|
||||||
reads[var.getIndex()]++;
|
reads[var.getIndex()]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insn instanceof StringConstantInstruction) {
|
insn.acceptVisitor(constantExtractor);
|
||||||
StringConstantInstruction stringConstant = (StringConstantInstruction) insn;
|
|
||||||
constants[stringConstant.getReceiver().getIndex()] = stringConstant.getConstant();
|
|
||||||
} else if (insn instanceof ClassConstantInstruction) {
|
|
||||||
ClassConstantInstruction classConstant = (ClassConstantInstruction) insn;
|
|
||||||
constants[classConstant.getReceiver().getIndex()] = classConstant.getConstant();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Phi phi : block.getPhis()) {
|
for (Phi phi : block.getPhis()) {
|
||||||
|
@ -96,4 +96,42 @@ class ReadWriteStatsBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class ConstantExtractor extends AbstractInstructionVisitor {
|
||||||
|
private Object[] constants;
|
||||||
|
|
||||||
|
public ConstantExtractor(Object[] constants) {
|
||||||
|
this.constants = constants;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ClassConstantInstruction insn) {
|
||||||
|
constants[insn.getReceiver().getIndex()] = insn.getConstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(StringConstantInstruction insn) {
|
||||||
|
constants[insn.getReceiver().getIndex()] = insn.getConstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(IntegerConstantInstruction insn) {
|
||||||
|
constants[insn.getReceiver().getIndex()] = insn.getConstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LongConstantInstruction insn) {
|
||||||
|
constants[insn.getReceiver().getIndex()] = insn.getConstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(FloatConstantInstruction insn) {
|
||||||
|
constants[insn.getReceiver().getIndex()] = insn.getConstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(DoubleConstantInstruction insn) {
|
||||||
|
constants[insn.getReceiver().getIndex()] = insn.getConstant();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,7 +317,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
||||||
ClassHierarchy hierarchy = new ClassHierarchy(classes);
|
ClassHierarchy hierarchy = new ClassHierarchy(classes);
|
||||||
TagRegistry tagRegistry = new TagRegistry(classes, hierarchy);
|
TagRegistry tagRegistry = new TagRegistry(classes, hierarchy);
|
||||||
|
|
||||||
Decompiler decompiler = new Decompiler(classes, new HashSet<>(), false, true);
|
Decompiler decompiler = new Decompiler(classes, new HashSet<>(), controller.isFriendlyToDebugger());
|
||||||
Characteristics characteristics = new Characteristics(controller.getUnprocessedClassSource());
|
Characteristics characteristics = new Characteristics(controller.getUnprocessedClassSource());
|
||||||
|
|
||||||
NameProvider nameProvider = new NameProvider(controller.getUnprocessedClassSource());
|
NameProvider nameProvider = new NameProvider(controller.getUnprocessedClassSource());
|
||||||
|
|
|
@ -477,7 +477,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
||||||
Set<MethodReference> splitMethods = new HashSet<>(asyncMethods);
|
Set<MethodReference> splitMethods = new HashSet<>(asyncMethods);
|
||||||
splitMethods.addAll(asyncFamilyMethods);
|
splitMethods.addAll(asyncFamilyMethods);
|
||||||
|
|
||||||
Decompiler decompiler = new Decompiler(classes, splitMethods, controller.isFriendlyToDebugger(), false);
|
Decompiler decompiler = new Decompiler(classes, splitMethods, controller.isFriendlyToDebugger());
|
||||||
|
|
||||||
List<PreparedClass> classNodes = new ArrayList<>();
|
List<PreparedClass> classNodes = new ArrayList<>();
|
||||||
for (String className : getClassOrdering(classes)) {
|
for (String className : getClassOrdering(classes)) {
|
||||||
|
|
|
@ -331,7 +331,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
WasmClassGenerator classGenerator = new WasmClassGenerator(classes, controller.getUnprocessedClassSource(),
|
WasmClassGenerator classGenerator = new WasmClassGenerator(classes, controller.getUnprocessedClassSource(),
|
||||||
vtableProvider, tagRegistry, binaryWriter, names);
|
vtableProvider, tagRegistry, binaryWriter, names);
|
||||||
|
|
||||||
Decompiler decompiler = new Decompiler(classes, new HashSet<>(), false, true);
|
Decompiler decompiler = new Decompiler(classes, new HashSet<>(), false);
|
||||||
WasmStringPool stringPool = classGenerator.getStringPool();
|
WasmStringPool stringPool = classGenerator.getStringPool();
|
||||||
WasmGenerationContext context = new WasmGenerationContext(classes, module, controller.getDiagnostics(),
|
WasmGenerationContext context = new WasmGenerationContext(classes, module, controller.getDiagnostics(),
|
||||||
vtableProvider, tagRegistry, stringPool, names);
|
vtableProvider, tagRegistry, stringPool, names);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user