mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Fix dominator tree builder, make it possible to choose starting node
This commit is contained in:
parent
d710870c65
commit
c89bc11d02
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.common;
|
package org.teavm.common;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
class DefaultDominatorTree implements DominatorTree {
|
class DefaultDominatorTree implements DominatorTree {
|
||||||
private LCATree lcaTree;
|
private LCATree lcaTree;
|
||||||
private int[] indexes;
|
private int[] indexes;
|
||||||
|
@ -24,7 +26,7 @@ class DefaultDominatorTree implements DominatorTree {
|
||||||
lcaTree = new LCATree(dominators.length + 1);
|
lcaTree = new LCATree(dominators.length + 1);
|
||||||
indexes = new int[dominators.length + 1];
|
indexes = new int[dominators.length + 1];
|
||||||
nodes = new int[dominators.length + 1];
|
nodes = new int[dominators.length + 1];
|
||||||
indexes[0] = -1;
|
Arrays.fill(nodes, -1);
|
||||||
for (int i = 0; i < dominators.length; ++i) {
|
for (int i = 0; i < dominators.length; ++i) {
|
||||||
int v = vertices[i];
|
int v = vertices[i];
|
||||||
if (v < 0) {
|
if (v < 0) {
|
||||||
|
@ -58,9 +60,6 @@ class DefaultDominatorTree implements DominatorTree {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int immediateDominatorOf(int a) {
|
public int immediateDominatorOf(int a) {
|
||||||
if (a == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int result = lcaTree.parentOf(indexes[a + 1]);
|
int result = lcaTree.parentOf(indexes[a + 1]);
|
||||||
return result >= 0 ? nodes[result] : -1;
|
return result >= 0 ? nodes[result] : -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,20 +32,23 @@ class DominatorTreeBuilder {
|
||||||
private IntegerArray[] bucket;
|
private IntegerArray[] bucket;
|
||||||
private int[] path;
|
private int[] path;
|
||||||
private int effectiveSize;
|
private int effectiveSize;
|
||||||
|
private int start;
|
||||||
|
|
||||||
public DominatorTreeBuilder(Graph graph) {
|
DominatorTreeBuilder(Graph graph, int start) {
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
|
this.start = start;
|
||||||
semidominators = new int[graph.size()];
|
semidominators = new int[graph.size()];
|
||||||
vertices = new int[graph.size()];
|
vertices = new int[graph.size()];
|
||||||
parents = new int[graph.size()];
|
parents = new int[graph.size()];
|
||||||
dominators = new int[graph.size()];
|
dominators = new int[graph.size()];
|
||||||
|
Arrays.fill(dominators, -1);
|
||||||
ancestors = new int[graph.size()];
|
ancestors = new int[graph.size()];
|
||||||
labels = new int[graph.size()];
|
labels = new int[graph.size()];
|
||||||
path = new int[graph.size()];
|
path = new int[graph.size()];
|
||||||
bucket = new IntegerArray[graph.size()];
|
bucket = new IntegerArray[graph.size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void build() {
|
void build() {
|
||||||
for (int i = 0; i < labels.length; ++i) {
|
for (int i = 0; i < labels.length; ++i) {
|
||||||
labels[i] = i;
|
labels[i] = i;
|
||||||
}
|
}
|
||||||
|
@ -56,12 +59,14 @@ class DominatorTreeBuilder {
|
||||||
if (parents[w] < 0) {
|
if (parents[w] < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (w != start) {
|
||||||
for (int v : graph.incomingEdges(w)) {
|
for (int v : graph.incomingEdges(w)) {
|
||||||
int u = eval(v);
|
int u = eval(v);
|
||||||
if (semidominators[u] >= 0) {
|
if (semidominators[u] >= 0) {
|
||||||
semidominators[w] = Math.min(semidominators[w], semidominators[u]);
|
semidominators[w] = Math.min(semidominators[w], semidominators[u]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
addToBucket(vertices[semidominators[w]], w);
|
addToBucket(vertices[semidominators[w]], w);
|
||||||
link(parents[w], w);
|
link(parents[w], w);
|
||||||
for (int v : getBucket(w)) {
|
for (int v : getBucket(w)) {
|
||||||
|
@ -70,7 +75,7 @@ class DominatorTreeBuilder {
|
||||||
}
|
}
|
||||||
bucket[w] = null;
|
bucket[w] = null;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < graph.size(); ++i) {
|
for (int i = 0; i < effectiveSize; ++i) {
|
||||||
int w = vertices[i];
|
int w = vertices[i];
|
||||||
if (w < 0 || parents[w] < 0) {
|
if (w < 0 || parents[w] < 0) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -79,6 +84,7 @@ class DominatorTreeBuilder {
|
||||||
dominators[w] = dominators[dominators[w]];
|
dominators[w] = dominators[dominators[w]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dominators[start] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addToBucket(int v, int w) {
|
private void addToBucket(int v, int w) {
|
||||||
|
@ -126,18 +132,15 @@ class DominatorTreeBuilder {
|
||||||
Arrays.fill(semidominators, -1);
|
Arrays.fill(semidominators, -1);
|
||||||
Arrays.fill(vertices, -1);
|
Arrays.fill(vertices, -1);
|
||||||
IntegerStack stack = new IntegerStack(graph.size());
|
IntegerStack stack = new IntegerStack(graph.size());
|
||||||
for (int i = graph.size() - 1; i >= 0; --i) {
|
stack.push(start);
|
||||||
if (graph.incomingEdgesCount(i) == 0) {
|
Arrays.fill(parents, -1);
|
||||||
stack.push(i);
|
|
||||||
parents[i] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (!stack.isEmpty()) {
|
while (!stack.isEmpty()) {
|
||||||
int v = stack.pop();
|
int v = stack.pop();
|
||||||
if (semidominators[v] >= 0) {
|
if (semidominators[v] >= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
dominators[v] = start;
|
||||||
// We don't need vertex index after its dominator has computed.
|
// We don't need vertex index after its dominator has computed.
|
||||||
semidominators[v] = i;
|
semidominators[v] = i;
|
||||||
vertices[i++] = v;
|
vertices[i++] = v;
|
||||||
|
@ -149,5 +152,6 @@ class DominatorTreeBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effectiveSize = i;
|
effectiveSize = i;
|
||||||
|
dominators[start] = start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,7 +307,11 @@ public final class GraphUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DominatorTree buildDominatorTree(Graph graph) {
|
public static DominatorTree buildDominatorTree(Graph graph) {
|
||||||
DominatorTreeBuilder builder = new DominatorTreeBuilder(graph);
|
return buildDominatorTree(graph, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DominatorTree buildDominatorTree(Graph graph, int start) {
|
||||||
|
DominatorTreeBuilder builder = new DominatorTreeBuilder(graph, start);
|
||||||
builder.build();
|
builder.build();
|
||||||
return new DefaultDominatorTree(builder.dominators, builder.vertices);
|
return new DefaultDominatorTree(builder.dominators, builder.vertices);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user