annotate graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java @ 18993:480bd3b1adcd

Rename BeginNode => AbstractBeginNode.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 28 Jan 2015 00:50:31 +0100
parents edf3a7fdd067
children a2cb19764970
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.*;
16841
cbd42807a31f moved NodeInfo and friends into separate com.oracle.graal.nodeinfo project so that annotation processor can be applied to the base Node class
Doug Simon <doug.simon@oracle.com>
parents: 16423
diff changeset
30 import com.oracle.graal.nodeinfo.*;
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
31 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
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 }
18970
edf3a7fdd067 Add utility methods to GuardsStage.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18937
diff changeset
49 assert graph.getGuardsStage().areFrameStatesAtDeopts();
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
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) {
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
60 Node predecessor = deopt.predecessor();
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
61 if (predecessor instanceof MergeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
62 MergeNode merge = (MergeNode) predecessor;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
63
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
64 // Process each predecessor at the merge, unpacking the reasons and speculations as
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
65 // needed.
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
66 ValueNode reason = deopt.getActionAndReason();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
67 ValuePhiNode reasonPhi = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
68 List<ValueNode> reasons = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
69 int expectedPhis = 0;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
70
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
71 if (reason instanceof ValuePhiNode) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
72 reasonPhi = (ValuePhiNode) reason;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
73 if (reasonPhi.merge() != merge) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
74 return;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
75 }
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
76 reasons = reasonPhi.values().snapshot();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
77 expectedPhis++;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
78 } else if (!reason.isConstant()) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
79 return;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
80 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
81
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
82 ValueNode speculation = deopt.getSpeculation();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
83 ValuePhiNode speculationPhi = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
84 List<ValueNode> speculations = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
85 if (speculation instanceof ValuePhiNode) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
86 speculationPhi = (ValuePhiNode) speculation;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
87 if (speculationPhi.merge() != merge) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
88 return;
15778
9ae1d2f3bda6 convert asserts into if tests and check for phis at merge
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15741
diff changeset
89 }
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
90 speculations = speculationPhi.values().snapshot();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
91 expectedPhis++;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
92 }
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
93
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
94 if (merge.phis().count() != expectedPhis) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
95 return;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
96 }
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
97
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
98 int index = 0;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
99 for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
100 ValueNode thisReason = reasons != null ? reasons.get(index) : reason;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
101 ValueNode thisSpeculation = speculations != null ? speculations.get(index++) : speculation;
18490
ca81508f2a19 Generalize NULL handling to work on arbitrary pointers.
Roland Schatz <roland.schatz@oracle.com>
parents: 18487
diff changeset
102 if (!thisReason.isConstant() || !thisSpeculation.isConstant() || !thisSpeculation.asConstant().equals(JavaConstant.NULL_POINTER)) {
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
103 continue;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
104 }
18187
9619ba4daf4c Rename Constant to JavaConstant.
Roland Schatz <roland.schatz@oracle.com>
parents: 17450
diff changeset
105 DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asJavaConstant());
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
106 tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, null);
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
107 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
108 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
109 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
110
18187
9619ba4daf4c Rename Constant to JavaConstant.
Roland Schatz <roland.schatz@oracle.com>
parents: 17450
diff changeset
111 private static void tryUseTrappingNullCheck(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, JavaConstant speculation) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
112 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
113 return;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
114 }
18490
ca81508f2a19 Generalize NULL handling to work on arbitrary pointers.
Roland Schatz <roland.schatz@oracle.com>
parents: 18487
diff changeset
115 if (speculation != null && !speculation.equals(JavaConstant.NULL_POINTER)) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
116 return;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
117 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
118 if (predecessor instanceof MergeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
119 MergeNode merge = (MergeNode) predecessor;
15778
9ae1d2f3bda6 convert asserts into if tests and check for phis at merge
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15741
diff changeset
120 if (merge.phis().isEmpty()) {
9ae1d2f3bda6 convert asserts into if tests and check for phis at merge
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15741
diff changeset
121 for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
9ae1d2f3bda6 convert asserts into if tests and check for phis at merge
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15741
diff changeset
122 checkPredecessor(deopt, end.predecessor(), deoptimizationReason);
9ae1d2f3bda6 convert asserts into if tests and check for phis at merge
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15741
diff changeset
123 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
124 }
18993
480bd3b1adcd Rename BeginNode => AbstractBeginNode.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18970
diff changeset
125 } else if (predecessor instanceof AbstractBeginNode) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
126 checkPredecessor(deopt, predecessor, deoptimizationReason);
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
127 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
128 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
129
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
130 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
131 Node current = predecessor;
18993
480bd3b1adcd Rename BeginNode => AbstractBeginNode.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18970
diff changeset
132 AbstractBeginNode branch = null;
480bd3b1adcd Rename BeginNode => AbstractBeginNode.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18970
diff changeset
133 while (current instanceof AbstractBeginNode) {
480bd3b1adcd Rename BeginNode => AbstractBeginNode.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18970
diff changeset
134 branch = (AbstractBeginNode) current;
16423
a9b85fe36dbc Don't rewrite to trapping null checks if the FrameState has an input that's anchored to the deopting branch.
Roland Schatz <roland.schatz@oracle.com>
parents: 16207
diff changeset
135 if (branch.anchored().isNotEmpty()) {
a9b85fe36dbc Don't rewrite to trapping null checks if the FrameState has an input that's anchored to the deopting branch.
Roland Schatz <roland.schatz@oracle.com>
parents: 16207
diff changeset
136 // some input of the deopt framestate is anchored to this branch
a9b85fe36dbc Don't rewrite to trapping null checks if the FrameState has an input that's anchored to the deopting branch.
Roland Schatz <roland.schatz@oracle.com>
parents: 16207
diff changeset
137 return;
a9b85fe36dbc Don't rewrite to trapping null checks if the FrameState has an input that's anchored to the deopting branch.
Roland Schatz <roland.schatz@oracle.com>
parents: 16207
diff changeset
138 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
139 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
140 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
141 if (current instanceof IfNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
142 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
143 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
144 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
145 }
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 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
147 if (condition instanceof IsNullNode) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
148 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
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 }
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
151 }
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
152
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
153 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
154 metricTrappingNullCheck.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
155 if (deopt instanceof DynamicDeoptimizeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
156 metricTrappingNullCheckDynamicDeoptimize.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
157 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
158 if (deoptimizationReason == DeoptimizationReason.UnreachedCode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
159 metricTrappingNullCheckUnreached.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
160 }
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
161 IsNullNode isNullNode = (IsNullNode) condition;
18993
480bd3b1adcd Rename BeginNode => AbstractBeginNode.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18970
diff changeset
162 AbstractBeginNode nonTrappingContinuation = ifNode.falseSuccessor();
480bd3b1adcd Rename BeginNode => AbstractBeginNode.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18970
diff changeset
163 AbstractBeginNode trappingContinuation = ifNode.trueSuccessor();
18845
f57d86eb036f removed Node factory methods
Doug Simon <doug.simon@oracle.com>
parents: 18490
diff changeset
164 NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.getValue()));
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
165 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
166 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
167
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
168 /*
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
169 * 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
170 * 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
171 * 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
172 */
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
173 nonTrappingContinuation.replaceAtUsages(InputType.Guard, trappingNullCheck);
18993
480bd3b1adcd Rename BeginNode => AbstractBeginNode.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18970
diff changeset
174 if (nonTrappingContinuation.getClass() == AbstractBeginNode.class) {
17054
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
175 FixedNode next = nonTrappingContinuation.next();
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
176 nonTrappingContinuation.clearSuccessors();
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
177 trappingNullCheck.setNext(next);
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
178 nonTrappingContinuation.safeDelete();
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
179 } else {
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
180 trappingNullCheck.setNext(nonTrappingContinuation);
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
181 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
182
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
183 GraphUtil.killCFG(trappingContinuation);
18937
ff232ff8d028 Add utility Node#hasNoUsages.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 18845
diff changeset
184 if (isNullNode.hasNoUsages()) {
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
185 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
186 }
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
187 }
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
188 }