mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-10 08:54:11 -08:00
Speed-up interference graph builder. Simplify API
This commit is contained in:
parent
45fe202740
commit
97dc66968e
|
@ -41,6 +41,11 @@
|
||||||
<artifactId>asm-debug-all</artifactId>
|
<artifactId>asm-debug-all</artifactId>
|
||||||
<version>4.2</version>
|
<version>4.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.carrotsearch</groupId>
|
||||||
|
<artifactId>hppc</artifactId>
|
||||||
|
<version>0.5.4</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -118,13 +118,8 @@ public class DependencyChecker implements DependencyInfo {
|
||||||
|
|
||||||
public void addDependencyListener(DependencyListener listener) {
|
public void addDependencyListener(DependencyListener listener) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
|
||||||
|
|
||||||
public void startListeners() {
|
|
||||||
for (DependencyListener listener : listeners) {
|
|
||||||
listener.started(this);
|
listener.started(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void addEntryPoint(MethodReference methodRef, String... argumentTypes) {
|
public void addEntryPoint(MethodReference methodRef, String... argumentTypes) {
|
||||||
ValueType[] parameters = methodRef.getDescriptor().getParameterTypes();
|
ValueType[] parameters = methodRef.getDescriptor().getParameterTypes();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.util;
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.IntOpenHashSet;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.common.Graph;
|
import org.teavm.common.Graph;
|
||||||
import org.teavm.common.GraphBuilder;
|
import org.teavm.common.GraphBuilder;
|
||||||
|
@ -26,9 +27,9 @@ import org.teavm.model.*;
|
||||||
*/
|
*/
|
||||||
class InterferenceGraphBuilder {
|
class InterferenceGraphBuilder {
|
||||||
public Graph build(Program program, int paramCount, LivenessAnalyzer liveness) {
|
public Graph build(Program program, int paramCount, LivenessAnalyzer liveness) {
|
||||||
List<Set<Integer>> edges = new ArrayList<>();
|
List<IntOpenHashSet> edges = new ArrayList<>();
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
edges.add(new HashSet<Integer>());
|
edges.add(new IntOpenHashSet());
|
||||||
}
|
}
|
||||||
UsageExtractor useExtractor = new UsageExtractor();
|
UsageExtractor useExtractor = new UsageExtractor();
|
||||||
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
||||||
|
@ -41,7 +42,7 @@ class InterferenceGraphBuilder {
|
||||||
for (BasicBlock succ : succExtractor.getTargets()) {
|
for (BasicBlock succ : succExtractor.getTargets()) {
|
||||||
liveOut.or(liveness.liveIn(succ.getIndex()));
|
liveOut.or(liveness.liveIn(succ.getIndex()));
|
||||||
}
|
}
|
||||||
Set<Integer> live = new HashSet<>();
|
IntOpenHashSet live = new IntOpenHashSet(8);
|
||||||
for (int j = 0; j < liveOut.length(); ++j) {
|
for (int j = 0; j < liveOut.length(); ++j) {
|
||||||
if (liveOut.get(j)) {
|
if (liveOut.get(j)) {
|
||||||
live.add(j);
|
live.add(j);
|
||||||
|
@ -70,7 +71,7 @@ class InterferenceGraphBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BitSet liveIn = liveness.liveIn(i);
|
BitSet liveIn = liveness.liveIn(i);
|
||||||
live = new HashSet<>();
|
live = new IntOpenHashSet();
|
||||||
for (int j = 0; j < liveOut.length(); ++j) {
|
for (int j = 0; j < liveOut.length(); ++j) {
|
||||||
if (liveIn.get(j)) {
|
if (liveIn.get(j)) {
|
||||||
live.add(j);
|
live.add(j);
|
||||||
|
@ -83,18 +84,38 @@ class InterferenceGraphBuilder {
|
||||||
edges.get(phi.getReceiver().getIndex()).addAll(live);
|
edges.get(phi.getReceiver().getIndex()).addAll(live);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GraphBuilder builder = new GraphBuilder();
|
GraphBuilder builder = new GraphBuilder(edges.size());
|
||||||
|
List<IntOpenHashSet> backEdges = new ArrayList<>(edges.size());
|
||||||
for (int i = 0; i < edges.size(); ++i) {
|
for (int i = 0; i < edges.size(); ++i) {
|
||||||
for (Integer j : edges.get(i)) {
|
backEdges.add(new IntOpenHashSet(8));
|
||||||
builder.addEdge(i, j);
|
}
|
||||||
builder.addEdge(j, i);
|
for (int i = 0; i < edges.size(); ++i) {
|
||||||
|
IntOpenHashSet edgeSet = edges.get(i);
|
||||||
|
for (int j = 0; j < edgeSet.allocated.length; ++j) {
|
||||||
|
if (edgeSet.allocated[j]) {
|
||||||
|
backEdges.get(edgeSet.keys[j]).add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < edges.size(); ++i) {
|
||||||
|
IntOpenHashSet edgeSet = edges.get(i);
|
||||||
|
for (int j = 0; j < edgeSet.allocated.length; ++j) {
|
||||||
|
if (edgeSet.allocated[j]) {
|
||||||
|
builder.addEdge(i, edgeSet.keys[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edgeSet = backEdges.get(i);
|
||||||
|
for (int j = 0; j < edgeSet.allocated.length; ++j) {
|
||||||
|
if (edgeSet.allocated[j]) {
|
||||||
|
builder.addEdge(edgeSet.keys[j], i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<List<Incoming>> getOutgoings(Program program) {
|
private List<List<Incoming>> getOutgoings(Program program) {
|
||||||
List<List<Incoming>> outgoings = new ArrayList<>();
|
List<List<Incoming>> outgoings = new ArrayList<>(program.basicBlockCount());
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
outgoings.add(new ArrayList<Incoming>());
|
outgoings.add(new ArrayList<Incoming>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,6 +210,9 @@ public class RegisterAllocator {
|
||||||
GraphBuilder renamedGraph = new GraphBuilder();
|
GraphBuilder renamedGraph = new GraphBuilder();
|
||||||
for (int i = 0; i < graph.size(); ++i) {
|
for (int i = 0; i < graph.size(); ++i) {
|
||||||
for (int j : graph.outgoingEdges(i)) {
|
for (int j : graph.outgoingEdges(i)) {
|
||||||
|
if (i >= varMap.length || j >= varMap.length) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
renamedGraph.addEdge(varMap[i], varMap[j]);
|
renamedGraph.addEdge(varMap[i], varMap[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,10 +148,6 @@ public class TeaVM implements TeaVMHost {
|
||||||
return classSource;
|
return classSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepare() {
|
|
||||||
dependencyChecker.startListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasMissingItems() {
|
public boolean hasMissingItems() {
|
||||||
return dependencyChecker.hasMissingItems();
|
return dependencyChecker.hasMissingItems();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.vm;
|
||||||
import org.teavm.common.FiniteExecutor;
|
import org.teavm.common.FiniteExecutor;
|
||||||
import org.teavm.common.SimpleFiniteExecutor;
|
import org.teavm.common.SimpleFiniteExecutor;
|
||||||
import org.teavm.model.ClassHolderSource;
|
import org.teavm.model.ClassHolderSource;
|
||||||
|
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -28,6 +29,11 @@ public class TeaVMBuilder {
|
||||||
ClassLoader classLoader;
|
ClassLoader classLoader;
|
||||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
FiniteExecutor executor = new SimpleFiniteExecutor();
|
||||||
|
|
||||||
|
public TeaVMBuilder() {
|
||||||
|
classLoader = TeaVMBuilder.class.getClassLoader();
|
||||||
|
classSource = new ClasspathClassHolderSource(classLoader);
|
||||||
|
}
|
||||||
|
|
||||||
public ClassHolderSource getClassSource() {
|
public ClassHolderSource getClassSource() {
|
||||||
return classSource;
|
return classSource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,6 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
for (ClassHolderTransformer transformer : instantiateTransformers(classLoader)) {
|
for (ClassHolderTransformer transformer : instantiateTransformers(classLoader)) {
|
||||||
vm.add(transformer);
|
vm.add(transformer);
|
||||||
}
|
}
|
||||||
vm.prepare();
|
|
||||||
if (mainClass != null) {
|
if (mainClass != null) {
|
||||||
MethodDescriptor mainMethodDesc = new MethodDescriptor("main", ValueType.arrayOf(
|
MethodDescriptor mainMethodDesc = new MethodDescriptor("main", ValueType.arrayOf(
|
||||||
ValueType.object("java.lang.String")), ValueType.VOID);
|
ValueType.object("java.lang.String")), ValueType.VOID);
|
||||||
|
|
|
@ -331,7 +331,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo {
|
||||||
for (ClassHolderTransformer transformer : transformerInstances) {
|
for (ClassHolderTransformer transformer : transformerInstances) {
|
||||||
vm.add(transformer);
|
vm.add(transformer);
|
||||||
}
|
}
|
||||||
vm.prepare();
|
|
||||||
File file = new File(outputDir, targetName);
|
File file = new File(outputDir, targetName);
|
||||||
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||||
MethodReference cons = new MethodReference(methodRef.getClassName(),
|
MethodReference cons = new MethodReference(methodRef.getClassName(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user