mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
Refactor optimization API
This commit is contained in:
parent
b7d760188e
commit
0b4629d959
|
@ -37,7 +37,7 @@ public class PreOptimizingClassHolderSource implements ClassHolderSource {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
new GlobalValueNumbering(true).optimize(method, method.getProgram());
|
new GlobalValueNumbering(true).optimize(method.getProgram());
|
||||||
new UnusedVariableElimination().optimize(method, method.getProgram());
|
new UnusedVariableElimination().optimize(method, method.getProgram());
|
||||||
}
|
}
|
||||||
cache.put(name, cls);
|
cache.put(name, cls);
|
||||||
|
|
|
@ -24,7 +24,7 @@ import org.teavm.model.util.DefinitionExtractor;
|
||||||
|
|
||||||
public class ArrayUnwrapMotion implements MethodOptimization {
|
public class ArrayUnwrapMotion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
optimize(program.basicBlockAt(i));
|
optimize(program.basicBlockAt(i));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ 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.Instruction;
|
import org.teavm.model.Instruction;
|
||||||
import org.teavm.model.MethodReader;
|
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
import org.teavm.model.instructions.EmptyInstruction;
|
import org.teavm.model.instructions.EmptyInstruction;
|
||||||
import org.teavm.model.instructions.InitClassInstruction;
|
import org.teavm.model.instructions.InitClassInstruction;
|
||||||
|
@ -34,13 +33,13 @@ import org.teavm.model.util.ProgramUtils;
|
||||||
|
|
||||||
public class ClassInitElimination implements MethodOptimization {
|
public class ClassInitElimination implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||||
DominatorTree dom = GraphUtils.buildDominatorTree(cfg);
|
DominatorTree dom = GraphUtils.buildDominatorTree(cfg);
|
||||||
Graph domGraph = GraphUtils.buildDominatorGraph(dom, program.basicBlockCount());
|
Graph domGraph = GraphUtils.buildDominatorGraph(dom, program.basicBlockCount());
|
||||||
|
|
||||||
Step start = new Step(0);
|
Step start = new Step(0);
|
||||||
start.initializedClasses.add(method.getOwnerName());
|
start.initializedClasses.add(context.getMethod().getOwnerName());
|
||||||
Deque<Step> stack = new ArrayDeque<>();
|
Deque<Step> stack = new ArrayDeque<>();
|
||||||
stack.push(start);
|
stack.push(start);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ package org.teavm.model.optimization;
|
||||||
|
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.BasicBlock;
|
||||||
import org.teavm.model.Instruction;
|
import org.teavm.model.Instruction;
|
||||||
import org.teavm.model.MethodReader;
|
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
import org.teavm.model.instructions.BinaryBranchingCondition;
|
import org.teavm.model.instructions.BinaryBranchingCondition;
|
||||||
import org.teavm.model.instructions.BinaryBranchingInstruction;
|
import org.teavm.model.instructions.BinaryBranchingInstruction;
|
||||||
|
@ -33,7 +32,7 @@ public class ConstantConditionElimination implements MethodOptimization {
|
||||||
private boolean[] nullConstants;
|
private boolean[] nullConstants;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
constants = new int[program.variableCount()];
|
constants = new int[program.variableCount()];
|
||||||
constantDefined = new boolean[program.variableCount()];
|
constantDefined = new boolean[program.variableCount()];
|
||||||
nullConstants = new boolean[program.variableCount()];
|
nullConstants = new boolean[program.variableCount()];
|
||||||
|
|
|
@ -16,14 +16,13 @@
|
||||||
package org.teavm.model.optimization;
|
package org.teavm.model.optimization;
|
||||||
|
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.BasicBlock;
|
||||||
import org.teavm.model.MethodReader;
|
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
import org.teavm.model.instructions.JumpInstruction;
|
import org.teavm.model.instructions.JumpInstruction;
|
||||||
import org.teavm.model.util.BasicBlockMapper;
|
import org.teavm.model.util.BasicBlockMapper;
|
||||||
|
|
||||||
public class EmptyBlockElimination implements MethodOptimization {
|
public class EmptyBlockElimination implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, final Program program) {
|
public boolean optimize(MethodOptimizationContext context, final Program program) {
|
||||||
boolean affected = true;
|
boolean affected = true;
|
||||||
final int[] blockMapping = new int[program.basicBlockCount()];
|
final int[] blockMapping = new int[program.basicBlockCount()];
|
||||||
for (int i = 0; i < blockMapping.length; ++i) {
|
for (int i = 0; i < blockMapping.length; ++i) {
|
||||||
|
|
|
@ -46,7 +46,11 @@ public class GlobalValueNumbering implements MethodOptimization {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
|
return optimize(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean optimize(Program program) {
|
||||||
boolean affected = false;
|
boolean affected = false;
|
||||||
this.program = program;
|
this.program = program;
|
||||||
knownValues.clear();
|
knownValues.clear();
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
private Program program;
|
private Program program;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
boolean affected = false;
|
boolean affected = false;
|
||||||
this.program = program;
|
this.program = program;
|
||||||
graph = new LoopGraph(ProgramUtils.buildControlFlowGraph(program));
|
graph = new LoopGraph(ProgramUtils.buildControlFlowGraph(program));
|
||||||
|
@ -42,7 +42,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
||||||
int[] defLocation = new int[program.variableCount()];
|
int[] defLocation = new int[program.variableCount()];
|
||||||
Arrays.fill(defLocation, -1);
|
Arrays.fill(defLocation, -1);
|
||||||
Instruction[] constantInstructions = new Instruction[program.variableCount()];
|
Instruction[] constantInstructions = new Instruction[program.variableCount()];
|
||||||
for (int i = 0; i <= method.parameterCount(); ++i) {
|
for (int i = 0; i <= context.getMethod().parameterCount(); ++i) {
|
||||||
defLocation[i] = 0;
|
defLocation[i] = 0;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < domGraph.size(); ++i) {
|
for (int i = 0; i < domGraph.size(); ++i) {
|
||||||
|
|
|
@ -20,7 +20,8 @@ import org.teavm.model.Program;
|
||||||
|
|
||||||
public class LoopInversion implements MethodOptimization {
|
public class LoopInversion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
|
MethodReader method = context.getMethod();
|
||||||
return new LoopInversionImpl(method, program, method.parameterCount() + 1).apply();
|
return new LoopInversionImpl(method, program, method.parameterCount() + 1).apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,10 +152,10 @@ class LoopInversionImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoopWithExits getLoopWithExits(Map<Loop, LoopWithExits> cache, Loop loop) {
|
private LoopWithExits getLoopWithExits(Map<Loop, LoopWithExits> cache, Loop loop) {
|
||||||
return cache.computeIfAbsent(loop, k ->
|
return cache.computeIfAbsent(loop, k -> {
|
||||||
new LoopWithExits(loop.getHead(), loop.getParent() != null
|
LoopWithExits parent = loop.getParent() != null ? getLoopWithExits(cache, loop.getParent()) : null;
|
||||||
? getLoopWithExits(cache, loop.getParent())
|
return new LoopWithExits(loop.getHead(), parent);
|
||||||
: null));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sortLoops(LoopWithExits loop, Set<LoopWithExits> visited, List<LoopWithExits> target) {
|
private void sortLoops(LoopWithExits loop, Set<LoopWithExits> visited, List<LoopWithExits> target) {
|
||||||
|
|
|
@ -15,9 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.optimization;
|
package org.teavm.model.optimization;
|
||||||
|
|
||||||
import org.teavm.model.MethodReader;
|
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
|
|
||||||
public interface MethodOptimization {
|
public interface MethodOptimization {
|
||||||
boolean optimize(MethodReader method, Program program);
|
boolean optimize(MethodOptimizationContext context, Program program);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model.optimization;
|
||||||
|
|
||||||
|
import org.teavm.dependency.DependencyInfo;
|
||||||
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
|
|
||||||
|
public interface MethodOptimizationContext {
|
||||||
|
MethodReader getMethod();
|
||||||
|
|
||||||
|
DependencyInfo getDependencyInfo();
|
||||||
|
|
||||||
|
ClassReaderSource getClassSource();
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ import org.teavm.common.Graph;
|
||||||
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;
|
||||||
import org.teavm.model.MethodReader;
|
|
||||||
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;
|
||||||
|
@ -33,7 +32,7 @@ import org.teavm.model.util.ProgramUtils;
|
||||||
|
|
||||||
public class RedundantJumpElimination implements MethodOptimization {
|
public class RedundantJumpElimination implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||||
int[] incomingCount = new int[cfg.size()];
|
int[] incomingCount = new int[cfg.size()];
|
||||||
Arrays.setAll(incomingCount, cfg::incomingEdgesCount);
|
Arrays.setAll(incomingCount, cfg::incomingEdgesCount);
|
||||||
|
|
|
@ -15,12 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.optimization;
|
package org.teavm.model.optimization;
|
||||||
|
|
||||||
import org.teavm.model.MethodReader;
|
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
|
|
||||||
public class UnreachableBasicBlockElimination implements MethodOptimization {
|
public class UnreachableBasicBlockElimination implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
new UnreachableBasicBlockEliminator().optimize(program);
|
new UnreachableBasicBlockEliminator().optimize(program);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@ import org.teavm.model.instructions.*;
|
||||||
|
|
||||||
public class UnusedVariableElimination implements MethodOptimization {
|
public class UnusedVariableElimination implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
|
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||||
|
return optimize(context.getMethod(), program);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean optimize(MethodReader method, Program program) {
|
public boolean optimize(MethodReader method, Program program) {
|
||||||
if (method.getProgram() == null) {
|
if (method.getProgram() == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.teavm.model.ClassReaderSource;
|
||||||
import org.teavm.model.ListableClassHolderSource;
|
import org.teavm.model.ListableClassHolderSource;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodHolder;
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.MutableClassHolderSource;
|
import org.teavm.model.MutableClassHolderSource;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
|
@ -58,6 +59,7 @@ import org.teavm.model.optimization.Inlining;
|
||||||
import org.teavm.model.optimization.LoopInvariantMotion;
|
import org.teavm.model.optimization.LoopInvariantMotion;
|
||||||
import org.teavm.model.optimization.LoopInversion;
|
import org.teavm.model.optimization.LoopInversion;
|
||||||
import org.teavm.model.optimization.MethodOptimization;
|
import org.teavm.model.optimization.MethodOptimization;
|
||||||
|
import org.teavm.model.optimization.MethodOptimizationContext;
|
||||||
import org.teavm.model.optimization.RedundantJumpElimination;
|
import org.teavm.model.optimization.RedundantJumpElimination;
|
||||||
import org.teavm.model.optimization.UnreachableBasicBlockElimination;
|
import org.teavm.model.optimization.UnreachableBasicBlockElimination;
|
||||||
import org.teavm.model.optimization.UnusedVariableElimination;
|
import org.teavm.model.optimization.UnusedVariableElimination;
|
||||||
|
@ -443,8 +445,9 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
ClassHolder cls = classes.get(className);
|
ClassHolder cls = classes.get(className);
|
||||||
for (MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
if (method.getProgram() != null) {
|
if (method.getProgram() != null) {
|
||||||
|
MethodOptimizationContextImpl context = new MethodOptimizationContextImpl(method, classes);
|
||||||
inlining.apply(method.getProgram(), classes);
|
inlining.apply(method.getProgram(), classes);
|
||||||
new UnusedVariableElimination().optimize(method, method.getProgram());
|
new UnusedVariableElimination().optimize(context, method.getProgram());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wasCancelled()) {
|
if (wasCancelled()) {
|
||||||
|
@ -473,6 +476,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
boolean noCache = method.getAnnotations().get(NoCache.class.getName()) != null;
|
boolean noCache = method.getAnnotations().get(NoCache.class.getName()) != null;
|
||||||
Program optimizedProgram = incremental && !noCache && programCache != null
|
Program optimizedProgram = incremental && !noCache && programCache != null
|
||||||
? programCache.get(method.getReference()) : null;
|
? programCache.get(method.getReference()) : null;
|
||||||
|
MethodOptimizationContextImpl context = new MethodOptimizationContextImpl(method, classSource);
|
||||||
if (optimizedProgram == null) {
|
if (optimizedProgram == null) {
|
||||||
optimizedProgram = ProgramUtils.copy(method.getProgram());
|
optimizedProgram = ProgramUtils.copy(method.getProgram());
|
||||||
if (optimizedProgram.basicBlockCount() > 0) {
|
if (optimizedProgram.basicBlockCount() > 0) {
|
||||||
|
@ -481,7 +485,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
changed = false;
|
changed = false;
|
||||||
for (MethodOptimization optimization : getOptimizations()) {
|
for (MethodOptimization optimization : getOptimizations()) {
|
||||||
try {
|
try {
|
||||||
changed |= optimization.optimize(method, optimizedProgram);
|
changed |= optimization.optimize(context, optimizedProgram);
|
||||||
} catch (Exception | AssertionError e) {
|
} catch (Exception | AssertionError e) {
|
||||||
ListingBuilder listingBuilder = new ListingBuilder();
|
ListingBuilder listingBuilder = new ListingBuilder();
|
||||||
String listing = listingBuilder.buildListing(optimizedProgram, "");
|
String listing = listingBuilder.buildListing(optimizedProgram, "");
|
||||||
|
@ -505,6 +509,31 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
method.setProgram(optimizedProgram);
|
method.setProgram(optimizedProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class MethodOptimizationContextImpl implements MethodOptimizationContext {
|
||||||
|
private MethodReader method;
|
||||||
|
private ClassReaderSource classSource;
|
||||||
|
|
||||||
|
public MethodOptimizationContextImpl(MethodReader method, ClassReaderSource classSource) {
|
||||||
|
this.method = method;
|
||||||
|
this.classSource = classSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodReader getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DependencyInfo getDependencyInfo() {
|
||||||
|
return dependencyChecker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassReaderSource getClassSource() {
|
||||||
|
return classSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<MethodOptimization> getOptimizations() {
|
private List<MethodOptimization> getOptimizations() {
|
||||||
List<MethodOptimization> optimizations = new ArrayList<>();
|
List<MethodOptimization> optimizations = new ArrayList<>();
|
||||||
optimizations.add(new RedundantJumpElimination());
|
optimizations.add(new RedundantJumpElimination());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user