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