annotate graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java @ 18187:9619ba4daf4c

Rename Constant to JavaConstant.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 30 Oct 2014 12:21:07 +0100
parents 45b45f902bed
children 0f4813e0b4a9
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.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
33 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
34 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
35 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
36 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
37 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
38
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 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
40
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
41 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
42 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
43 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
44
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
45 @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
46 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
47 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
48 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
49 }
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 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
51
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
52 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
53 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
54 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
55 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
56 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
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 }
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
59
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
60 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
61 Node predecessor = deopt.predecessor();
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
62 if (predecessor instanceof MergeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
63 MergeNode merge = (MergeNode) predecessor;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
64
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
65 // 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
66 // needed.
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
67 ValueNode reason = deopt.getActionAndReason();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
68 ValuePhiNode reasonPhi = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
69 List<ValueNode> reasons = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
70 int expectedPhis = 0;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
71
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
72 if (reason instanceof ValuePhiNode) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
73 reasonPhi = (ValuePhiNode) reason;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
74 if (reasonPhi.merge() != merge) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
75 return;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
76 }
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
77 reasons = reasonPhi.values().snapshot();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
78 expectedPhis++;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
79 } else if (!reason.isConstant()) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
80 return;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
81 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
82
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
83 ValueNode speculation = deopt.getSpeculation();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
84 ValuePhiNode speculationPhi = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
85 List<ValueNode> speculations = null;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
86 if (speculation instanceof ValuePhiNode) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
87 speculationPhi = (ValuePhiNode) speculation;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
88 if (speculationPhi.merge() != merge) {
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
89 return;
15778
9ae1d2f3bda6 convert asserts into if tests and check for phis at merge
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15741
diff changeset
90 }
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
91 speculations = speculationPhi.values().snapshot();
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
92 expectedPhis++;
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
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
95 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
96 return;
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
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
99 int index = 0;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
100 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
101 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
102 ValueNode thisSpeculation = speculations != null ? speculations.get(index++) : speculation;
18187
9619ba4daf4c Rename Constant to JavaConstant.
Roland Schatz <roland.schatz@oracle.com>
parents: 17450
diff changeset
103 if (!thisReason.isConstant() || !thisSpeculation.isConstant() || !thisSpeculation.asJavaConstant().equals(JavaConstant.NULL_OBJECT)) {
15807
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
104 continue;
c9f913e5a93b handle expected phis when converting to trapping null checks
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15778
diff changeset
105 }
18187
9619ba4daf4c Rename Constant to JavaConstant.
Roland Schatz <roland.schatz@oracle.com>
parents: 17450
diff changeset
106 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
107 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
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 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
111
18187
9619ba4daf4c Rename Constant to JavaConstant.
Roland Schatz <roland.schatz@oracle.com>
parents: 17450
diff changeset
112 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
113 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
114 return;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
115 }
18187
9619ba4daf4c Rename Constant to JavaConstant.
Roland Schatz <roland.schatz@oracle.com>
parents: 17450
diff changeset
116 if (speculation != null && !speculation.equals(JavaConstant.NULL_OBJECT)) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
117 return;
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
118 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
119 if (predecessor instanceof MergeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
120 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
121 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
122 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
123 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
124 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
125 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
126 } else if (predecessor instanceof BeginNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
127 checkPredecessor(deopt, predecessor, deoptimizationReason);
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
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
131 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
132 Node current = predecessor;
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
133 BeginNode branch = null;
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
134 while (current instanceof BeginNode) {
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 branch = (BeginNode) current;
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 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
137 // 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
138 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
139 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
140 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
141 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
142 if (current instanceof IfNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
143 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
144 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
145 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
146 }
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 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
148 if (condition instanceof IsNullNode) {
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
149 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
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 }
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
153
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
154 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
155 metricTrappingNullCheck.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
156 if (deopt instanceof DynamicDeoptimizeNode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
157 metricTrappingNullCheckDynamicDeoptimize.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
158 }
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
159 if (deoptimizationReason == DeoptimizationReason.UnreachedCode) {
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
160 metricTrappingNullCheckUnreached.increment();
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
161 }
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
162 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
163 BeginNode nonTrappingContinuation = ifNode.falseSuccessor();
df2ef5204f2b Remove AbstractBeginNode, move the framestate from AbstractBeginNode to BeginStateSplitNode.
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 14734
diff changeset
164 BeginNode trappingContinuation = ifNode.trueSuccessor();
16895
06c15e88d383 added factory method to all Node classes; replaced Node classes instantiation with calls to factory methods; replaced identity tests on Node classes with ' == <node class>.getGenClass()' idiom
Doug Simon <doug.simon@oracle.com>
parents: 16841
diff changeset
165 NullCheckNode trappingNullCheck = deopt.graph().add(NullCheckNode.create(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
166 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
167 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
168
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
169 /*
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
170 * 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
171 * 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
172 * 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
173 */
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
174 nonTrappingContinuation.replaceAtUsages(InputType.Guard, trappingNullCheck);
17450
45b45f902bed removed Node generation (GRAAL-857)
Doug Simon <doug.simon@oracle.com>
parents: 17054
diff changeset
175 if (nonTrappingContinuation.getClass() == BeginNode.class) {
17054
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
176 FixedNode next = nonTrappingContinuation.next();
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
177 nonTrappingContinuation.clearSuccessors();
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
178 trappingNullCheck.setNext(next);
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
179 nonTrappingContinuation.safeDelete();
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
180 } else {
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
181 trappingNullCheck.setNext(nonTrappingContinuation);
fb8fe09c00a3 Don't remove LoopExitNodes in UseTrappingNullChecksPhase.
Roland Schatz <roland.schatz@oracle.com>
parents: 16895
diff changeset
182 }
15698
eaeba148bb15 more aggressively fold implicit nulls into memory operations
Tom Rodriguez <tom.rodriguez@oracle.com>
parents: 15145
diff changeset
183
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
184 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
185 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
186 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
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 }
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
189 }