Speed-up interference graph builder. Simplify API

This commit is contained in:
Alexey Andreev 2014-03-15 00:43:13 +04:00
parent 45fe202740
commit 97dc66968e
8 changed files with 45 additions and 21 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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