mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -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;
|
||||
}
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
new GlobalValueNumbering(true).optimize(method, method.getProgram());
|
||||
new GlobalValueNumbering(true).optimize(method.getProgram());
|
||||
new UnusedVariableElimination().optimize(method, method.getProgram());
|
||||
}
|
||||
cache.put(name, cls);
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.teavm.model.util.DefinitionExtractor;
|
|||
|
||||
public class ArrayUnwrapMotion implements MethodOptimization {
|
||||
@Override
|
||||
public boolean optimize(MethodReader method, Program program) {
|
||||
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
optimize(program.basicBlockAt(i));
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.teavm.common.Graph;
|
|||
import org.teavm.common.GraphUtils;
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.Instruction;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.instructions.EmptyInstruction;
|
||||
import org.teavm.model.instructions.InitClassInstruction;
|
||||
|
@ -34,13 +33,13 @@ import org.teavm.model.util.ProgramUtils;
|
|||
|
||||
public class ClassInitElimination implements MethodOptimization {
|
||||
@Override
|
||||
public boolean optimize(MethodReader method, Program program) {
|
||||
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||
DominatorTree dom = GraphUtils.buildDominatorTree(cfg);
|
||||
Graph domGraph = GraphUtils.buildDominatorGraph(dom, program.basicBlockCount());
|
||||
|
||||
Step start = new Step(0);
|
||||
start.initializedClasses.add(method.getOwnerName());
|
||||
start.initializedClasses.add(context.getMethod().getOwnerName());
|
||||
Deque<Step> stack = new ArrayDeque<>();
|
||||
stack.push(start);
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ package org.teavm.model.optimization;
|
|||
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.Instruction;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.instructions.BinaryBranchingCondition;
|
||||
import org.teavm.model.instructions.BinaryBranchingInstruction;
|
||||
|
@ -33,7 +32,7 @@ public class ConstantConditionElimination implements MethodOptimization {
|
|||
private boolean[] nullConstants;
|
||||
|
||||
@Override
|
||||
public boolean optimize(MethodReader method, Program program) {
|
||||
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||
constants = new int[program.variableCount()];
|
||||
constantDefined = new boolean[program.variableCount()];
|
||||
nullConstants = new boolean[program.variableCount()];
|
||||
|
|
|
@ -16,14 +16,13 @@
|
|||
package org.teavm.model.optimization;
|
||||
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.instructions.JumpInstruction;
|
||||
import org.teavm.model.util.BasicBlockMapper;
|
||||
|
||||
public class EmptyBlockElimination implements MethodOptimization {
|
||||
@Override
|
||||
public boolean optimize(MethodReader method, final Program program) {
|
||||
public boolean optimize(MethodOptimizationContext context, final Program program) {
|
||||
boolean affected = true;
|
||||
final int[] blockMapping = new int[program.basicBlockCount()];
|
||||
for (int i = 0; i < blockMapping.length; ++i) {
|
||||
|
|
|
@ -46,7 +46,11 @@ public class GlobalValueNumbering implements MethodOptimization {
|
|||
}
|
||||
|
||||
@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;
|
||||
this.program = program;
|
||||
knownValues.clear();
|
||||
|
|
|
@ -30,7 +30,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
|||
private Program program;
|
||||
|
||||
@Override
|
||||
public boolean optimize(MethodReader method, Program program) {
|
||||
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||
boolean affected = false;
|
||||
this.program = program;
|
||||
graph = new LoopGraph(ProgramUtils.buildControlFlowGraph(program));
|
||||
|
@ -42,7 +42,7 @@ public class LoopInvariantMotion implements MethodOptimization {
|
|||
int[] defLocation = new int[program.variableCount()];
|
||||
Arrays.fill(defLocation, -1);
|
||||
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;
|
||||
}
|
||||
for (int i = 0; i < domGraph.size(); ++i) {
|
||||
|
|
|
@ -20,7 +20,8 @@ import org.teavm.model.Program;
|
|||
|
||||
public class LoopInversion implements MethodOptimization {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,10 +152,10 @@ class LoopInversionImpl {
|
|||
}
|
||||
|
||||
private LoopWithExits getLoopWithExits(Map<Loop, LoopWithExits> cache, Loop loop) {
|
||||
return cache.computeIfAbsent(loop, k ->
|
||||
new LoopWithExits(loop.getHead(), loop.getParent() != null
|
||||
? getLoopWithExits(cache, loop.getParent())
|
||||
: null));
|
||||
return cache.computeIfAbsent(loop, k -> {
|
||||
LoopWithExits parent = loop.getParent() != null ? getLoopWithExits(cache, loop.getParent()) : null;
|
||||
return new LoopWithExits(loop.getHead(), parent);
|
||||
});
|
||||
}
|
||||
|
||||
private void sortLoops(LoopWithExits loop, Set<LoopWithExits> visited, List<LoopWithExits> target) {
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
*/
|
||||
package org.teavm.model.optimization;
|
||||
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.Program;
|
||||
|
||||
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.Incoming;
|
||||
import org.teavm.model.Instruction;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.Phi;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.TryCatchBlock;
|
||||
|
@ -33,7 +32,7 @@ import org.teavm.model.util.ProgramUtils;
|
|||
|
||||
public class RedundantJumpElimination implements MethodOptimization {
|
||||
@Override
|
||||
public boolean optimize(MethodReader method, Program program) {
|
||||
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||
int[] incomingCount = new int[cfg.size()];
|
||||
Arrays.setAll(incomingCount, cfg::incomingEdgesCount);
|
||||
|
|
|
@ -15,12 +15,11 @@
|
|||
*/
|
||||
package org.teavm.model.optimization;
|
||||
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.Program;
|
||||
|
||||
public class UnreachableBasicBlockElimination implements MethodOptimization {
|
||||
@Override
|
||||
public boolean optimize(MethodReader method, Program program) {
|
||||
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||
new UnreachableBasicBlockEliminator().optimize(program);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ import org.teavm.model.instructions.*;
|
|||
|
||||
public class UnusedVariableElimination implements MethodOptimization {
|
||||
@Override
|
||||
public boolean optimize(MethodOptimizationContext context, Program program) {
|
||||
return optimize(context.getMethod(), program);
|
||||
}
|
||||
|
||||
public boolean optimize(MethodReader method, Program program) {
|
||||
if (method.getProgram() == null) {
|
||||
return false;
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.teavm.model.ClassReaderSource;
|
|||
import org.teavm.model.ListableClassHolderSource;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.MutableClassHolderSource;
|
||||
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.LoopInversion;
|
||||
import org.teavm.model.optimization.MethodOptimization;
|
||||
import org.teavm.model.optimization.MethodOptimizationContext;
|
||||
import org.teavm.model.optimization.RedundantJumpElimination;
|
||||
import org.teavm.model.optimization.UnreachableBasicBlockElimination;
|
||||
import org.teavm.model.optimization.UnusedVariableElimination;
|
||||
|
@ -443,8 +445,9 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
ClassHolder cls = classes.get(className);
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
if (method.getProgram() != null) {
|
||||
MethodOptimizationContextImpl context = new MethodOptimizationContextImpl(method, classes);
|
||||
inlining.apply(method.getProgram(), classes);
|
||||
new UnusedVariableElimination().optimize(method, method.getProgram());
|
||||
new UnusedVariableElimination().optimize(context, method.getProgram());
|
||||
}
|
||||
}
|
||||
if (wasCancelled()) {
|
||||
|
@ -473,6 +476,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
boolean noCache = method.getAnnotations().get(NoCache.class.getName()) != null;
|
||||
Program optimizedProgram = incremental && !noCache && programCache != null
|
||||
? programCache.get(method.getReference()) : null;
|
||||
MethodOptimizationContextImpl context = new MethodOptimizationContextImpl(method, classSource);
|
||||
if (optimizedProgram == null) {
|
||||
optimizedProgram = ProgramUtils.copy(method.getProgram());
|
||||
if (optimizedProgram.basicBlockCount() > 0) {
|
||||
|
@ -481,7 +485,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
changed = false;
|
||||
for (MethodOptimization optimization : getOptimizations()) {
|
||||
try {
|
||||
changed |= optimization.optimize(method, optimizedProgram);
|
||||
changed |= optimization.optimize(context, optimizedProgram);
|
||||
} catch (Exception | AssertionError e) {
|
||||
ListingBuilder listingBuilder = new ListingBuilder();
|
||||
String listing = listingBuilder.buildListing(optimizedProgram, "");
|
||||
|
@ -505,6 +509,31 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
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() {
|
||||
List<MethodOptimization> optimizations = new ArrayList<>();
|
||||
optimizations.add(new RedundantJumpElimination());
|
||||
|
|
Loading…
Reference in New Issue
Block a user