annotate graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java @ 15741:c82a77d94067

do not assert for MergeNode in UseTrappingNullChecksPhase
author Lukas Stadler <lukas.stadler@oracle.com>
date Mon, 19 May 2014 10:23:05 +0200
parents eaeba148bb15
children 9ae1d2f3bda6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
1 /*
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
2 * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
4 *
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
7 * published by the Free Software Foundation.
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
8 *
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
13 * accompanied this code).
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
14 *
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
18 *
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
21 * questions.
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
22 */
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
23 package com.oracle.graal.phases.common;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
24
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
25 import java.util.*;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
26
13668
a5206a3b92f2 UseTrappingNullChecksPhase: do not use trapping null check for a reason which is not null check or has an attached speculation
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 13635
diff changeset
27 import com.oracle.graal.api.meta.*;
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
28 import com.oracle.graal.debug.*;
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
29 import com.oracle.graal.graph.*;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
30 import com.oracle.graal.nodes.*;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
31 import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
32 import com.oracle.graal.nodes.calc.*;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
33 import com.oracle.graal.nodes.extended.*;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
34 import com.oracle.graal.nodes.util.*;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
35 import com.oracle.graal.phases.*;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
36 import com.oracle.graal.phases.tiers.*;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
37
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
38 public class UseTrappingNullChecksPhase extends BasePhase<LowTierContext> {
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
39
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
40 private static final DebugMetric metricTrappingNullCheck = Debug.metric("TrappingNullCheck");
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
41 private static final DebugMetric metricTrappingNullCheckUnreached = Debug.metric("TrappingNullCheckUnreached");
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
42 private static final DebugMetric metricTrappingNullCheckDynamicDeoptimize = Debug.metric("TrappingNullCheckDynamicDeoptimize");
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
43
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
44 @Override
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
45 protected void run(StructuredGraph graph, LowTierContext context) {
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
46 if (context.getTarget().implicitNullCheckLimit <= 0) {
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
47 return;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
48 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
49 assert graph.getGuardsStage().ordinal() >= GuardsStage.AFTER_FSA.ordinal();
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
50
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
51 for (DeoptimizeNode deopt : graph.getNodes(DeoptimizeNode.class)) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
52 tryUseTrappingNullCheck(deopt, deopt.predecessor(), deopt.reason(), deopt.getSpeculation());
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
53 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
54 for (DynamicDeoptimizeNode deopt : graph.getNodes(DynamicDeoptimizeNode.class)) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
55 tryUseTrappingNullCheck(context.getMetaAccess(), deopt);
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
56 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
57 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
58
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
59 private static void tryUseTrappingNullCheck(MetaAccessProvider metaAccessProvider, DynamicDeoptimizeNode deopt) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
60 ValueNode speculation = deopt.getSpeculation();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
61 if (!speculation.isConstant() || !speculation.asConstant().equals(Constant.NULL_OBJECT)) {
13668
a5206a3b92f2 UseTrappingNullChecksPhase: do not use trapping null check for a reason which is not null check or has an attached speculation
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 13635
diff changeset
62 return;
a5206a3b92f2 UseTrappingNullChecksPhase: do not use trapping null check for a reason which is not null check or has an attached speculation
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 13635
diff changeset
63 }
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
64 Node predecessor = deopt.predecessor();
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
65 if (predecessor instanceof MergeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
66 MergeNode merge = (MergeNode) predecessor;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
67
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
68 // Process each predecessor at the merge, unpacking the reasons as needed.
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
69 ValueNode reason = deopt.getActionAndReason();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
70 List<ValueNode> values = reason instanceof ValuePhiNode ? ((ValuePhiNode) reason).values().snapshot() : Collections.nCopies(merge.forwardEndCount(), reason);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
71
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
72 int index = 0;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
73 for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
74 ValueNode thisReason = values.get(index++);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
75 assert thisReason.isConstant();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
76 DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asConstant());
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
77 tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, null);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
78 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
79 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
80 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
81
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
82 private static void tryUseTrappingNullCheck(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, Constant speculation) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
83 if (deoptimizationReason != DeoptimizationReason.NullCheckException && deoptimizationReason != DeoptimizationReason.UnreachedCode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
84 return;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
85 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
86 if (speculation != null && !speculation.equals(Constant.NULL_OBJECT)) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
87 return;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
88 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
89 if (predecessor instanceof MergeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
90 MergeNode merge = (MergeNode) predecessor;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
91 for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
92 checkPredecessor(deopt, end.predecessor(), deoptimizationReason);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
93 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
94
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
95 } else if (predecessor instanceof BeginNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
96 checkPredecessor(deopt, predecessor, deoptimizationReason);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
97 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
98 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
99
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
100 private static void checkPredecessor(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
101 Node current = predecessor;
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
102 Node branch = null;
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
103 while (current instanceof BeginNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
104 branch = current;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
105 current = current.predecessor();
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
106 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
107 if (current instanceof IfNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
108 IfNode ifNode = (IfNode) current;
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
109 if (branch != ifNode.trueSuccessor()) {
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
110 return;
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
111 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
112 LogicNode condition = ifNode.condition();
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
113 if (condition instanceof IsNullNode) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
114 replaceWithTrappingNullCheck(deopt, ifNode, condition, deoptimizationReason);
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
115 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
116 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
117 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
118
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
119 private static void replaceWithTrappingNullCheck(AbstractDeoptimizeNode deopt, IfNode ifNode, LogicNode condition, DeoptimizationReason deoptimizationReason) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
120 metricTrappingNullCheck.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
121 if (deopt instanceof DynamicDeoptimizeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
122 metricTrappingNullCheckDynamicDeoptimize.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
123 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
124 if (deoptimizationReason == DeoptimizationReason.UnreachedCode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
125 metricTrappingNullCheckUnreached.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
126 }
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
127 IsNullNode isNullNode = (IsNullNode) condition;
15145
df2ef5204f2b Remove AbstractBeginNode, move the framestate from AbstractBeginNode to BeginStateSplitNode.
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 14734
diff changeset
128 BeginNode nonTrappingContinuation = ifNode.falseSuccessor();
df2ef5204f2b Remove AbstractBeginNode, move the framestate from AbstractBeginNode to BeginStateSplitNode.
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 14734
diff changeset
129 BeginNode trappingContinuation = ifNode.trueSuccessor();
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
130 NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.object()));
14734
6ae9af961b7c Introduce separate interfaces for deoptimizing nodes that deopt to a state before, during or after their execution.
Roland Schatz <roland.schatz@oracle.com>
parents: 13684
diff changeset
131 trappingNullCheck.setStateBefore(deopt.stateBefore());
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
132 deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation);
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
133
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
134 /*
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
135 * We now have the pattern NullCheck/BeginNode/... It's possible some node is using the
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
136 * BeginNode as a guard input, so replace guard users of the Begin with the NullCheck and
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
137 * then remove the Begin from the graph.
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
138 */
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
139 nonTrappingContinuation.replaceAtUsages(InputType.Guard, trappingNullCheck);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
140 FixedNode next = nonTrappingContinuation.next();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
141 nonTrappingContinuation.clearSuccessors();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
142 trappingNullCheck.setNext(next);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
143 nonTrappingContinuation.safeDelete();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
144
13635
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
145 GraphUtil.killCFG(trappingContinuation);
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
146 if (isNullNode.usages().isEmpty()) {
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
147 GraphUtil.killWithUnusedFloatingInputs(isNullNode);
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
148 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
149 }
e57115c41164 Make a separate phase to use trapping null checks instead of branches when implicitNullCheckLimit > 0
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
diff changeset
150 }