annotate src/share/vm/opto/loopUnswitch.cpp @ 4710:41406797186b

7113012: G1: rename not-fully-young GCs as "mixed" Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets). Reviewed-by: johnc, brutisso
author tonyp
date Fri, 16 Dec 2011 02:14:27 -0500
parents c96c3eb1efae
children 5e990493719e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2426
1d1603768966 7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents: 2383
diff changeset
2 * Copyright (c) 2006, 2011, 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 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
62 uint nodes_left = MaxNodeLimit - phase->C->unique();
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);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 use->set_req(1, nuse);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 _igvn._worklist.push(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 register_new_node(nuse, invar_proj);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Same for the clone
a61af66fc99e Initial load
duke
parents:
diff changeset
182 Node* use_clone = old_new[use->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
183 _igvn.hash_delete(use_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
184 use_clone->set_req(1, nuse);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 _igvn._worklist.push(use_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // Hardwire the control paths in the loops into if(true) and if(false)
a61af66fc99e Initial load
duke
parents:
diff changeset
190 _igvn.hash_delete(unswitch_iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 short_circuit_if(unswitch_iff, proj_true);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 _igvn._worklist.push(unswitch_iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
195 _igvn.hash_delete(unswitch_iff_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
196 short_circuit_if(unswitch_iff_clone, proj_false);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _igvn._worklist.push(unswitch_iff_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // Reoptimize loops
a61af66fc99e Initial load
duke
parents:
diff changeset
200 loop->record_for_igvn();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 for(int i = loop->_body.size() - 1; i >= 0 ; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 Node *n = loop->_body[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
203 Node *n_clone = old_new[n->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
204 _igvn._worklist.push(n_clone);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
208 if (TraceLoopUnswitching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 tty->print_cr("Loop unswitching orig: %d @ %d new: %d @ %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
210 head->_idx, unswitch_iff->_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
211 old_new[head->_idx]->_idx, unswitch_iff_clone->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
213 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 //-------------------------create_slow_version_of_loop------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // Create a slow version of the loop by cloning the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // and inserting an if to select fast-slow versions.
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Return control projection of the entry to the fast version.
a61af66fc99e Initial load
duke
parents:
diff changeset
222 ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
223 Node_List &old_new) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 LoopNode* head = loop->_head->as_Loop();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
225 bool counted_loop = head->is_CountedLoop();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
226 Node* entry = head->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
227 _igvn.hash_delete(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _igvn._worklist.push(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 IdealLoopTree* outer_loop = loop->_parent;
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 Node *cont = _igvn.intcon(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
232 set_ctrl(cont, C->root());
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 108
diff changeset
233 Node* opq = new (C, 2) Opaque1Node(C, cont);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
234 register_node(opq, outer_loop, entry, dom_depth(entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
235 Node *bol = new (C, 2) Conv2BNode(opq);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 register_node(bol, outer_loop, entry, dom_depth(entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
237 IfNode* iff = new (C, 2) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
238 register_node(iff, outer_loop, entry, dom_depth(entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
239 ProjNode* iffast = new (C, 1) IfTrueNode(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 register_node(iffast, outer_loop, iff, dom_depth(iff));
a61af66fc99e Initial load
duke
parents:
diff changeset
241 ProjNode* ifslow = new (C, 1) IfFalseNode(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
242 register_node(ifslow, outer_loop, iff, dom_depth(iff));
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // 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
245 // original pre-header will (illegally) have 3 control users
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
246 // (old & new loops & new if).
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 clone_loop(loop, old_new, dom_depth(head), iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 assert(old_new[head->_idx]->is_Loop(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Fast (true) control
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 2468
diff changeset
251 Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
252 _igvn.hash_delete(head);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
253 head->set_req(LoopNode::EntryControl, iffast_pred);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
254 set_idom(head, iffast_pred, dom_depth(head));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
255 _igvn._worklist.push(head);
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // Slow (false) control
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3345
diff changeset
258 Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
259 LoopNode* slow_head = old_new[head->_idx]->as_Loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
260 _igvn.hash_delete(slow_head);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
261 slow_head->set_req(LoopNode::EntryControl, ifslow_pred);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2383
diff changeset
262 set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
263 _igvn._worklist.push(slow_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 recompute_dom_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 return iffast;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }