22 */ |
22 */ |
23 |
23 |
24 |
24 |
25 package org.graalvm.compiler.loop.phases; |
25 package org.graalvm.compiler.loop.phases; |
26 |
26 |
|
27 import jdk.internal.vm.compiler.collections.EconomicMap; |
|
28 import jdk.internal.vm.compiler.collections.Equivalence; |
27 import org.graalvm.compiler.graph.Graph; |
29 import org.graalvm.compiler.graph.Graph; |
28 import org.graalvm.compiler.loop.LoopEx; |
30 import org.graalvm.compiler.loop.LoopEx; |
29 import org.graalvm.compiler.loop.LoopPolicies; |
31 import org.graalvm.compiler.loop.LoopPolicies; |
30 import org.graalvm.compiler.loop.LoopsData; |
32 import org.graalvm.compiler.loop.LoopsData; |
|
33 import org.graalvm.compiler.nodes.LoopBeginNode; |
31 import org.graalvm.compiler.nodes.StructuredGraph; |
34 import org.graalvm.compiler.nodes.StructuredGraph; |
|
35 import org.graalvm.compiler.nodes.extended.OpaqueNode; |
32 import org.graalvm.compiler.phases.common.CanonicalizerPhase; |
36 import org.graalvm.compiler.phases.common.CanonicalizerPhase; |
33 import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener; |
37 import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener; |
34 import org.graalvm.compiler.phases.tiers.PhaseContext; |
38 import org.graalvm.compiler.phases.tiers.PhaseContext; |
35 |
39 |
36 public class LoopPartialUnrollPhase extends LoopPhase<LoopPolicies> { |
40 public class LoopPartialUnrollPhase extends LoopPhase<LoopPolicies> { |
37 |
41 |
38 private final CanonicalizerPhase canonicalizer; |
42 private final CanonicalizerPhase canonicalizer; |
44 |
48 |
45 @Override |
49 @Override |
46 @SuppressWarnings("try") |
50 @SuppressWarnings("try") |
47 protected void run(StructuredGraph graph, PhaseContext context) { |
51 protected void run(StructuredGraph graph, PhaseContext context) { |
48 if (graph.hasLoops()) { |
52 if (graph.hasLoops()) { |
49 HashSetNodeEventListener listener = new HashSetNodeEventListener(); |
53 EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener(); |
50 boolean changed = true; |
54 boolean changed = true; |
|
55 EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides = null; |
51 while (changed) { |
56 while (changed) { |
52 changed = false; |
57 changed = false; |
53 try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) { |
58 try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) { |
54 LoopsData dataCounted = new LoopsData(graph); |
59 LoopsData dataCounted = new LoopsData(graph); |
55 dataCounted.detectedCountedLoops(); |
60 dataCounted.detectedCountedLoops(); |
64 // First perform the pre/post transformation and do the partial |
69 // First perform the pre/post transformation and do the partial |
65 // unroll when we come around again. |
70 // unroll when we come around again. |
66 LoopTransformations.insertPrePostLoops(loop); |
71 LoopTransformations.insertPrePostLoops(loop); |
67 prePostInserted = true; |
72 prePostInserted = true; |
68 } else { |
73 } else { |
69 LoopTransformations.partialUnroll(loop); |
74 if (opaqueUnrolledStrides == null) { |
|
75 opaqueUnrolledStrides = EconomicMap.create(Equivalence.IDENTITY); |
|
76 } |
|
77 LoopTransformations.partialUnroll(loop, opaqueUnrolledStrides); |
70 } |
78 } |
71 changed = true; |
79 changed = true; |
72 } |
80 } |
73 } |
81 } |
74 dataCounted.deleteUnusedNodes(); |
82 dataCounted.deleteUnusedNodes(); |
77 canonicalizer.applyIncremental(graph, context, listener.getNodes()); |
85 canonicalizer.applyIncremental(graph, context, listener.getNodes()); |
78 listener.getNodes().clear(); |
86 listener.getNodes().clear(); |
79 } |
87 } |
80 |
88 |
81 assert !prePostInserted || checkCounted(graph, mark); |
89 assert !prePostInserted || checkCounted(graph, mark); |
|
90 } |
|
91 } |
|
92 if (opaqueUnrolledStrides != null) { |
|
93 try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) { |
|
94 for (OpaqueNode opaque : opaqueUnrolledStrides.getValues()) { |
|
95 opaque.remove(); |
|
96 } |
|
97 if (!listener.getNodes().isEmpty()) { |
|
98 canonicalizer.applyIncremental(graph, context, listener.getNodes()); |
|
99 } |
82 } |
100 } |
83 } |
101 } |
84 } |
102 } |
85 } |
103 } |
86 |
104 |