mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 08:34:11 -08:00
Further work on incremental phi updater
This commit is contained in:
parent
5ac195df5a
commit
ca521f74f0
|
@ -19,10 +19,6 @@ import java.util.*;
|
||||||
import org.teavm.common.MutableGraphNode;
|
import org.teavm.common.MutableGraphNode;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
class InterferenceGraphBuilder {
|
class InterferenceGraphBuilder {
|
||||||
public List<MutableGraphNode> build(Program program, int paramCount, LivenessAnalyzer liveness) {
|
public List<MutableGraphNode> build(Program program, int paramCount, LivenessAnalyzer liveness) {
|
||||||
List<MutableGraphNode> nodes = new ArrayList<>();
|
List<MutableGraphNode> nodes = new ArrayList<>();
|
||||||
|
@ -32,7 +28,7 @@ class InterferenceGraphBuilder {
|
||||||
UsageExtractor useExtractor = new UsageExtractor();
|
UsageExtractor useExtractor = new UsageExtractor();
|
||||||
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
||||||
InstructionTransitionExtractor succExtractor = new InstructionTransitionExtractor();
|
InstructionTransitionExtractor succExtractor = new InstructionTransitionExtractor();
|
||||||
List<List<Incoming>> outgoings = getOutgoings(program);
|
List<List<Incoming>> outgoings = ProgramUtils.getPhiOutputs(program);
|
||||||
Set<MutableGraphNode> live = new HashSet<>(128);
|
Set<MutableGraphNode> live = new HashSet<>(128);
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
@ -98,20 +94,4 @@ class InterferenceGraphBuilder {
|
||||||
}
|
}
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<List<Incoming>> getOutgoings(Program program) {
|
|
||||||
List<List<Incoming>> outgoings = new ArrayList<>(program.basicBlockCount());
|
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
|
||||||
outgoings.add(new ArrayList<Incoming>());
|
|
||||||
}
|
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
|
||||||
for (Phi phi : block.getPhis()) {
|
|
||||||
for (Incoming incoming : phi.getIncomings()) {
|
|
||||||
outgoings.get(incoming.getSource().getIndex()).add(incoming);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return outgoings;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,57 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.util;
|
package org.teavm.model.util;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
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.model.*;
|
import org.teavm.model.BasicBlock;
|
||||||
import org.teavm.model.instructions.*;
|
import org.teavm.model.Incoming;
|
||||||
|
import org.teavm.model.Instruction;
|
||||||
|
import org.teavm.model.InvokeDynamicInstruction;
|
||||||
|
import org.teavm.model.Phi;
|
||||||
|
import org.teavm.model.Program;
|
||||||
|
import org.teavm.model.TryCatchBlock;
|
||||||
|
import org.teavm.model.Variable;
|
||||||
|
import org.teavm.model.instructions.ArrayLengthInstruction;
|
||||||
|
import org.teavm.model.instructions.AssignInstruction;
|
||||||
|
import org.teavm.model.instructions.BinaryBranchingInstruction;
|
||||||
|
import org.teavm.model.instructions.BinaryInstruction;
|
||||||
|
import org.teavm.model.instructions.BranchingInstruction;
|
||||||
|
import org.teavm.model.instructions.CastInstruction;
|
||||||
|
import org.teavm.model.instructions.CastIntegerInstruction;
|
||||||
|
import org.teavm.model.instructions.CastNumberInstruction;
|
||||||
|
import org.teavm.model.instructions.ClassConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.CloneArrayInstruction;
|
||||||
|
import org.teavm.model.instructions.ConstructArrayInstruction;
|
||||||
|
import org.teavm.model.instructions.ConstructInstruction;
|
||||||
|
import org.teavm.model.instructions.ConstructMultiArrayInstruction;
|
||||||
|
import org.teavm.model.instructions.DoubleConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.EmptyInstruction;
|
||||||
|
import org.teavm.model.instructions.ExitInstruction;
|
||||||
|
import org.teavm.model.instructions.FloatConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.GetElementInstruction;
|
||||||
|
import org.teavm.model.instructions.GetFieldInstruction;
|
||||||
|
import org.teavm.model.instructions.InitClassInstruction;
|
||||||
|
import org.teavm.model.instructions.InstructionVisitor;
|
||||||
|
import org.teavm.model.instructions.IntegerConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.InvokeInstruction;
|
||||||
|
import org.teavm.model.instructions.IsInstanceInstruction;
|
||||||
|
import org.teavm.model.instructions.JumpInstruction;
|
||||||
|
import org.teavm.model.instructions.LongConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.MonitorEnterInstruction;
|
||||||
|
import org.teavm.model.instructions.MonitorExitInstruction;
|
||||||
|
import org.teavm.model.instructions.NegateInstruction;
|
||||||
|
import org.teavm.model.instructions.NullCheckInstruction;
|
||||||
|
import org.teavm.model.instructions.NullConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.PutElementInstruction;
|
||||||
|
import org.teavm.model.instructions.PutFieldInstruction;
|
||||||
|
import org.teavm.model.instructions.RaiseInstruction;
|
||||||
|
import org.teavm.model.instructions.StringConstantInstruction;
|
||||||
|
import org.teavm.model.instructions.SwitchInstruction;
|
||||||
|
import org.teavm.model.instructions.UnwrapArrayInstruction;
|
||||||
|
|
||||||
public class PhiUpdater {
|
public class PhiUpdater {
|
||||||
private Program program;
|
private Program program;
|
||||||
|
@ -30,13 +75,15 @@ public class PhiUpdater {
|
||||||
private BasicBlock currentBlock;
|
private BasicBlock currentBlock;
|
||||||
private Phi[][] phiMap;
|
private Phi[][] phiMap;
|
||||||
private int[][] phiIndexMap;
|
private int[][] phiIndexMap;
|
||||||
|
private List<List<Phi>> synthesizedPhis = new ArrayList<>();
|
||||||
|
private boolean[] usedDefinitions;
|
||||||
|
|
||||||
public void updatePhis(Program program, Variable[] arguments) {
|
public void updatePhis(Program program, Variable[] arguments) {
|
||||||
if (program.basicBlockCount() == 0) {
|
if (program.basicBlockCount() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.program = program;
|
this.program = program;
|
||||||
cfg = ProgramUtils.buildControlFlowGraphWithTryCatch(program);
|
cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||||
DominatorTree domTree = GraphUtils.buildDominatorTree(cfg);
|
DominatorTree domTree = GraphUtils.buildDominatorTree(cfg);
|
||||||
domFrontiers = new int[cfg.size()][];
|
domFrontiers = new int[cfg.size()][];
|
||||||
variableMap = new Variable[program.variableCount()];
|
variableMap = new Variable[program.variableCount()];
|
||||||
|
@ -50,6 +97,12 @@ public class PhiUpdater {
|
||||||
phiIndexMap[i] = new int[program.variableCount()];
|
phiIndexMap[i] = new int[program.variableCount()];
|
||||||
}
|
}
|
||||||
domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree);
|
domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree);
|
||||||
|
|
||||||
|
synthesizedPhis.clear();
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
synthesizedPhis.add(new ArrayList<>());
|
||||||
|
}
|
||||||
|
usedDefinitions = new boolean[program.variableCount()];
|
||||||
estimatePhis();
|
estimatePhis();
|
||||||
renameVariables();
|
renameVariables();
|
||||||
}
|
}
|
||||||
|
@ -89,61 +142,54 @@ public class PhiUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<List<TryCatchBlock>> caughtBlocks = new ArrayList<>();
|
List<List<Incoming>> phiOutputs = ProgramUtils.getPhiOutputs(program);
|
||||||
List<List<Phi>> specialPhis = new ArrayList<>();
|
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
|
||||||
caughtBlocks.add(new ArrayList<>());
|
|
||||||
specialPhis.add(new ArrayList<>());
|
|
||||||
}
|
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
|
||||||
for (TryCatchBlock tryCatch : program.basicBlockAt(i).getTryCatchBlocks()) {
|
|
||||||
caughtBlocks.get(tryCatch.getHandler().getIndex()).add(tryCatch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boolean[] processed = new boolean[program.basicBlockCount()];
|
boolean[] processed = new boolean[program.basicBlockCount()];
|
||||||
while (head > 0) {
|
while (head > 0) {
|
||||||
Task task = stack[--head];
|
Task task = stack[--head];
|
||||||
currentBlock = task.block;
|
currentBlock = task.block;
|
||||||
if (processed[currentBlock.getIndex()]) {
|
int index = currentBlock.getIndex();
|
||||||
|
if (processed[index]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
processed[currentBlock.getIndex()] = true;
|
processed[index] = true;
|
||||||
variableMap = Arrays.copyOf(task.variables, task.variables.length);
|
variableMap = Arrays.copyOf(task.variables, task.variables.length);
|
||||||
for (Phi phi : currentBlock.getPhis()) {
|
|
||||||
|
for (Phi phi : synthesizedPhis.get(index)) {
|
||||||
Variable var = program.createVariable();
|
Variable var = program.createVariable();
|
||||||
var.getDebugNames().addAll(phi.getReceiver().getDebugNames());
|
var.getDebugNames().addAll(phi.getReceiver().getDebugNames());
|
||||||
variableMap[phi.getReceiver().getIndex()] = var;
|
variableMap[phi.getReceiver().getIndex()] = var;
|
||||||
phi.setReceiver(var);
|
phi.setReceiver(var);
|
||||||
}
|
}
|
||||||
if (!caughtBlocks.get(currentBlock.getIndex()).isEmpty()) {
|
|
||||||
Phi phi = new Phi();
|
for (Phi phi : currentBlock.getPhis()) {
|
||||||
phi.setReceiver(program.createVariable());
|
phi.setReceiver(define(phi.getReceiver()));
|
||||||
for (TryCatchBlock tryCatch : caughtBlocks.get(currentBlock.getIndex())) {
|
|
||||||
variableMap[tryCatch.getExceptionVariable().getIndex()] = phi.getReceiver();
|
|
||||||
Set<String> debugNames = tryCatch.getExceptionVariable().getDebugNames();
|
|
||||||
tryCatch.setExceptionVariable(program.createVariable());
|
|
||||||
tryCatch.getExceptionVariable().getDebugNames().addAll(debugNames);
|
|
||||||
Incoming incoming = new Incoming();
|
|
||||||
incoming.setSource(tryCatch.getProtectedBlock());
|
|
||||||
incoming.setValue(tryCatch.getExceptionVariable());
|
|
||||||
phi.getIncomings().add(incoming);
|
|
||||||
}
|
|
||||||
specialPhis.get(currentBlock.getIndex()).add(phi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Instruction insn : currentBlock.getInstructions()) {
|
for (Instruction insn : currentBlock.getInstructions()) {
|
||||||
insn.acceptVisitor(consumer);
|
insn.acceptVisitor(consumer);
|
||||||
}
|
}
|
||||||
int[] successors = domGraph.outgoingEdges(currentBlock.getIndex());
|
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
|
||||||
|
Variable var = tryCatch.getExceptionVariable();
|
||||||
|
if (var != null) {
|
||||||
|
tryCatch.setExceptionVariable(define(var));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Incoming output : phiOutputs.get(index)) {
|
||||||
|
output.setValue(use(output.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] successors = domGraph.outgoingEdges(index);
|
||||||
for (int successor : successors) {
|
for (int successor : successors) {
|
||||||
Task next = new Task();
|
Task next = new Task();
|
||||||
next.variables = Arrays.copyOf(variableMap, variableMap.length);
|
next.variables = Arrays.copyOf(variableMap, variableMap.length);
|
||||||
next.block = program.basicBlockAt(successor);
|
next.block = program.basicBlockAt(successor);
|
||||||
stack[head++] = next;
|
stack[head++] = next;
|
||||||
}
|
}
|
||||||
successors = cfg.outgoingEdges(currentBlock.getIndex());
|
successors = cfg.outgoingEdges(index);
|
||||||
for (int successor : successors) {
|
for (int successor : successors) {
|
||||||
int[] phiIndexes = phiIndexMap[successor];
|
int[] phiIndexes = phiIndexMap[successor];
|
||||||
List<Phi> phis = program.basicBlockAt(successor).getPhis();
|
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 = variableMap[phiIndexes[j]];
|
Variable var = variableMap[phiIndexes[j]];
|
||||||
|
@ -156,9 +202,8 @@ public class PhiUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (int i = 0; i < specialPhis.size(); ++i) {
|
program.basicBlockAt(index).getPhis().addAll(synthesizedPhis.get(index));
|
||||||
program.basicBlockAt(i).getPhis().addAll(specialPhis.get(i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,13 +219,12 @@ public class PhiUpdater {
|
||||||
}
|
}
|
||||||
for (int frontier : frontiers) {
|
for (int frontier : frontiers) {
|
||||||
BasicBlock frontierBlock = program.basicBlockAt(frontier);
|
BasicBlock frontierBlock = program.basicBlockAt(frontier);
|
||||||
frontierBlock.getPhis();
|
|
||||||
Phi phi = phiMap[frontier][var.getIndex()];
|
Phi phi = phiMap[frontier][var.getIndex()];
|
||||||
if (phi == null) {
|
if (phi == null) {
|
||||||
phi = new Phi();
|
phi = new Phi();
|
||||||
phi.setReceiver(var);
|
phi.setReceiver(var);
|
||||||
phiIndexMap[frontier][frontierBlock.getPhis().size()] = var.getIndex();
|
phiIndexMap[frontier][synthesizedPhis.get(frontier).size()] = var.getIndex();
|
||||||
frontierBlock.getPhis().add(phi);
|
synthesizedPhis.get(frontier).add(phi);
|
||||||
phiMap[frontier][var.getIndex()] = phi;
|
phiMap[frontier][var.getIndex()] = phi;
|
||||||
worklist[head++] = frontierBlock;
|
worklist[head++] = frontierBlock;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +233,14 @@ public class PhiUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Variable define(Variable var) {
|
private Variable define(Variable var) {
|
||||||
Variable result = program.createVariable();
|
Variable result;
|
||||||
|
if (!usedDefinitions[var.getIndex()]) {
|
||||||
|
usedDefinitions[var.getIndex()] = true;
|
||||||
|
result = var;
|
||||||
|
} else {
|
||||||
|
result = program.createVariable();
|
||||||
|
}
|
||||||
|
|
||||||
variableMap[var.getIndex()] = result;
|
variableMap[var.getIndex()] = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,30 +59,6 @@ public final class ProgramUtils {
|
||||||
return graphBuilder.build();
|
return graphBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Graph buildControlFlowGraphWithTryCatch(Program program) {
|
|
||||||
GraphBuilder graphBuilder = new GraphBuilder(program.basicBlockCount());
|
|
||||||
InstructionTransitionExtractor transitionExtractor = new InstructionTransitionExtractor();
|
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
|
||||||
Instruction insn = block.getLastInstruction();
|
|
||||||
if (insn != null) {
|
|
||||||
insn.acceptVisitor(transitionExtractor);
|
|
||||||
if (transitionExtractor.getTargets() != null) {
|
|
||||||
for (BasicBlock successor : transitionExtractor.getTargets()) {
|
|
||||||
graphBuilder.addEdge(i, successor.getIndex());
|
|
||||||
for (TryCatchBlock succTryCatch : successor.getTryCatchBlocks()) {
|
|
||||||
graphBuilder.addEdge(i, succTryCatch.getHandler().getIndex());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
|
||||||
graphBuilder.addEdge(i, tryCatch.getHandler().getIndex());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return graphBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<InstructionLocation, InstructionLocation[]> getLocationCFG(Program program) {
|
public static Map<InstructionLocation, InstructionLocation[]> getLocationCFG(Program program) {
|
||||||
return new LocationGraphBuilder().build(program);
|
return new LocationGraphBuilder().build(program);
|
||||||
}
|
}
|
||||||
|
@ -149,4 +125,22 @@ public final class ProgramUtils {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<List<Incoming>> getPhiOutputs(Program program) {
|
||||||
|
List<List<Incoming>> outputs = new ArrayList<>(program.basicBlockCount());
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
outputs.add(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
for (Phi phi : block.getPhis()) {
|
||||||
|
for (Incoming incoming : phi.getIncomings()) {
|
||||||
|
outputs.get(incoming.getSource().getIndex()).add(incoming);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.optimization;
|
package org.teavm.optimization;
|
||||||
|
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
import org.teavm.model.MethodReader;
|
import org.teavm.model.MethodReader;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
|
|
||||||
public class LoopInversion implements MethodOptimization {
|
public class LoopInversion implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void optimize(MethodReader method, Program program) {
|
public void optimize(MethodReader method, Program program) {
|
||||||
new LoopInversionImpl(program).apply();
|
new LoopInversionImpl(program, method.parameterCount() + 1).apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,10 @@ import org.teavm.model.Instruction;
|
||||||
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;
|
||||||
|
import org.teavm.model.Variable;
|
||||||
import org.teavm.model.util.BasicBlockMapper;
|
import org.teavm.model.util.BasicBlockMapper;
|
||||||
import org.teavm.model.util.InstructionCopyReader;
|
import org.teavm.model.util.InstructionCopyReader;
|
||||||
|
import org.teavm.model.util.PhiUpdater;
|
||||||
import org.teavm.model.util.ProgramUtils;
|
import org.teavm.model.util.ProgramUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,12 +76,15 @@ import org.teavm.model.util.ProgramUtils;
|
||||||
*/
|
*/
|
||||||
class LoopInversionImpl {
|
class LoopInversionImpl {
|
||||||
private final Program program;
|
private final Program program;
|
||||||
|
private final int parameterCount;
|
||||||
private Graph cfg;
|
private Graph cfg;
|
||||||
private DominatorTree dom;
|
private DominatorTree dom;
|
||||||
private boolean postponed;
|
private boolean postponed;
|
||||||
|
private boolean changed;
|
||||||
|
|
||||||
LoopInversionImpl(Program program) {
|
LoopInversionImpl(Program program, int parameterCount) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
|
this.parameterCount = parameterCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply() {
|
void apply() {
|
||||||
|
@ -90,8 +95,17 @@ class LoopInversionImpl {
|
||||||
List<LoopWithExits> loops = getLoopsWithExits(loopGraph);
|
List<LoopWithExits> loops = getLoopsWithExits(loopGraph);
|
||||||
|
|
||||||
postponed = false;
|
postponed = false;
|
||||||
for (LoopWithExits loop : loops) {
|
if (!loops.isEmpty()) {
|
||||||
loop.invert();
|
for (LoopWithExits loop : loops) {
|
||||||
|
loop.invert();
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
Variable[] inputs = new Variable[parameterCount];
|
||||||
|
for (int i = 0; i < inputs.length; ++i) {
|
||||||
|
inputs[i] = program.variableAt(i);
|
||||||
|
}
|
||||||
|
new PhiUpdater().updatePhis(program, inputs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (postponed);
|
} while (postponed);
|
||||||
}
|
}
|
||||||
|
@ -185,6 +199,7 @@ class LoopInversionImpl {
|
||||||
removeInternalPhiInputsFromCondition();
|
removeInternalPhiInputsFromCondition();
|
||||||
removeExternalPhiInputsFromConditionCopy();
|
removeExternalPhiInputsFromConditionCopy();
|
||||||
|
|
||||||
|
changed = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,26 +15,89 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.vm;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.Set;
|
||||||
import org.teavm.cache.NoCache;
|
import org.teavm.cache.NoCache;
|
||||||
import org.teavm.codegen.*;
|
import org.teavm.codegen.AliasProvider;
|
||||||
|
import org.teavm.codegen.DefaultAliasProvider;
|
||||||
|
import org.teavm.codegen.DefaultNamingStrategy;
|
||||||
|
import org.teavm.codegen.MinifyingAliasProvider;
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.codegen.SourceWriterBuilder;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.debugging.information.DebugInformationEmitter;
|
import org.teavm.debugging.information.DebugInformationEmitter;
|
||||||
import org.teavm.debugging.information.SourceLocation;
|
import org.teavm.debugging.information.SourceLocation;
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.BootstrapMethodSubstitutor;
|
||||||
|
import org.teavm.dependency.DependencyChecker;
|
||||||
|
import org.teavm.dependency.DependencyInfo;
|
||||||
|
import org.teavm.dependency.DependencyListener;
|
||||||
|
import org.teavm.dependency.Linker;
|
||||||
|
import org.teavm.dependency.MethodDependency;
|
||||||
import org.teavm.diagnostics.AccumulationDiagnostics;
|
import org.teavm.diagnostics.AccumulationDiagnostics;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
import org.teavm.javascript.*;
|
import org.teavm.javascript.Decompiler;
|
||||||
|
import org.teavm.javascript.EmptyRegularMethodNodeCache;
|
||||||
|
import org.teavm.javascript.MethodNodeCache;
|
||||||
|
import org.teavm.javascript.Renderer;
|
||||||
|
import org.teavm.javascript.RenderingException;
|
||||||
import org.teavm.javascript.ast.ClassNode;
|
import org.teavm.javascript.ast.ClassNode;
|
||||||
import org.teavm.javascript.spi.GeneratedBy;
|
import org.teavm.javascript.spi.GeneratedBy;
|
||||||
import org.teavm.javascript.spi.Generator;
|
import org.teavm.javascript.spi.Generator;
|
||||||
import org.teavm.javascript.spi.InjectedBy;
|
import org.teavm.javascript.spi.InjectedBy;
|
||||||
import org.teavm.javascript.spi.Injector;
|
import org.teavm.javascript.spi.Injector;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.BasicBlock;
|
||||||
import org.teavm.model.instructions.*;
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.util.*;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.optimization.*;
|
import org.teavm.model.ClassHolderSource;
|
||||||
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
import org.teavm.model.ClassReader;
|
||||||
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
import org.teavm.model.ElementHolder;
|
||||||
|
import org.teavm.model.ElementModifier;
|
||||||
|
import org.teavm.model.InstructionLocation;
|
||||||
|
import org.teavm.model.ListableClassHolderSource;
|
||||||
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
|
import org.teavm.model.MethodHolder;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.MutableClassHolderSource;
|
||||||
|
import org.teavm.model.Program;
|
||||||
|
import org.teavm.model.ProgramCache;
|
||||||
|
import org.teavm.model.ValueType;
|
||||||
|
import org.teavm.model.Variable;
|
||||||
|
import org.teavm.model.instructions.ConstructInstruction;
|
||||||
|
import org.teavm.model.instructions.InvocationType;
|
||||||
|
import org.teavm.model.instructions.InvokeInstruction;
|
||||||
|
import org.teavm.model.instructions.RaiseInstruction;
|
||||||
|
import org.teavm.model.instructions.StringConstantInstruction;
|
||||||
|
import org.teavm.model.util.AsyncMethodFinder;
|
||||||
|
import org.teavm.model.util.ListingBuilder;
|
||||||
|
import org.teavm.model.util.MissingItemsProcessor;
|
||||||
|
import org.teavm.model.util.ModelUtils;
|
||||||
|
import org.teavm.model.util.ProgramUtils;
|
||||||
|
import org.teavm.model.util.RegisterAllocator;
|
||||||
|
import org.teavm.optimization.ArrayUnwrapMotion;
|
||||||
|
import org.teavm.optimization.Devirtualization;
|
||||||
|
import org.teavm.optimization.GlobalValueNumbering;
|
||||||
|
import org.teavm.optimization.LoopInvariantMotion;
|
||||||
|
import org.teavm.optimization.LoopInversion;
|
||||||
|
import org.teavm.optimization.MethodOptimization;
|
||||||
|
import org.teavm.optimization.UnusedVariableElimination;
|
||||||
import org.teavm.vm.spi.RendererListener;
|
import org.teavm.vm.spi.RendererListener;
|
||||||
import org.teavm.vm.spi.TeaVMHost;
|
import org.teavm.vm.spi.TeaVMHost;
|
||||||
import org.teavm.vm.spi.TeaVMPlugin;
|
import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
|
@ -649,7 +712,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MethodOptimization> getOptimizations() {
|
private List<MethodOptimization> getOptimizations() {
|
||||||
return Arrays.asList(new ArrayUnwrapMotion(), /*new LoopInversion(),*/ new LoopInvariantMotion(),
|
return Arrays.asList(new ArrayUnwrapMotion(), new LoopInversion(), new LoopInvariantMotion(),
|
||||||
new GlobalValueNumbering(), new UnusedVariableElimination());
|
new GlobalValueNumbering(), new UnusedVariableElimination());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user