Bugfixes. Start to implement phi eliminator through interting copies for

all phi arguments and then coalescing.
This commit is contained in:
konsoletyper 2014-01-23 17:19:36 +04:00
parent e5a083b4c7
commit 73884794a4
6 changed files with 260 additions and 12 deletions

View File

@ -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) {

View File

@ -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) {
}
}

View File

@ -195,5 +195,6 @@ public class DefinitionExtractor implements InstructionVisitor {
@Override
public void visit(InitClassInstruction insn) {
definedVariables = new Variable[0];
}
}

View File

@ -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) {

View File

@ -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()) {

View File

@ -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();
}
}