annotate src/share/vm/opto/loopPredicate.cpp @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 55fb97c4c58d
children 4ca6dc0799b6 78bbf4d43a14
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
1 /*
17467
55fb97c4c58d 8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents: 12956
diff changeset
2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
4 *
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
7 * published by the Free Software Foundation.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
8 *
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
13 * accompanied this code).
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
14 *
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
18 *
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
21 * questions.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
22 *
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
23 */
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
24
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
25 #include "precompiled.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
26 #include "opto/loopnode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
27 #include "opto/addnode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
28 #include "opto/callnode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
29 #include "opto/connode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
30 #include "opto/loopnode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
31 #include "opto/mulnode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
32 #include "opto/rootnode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
33 #include "opto/subnode.hpp"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
34
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
35 /*
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
36 * The general idea of Loop Predication is to insert a predicate on the entry
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
37 * path to a loop, and raise a uncommon trap if the check of the condition fails.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
38 * The condition checks are promoted from inside the loop body, and thus
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
39 * the checks inside the loop could be eliminated. Currently, loop predication
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
40 * optimization has been applied to remove array range check and loop invariant
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
41 * checks (such as null checks).
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
42 */
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
43
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
44 //-------------------------------register_control-------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
45 void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
46 assert(n->is_CFG(), "must be control node");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
47 _igvn.register_new_node_with_optimizer(n);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
48 loop->_body.push(n);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
49 set_loop(n, loop);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
50 // When called from beautify_loops() idom is not constructed yet.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
51 if (_idom != NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
52 set_idom(n, pred, dom_depth(pred));
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
53 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
54 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
55
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
56 //------------------------------create_new_if_for_predicate------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
57 // create a new if above the uct_if_pattern for the predicate to be promoted.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
58 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
59 // before after
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
60 // ---------- ----------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
61 // ctrl ctrl
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
62 // | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
63 // | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
64 // v v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
65 // iff new_iff
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
66 // / \ / \
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
67 // / \ / \
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
68 // v v v v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
69 // uncommon_proj cont_proj if_uct if_cont
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
70 // \ | | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
71 // \ | | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
72 // v v v | v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
73 // rgn loop | iff
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
74 // | | / \
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
75 // | | / \
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
76 // v | v v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
77 // uncommon_trap | uncommon_proj cont_proj
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
78 // \ \ | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
79 // \ \ | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
80 // v v v v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
81 // rgn loop
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
82 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
83 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
84 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
85 // uncommon_trap
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
86 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
87 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
88 // We will create a region to guard the uct call if there is no one there.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
89 // The true projecttion (if_cont) of the new_iff is returned.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
90 // This code is also used to clone predicates to clonned loops.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
91 ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
92 Deoptimization::DeoptReason reason) {
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
93 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
94 IfNode* iff = cont_proj->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
95
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
96 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
97 Node *rgn = uncommon_proj->unique_ctrl_out();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
98 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
99
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
100 uint proj_index = 1; // region's edge corresponding to uncommon_proj
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
101 if (!rgn->is_Region()) { // create a region to guard the call
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
102 assert(rgn->is_Call(), "must be call uct");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
103 CallNode* call = rgn->as_Call();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
104 IdealLoopTree* loop = get_loop(call);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
105 rgn = new (C) RegionNode(1);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
106 rgn->add_req(uncommon_proj);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
107 register_control(rgn, loop, uncommon_proj);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
108 _igvn.hash_delete(call);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
109 call->set_req(0, rgn);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
110 // When called from beautify_loops() idom is not constructed yet.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
111 if (_idom != NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
112 set_idom(call, rgn, dom_depth(rgn));
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
113 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
114 } else {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
115 // Find region's edge corresponding to uncommon_proj
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
116 for (; proj_index < rgn->req(); proj_index++)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
117 if (rgn->in(proj_index) == uncommon_proj) break;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
118 assert(proj_index < rgn->req(), "sanity");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
119 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
120
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
121 Node* entry = iff->in(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
122 if (new_entry != NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
123 // Clonning the predicate to new location.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
124 entry = new_entry;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
125 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
126 // Create new_iff
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
127 IdealLoopTree* lp = get_loop(entry);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
128 IfNode *new_iff = iff->clone()->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
129 new_iff->set_req(0, entry);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
130 register_control(new_iff, lp, entry);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
131 Node *if_cont = new (C) IfTrueNode(new_iff);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
132 Node *if_uct = new (C) IfFalseNode(new_iff);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
133 if (cont_proj->is_IfFalse()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
134 // Swap
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
135 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
136 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
137 register_control(if_cont, lp, new_iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
138 register_control(if_uct, get_loop(rgn), new_iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
139
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
140 // if_uct to rgn
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
141 _igvn.hash_delete(rgn);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
142 rgn->add_req(if_uct);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
143 // When called from beautify_loops() idom is not constructed yet.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
144 if (_idom != NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
145 Node* ridom = idom(rgn);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
146 Node* nrdom = dom_lca(ridom, new_iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
147 set_idom(rgn, nrdom, dom_depth(rgn));
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
148 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
149
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
150 // If rgn has phis add new edges which has the same
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
151 // value as on original uncommon_proj pass.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
152 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
153 bool has_phi = false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
154 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
155 Node* use = rgn->fast_out(i);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
156 if (use->is_Phi() && use->outcnt() > 0) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
157 assert(use->in(0) == rgn, "");
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3850
diff changeset
158 _igvn.rehash_node_delayed(use);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
159 use->add_req(use->in(proj_index));
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
160 has_phi = true;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
161 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
162 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
163 assert(!has_phi || rgn->req() > 3, "no phis when region is created");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
164
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
165 if (new_entry == NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
166 // Attach if_cont to iff
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
167 _igvn.hash_delete(iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
168 iff->set_req(0, if_cont);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
169 if (_idom != NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
170 set_idom(iff, if_cont, dom_depth(iff));
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
171 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
172 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
173 return if_cont->as_Proj();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
174 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
175
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
176 //------------------------------create_new_if_for_predicate------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
177 // Create a new if below new_entry for the predicate to be cloned (IGVN optimization)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
178 ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
179 Deoptimization::DeoptReason reason) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
180 assert(new_entry != 0, "only used for clone predicate");
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
181 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
182 IfNode* iff = cont_proj->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
183
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
184 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
185 Node *rgn = uncommon_proj->unique_ctrl_out();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
186 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
187
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
188 uint proj_index = 1; // region's edge corresponding to uncommon_proj
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
189 if (!rgn->is_Region()) { // create a region to guard the call
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
190 assert(rgn->is_Call(), "must be call uct");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
191 CallNode* call = rgn->as_Call();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
192 rgn = new (C) RegionNode(1);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
193 register_new_node_with_optimizer(rgn);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
194 rgn->add_req(uncommon_proj);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
195 hash_delete(call);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
196 call->set_req(0, rgn);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
197 } else {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
198 // Find region's edge corresponding to uncommon_proj
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
199 for (; proj_index < rgn->req(); proj_index++)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
200 if (rgn->in(proj_index) == uncommon_proj) break;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
201 assert(proj_index < rgn->req(), "sanity");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
202 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
203
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
204 // Create new_iff in new location.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
205 IfNode *new_iff = iff->clone()->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
206 new_iff->set_req(0, new_entry);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
207
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
208 register_new_node_with_optimizer(new_iff);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
209 Node *if_cont = new (C) IfTrueNode(new_iff);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
210 Node *if_uct = new (C) IfFalseNode(new_iff);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
211 if (cont_proj->is_IfFalse()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
212 // Swap
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
213 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
214 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
215 register_new_node_with_optimizer(if_cont);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
216 register_new_node_with_optimizer(if_uct);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
217
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
218 // if_uct to rgn
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
219 hash_delete(rgn);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
220 rgn->add_req(if_uct);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
221
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
222 // If rgn has phis add corresponding new edges which has the same
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
223 // value as on original uncommon_proj pass.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
224 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
225 bool has_phi = false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
226 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
227 Node* use = rgn->fast_out(i);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
228 if (use->is_Phi() && use->outcnt() > 0) {
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3850
diff changeset
229 rehash_node_delayed(use);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
230 use->add_req(use->in(proj_index));
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
231 has_phi = true;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
232 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
233 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
234 assert(!has_phi || rgn->req() > 3, "no phis when region is created");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
235
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
236 return if_cont->as_Proj();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
237 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
238
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
239 //--------------------------clone_predicate-----------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
240 ProjNode* PhaseIdealLoop::clone_predicate(ProjNode* predicate_proj, Node* new_entry,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
241 Deoptimization::DeoptReason reason,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
242 PhaseIdealLoop* loop_phase,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
243 PhaseIterGVN* igvn) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
244 ProjNode* new_predicate_proj;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
245 if (loop_phase != NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
246 new_predicate_proj = loop_phase->create_new_if_for_predicate(predicate_proj, new_entry, reason);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
247 } else {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
248 new_predicate_proj = igvn->create_new_if_for_predicate(predicate_proj, new_entry, reason);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
249 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
250 IfNode* iff = new_predicate_proj->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
251 Node* ctrl = iff->in(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
252
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
253 // Match original condition since predicate's projections could be swapped.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
254 assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
255 Node* opq = new (igvn->C) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1));
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
256 igvn->C->add_predicate_opaq(opq);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
257
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
258 Node* bol = new (igvn->C) Conv2BNode(opq);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
259 if (loop_phase != NULL) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
260 loop_phase->register_new_node(opq, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
261 loop_phase->register_new_node(bol, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
262 } else {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
263 igvn->register_new_node_with_optimizer(opq);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
264 igvn->register_new_node_with_optimizer(bol);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
265 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
266 igvn->hash_delete(iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
267 iff->set_req(1, bol);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
268 return new_predicate_proj;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
269 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
270
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
271
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
272 //--------------------------clone_loop_predicates-----------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
273 // Interface from IGVN
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
274 Node* PhaseIterGVN::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) {
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
275 return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, clone_limit_check, NULL, this);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
276 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
277
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
278 // Interface from PhaseIdealLoop
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
279 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) {
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
280 return clone_loop_predicates(old_entry, new_entry, clone_limit_check, this, &this->_igvn);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
281 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
282
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
283 // Clone loop predicates to cloned loops (peeled, unswitched, split_if).
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
284 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry,
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
285 bool clone_limit_check,
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
286 PhaseIdealLoop* loop_phase,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
287 PhaseIterGVN* igvn) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
288 #ifdef ASSERT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
289 if (new_entry == NULL || !(new_entry->is_Proj() || new_entry->is_Region() || new_entry->is_SafePoint())) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
290 if (new_entry != NULL)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
291 new_entry->dump();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
292 assert(false, "not IfTrue, IfFalse, Region or SafePoint");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
293 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
294 #endif
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
295 // Search original predicates
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
296 Node* entry = old_entry;
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
297 ProjNode* limit_check_proj = NULL;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
298 if (LoopLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
299 limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
300 if (limit_check_proj != NULL) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
301 entry = entry->in(0)->in(0);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
302 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
303 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
304 if (UseLoopPredicate) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
305 ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
306 if (predicate_proj != NULL) { // right pattern that can be used by loop predication
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
307 // clone predicate
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
308 new_entry = clone_predicate(predicate_proj, new_entry,
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
309 Deoptimization::Reason_predicate,
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
310 loop_phase, igvn);
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
311 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone predicate");
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
312 if (TraceLoopPredicate) {
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
313 tty->print("Loop Predicate cloned: ");
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
314 debug_only( new_entry->in(0)->dump(); )
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
315 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
316 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
317 }
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
318 if (limit_check_proj != NULL && clone_limit_check) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
319 // Clone loop limit check last to insert it before loop.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
320 // Don't clone a limit check which was already finalized
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
321 // for this counted loop (only one limit check is needed).
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
322 new_entry = clone_predicate(limit_check_proj, new_entry,
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
323 Deoptimization::Reason_loop_limit_check,
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
324 loop_phase, igvn);
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
325 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone limit check");
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
326 if (TraceLoopLimitCheck) {
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3840
diff changeset
327 tty->print("Loop Limit Check cloned: ");
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
328 debug_only( new_entry->in(0)->dump(); )
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
329 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
330 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
331 return new_entry;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
332 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
333
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
334 //--------------------------skip_loop_predicates------------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
335 // Skip related predicates.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
336 Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
337 Node* predicate = NULL;
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
338 if (LoopLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
339 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
340 if (predicate != NULL) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
341 entry = entry->in(0)->in(0);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
342 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
343 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
344 if (UseLoopPredicate) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
345 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
346 if (predicate != NULL) { // right pattern that can be used by loop predication
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
347 IfNode* iff = entry->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
348 ProjNode* uncommon_proj = iff->proj_out(1 - entry->as_Proj()->_con);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
349 Node* rgn = uncommon_proj->unique_ctrl_out();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
350 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
351 entry = entry->in(0)->in(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
352 while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
353 uncommon_proj = entry->in(0)->as_If()->proj_out(1 - entry->as_Proj()->_con);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
354 if (uncommon_proj->unique_ctrl_out() != rgn)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
355 break;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
356 entry = entry->in(0)->in(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
357 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
358 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
359 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
360 return entry;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
361 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
362
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
363 //--------------------------find_predicate_insertion_point-------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
364 // Find a good location to insert a predicate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
365 ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
366 if (start_c == NULL || !start_c->is_Proj())
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
367 return NULL;
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
368 if (start_c->as_Proj()->is_uncommon_trap_if_pattern(reason)) {
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
369 return start_c->as_Proj();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
370 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
371 return NULL;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
372 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
373
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
374 //--------------------------find_predicate------------------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
375 // Find a predicate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
376 Node* PhaseIdealLoop::find_predicate(Node* entry) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
377 Node* predicate = NULL;
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
378 if (LoopLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
379 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
380 if (predicate != NULL) { // right pattern that can be used by loop predication
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
381 return entry;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
382 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
383 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
384 if (UseLoopPredicate) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
385 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
386 if (predicate != NULL) { // right pattern that can be used by loop predication
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
387 return entry;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
388 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
389 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
390 return NULL;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
391 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
392
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
393 //------------------------------Invariance-----------------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
394 // Helper class for loop_predication_impl to compute invariance on the fly and
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
395 // clone invariants.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
396 class Invariance : public StackObj {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
397 VectorSet _visited, _invariant;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
398 Node_Stack _stack;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
399 VectorSet _clone_visited;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
400 Node_List _old_new; // map of old to new (clone)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
401 IdealLoopTree* _lpt;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
402 PhaseIdealLoop* _phase;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
403
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
404 // Helper function to set up the invariance for invariance computation
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
405 // If n is a known invariant, set up directly. Otherwise, look up the
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
406 // the possibility to push n onto the stack for further processing.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
407 void visit(Node* use, Node* n) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
408 if (_lpt->is_invariant(n)) { // known invariant
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
409 _invariant.set(n->_idx);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
410 } else if (!n->is_CFG()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
411 Node *n_ctrl = _phase->ctrl_or_self(n);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
412 Node *u_ctrl = _phase->ctrl_or_self(use); // self if use is a CFG
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
413 if (_phase->is_dominator(n_ctrl, u_ctrl)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
414 _stack.push(n, n->in(0) == NULL ? 1 : 0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
415 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
416 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
417 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
418
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
419 // Compute invariance for "the_node" and (possibly) all its inputs recursively
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
420 // on the fly
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
421 void compute_invariance(Node* n) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
422 assert(_visited.test(n->_idx), "must be");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
423 visit(n, n);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
424 while (_stack.is_nonempty()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
425 Node* n = _stack.node();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
426 uint idx = _stack.index();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
427 if (idx == n->req()) { // all inputs are processed
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
428 _stack.pop();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
429 // n is invariant if it's inputs are all invariant
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
430 bool all_inputs_invariant = true;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
431 for (uint i = 0; i < n->req(); i++) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
432 Node* in = n->in(i);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
433 if (in == NULL) continue;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
434 assert(_visited.test(in->_idx), "must have visited input");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
435 if (!_invariant.test(in->_idx)) { // bad guy
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
436 all_inputs_invariant = false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
437 break;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
438 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
439 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
440 if (all_inputs_invariant) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
441 _invariant.set(n->_idx); // I am a invariant too
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
442 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
443 } else { // process next input
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
444 _stack.set_index(idx + 1);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
445 Node* m = n->in(idx);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
446 if (m != NULL && !_visited.test_set(m->_idx)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
447 visit(n, m);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
448 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
449 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
450 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
451 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
452
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
453 // Helper function to set up _old_new map for clone_nodes.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
454 // If n is a known invariant, set up directly ("clone" of n == n).
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
455 // Otherwise, push n onto the stack for real cloning.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
456 void clone_visit(Node* n) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
457 assert(_invariant.test(n->_idx), "must be invariant");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
458 if (_lpt->is_invariant(n)) { // known invariant
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
459 _old_new.map(n->_idx, n);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
460 } else { // to be cloned
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
461 assert(!n->is_CFG(), "should not see CFG here");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
462 _stack.push(n, n->in(0) == NULL ? 1 : 0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
463 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
464 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
465
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
466 // Clone "n" and (possibly) all its inputs recursively
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
467 void clone_nodes(Node* n, Node* ctrl) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
468 clone_visit(n);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
469 while (_stack.is_nonempty()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
470 Node* n = _stack.node();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
471 uint idx = _stack.index();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
472 if (idx == n->req()) { // all inputs processed, clone n!
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
473 _stack.pop();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
474 // clone invariant node
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
475 Node* n_cl = n->clone();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
476 _old_new.map(n->_idx, n_cl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
477 _phase->register_new_node(n_cl, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
478 for (uint i = 0; i < n->req(); i++) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
479 Node* in = n_cl->in(i);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
480 if (in == NULL) continue;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
481 n_cl->set_req(i, _old_new[in->_idx]);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
482 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
483 } else { // process next input
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
484 _stack.set_index(idx + 1);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
485 Node* m = n->in(idx);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
486 if (m != NULL && !_clone_visited.test_set(m->_idx)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
487 clone_visit(m); // visit the input
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
488 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
489 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
490 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
491 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
492
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
493 public:
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
494 Invariance(Arena* area, IdealLoopTree* lpt) :
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
495 _lpt(lpt), _phase(lpt->_phase),
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
496 _visited(area), _invariant(area), _stack(area, 10 /* guess */),
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
497 _clone_visited(area), _old_new(area)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
498 {}
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
499
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
500 // Map old to n for invariance computation and clone
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
501 void map_ctrl(Node* old, Node* n) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
502 assert(old->is_CFG() && n->is_CFG(), "must be");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
503 _old_new.map(old->_idx, n); // "clone" of old is n
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
504 _invariant.set(old->_idx); // old is invariant
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
505 _clone_visited.set(old->_idx);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
506 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
507
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
508 // Driver function to compute invariance
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
509 bool is_invariant(Node* n) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
510 if (!_visited.test_set(n->_idx))
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
511 compute_invariance(n);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
512 return (_invariant.test(n->_idx) != 0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
513 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
514
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
515 // Driver function to clone invariant
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
516 Node* clone(Node* n, Node* ctrl) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
517 assert(ctrl->is_CFG(), "must be");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
518 assert(_invariant.test(n->_idx), "must be an invariant");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
519 if (!_clone_visited.test(n->_idx))
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
520 clone_nodes(n, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
521 return _old_new[n->_idx];
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
522 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
523 };
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
524
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
525 //------------------------------is_range_check_if -----------------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
526 // Returns true if the predicate of iff is in "scale*iv + offset u< load_range(ptr)" format
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
527 // Note: this function is particularly designed for loop predication. We require load_range
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
528 // and offset to be loop invariant computed on the fly by "invar"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
529 bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
530 if (!is_loop_exit(iff)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
531 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
532 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
533 if (!iff->in(1)->is_Bool()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
534 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
535 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
536 const BoolNode *bol = iff->in(1)->as_Bool();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
537 if (bol->_test._test != BoolTest::lt) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
538 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
539 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
540 if (!bol->in(1)->is_Cmp()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
541 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
542 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
543 const CmpNode *cmp = bol->in(1)->as_Cmp();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
544 if (cmp->Opcode() != Op_CmpU) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
545 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
546 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
547 Node* range = cmp->in(2);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
548 if (range->Opcode() != Op_LoadRange) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
549 const TypeInt* tint = phase->_igvn.type(range)->isa_int();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
550 if (tint == NULL || tint->empty() || tint->_lo < 0) {
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
551 // Allow predication on positive values that aren't LoadRanges.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
552 // This allows optimization of loops where the length of the
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
553 // array is a known value and doesn't need to be loaded back
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
554 // from the array.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
555 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
556 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
557 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
558 if (!invar.is_invariant(range)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
559 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
560 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
561 Node *iv = _head->as_CountedLoop()->phi();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
562 int scale = 0;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
563 Node *offset = NULL;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
564 if (!phase->is_scaled_iv_plus_offset(cmp->in(1), iv, &scale, &offset)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
565 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
566 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
567 if (offset && !invar.is_invariant(offset)) { // offset must be invariant
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
568 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
569 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
570 return true;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
571 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
572
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
573 //------------------------------rc_predicate-----------------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
574 // Create a range check predicate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
575 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
576 // for (i = init; i < limit; i += stride) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
577 // a[scale*i+offset]
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
578 // }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
579 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
580 // Compute max(scale*i + offset) for init <= i < limit and build the predicate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
581 // as "max(scale*i + offset) u< a.length".
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
582 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
583 // There are two cases for max(scale*i + offset):
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
584 // (1) stride*scale > 0
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
585 // max(scale*i + offset) = scale*(limit-stride) + offset
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
586 // (2) stride*scale < 0
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
587 // max(scale*i + offset) = scale*init + offset
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
588 BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
589 int scale, Node* offset,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
590 Node* init, Node* limit, Node* stride,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
591 Node* range, bool upper) {
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
592 stringStream* predString = NULL;
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
593 if (TraceLoopPredicate) {
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
594 predString = new stringStream();
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
595 predString->print("rc_predicate ");
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
596 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
597
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
598 Node* max_idx_expr = init;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
599 int stride_con = stride->get_int();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
600 if ((stride_con > 0) == (scale > 0) == upper) {
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
601 if (LoopLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
602 // With LoopLimitCheck limit is not exact.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
603 // Calculate exact limit here.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
604 // Note, counted loop's test is '<' or '>'.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
605 limit = exact_limit(loop);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
606 max_idx_expr = new (C) SubINode(limit, stride);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
607 register_new_node(max_idx_expr, ctrl);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
608 if (TraceLoopPredicate) predString->print("(limit - stride) ");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
609 } else {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
610 max_idx_expr = new (C) SubINode(limit, stride);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
611 register_new_node(max_idx_expr, ctrl);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
612 if (TraceLoopPredicate) predString->print("(limit - stride) ");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
613 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
614 } else {
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
615 if (TraceLoopPredicate) predString->print("init ");
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
616 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
617
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
618 if (scale != 1) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
619 ConNode* con_scale = _igvn.intcon(scale);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
620 max_idx_expr = new (C) MulINode(max_idx_expr, con_scale);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
621 register_new_node(max_idx_expr, ctrl);
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
622 if (TraceLoopPredicate) predString->print("* %d ", scale);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
623 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
624
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
625 if (offset && (!offset->is_Con() || offset->get_int() != 0)){
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
626 max_idx_expr = new (C) AddINode(max_idx_expr, offset);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
627 register_new_node(max_idx_expr, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
628 if (TraceLoopPredicate)
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
629 if (offset->is_Con()) predString->print("+ %d ", offset->get_int());
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
630 else predString->print("+ offset ");
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
631 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
632
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
633 CmpUNode* cmp = new (C) CmpUNode(max_idx_expr, range);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
634 register_new_node(cmp, ctrl);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
635 BoolNode* bol = new (C) BoolNode(cmp, BoolTest::lt);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
636 register_new_node(bol, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
637
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
638 if (TraceLoopPredicate) {
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
639 predString->print_cr("<u range");
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
640 tty->print(predString->as_string());
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2445
diff changeset
641 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
642 return bol;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
643 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
644
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
645 //------------------------------ loop_predication_impl--------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
646 // Insert loop predicates for null checks and range checks
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
647 bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
648 if (!UseLoopPredicate) return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
649
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
650 if (!loop->_head->is_Loop()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
651 // Could be a simple region when irreducible loops are present.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
652 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
653 }
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
654 LoopNode* head = loop->_head->as_Loop();
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
655
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
656 if (head->unique_ctrl_out()->Opcode() == Op_NeverBranch) {
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
657 // do nothing for infinite loops
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
658 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
659 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
660
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
661 CountedLoopNode *cl = NULL;
3850
6987871cfb9b 7077439: Possible reference through NULL in loopPredicate.cpp:726
kvn
parents: 3845
diff changeset
662 if (head->is_valid_counted_loop()) {
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
663 cl = head->as_CountedLoop();
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
664 // do nothing for iteration-splitted loops
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
665 if (!cl->is_normal_loop()) return false;
3840
4e761e7e6e12 7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents: 3345
diff changeset
666 // Avoid RCE if Counted loop's test is '!='.
4e761e7e6e12 7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents: 3345
diff changeset
667 BoolTest::mask bt = cl->loopexit()->test_trip();
4e761e7e6e12 7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents: 3345
diff changeset
668 if (bt != BoolTest::lt && bt != BoolTest::gt)
4e761e7e6e12 7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents: 3345
diff changeset
669 cl = NULL;
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
670 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
671
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
672 Node* entry = head->in(LoopNode::EntryControl);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
673 ProjNode *predicate_proj = NULL;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
674 // Loop limit check predicate should be near the loop.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
675 if (LoopLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
676 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
677 if (predicate_proj != NULL)
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
678 entry = predicate_proj->in(0)->in(0);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
679 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
680
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
681 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
682 if (!predicate_proj) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
683 #ifndef PRODUCT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
684 if (TraceLoopPredicate) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
685 tty->print("missing predicate:");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
686 loop->dump_head();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
687 head->dump(1);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
688 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
689 #endif
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
690 return false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
691 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
692 ConNode* zero = _igvn.intcon(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
693 set_ctrl(zero, C->root());
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
694
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
695 ResourceArea *area = Thread::current()->resource_area();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
696 Invariance invar(area, loop);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
697
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
698 // Create list of if-projs such that a newer proj dominates all older
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
699 // projs in the list, and they all dominate loop->tail()
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
700 Node_List if_proj_list(area);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
701 Node *current_proj = loop->tail(); //start from tail
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
702 while (current_proj != head) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
703 if (loop == get_loop(current_proj) && // still in the loop ?
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
704 current_proj->is_Proj() && // is a projection ?
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
705 current_proj->in(0)->Opcode() == Op_If) { // is a if projection ?
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
706 if_proj_list.push(current_proj);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
707 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
708 current_proj = idom(current_proj);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
709 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
710
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
711 bool hoisted = false; // true if at least one proj is promoted
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
712 while (if_proj_list.size() > 0) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
713 // Following are changed to nonnull when a predicate can be hoisted
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
714 ProjNode* new_predicate_proj = NULL;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
715
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
716 ProjNode* proj = if_proj_list.pop()->as_Proj();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
717 IfNode* iff = proj->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
718
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
719 if (!proj->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
720 if (loop->is_loop_exit(iff)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
721 // stop processing the remaining projs in the list because the execution of them
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
722 // depends on the condition of "iff" (iff->in(1)).
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
723 break;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
724 } else {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
725 // Both arms are inside the loop. There are two cases:
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
726 // (1) there is one backward branch. In this case, any remaining proj
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
727 // in the if_proj list post-dominates "iff". So, the condition of "iff"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
728 // does not determine the execution the remining projs directly, and we
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
729 // can safely continue.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
730 // (2) both arms are forwarded, i.e. a diamond shape. In this case, "proj"
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
731 // does not dominate loop->tail(), so it can not be in the if_proj list.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
732 continue;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
733 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
734 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
735
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
736 Node* test = iff->in(1);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
737 if (!test->is_Bool()){ //Conv2B, ...
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
738 continue;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
739 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
740 BoolNode* bol = test->as_Bool();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
741 if (invar.is_invariant(bol)) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
742 // Invariant test
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
743 new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
744 Deoptimization::Reason_predicate);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
745 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
746 BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
747
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
748 // Negate test if necessary
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
749 bool negated = false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
750 if (proj->_con != predicate_proj->_con) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
751 new_predicate_bol = new (C) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
752 register_new_node(new_predicate_bol, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
753 negated = true;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
754 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
755 IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
756 _igvn.hash_delete(new_predicate_iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
757 new_predicate_iff->set_req(1, new_predicate_bol);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
758 #ifndef PRODUCT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
759 if (TraceLoopPredicate) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
760 tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
761 loop->dump_head();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
762 } else if (TraceLoopOpts) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
763 tty->print("Predicate IC ");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
764 loop->dump_head();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
765 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
766 #endif
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 6842
diff changeset
767 } else if ((cl != NULL) && (proj->_con == predicate_proj->_con) &&
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 6842
diff changeset
768 loop->is_range_check_if(iff, this, invar)) {
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
769
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
770 // Range check for counted loops
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
771 const Node* cmp = bol->in(1)->as_Cmp();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
772 Node* idx = cmp->in(1);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
773 assert(!invar.is_invariant(idx), "index is variant");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
774 Node* rng = cmp->in(2);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
775 assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be");
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
776 assert(invar.is_invariant(rng), "range must be invariant");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
777 int scale = 1;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
778 Node* offset = zero;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
779 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
780 assert(ok, "must be index expression");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
781
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
782 Node* init = cl->init_trip();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
783 Node* limit = cl->limit();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
784 Node* stride = cl->stride();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
785
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
786 // Build if's for the upper and lower bound tests. The
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
787 // lower_bound test will dominate the upper bound test and all
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
788 // cloned or created nodes will use the lower bound test as
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
789 // their declared control.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
790 ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
791 ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
792 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
793 Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
794
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
795 // Perform cloning to keep Invariance state correct since the
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
796 // late schedule will place invariant things in the loop.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
797 rng = invar.clone(rng, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
798 if (offset && offset != zero) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
799 assert(invar.is_invariant(offset), "offset must be loop invariant");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
800 offset = invar.clone(offset, ctrl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
801 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
802
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
803 // Test the lower bound
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3336
diff changeset
804 Node* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
805 IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
806 _igvn.hash_delete(lower_bound_iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
807 lower_bound_iff->set_req(1, lower_bound_bol);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
808 if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
809
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
810 // Test the upper bound
3840
4e761e7e6e12 7070134: Hotspot crashes with sigsegv from PorterStemmer
kvn
parents: 3345
diff changeset
811 Node* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
812 IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
813 _igvn.hash_delete(upper_bound_iff);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
814 upper_bound_iff->set_req(1, upper_bound_bol);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
815 if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
816
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
817 // Fall through into rest of the clean up code which will move
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
818 // any dependent nodes onto the upper bound test.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
819 new_predicate_proj = upper_bound_proj;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
820
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
821 #ifndef PRODUCT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
822 if (TraceLoopOpts && !TraceLoopPredicate) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
823 tty->print("Predicate RC ");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
824 loop->dump_head();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
825 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
826 #endif
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
827 } else {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
828 // Loop variant check (for example, range check in non-counted loop)
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
829 // with uncommon trap.
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
830 continue;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
831 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
832 assert(new_predicate_proj != NULL, "sanity");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
833 // Success - attach condition (new_predicate_bol) to predicate if
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
834 invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
835
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
836 // Eliminate the old If in the loop body
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
837 dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con );
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
838
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
839 hoisted = true;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
840 C->set_major_progress();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
841 } // end while
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
842
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
843 #ifndef PRODUCT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
844 // report that the loop predication has been actually performed
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
845 // for this loop
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
846 if (TraceLoopPredicate && hoisted) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
847 tty->print("Loop Predication Performed:");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
848 loop->dump_head();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
849 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
850 #endif
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
851
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
852 return hoisted;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
853 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
854
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
855 //------------------------------loop_predication--------------------------------
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
856 // driver routine for loop predication optimization
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
857 bool IdealLoopTree::loop_predication( PhaseIdealLoop *phase) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
858 bool hoisted = false;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
859 // Recursively promote predicates
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
860 if (_child) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
861 hoisted = _child->loop_predication( phase);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
862 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
863
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
864 // self
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
865 if (!_irreducible && !tail()->is_top()) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
866 hoisted |= phase->loop_predication_impl(this);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
867 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
868
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
869 if (_next) { //sibling
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
870 hoisted |= _next->loop_predication( phase);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
871 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
872
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
873 return hoisted;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents:
diff changeset
874 }