src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java Mon Jun 26 15:43:50 2017
--- new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java Mon Jun 26 15:43:50 2017
*** 28,37 ****
--- 28,38 ----
import java.util.Iterator;
import java.util.List;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
+ import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.StructuredGraph;
*** 60,91 ****
--- 61,93 ----
}
}
}
/**
! * Remove redundant {@link InitializeKlassNode} instances from the graph.
! * Remove redundant {@link InitializeKlassNode} or {@link ResolveConstantNode} instances from
+ * the graph.
*
* @param graph the program graph
*/
private static void removeRedundantInits(StructuredGraph graph) {
! // Find and remove redundant instances of {@link InitializeKlassNode} from the graph.
! List<InitializeKlassNode> redundantInits = findRedundantInits(graph);
! for (InitializeKlassNode n : redundantInits) {
! // Find and remove redundant nodes from the graph.
! List<FixedWithNextNode> redundantNodes = findRedundantInits(graph);
! for (FixedWithNextNode n : redundantNodes) {
graph.removeFixed(n);
}
}
/**
! * Find {@link InitializeKlassNode} instances that can be removed because there is an existing
! * dominating initialization.
! * Find {@link InitializeKlassNode} and {@link ResolveConstantNode} instances that can be
! * removed because there is an existing dominating node.
*
* @param graph the program graph
*/
! private static List<InitializeKlassNode> findRedundantInits(StructuredGraph graph) {
! private static List<FixedWithNextNode> findRedundantInits(StructuredGraph graph) {
EliminateRedundantInitializationIterator i = new EliminateRedundantInitializationIterator(graph.start(), new InitializedTypes());
i.apply();
! return i.getRedundantInits();
! return i.getRedundantNodes();
}
/**
* State for {@link EliminateRedundantInitializationIterator}.
*/
*** 104,114 ****
--- 106,116 ----
public InitializedTypes clone() {
return new InitializedTypes(EconomicSet.create(types));
}
public boolean contains(ResolvedJavaType type) {
! if (type.isInterface() || type.isArray()) {
// Check for exact match for interfaces
return types.contains(type);
}
// For other types see if there is the same type or a subtype
return anyMatch(types, t -> type.isAssignableFrom(t));
*** 117,137 ****
--- 119,139 ----
public void add(ResolvedJavaType type) {
types.add(type);
}
/**
! * Merge two given types. Interfaces have to be the same to merge successfully. For other
! * types the answer is the LCA.
! * Merge two given types. Interfaces and arrays have to be the same to merge successfully.
! * For other types the answer is the LCA.
*
* @param a initialized type
* @param b initialized type
* @return lowest common type that is initialized if either a or b are initialized, null if
* no such type exists.
*/
private static ResolvedJavaType merge(ResolvedJavaType a, ResolvedJavaType b) {
! // We want exact match for interfaces or arrays
! if (a.isInterface() || b.isInterface() || a.isArray() || b.isArray()) {
if (a.equals(b)) {
return a;
} else {
return null;
}
*** 160,171 ****
--- 162,174 ----
for (ResolvedJavaType ta : a) {
for (ResolvedJavaType tb : b) {
ResolvedJavaType tc = merge(ta, tb);
if (tc != null) {
c.add(tc);
! if (tc.isInterface() || tc.isArray()) {
! // Interface is not going merge with anything else, so bail out early.
! // Interfaces and arrays are not going merge with anything else, so bail
+ // out early.
break;
}
}
}
}
*** 200,238 ****
--- 203,255 ----
return toString(types);
}
}
/**
! * Do data flow analysis of class initializations. Collect redundant initialization nodes.
! * Do data flow analysis of class initializations and array resolutions. Collect redundant
+ * nodes.
*/
private static class EliminateRedundantInitializationIterator extends PostOrderNodeIterator<InitializedTypes> {
! private List<InitializeKlassNode> redundantInits = new ArrayList<>();
! private List<FixedWithNextNode> redundantNodes = new ArrayList<>();
! public List<InitializeKlassNode> getRedundantInits() {
! return redundantInits;
! public List<FixedWithNextNode> getRedundantNodes() {
! return redundantNodes;
}
EliminateRedundantInitializationIterator(FixedNode start, InitializedTypes initialState) {
super(start, initialState);
}
@Override
protected void node(FixedNode node) {
if (node instanceof InitializeKlassNode) {
InitializeKlassNode i = (InitializeKlassNode) node;
Constant c = i.value().asConstant();
assert c != null : "Klass should be a constant at this point";
+ private void processType(FixedWithNextNode node, Constant c) {
HotSpotMetaspaceConstant klass = (HotSpotMetaspaceConstant) c;
ResolvedJavaType t = klass.asResolvedJavaType();
+ if (t != null) {
if (state.contains(t)) {
! redundantInits.add(i);
! redundantNodes.add(node);
} else {
state.add(t);
}
}
}
+ @Override
+ protected void node(FixedNode node) {
+ if (node instanceof InitializeKlassNode) {
+ InitializeKlassNode i = (InitializeKlassNode) node;
+ if (i.value().isConstant()) {
+ processType(i, i.value().asConstant());
+ }
+ } else if (node instanceof ResolveConstantNode) {
+ ResolveConstantNode r = (ResolveConstantNode) node;
+ if (r.hasNoUsages()) {
+ if (r.value().isConstant()) {
+ processType(r, r.value().asConstant());
+ }
+ }
+ }
+ }
+
}
@Override
protected void run(StructuredGraph graph, PhaseContext context) {
removeInitsAtStaticCalls(graph);
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File