22 */ |
22 */ |
23 |
23 |
24 |
24 |
25 package org.graalvm.compiler.phases.common; |
25 package org.graalvm.compiler.phases.common; |
26 |
26 |
|
27 import java.util.Iterator; |
27 import java.util.LinkedList; |
28 import java.util.LinkedList; |
28 import java.util.List; |
29 import java.util.List; |
29 |
30 |
30 import org.graalvm.compiler.core.common.cfg.Loop; |
31 import org.graalvm.compiler.core.common.cfg.Loop; |
31 import org.graalvm.compiler.core.common.type.StampFactory; |
32 import org.graalvm.compiler.core.common.type.StampFactory; |
32 import org.graalvm.compiler.debug.DebugCloseable; |
33 import org.graalvm.compiler.debug.DebugCloseable; |
33 import org.graalvm.compiler.nodes.AbstractDeoptimizeNode; |
34 import org.graalvm.compiler.nodes.AbstractDeoptimizeNode; |
34 import org.graalvm.compiler.nodes.AbstractMergeNode; |
35 import org.graalvm.compiler.nodes.AbstractMergeNode; |
35 import org.graalvm.compiler.nodes.DynamicDeoptimizeNode; |
36 import org.graalvm.compiler.nodes.DynamicDeoptimizeNode; |
36 import org.graalvm.compiler.nodes.EndNode; |
37 import org.graalvm.compiler.nodes.EndNode; |
37 import org.graalvm.compiler.nodes.FixedNode; |
|
38 import org.graalvm.compiler.nodes.FrameState; |
38 import org.graalvm.compiler.nodes.FrameState; |
39 import org.graalvm.compiler.nodes.LoopBeginNode; |
39 import org.graalvm.compiler.nodes.LoopBeginNode; |
40 import org.graalvm.compiler.nodes.LoopExitNode; |
40 import org.graalvm.compiler.nodes.LoopExitNode; |
41 import org.graalvm.compiler.nodes.MergeNode; |
41 import org.graalvm.compiler.nodes.MergeNode; |
42 import org.graalvm.compiler.nodes.PhiNode; |
42 import org.graalvm.compiler.nodes.PhiNode; |
57 @Override |
57 @Override |
58 @SuppressWarnings("try") |
58 @SuppressWarnings("try") |
59 protected void run(StructuredGraph graph, MidTierContext context) { |
59 protected void run(StructuredGraph graph, MidTierContext context) { |
60 ControlFlowGraph cfg = null; |
60 ControlFlowGraph cfg = null; |
61 for (FrameState fs : graph.getNodes(FrameState.TYPE)) { |
61 for (FrameState fs : graph.getNodes(FrameState.TYPE)) { |
62 FixedNode target = null; |
62 Iterator<AbstractDeoptimizeNode> iterator = fs.usages().filter(AbstractDeoptimizeNode.class).iterator(); |
63 PhiNode reasonActionPhi = null; |
63 if (!iterator.hasNext()) { |
64 PhiNode speculationPhi = null; |
64 // No deopt |
65 List<AbstractDeoptimizeNode> obsoletes = null; |
65 continue; |
66 for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) { |
66 } |
67 if (target == null) { |
67 AbstractDeoptimizeNode first = iterator.next(); |
68 target = deopt; |
68 if (!iterator.hasNext()) { |
69 } else { |
69 // Only 1 deopt |
70 if (cfg == null) { |
70 continue; |
71 cfg = ControlFlowGraph.compute(graph, true, true, false, false); |
71 } |
72 } |
72 // There is more than one deopt, create a merge |
73 AbstractMergeNode merge; |
73 if (cfg == null) { |
74 if (target instanceof AbstractDeoptimizeNode) { |
74 cfg = ControlFlowGraph.compute(graph, true, true, false, false); |
75 merge = graph.add(new MergeNode()); |
75 } |
76 EndNode firstEnd = graph.add(new EndNode()); |
76 AbstractMergeNode merge = graph.add(new MergeNode()); |
77 ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess()); |
77 EndNode firstEnd = graph.add(new EndNode()); |
78 ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess()); |
78 ValueNode actionAndReason = first.getActionAndReason(context.getMetaAccess()); |
79 reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge)); |
79 ValueNode speculation = first.getSpeculation(context.getMetaAccess()); |
80 speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge)); |
80 PhiNode reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge)); |
81 merge.addForwardEnd(firstEnd); |
81 PhiNode speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge)); |
82 reasonActionPhi.addInput(actionAndReason); |
82 merge.addForwardEnd(firstEnd); |
83 speculationPhi.addInput(speculation); |
83 reasonActionPhi.addInput(actionAndReason); |
84 target.replaceAtPredecessor(firstEnd); |
84 speculationPhi.addInput(speculation); |
|
85 first.replaceAtPredecessor(firstEnd); |
|
86 exitLoops(first, firstEnd, cfg); |
|
87 DynamicDeoptimizeNode dynamicDeopt; |
|
88 try (DebugCloseable position = first.withNodeSourcePosition()) { |
|
89 dynamicDeopt = new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi); |
|
90 merge.setNext(graph.add(dynamicDeopt)); |
|
91 } |
|
92 List<AbstractDeoptimizeNode> obsoletes = new LinkedList<>(); |
|
93 obsoletes.add(first); |
85 |
94 |
86 exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg); |
95 do { |
87 try (DebugCloseable position = target.withNodeSourcePosition()) { |
96 AbstractDeoptimizeNode deopt = iterator.next(); |
88 merge.setNext(graph.add(new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi))); |
97 EndNode newEnd = graph.add(new EndNode()); |
89 } |
98 merge.addForwardEnd(newEnd); |
90 obsoletes = new LinkedList<>(); |
99 reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess())); |
91 obsoletes.add((AbstractDeoptimizeNode) target); |
100 speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess())); |
92 target = merge; |
101 deopt.replaceAtPredecessor(newEnd); |
93 } else { |
102 exitLoops(deopt, newEnd, cfg); |
94 merge = (AbstractMergeNode) target; |
103 obsoletes.add(deopt); |
95 } |
104 } while (iterator.hasNext()); |
96 EndNode newEnd = graph.add(new EndNode()); |
105 |
97 merge.addForwardEnd(newEnd); |
106 dynamicDeopt.setStateBefore(fs); |
98 reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess())); |
107 for (AbstractDeoptimizeNode obsolete : obsoletes) { |
99 speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess())); |
108 obsolete.safeDelete(); |
100 deopt.replaceAtPredecessor(newEnd); |
|
101 exitLoops(deopt, newEnd, cfg); |
|
102 obsoletes.add(deopt); |
|
103 } |
|
104 } |
|
105 if (obsoletes != null) { |
|
106 ((DynamicDeoptimizeNode) ((AbstractMergeNode) target).next()).setStateBefore(fs); |
|
107 for (AbstractDeoptimizeNode obsolete : obsoletes) { |
|
108 obsolete.safeDelete(); |
|
109 } |
|
110 } |
109 } |
111 } |
110 } |
112 } |
111 } |
113 |
112 |
114 private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) { |
113 private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) { |