1 /* |
1 /* |
2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
57 import org.graalvm.compiler.nodes.StructuredGraph; |
57 import org.graalvm.compiler.nodes.StructuredGraph; |
58 import org.graalvm.compiler.nodes.ValueNode; |
58 import org.graalvm.compiler.nodes.ValueNode; |
59 import org.graalvm.compiler.nodes.ValuePhiNode; |
59 import org.graalvm.compiler.nodes.ValuePhiNode; |
60 import org.graalvm.compiler.nodes.calc.CompareNode; |
60 import org.graalvm.compiler.nodes.calc.CompareNode; |
61 import org.graalvm.compiler.nodes.cfg.Block; |
61 import org.graalvm.compiler.nodes.cfg.Block; |
|
62 import org.graalvm.compiler.nodes.spi.CoreProviders; |
62 import org.graalvm.compiler.nodes.spi.LoweringProvider; |
63 import org.graalvm.compiler.nodes.spi.LoweringProvider; |
63 import org.graalvm.compiler.nodes.util.GraphUtil; |
64 import org.graalvm.compiler.nodes.util.GraphUtil; |
64 import org.graalvm.compiler.phases.BasePhase; |
65 import org.graalvm.compiler.phases.BasePhase; |
65 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase; |
66 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase; |
66 import org.graalvm.compiler.phases.common.LazyValue; |
67 import org.graalvm.compiler.phases.common.LazyValue; |
67 import org.graalvm.compiler.phases.tiers.PhaseContext; |
|
68 |
68 |
69 import jdk.vm.ci.meta.Constant; |
69 import jdk.vm.ci.meta.Constant; |
70 import jdk.vm.ci.meta.DeoptimizationAction; |
70 import jdk.vm.ci.meta.DeoptimizationAction; |
71 |
71 |
72 /** |
72 /** |
79 * This is currently only done for branches that start from a {@link IfNode}. If it encounters a |
79 * This is currently only done for branches that start from a {@link IfNode}. If it encounters a |
80 * branch starting at an other kind of {@link ControlSplitNode}, it will only bring the |
80 * branch starting at an other kind of {@link ControlSplitNode}, it will only bring the |
81 * {@link DeoptimizeNode} as close to the {@link ControlSplitNode} as possible. |
81 * {@link DeoptimizeNode} as close to the {@link ControlSplitNode} as possible. |
82 * |
82 * |
83 */ |
83 */ |
84 public class ConvertDeoptimizeToGuardPhase extends BasePhase<PhaseContext> { |
84 public class ConvertDeoptimizeToGuardPhase extends BasePhase<CoreProviders> { |
85 @Override |
85 @Override |
86 @SuppressWarnings("try") |
86 @SuppressWarnings("try") |
87 protected void run(final StructuredGraph graph, PhaseContext context) { |
87 protected void run(final StructuredGraph graph, CoreProviders context) { |
88 assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies"; |
88 assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies"; |
89 assert !graph.getGuardsStage().areFrameStatesAtDeopts() : graph.getGuardsStage(); |
89 assert !graph.getGuardsStage().areFrameStatesAtDeopts() : graph.getGuardsStage(); |
90 LazyValue<LoopsData> lazyLoops = new LazyValue<>(() -> new LoopsData(graph)); |
90 LazyValue<LoopsData> lazyLoops = new LazyValue<>(() -> new LoopsData(graph)); |
91 |
91 |
92 for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.TYPE)) { |
92 for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.TYPE)) { |
108 } |
108 } |
109 |
109 |
110 new DeadCodeEliminationPhase(Optional).apply(graph); |
110 new DeadCodeEliminationPhase(Optional).apply(graph); |
111 } |
111 } |
112 |
112 |
113 private static void trySplitFixedGuard(FixedGuardNode fixedGuard, PhaseContext context, LazyValue<LoopsData> lazyLoops) { |
113 private static void trySplitFixedGuard(FixedGuardNode fixedGuard, CoreProviders context, LazyValue<LoopsData> lazyLoops) { |
114 LogicNode condition = fixedGuard.condition(); |
114 LogicNode condition = fixedGuard.condition(); |
115 if (condition instanceof CompareNode) { |
115 if (condition instanceof CompareNode) { |
116 CompareNode compare = (CompareNode) condition; |
116 CompareNode compare = (CompareNode) condition; |
117 ValueNode x = compare.getX(); |
117 ValueNode x = compare.getX(); |
118 ValuePhiNode xPhi = (x instanceof ValuePhiNode) ? (ValuePhiNode) x : null; |
118 ValuePhiNode xPhi = (x instanceof ValuePhiNode) ? (ValuePhiNode) x : null; |
124 } |
124 } |
125 } |
125 } |
126 } |
126 } |
127 } |
127 } |
128 |
128 |
129 private static void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, |
129 private static void processFixedGuardAndPhis(FixedGuardNode fixedGuard, CoreProviders context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, |
130 LazyValue<LoopsData> lazyLoops) { |
130 LazyValue<LoopsData> lazyLoops) { |
131 AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard); |
131 AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard); |
132 if (pred instanceof AbstractMergeNode) { |
132 if (pred instanceof AbstractMergeNode) { |
133 AbstractMergeNode merge = (AbstractMergeNode) pred; |
133 AbstractMergeNode merge = (AbstractMergeNode) pred; |
134 if (xPhi != null && xPhi.merge() != merge) { |
134 if (xPhi != null && xPhi.merge() != merge) { |
141 processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge, lazyLoops); |
141 processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge, lazyLoops); |
142 } |
142 } |
143 } |
143 } |
144 |
144 |
145 @SuppressWarnings("try") |
145 @SuppressWarnings("try") |
146 private static void processFixedGuardAndMerge(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, |
146 private static void processFixedGuardAndMerge(FixedGuardNode fixedGuard, CoreProviders context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, |
147 AbstractMergeNode merge, LazyValue<LoopsData> lazyLoops) { |
147 AbstractMergeNode merge, LazyValue<LoopsData> lazyLoops) { |
148 List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot(); |
148 List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot(); |
149 for (AbstractEndNode mergePredecessor : mergePredecessors) { |
149 for (AbstractEndNode mergePredecessor : mergePredecessors) { |
150 if (!mergePredecessor.isAlive()) { |
150 if (!mergePredecessor.isAlive()) { |
151 break; |
151 break; |