mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Fixes bugs. Adds JCL implementation
This commit is contained in:
parent
59e6095fef
commit
31b9525309
|
@ -54,6 +54,9 @@
|
|||
<configuration>
|
||||
<minifying>false</minifying>
|
||||
<numThreads>1</numThreads>
|
||||
<wildcards>
|
||||
<param>**.ArraysTest</param>
|
||||
</wildcards>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
|
|
|
@ -128,10 +128,10 @@ public class TArrayList<E> extends TAbstractList<E> implements TCloneable, TSeri
|
|||
}
|
||||
ensureCapacity(size + c.size());
|
||||
int gap = c.size();
|
||||
size += gap;
|
||||
for (int i = gap - 1; i > index; --i) {
|
||||
array[i] = array[i - gap];
|
||||
for (int i = size - 1; i >= index; --i) {
|
||||
array[i + gap] = array[i];
|
||||
}
|
||||
size += gap;
|
||||
TIterator<? extends E> iter = c.iterator();
|
||||
for (int i = 0; i < gap; ++i) {
|
||||
array[index++] = iter.next();
|
||||
|
|
|
@ -182,4 +182,99 @@ public class TArrays extends TObject {
|
|||
public static void fill(TObject[] a, TObject val) {
|
||||
fill(a, 0, a.length, val);
|
||||
}
|
||||
|
||||
|
||||
public static void sort(Object[] a) {
|
||||
sort(a, new NaturalOrder());
|
||||
}
|
||||
|
||||
public static void sort(Object[] a, int fromIndex, int toIndex) {
|
||||
sort(a, fromIndex, toIndex, new NaturalOrder());
|
||||
}
|
||||
|
||||
private static class NaturalOrder implements TComparator<Object> {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override public int compare(Object o1, Object o2) {
|
||||
if (o1 != null) {
|
||||
return ((TComparable)o1).compareTo((TComparable)o2);
|
||||
} else if (o2 != null) {
|
||||
return ((TComparable)o2).compareTo((TComparable)o1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void sort(T[] a, int fromIndex, int toIndex, TComparator<? super T> c) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] subarray = (T[])new Object[toIndex - fromIndex];
|
||||
for (int i = fromIndex; i < toIndex; ++i) {
|
||||
subarray[i - fromIndex] = a[i];
|
||||
}
|
||||
sort(subarray, c);
|
||||
for (int i = fromIndex; i < toIndex; ++i) {
|
||||
a[i] = subarray[i - fromIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> void sort(T[] a, TComparator<? super T> c) {
|
||||
Object[] first = a;
|
||||
Object[] second = new Object[a.length];
|
||||
int chunkSize = 1;
|
||||
while (chunkSize < a.length) {
|
||||
for (int i = 0; i < first.length; i += chunkSize * 2) {
|
||||
merge(first, second, i, Math.min(first.length, i + chunkSize),
|
||||
Math.min(first.length, i + 2 * chunkSize), (TComparator<Object>)c);
|
||||
}
|
||||
Object[] tmp = first;
|
||||
first = second;
|
||||
second = tmp;
|
||||
chunkSize *= 2;
|
||||
}
|
||||
if (first != a) {
|
||||
for (int i = 0; i < first.length; ++i) {
|
||||
second[i] = first[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void merge(Object[] a, Object[] b, int from, int split, int to, TComparator<Object> comp) {
|
||||
int index = from;
|
||||
int from2 = split;
|
||||
while (true) {
|
||||
if (from == split) {
|
||||
while (from2 < to) {
|
||||
b[index++] = a[from2++];
|
||||
}
|
||||
break;
|
||||
} else if (from2 == to) {
|
||||
while (from < split) {
|
||||
b[index++] = a[from++];
|
||||
}
|
||||
break;
|
||||
}
|
||||
Object p = a[from];
|
||||
Object q = a[from2];
|
||||
if (comp.compare(p, q) <= 0) {
|
||||
b[index++] = p;
|
||||
++from;
|
||||
} else {
|
||||
b[index++] = q;
|
||||
++from2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> TList<T> asList(final T... a) {
|
||||
return new TAbstractList<T>() {
|
||||
@Override public T get(int index) {
|
||||
return a[index];
|
||||
}
|
||||
@Override public int size() {
|
||||
return a.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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.classlib.java.util;
|
||||
|
||||
import org.teavm.classlib.java.lang.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TCollections extends TObject {
|
||||
public static <T> TIterator<T> emptyIterator() {
|
||||
return new TIterator<T>() {
|
||||
@Override public boolean hasNext() {
|
||||
return false;
|
||||
}
|
||||
@Override public T next() {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
@Override public void remove() {
|
||||
throw new TIllegalStateException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> TListIterator<T> emptyListIterator() {
|
||||
return new TListIterator<T>() {
|
||||
@Override public boolean hasNext() {
|
||||
return false;
|
||||
}
|
||||
@Override public T next() {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
@Override public void remove() {
|
||||
throw new TIllegalStateException();
|
||||
}
|
||||
@Override public boolean hasPrevious() {
|
||||
return false;
|
||||
}
|
||||
@Override public T previous() {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
@Override public int nextIndex() {
|
||||
return 0;
|
||||
}
|
||||
@Override public int previousIndex() {
|
||||
return -1;
|
||||
}
|
||||
@Override public void set(T e) {
|
||||
throw new TUnsupportedOperationException();
|
||||
}
|
||||
@Override public void add(T e) {
|
||||
throw new TUnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static final <T> TList<T> emptyList() {
|
||||
return new TAbstractList<T>() {
|
||||
@Override public T get(int index) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
@Override public int size() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> TList<T> singletonList(final T o) {
|
||||
return new TAbstractList<T>() {
|
||||
@Override public T get(int index) {
|
||||
if (index != 0) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
@Override public int size() {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> TList<T> nCopies(final int n, final T o) {
|
||||
return new TAbstractList<T>() {
|
||||
@Override public T get(int index) {
|
||||
if (index < 0 || index >= n) {
|
||||
throw new TIndexOutOfBoundsException();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
@Override public int size() {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void swap(TList<?> list, int i, int j) {
|
||||
@SuppressWarnings("unchecked")
|
||||
TList<Object> objList = (TList<Object>)list;
|
||||
Object tmp = objList.get(i);
|
||||
objList.set(i, objList.get(j));
|
||||
objList.set(j, tmp);
|
||||
}
|
||||
|
||||
public static <T> void sort(TList<T> list, TComparator<? super T> c) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T[] array = (T[])new Object[list.size()];
|
||||
list.toArray(array);
|
||||
TArrays.sort(array, c);
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
list.set(i, array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends TComparable<? super T>> void sort(TList<T> list) {
|
||||
sort(list, new TComparator<T>() {
|
||||
@Override public int compare(T o1, T o2) {
|
||||
return o1 != null ? o1.compareTo(o2) : -o2.compareTo(o1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -15,14 +15,10 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import org.teavm.classlib.java.lang.TObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public interface TComparator<T extends TObject> {
|
||||
public interface TComparator<T> {
|
||||
int compare(T o1, T o2);
|
||||
|
||||
boolean equals(TObject obj);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,35 @@ public class ArrayListTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void manyElementsAdded() {
|
||||
List<Integer> list = fillFromZeroToNine();
|
||||
list.addAll(3, fillFromZeroToNine());
|
||||
assertEquals(20, list.size());
|
||||
assertEquals(Integer.valueOf(2), list.get(2));
|
||||
assertEquals(Integer.valueOf(0), list.get(3));
|
||||
assertEquals(Integer.valueOf(9), list.get(12));
|
||||
assertEquals(Integer.valueOf(3), list.get(13));
|
||||
assertEquals(Integer.valueOf(9), list.get(19));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void manyElementsRemoved() {
|
||||
List<Integer> list = fillFromZeroToNine();
|
||||
list.subList(2, 4).clear();
|
||||
assertEquals(8, list.size());
|
||||
assertEquals(Integer.valueOf(1), list.get(1));
|
||||
assertEquals(Integer.valueOf(4), list.get(2));
|
||||
assertEquals(Integer.valueOf(9), list.get(7));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void elementIndexFound() {
|
||||
List<Integer> list = fillFromZeroToNine();
|
||||
assertEquals(3, list.indexOf(3));
|
||||
assertEquals(-1, list.indexOf(100));
|
||||
}
|
||||
|
||||
private List<Integer> fillFromZeroToNine() {
|
||||
List<Integer> list = new ArrayList<>();
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.classlib.java.lang.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class ArraysTest {
|
||||
@Test
|
||||
public void arraySorted() {
|
||||
Integer[] array = { 2, 5, 7, 3, 5, 6 };
|
||||
Arrays.sort(array);
|
||||
assertEquals(Integer.valueOf(2), array[0]);
|
||||
assertEquals(Integer.valueOf(3), array[1]);
|
||||
assertEquals(Integer.valueOf(5), array[2]);
|
||||
assertEquals(Integer.valueOf(5), array[3]);
|
||||
assertEquals(Integer.valueOf(6), array[4]);
|
||||
assertEquals(Integer.valueOf(7), array[5]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayExposedAsList() {
|
||||
Integer[] array = { 2, 3, 4 };
|
||||
List<Integer> list = Arrays.asList(array);
|
||||
assertEquals(3, list.size());
|
||||
assertEquals(Integer.valueOf(4), list.get(2));
|
||||
}
|
||||
}
|
|
@ -43,8 +43,8 @@ public class GraphBuilder {
|
|||
}
|
||||
|
||||
public void addEdge(int from, int to) {
|
||||
if (to < 0) {
|
||||
throw new IllegalArgumentException("To is negative: " + to);
|
||||
if (to < 0 || from < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
sz = Math.max(sz, Math.max(from, to) + 1);
|
||||
builtGraph = null;
|
||||
|
|
|
@ -141,7 +141,6 @@ public class DependencyChecker implements DependencyInfo {
|
|||
}
|
||||
|
||||
public void schedulePropagation(final DependencyConsumer consumer, final String type) {
|
||||
System.out.print("");
|
||||
executor.executeFast(new Runnable() {
|
||||
@Override public void run() {
|
||||
consumer.consume(type);
|
||||
|
|
|
@ -41,8 +41,8 @@ class DependencyNodeToNodeTransition implements DependencyConsumer {
|
|||
}
|
||||
if (!destination.hasType(type)) {
|
||||
destination.propagate(type);
|
||||
source.getArrayItem().connect(destination.getArrayItem());
|
||||
destination.getArrayItem().connect(source.getArrayItem());
|
||||
}
|
||||
source.getArrayItem().connect(destination.getArrayItem());
|
||||
destination.getArrayItem().connect(source.getArrayItem());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* 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.Variable;
|
||||
import org.teavm.model.instructions.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public abstract class InstructionVariableMapper implements InstructionVisitor {
|
||||
protected abstract Variable map(Variable var);
|
||||
|
||||
@Override
|
||||
public void visit(EmptyInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ClassConstantInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NullConstantInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IntegerConstantInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LongConstantInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FloatConstantInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DoubleConstantInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(StringConstantInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setFirstOperand(map(insn.getFirstOperand()));
|
||||
insn.setSecondOperand(map(insn.getSecondOperand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NegateInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setOperand(map(insn.getOperand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AssignInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setAssignee(map(insn.getAssignee()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CastInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setValue(map(insn.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CastNumberInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setValue(map(insn.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CastIntegerInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setValue(map(insn.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BranchingInstruction insn) {
|
||||
insn.setOperand(map(insn.getOperand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryBranchingInstruction insn) {
|
||||
insn.setFirstOperand(map(insn.getFirstOperand()));
|
||||
insn.setSecondOperand(map(insn.getSecondOperand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(JumpInstruction insn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SwitchInstruction insn) {
|
||||
insn.setCondition(insn.getCondition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ExitInstruction insn) {
|
||||
if (insn.getValueToReturn() != null) {
|
||||
insn.setValueToReturn(map(insn.getValueToReturn()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RaiseInstruction insn) {
|
||||
insn.setException(map(insn.getException()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructArrayInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setSize(map(insn.getSize()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ConstructMultiArrayInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
for (int i = 0; i < insn.getDimensions().size(); ++i) {
|
||||
insn.getDimensions().set(i, map(insn.getDimensions().get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GetFieldInstruction insn) {
|
||||
if (insn.getInstance() != null) {
|
||||
insn.setInstance(map(insn.getInstance()));
|
||||
}
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PutFieldInstruction insn) {
|
||||
if (insn.getInstance() != null) {
|
||||
insn.setInstance(map(insn.getInstance()));
|
||||
}
|
||||
insn.setValue(map(insn.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ArrayLengthInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setArray(map(insn.getArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CloneArrayInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setArray(map(insn.getArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UnwrapArrayInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setArray(map(insn.getArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(GetElementInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setArray(map(insn.getArray()));
|
||||
insn.setIndex(map(insn.getIndex()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PutElementInstruction insn) {
|
||||
insn.setValue(map(insn.getValue()));
|
||||
insn.setArray(map(insn.getArray()));
|
||||
insn.setIndex(map(insn.getIndex()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(InvokeInstruction insn) {
|
||||
if (insn.getReceiver() != null) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
}
|
||||
if (insn.getInstance() != null) {
|
||||
insn.setInstance(map(insn.getInstance()));
|
||||
}
|
||||
for (int i = 0; i < insn.getArguments().size(); ++i) {
|
||||
insn.getArguments().set(i, map(insn.getArguments().get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IsInstanceInstruction insn) {
|
||||
insn.setReceiver(map(insn.getReceiver()));
|
||||
insn.setValue(map(insn.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(InitClassInstruction insn) {
|
||||
}
|
||||
|
||||
}
|
|
@ -150,11 +150,15 @@ public class RegisterAllocator {
|
|||
copy.incoming.setValue(program.variableAt(copy.original));
|
||||
for (MutableGraphEdge edge : interferenceGraph.get(varClass).getEdges()
|
||||
.toArray(new MutableGraphEdge[0])) {
|
||||
edge.setFirst(interferenceGraph.get(newClass));
|
||||
if (edge.getFirst() != null) {
|
||||
edge.setFirst(interferenceGraph.get(newClass));
|
||||
}
|
||||
}
|
||||
for (MutableGraphEdge edge : interferenceGraph.get(origClass).getEdges()
|
||||
.toArray(new MutableGraphEdge[0])) {
|
||||
edge.setFirst(interferenceGraph.get(newClass));
|
||||
if (edge.getFirst() != null) {
|
||||
edge.setFirst(interferenceGraph.get(newClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class ClassSetOptimizer {
|
|||
}
|
||||
|
||||
private List<MethodOptimization> getOptimizations() {
|
||||
return Arrays.<MethodOptimization>asList(new CommonSubexpressionElimination(), new UnusedVariableElimination());
|
||||
return Arrays.<MethodOptimization>asList(new UnusedVariableElimination());
|
||||
}
|
||||
|
||||
public void optimizeAll(ListableClassHolderSource classSource) {
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
*/
|
||||
package org.teavm.optimization;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.teavm.common.DominatorTree;
|
||||
import org.teavm.common.Graph;
|
||||
|
@ -52,6 +54,7 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
|||
for (int i = 0; i < map.length; ++i) {
|
||||
map[i] = i;
|
||||
}
|
||||
List<List<Incoming>> outgoings = findOutgoings(program);
|
||||
|
||||
int[] stack = new int[cfg.size() * 2];
|
||||
int top = 0;
|
||||
|
@ -64,7 +67,7 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
|||
int v = stack[--top];
|
||||
currentBlockIndex = v;
|
||||
BasicBlock block = program.basicBlockAt(v);
|
||||
for (int i = 0; i < block.getPhis().size(); ++i) {
|
||||
/*for (int i = 0; i < block.getPhis().size(); ++i) {
|
||||
Phi phi = block.getPhis().get(i);
|
||||
int sharedValue = -2;
|
||||
for (Incoming incoming : phi.getIncomings()) {
|
||||
|
@ -77,32 +80,31 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
|||
}
|
||||
}
|
||||
if (sharedValue != -1) {
|
||||
map[phi.getReceiver().getIndex()] = sharedValue;
|
||||
if (sharedValue != -2) {
|
||||
AssignInstruction assignInsn = new AssignInstruction();
|
||||
assignInsn.setReceiver(phi.getReceiver());
|
||||
assignInsn.setAssignee(program.variableAt(sharedValue));
|
||||
block.getInstructions().add(0, assignInsn);
|
||||
}
|
||||
block.getPhis().remove(i--);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
for (int i = 0; i < block.getInstructions().size(); ++i) {
|
||||
Instruction currentInsn = block.getInstructions().get(i);
|
||||
currentInsn.acceptVisitor(optimizer);
|
||||
if (eliminate) {
|
||||
block.getInstructions().remove(i--);
|
||||
block.getInstructions().set(i, new EmptyInstruction());
|
||||
eliminate = false;
|
||||
}
|
||||
}
|
||||
for (Incoming incoming : outgoings.get(v)) {
|
||||
int value = map[incoming.getValue().getIndex()];
|
||||
incoming.setValue(program.variableAt(value));
|
||||
}
|
||||
for (int succ : dom.outgoingEdges(v)) {
|
||||
stack[top++] = succ;
|
||||
}
|
||||
}
|
||||
for (int v = 0; v < program.basicBlockCount(); ++v) {
|
||||
BasicBlock block = program.basicBlockAt(v);
|
||||
for (int i = 0; i < block.getPhis().size(); ++i) {
|
||||
Phi phi = block.getPhis().get(i);
|
||||
for (Incoming incoming : phi.getIncomings()) {
|
||||
int value = map[incoming.getValue().getIndex()];
|
||||
incoming.setValue(program.variableAt(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < map.length; ++i) {
|
||||
if (map[i] != i) {
|
||||
|
@ -114,6 +116,21 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
|||
program = null;
|
||||
}
|
||||
|
||||
private List<List<Incoming>> findOutgoings(Program program) {
|
||||
List<List<Incoming>> outgoings = new ArrayList<>();
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
outgoings.add(new ArrayList<Incoming>());
|
||||
}
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
for (Phi phi : program.basicBlockAt(i).getPhis()) {
|
||||
for (Incoming incoming : phi.getIncomings()) {
|
||||
outgoings.get(incoming.getSource().getIndex()).add(incoming);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outgoings;
|
||||
}
|
||||
|
||||
private void bind(int var, String value) {
|
||||
KnownValue known = knownValues.get(value);
|
||||
if (known != null && domTree.dominates(known.location, currentBlockIndex)) {
|
||||
|
@ -166,16 +183,19 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
|||
int b = map[insn.getSecondOperand().getIndex()];
|
||||
insn.setFirstOperand(program.variableAt(a));
|
||||
insn.setSecondOperand(program.variableAt(b));
|
||||
boolean commutative = false;
|
||||
String value;
|
||||
switch (insn.getOperation()) {
|
||||
case ADD:
|
||||
value = "+";
|
||||
commutative = true;
|
||||
break;
|
||||
case SUBTRACT:
|
||||
value = "-";
|
||||
break;
|
||||
case MULTIPLY:
|
||||
value = "*";
|
||||
commutative = true;
|
||||
break;
|
||||
case DIVIDE:
|
||||
value = "/";
|
||||
|
@ -188,12 +208,15 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
|||
break;
|
||||
case AND:
|
||||
value = "&";
|
||||
commutative = true;
|
||||
break;
|
||||
case OR:
|
||||
value = "|";
|
||||
commutative = true;
|
||||
break;
|
||||
case XOR:
|
||||
value = "^";
|
||||
commutative = true;
|
||||
break;
|
||||
case SHIFT_LEFT:
|
||||
value = "<<";
|
||||
|
@ -207,8 +230,10 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
|||
default:
|
||||
return;
|
||||
}
|
||||
value = "@" + a + value + "@" + b;
|
||||
bind(insn.getReceiver().getIndex(), value);
|
||||
bind(insn.getReceiver().getIndex(), "@" + a + value + "@" + b);
|
||||
if (commutative) {
|
||||
bind(insn.getReceiver().getIndex(), "@" + b + value + "@" + a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue
Block a user