mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Bugfixes. Start to implement phi eliminator through interting copies for
all phi arguments and then coalescing.
This commit is contained in:
parent
e5a083b4c7
commit
73884794a4
|
@ -43,6 +43,9 @@ public class GraphBuilder {
|
|||
}
|
||||
|
||||
public void addEdge(int from, int to) {
|
||||
if (to < 0) {
|
||||
throw new IllegalArgumentException("To is negative: " + to);
|
||||
}
|
||||
sz = Math.max(sz, Math.max(from, to) + 1);
|
||||
builtGraph = null;
|
||||
if (addedEdges.size() == from) {
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright 2014 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.util;
|
||||
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.Incoming;
|
||||
import org.teavm.model.Phi;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.instructions.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public abstract class BasicBlockMapper implements InstructionVisitor {
|
||||
protected abstract BasicBlock map(BasicBlock block);
|
||||
|
||||
public void transform(Program program) {
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
block.getLastInstruction().acceptVisitor(this);
|
||||
for (Phi phi : block.getPhis()) {
|
||||
for (Incoming incoming : phi.getIncomings()) {
|
||||
incoming.setSource(map(incoming.getSource()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(EmptyInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ClassConstantInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NullConstantInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IntegerConstantInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LongConstantInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FloatConstantInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DoubleConstantInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(StringConstantInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NegateInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AssignInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CastInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CastNumberInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CastIntegerInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BranchingInstruction insn) {
|
||||
insn.setConsequent(map(insn.getConsequent()));
|
||||
insn.setAlternative(map(insn.getAlternative()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryBranchingInstruction insn) {
|
||||
insn.setConsequent(map(insn.getConsequent()));
|
||||
insn.setAlternative(map(insn.getAlternative()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(JumpInstruction insn) {
|
||||
insn.setTarget(map(insn.getTarget()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SwitchInstruction insn) {
|
||||
for (SwitchTableEntry entry : insn.getEntries()) {
|
||||
entry.setTarget(map(entry.getTarget()));
|
||||
}
|
||||
insn.setDefaultTarget(map(insn.getDefaultTarget()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ExitInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaiseInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructArrayInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructMultiArrayInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GetFieldInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PutFieldInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ArrayLengthInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CloneArrayInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UnwrapArrayInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GetElementInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PutElementInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(InvokeInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IsInstanceInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(InitClassInstruction insn) {
|
||||
}
|
||||
}
|
|
@ -195,5 +195,6 @@ public class DefinitionExtractor implements InstructionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(InitClassInstruction insn) {
|
||||
definedVariables = new Variable[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,9 @@ public class RegisterAllocator {
|
|||
for (int i = 0; i < method.parameterCount(); ++i) {
|
||||
colors[i] = i;
|
||||
}
|
||||
List<List<Incoming>> involvedIncomings = getInvolvedIncomings(method.getProgram());
|
||||
GraphBuilder graphBuilder = new GraphBuilder();
|
||||
Program program = method.getProgram();
|
||||
for (int v = 0; v < program.variableCount(); ++v) {
|
||||
for (int v = 0; v < interferenceGraph.size(); ++v) {
|
||||
for (int w : interferenceGraph.outgoingEdges(v)) {
|
||||
if (w <= v) {
|
||||
continue;
|
||||
|
@ -55,20 +54,21 @@ public class RegisterAllocator {
|
|||
return colors;
|
||||
}
|
||||
|
||||
private List<List<Incoming>> getInvolvedIncomings(Program program) {
|
||||
List<List<Incoming>> involvedIncomings = new ArrayList<>();
|
||||
for (int i = 0; i < program.variableCount(); ++i) {
|
||||
involvedIncomings.add(new ArrayList<Incoming>());
|
||||
private static class PhiArgumentCopy {
|
||||
Incoming incoming;
|
||||
int original;
|
||||
}
|
||||
|
||||
private List<PhiArgumentCopy> insertPhiArgumentsCopies(Program program) {
|
||||
List<PhiArgumentCopy> copies = new ArrayList<>();
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
for (Phi phi : block.getPhis()) {
|
||||
for (Phi phi : program.basicBlockAt(i).getPhis()) {
|
||||
for (Incoming incoming : phi.getIncomings()) {
|
||||
involvedIncomings.get(incoming.getValue().getIndex()).add(incoming);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return involvedIncomings;
|
||||
return copies;
|
||||
}
|
||||
|
||||
private int[] buildPhiCongruenceClasses(Program program) {
|
||||
|
|
|
@ -27,7 +27,8 @@ import org.teavm.model.MethodHolder;
|
|||
*/
|
||||
public class ClassSetOptimizer {
|
||||
private List<MethodOptimization> optimizations = Arrays.<MethodOptimization>asList(
|
||||
new CommonSubexpressionElimination(), new UnusedVariableElimination());
|
||||
new CommonSubexpressionElimination(), new UnusedVariableElimination(),
|
||||
new EmptyBlockElimination());
|
||||
|
||||
public void optimizeAll(ListableClassHolderSource classSource) {
|
||||
for (String className : classSource.getClassNames()) {
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2014 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.optimization;
|
||||
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.instructions.JumpInstruction;
|
||||
import org.teavm.model.util.BasicBlockMapper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class EmptyBlockElimination implements MethodOptimization {
|
||||
@Override
|
||||
public void optimize(MethodHolder method) {
|
||||
final Program program = method.getProgram();
|
||||
final int[] blockMapping = new int[program.basicBlockCount()];
|
||||
for (int i = 0; i < blockMapping.length; ++i) {
|
||||
blockMapping[i] = i;
|
||||
}
|
||||
int lastNonEmpty = program.basicBlockCount() - 1;
|
||||
for (int i = program.basicBlockCount() - 2; i > 0; --i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
if (block.getPhis().isEmpty() && block.getInstructions().size() == 1 &&
|
||||
block.getLastInstruction() instanceof JumpInstruction) {
|
||||
JumpInstruction insn = (JumpInstruction)block.getLastInstruction();
|
||||
if (insn.getTarget().getIndex() == i + 1) {
|
||||
blockMapping[i] = lastNonEmpty;
|
||||
}
|
||||
}
|
||||
lastNonEmpty = blockMapping[i];
|
||||
}
|
||||
new BasicBlockMapper() {
|
||||
@Override protected BasicBlock map(BasicBlock block) {
|
||||
return program.basicBlockAt(blockMapping[block.getIndex()]);
|
||||
}
|
||||
}.transform(program);
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
if (blockMapping[i] != i) {
|
||||
program.deleteBasicBlock(i);
|
||||
}
|
||||
}
|
||||
program.pack();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user