annotate src/share/vm/opto/loopUnswitch.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 2aff40cb4703
children 9e69e8d1c900
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6842
b9a9ed0f8eeb 7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents: 6804
diff changeset
2 * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 605
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 605
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 605
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "opto/connode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "opto/loopnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "opto/rootnode.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 //================= Loop Unswitching =====================
a61af66fc99e Initial load
duke
parents:
diff changeset
32 //
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // orig: transformed:
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // if (invariant-test) then
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
35 // predicate predicate
0
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // loop loop
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // stmt1 stmt1
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // if (invariant-test) then stmt2
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // stmt2 stmt4
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // else endloop
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // stmt3 else
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
42 // endif predicate [clone]
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
43 // stmt4 loop [clone]
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
44 // endloop stmt1 [clone]
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
45 // stmt3
0
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // stmt4 [clone]
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // endloop
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // endif
a61af66fc99e Initial load
duke
parents:
diff changeset
49 //
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Note: the "else" clause may be empty
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 //------------------------------policy_unswitching-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Return TRUE or FALSE if the loop should be unswitched
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // (ie. clone loop with an invariant test that does not exit the loop)
a61af66fc99e Initial load
duke
parents:
diff changeset
55 bool IdealLoopTree::policy_unswitching( PhaseIdealLoop *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 if( !LoopUnswitching ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
108
a761c2d3b76a 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 0
diff changeset
59 if (!_head->is_Loop()) {
a761c2d3b76a 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 0
diff changeset
60 return false;
a761c2d3b76a 6684385: Loop unswitching crashes without LoopNode
rasbold
parents: 0
diff changeset
61 }
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 6842
diff changeset
62 uint nodes_left = MaxNodeLimit - phase->C->live_nodes();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
63 if (2 * _body.size() > nodes_left) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 return false; // Too speculative if running low on nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66 LoopNode* head = _head->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
67 if (head->unswitch_count() + 1 > head->unswitch_max()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 return phase->find_unswitching_candidate(this) != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 //------------------------------find_unswitching_candidate-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Find candidate "if" for unswitching
a61af66fc99e Initial load
duke
parents:
diff changeset
75 IfNode* PhaseIdealLoop::find_unswitching_candidate(const IdealLoopTree *loop) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // Find first invariant test that doesn't exit the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
78 LoopNode *head = loop->_head->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
79 IfNode* unswitch_iff = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 Node* n = head->in(LoopNode::LoopBackControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 while (n != head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 Node* n_dom = idom(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 if (n->is_Region()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (n_dom->is_If()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 IfNode* iff = n_dom->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
86 if (iff->in(1)->is_Bool()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 BoolNode* bol = iff->in(1)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
88 if (bol->in(1)->is_Cmp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // If condition is invariant and not a loop exit,
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // then found reason to unswitch.
a61af66fc99e Initial load
duke
parents:
diff changeset
91 if (loop->is_invariant(bol) && !loop->is_loop_exit(iff)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 unswitch_iff = iff;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 n = n_dom;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100 return unswitch_iff;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 //------------------------------do_unswitching-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // Clone loop with an invariant test (that does not exit) and
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // insert a clone of the test that selects which version to
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // execute.
a61af66fc99e Initial load
duke
parents:
diff changeset
107 void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Find first invariant test that doesn't exit the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
110 LoopNode *head = loop->_head->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 assert(unswitch_iff != NULL, "should be at least one");
a61af66fc99e Initial load
duke
parents:
diff changeset
114
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
115 #ifndef PRODUCT
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
116 if (TraceLoopOpts) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
117 tty->print("Unswitch %d ", head->unswitch_count()+1);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
118 loop->dump_head();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
119 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
120 #endif
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
121
0
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Need to revert back to normal loop
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 head->as_CountedLoop()->set_normal_loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 ProjNode* proj_true = create_slow_version_of_loop(loop, old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
128
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
129 #ifdef ASSERT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
130 Node* uniqc = proj_true->unique_ctrl_out();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
131 Node* entry = head->in(LoopNode::EntryControl);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
132 Node* predicate = find_predicate(entry);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
133 if (predicate != NULL && LoopLimitCheck && UseLoopPredicate) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
134 // We may have two predicates, find first.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
135 entry = find_predicate(entry->in(0)->in(0));
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
136 if (entry != NULL) predicate = entry;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
137 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
138 if (predicate != NULL) predicate = predicate->in(0);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
139 assert(proj_true->is_IfTrue() &&
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
140 (predicate == NULL && uniqc == head ||
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
141 predicate != NULL && uniqc == predicate), "by construction");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
142 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Increment unswitch count
a61af66fc99e Initial load
duke
parents:
diff changeset
144 LoopNode* head_clone = old_new[head->_idx]->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
145 int nct = head->unswitch_count() + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 head->set_unswitch_count(nct);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 head_clone->set_unswitch_count(nct);
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Add test to new "if" outside of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
150 IfNode* invar_iff = proj_true->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 Node* invar_iff_c = invar_iff->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 BoolNode* bol = unswitch_iff->in(1)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
153 invar_iff->set_req(1, bol);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 invar_iff->_prob = unswitch_iff->_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
157
605
98cb887364d3 6810672: Comment typos
twisti
parents: 235
diff changeset
158 // Hoist invariant casts out of each loop to the appropriate
0
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // control projection.
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 Node_List worklist;
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 for (DUIterator_Fast imax, i = unswitch_iff->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 ProjNode* proj= unswitch_iff->fast_out(i)->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Copy to a worklist for easier manipulation
a61af66fc99e Initial load
duke
parents:
diff changeset
166 for (DUIterator_Fast jmax, j = proj->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 Node* use = proj->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 if (use->Opcode() == Op_CheckCastPP && loop->is_invariant(use->in(1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172 ProjNode* invar_proj = invar_iff->proj_out(proj->_con)->as_Proj();
a61af66fc99e Initial load
duke
parents:
diff changeset
173 while (worklist.size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 Node* use = worklist.pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
175 Node* nuse = use->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
176 nuse->set_req(0, invar_proj);
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3845
diff changeset
177 _igvn.replace_input_of(use, 1, nuse);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
178 register_new_node(nuse, invar_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Same for the clone
a61af66fc99e Initial load
duke
parents:
diff changeset
180 Node* use_clone = old_new[use->_idx];
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3845
diff changeset
181 _igvn.replace_input_of(use_clone, 1, nuse);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Hardwire the control paths in the loops into if(true) and if(false)
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3845
diff changeset
186 _igvn.rehash_node_delayed(unswitch_iff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
187 short_circuit_if(unswitch_iff, proj_true);
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If();
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3845
diff changeset
190 _igvn.rehash_node_delayed(unswitch_iff_clone);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
191 short_circuit_if(unswitch_iff_clone, proj_false);
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // Reoptimize loops
a61af66fc99e Initial load
duke
parents:
diff changeset
194 loop->record_for_igvn();
a61af66fc99e Initial load
duke
parents:
diff changeset
195 for(int i = loop->_body.size() - 1; i >= 0 ; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 Node *n = loop->_body[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
197 Node *n_clone = old_new[n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
198 _igvn._worklist.push(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if (TraceLoopUnswitching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 tty->print_cr("Loop unswitching orig: %d @ %d new: %d @ %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
204 head->_idx, unswitch_iff->_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
205 old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 //-------------------------create_slow_version_of_loop------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // Create a slow version of the loop by cloning the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // and inserting an if to select fast-slow versions.
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Return control projection of the entry to the fast version.
a61af66fc99e Initial load
duke
parents:
diff changeset
216 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
217 Node_List &old_new) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 LoopNode* head = loop->_head->as_Loop();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
219 bool counted_loop = head->is_CountedLoop();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220 Node* entry = head->in(LoopNode::EntryControl);
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3845
diff changeset
221 _igvn.rehash_node_delayed(entry);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
222 IdealLoopTree* outer_loop = loop->_parent;
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 Node *cont = _igvn.intcon(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 set_ctrl(cont, C->root());
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
226 Node* opq = new (C) Opaque1Node(C, cont);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227 register_node(opq, outer_loop, entry, dom_depth(entry));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
228 Node *bol = new (C) Conv2BNode(opq);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
229 register_node(bol, outer_loop, entry, dom_depth(entry));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
230 IfNode* iff = new (C) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
231 register_node(iff, outer_loop, entry, dom_depth(entry));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
232 ProjNode* iffast = new (C) IfTrueNode(iff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
233 register_node(iffast, outer_loop, iff, dom_depth(iff));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6144
diff changeset
234 ProjNode* ifslow = new (C) IfFalseNode(iff);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
235 register_node(ifslow, outer_loop, iff, dom_depth(iff));
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Clone the loop body. The clone becomes the fast loop. The
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
238 // original pre-header will (illegally) have 3 control users
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
239 // (old & new loops & new if).
0
a61af66fc99e Initial load
duke
parents:
diff changeset
240 clone_loop(loop, old_new, dom_depth(head), iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 assert(old_new[head->_idx]->is_Loop(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // Fast (true) control
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
244 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3845
diff changeset
245 _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
246 set_idom(head, iffast_pred, dom_depth(head));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Slow (false) control
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3345
diff changeset
249 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
250 LoopNode* slow_head = old_new[head->_idx]->as_Loop();
6144
5e990493719e 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 3845
diff changeset
251 _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
252 set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 recompute_dom_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return iffast;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }