Mercurial > hg > truffle
annotate src/share/vm/opto/split_if.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 6027dddc26c6 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1273
diff
changeset
|
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1273
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1273
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:
1273
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_split_if.cpp.incl" | |
27 | |
28 | |
29 //------------------------------split_thru_region------------------------------ | |
30 // Split Node 'n' through merge point. | |
31 Node *PhaseIdealLoop::split_thru_region( Node *n, Node *region ) { | |
32 uint wins = 0; | |
33 assert( n->is_CFG(), "" ); | |
34 assert( region->is_Region(), "" ); | |
35 Node *r = new (C, region->req()) RegionNode( region->req() ); | |
36 IdealLoopTree *loop = get_loop( n ); | |
37 for( uint i = 1; i < region->req(); i++ ) { | |
38 Node *x = n->clone(); | |
39 Node *in0 = n->in(0); | |
40 if( in0->in(0) == region ) x->set_req( 0, in0->in(i) ); | |
41 for( uint j = 1; j < n->req(); j++ ) { | |
42 Node *in = n->in(j); | |
43 if( get_ctrl(in) == region ) | |
44 x->set_req( j, in->in(i) ); | |
45 } | |
46 _igvn.register_new_node_with_optimizer(x); | |
47 set_loop(x, loop); | |
48 set_idom(x, x->in(0), dom_depth(x->in(0))+1); | |
49 r->init_req(i, x); | |
50 } | |
51 | |
52 // Record region | |
53 r->set_req(0,region); // Not a TRUE RegionNode | |
54 _igvn.register_new_node_with_optimizer(r); | |
55 set_loop(r, loop); | |
56 if( !loop->_child ) | |
57 loop->_body.push(r); | |
58 return r; | |
59 } | |
60 | |
61 //------------------------------split_up--------------------------------------- | |
62 // Split block-local op up through the phis to empty the current block | |
63 bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) { | |
64 if( n->is_CFG() ) { | |
65 assert( n->in(0) != blk1, "Lousy candidate for split-if" ); | |
66 return false; | |
67 } | |
68 if( get_ctrl(n) != blk1 && get_ctrl(n) != blk2 ) | |
69 return false; // Not block local | |
70 if( n->is_Phi() ) return false; // Local PHIs are expected | |
71 | |
72 // Recursively split-up inputs | |
73 for (uint i = 1; i < n->req(); i++) { | |
74 if( split_up( n->in(i), blk1, blk2 ) ) { | |
75 // Got split recursively and self went dead? | |
76 if (n->outcnt() == 0) | |
77 _igvn.remove_dead_node(n); | |
78 return true; | |
79 } | |
80 } | |
81 | |
82 // Check for needing to clone-up a compare. Can't do that, it forces | |
83 // another (nested) split-if transform. Instead, clone it "down". | |
84 if( n->is_Cmp() ) { | |
85 assert(get_ctrl(n) == blk2 || get_ctrl(n) == blk1, "must be in block with IF"); | |
86 // Check for simple Cmp/Bool/CMove which we can clone-up. Cmp/Bool/CMove | |
87 // sequence can have no other users and it must all reside in the split-if | |
88 // block. Non-simple Cmp/Bool/CMove sequences are 'cloned-down' below - | |
89 // private, per-use versions of the Cmp and Bool are made. These sink to | |
90 // the CMove block. If the CMove is in the split-if block, then in the | |
91 // next iteration this will become a simple Cmp/Bool/CMove set to clone-up. | |
92 Node *bol, *cmov; | |
93 if( !(n->outcnt() == 1 && n->unique_out()->is_Bool() && | |
94 (bol = n->unique_out()->as_Bool()) && | |
95 (get_ctrl(bol) == blk1 || | |
96 get_ctrl(bol) == blk2) && | |
97 bol->outcnt() == 1 && | |
98 bol->unique_out()->is_CMove() && | |
99 (cmov = bol->unique_out()->as_CMove()) && | |
100 (get_ctrl(cmov) == blk1 || | |
101 get_ctrl(cmov) == blk2) ) ) { | |
102 | |
103 // Must clone down | |
104 #ifndef PRODUCT | |
105 if( PrintOpto && VerifyLoopOptimizations ) { | |
106 tty->print("Cloning down: "); | |
107 n->dump(); | |
108 } | |
109 #endif | |
110 // Clone down any block-local BoolNode uses of this CmpNode | |
111 for (DUIterator i = n->outs(); n->has_out(i); i++) { | |
112 Node* bol = n->out(i); | |
113 assert( bol->is_Bool(), "" ); | |
114 if (bol->outcnt() == 1) { | |
115 Node* use = bol->unique_out(); | |
116 Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use); | |
117 if (use_c == blk1 || use_c == blk2) { | |
118 continue; | |
119 } | |
120 } | |
121 if (get_ctrl(bol) == blk1 || get_ctrl(bol) == blk2) { | |
122 // Recursively sink any BoolNode | |
123 #ifndef PRODUCT | |
124 if( PrintOpto && VerifyLoopOptimizations ) { | |
125 tty->print("Cloning down: "); | |
126 bol->dump(); | |
127 } | |
128 #endif | |
129 for (DUIterator_Last jmin, j = bol->last_outs(jmin); j >= jmin; --j) { | |
130 // Uses are either IfNodes or CMoves | |
131 Node* iff = bol->last_out(j); | |
132 assert( iff->in(1) == bol, "" ); | |
133 // Get control block of either the CMove or the If input | |
134 Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff); | |
135 Node *x = bol->clone(); | |
136 register_new_node(x, iff_ctrl); | |
137 _igvn.hash_delete(iff); | |
138 iff->set_req(1, x); | |
139 _igvn._worklist.push(iff); | |
140 } | |
141 _igvn.remove_dead_node( bol ); | |
142 --i; | |
143 } | |
144 } | |
145 // Clone down this CmpNode | |
146 for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; --j) { | |
147 Node* bol = n->last_out(j); | |
148 assert( bol->in(1) == n, "" ); | |
149 Node *x = n->clone(); | |
150 register_new_node(x, get_ctrl(bol)); | |
151 _igvn.hash_delete(bol); | |
152 bol->set_req(1, x); | |
153 _igvn._worklist.push(bol); | |
154 } | |
155 _igvn.remove_dead_node( n ); | |
156 | |
157 return true; | |
158 } | |
159 } | |
160 | |
161 // See if splitting-up a Store. Any anti-dep loads must go up as | |
162 // well. An anti-dep load might be in the wrong block, because in | |
163 // this particular layout/schedule we ignored anti-deps and allow | |
164 // memory to be alive twice. This only works if we do the same | |
165 // operations on anti-dep loads as we do their killing stores. | |
166 if( n->is_Store() && n->in(MemNode::Memory)->in(0) == n->in(0) ) { | |
167 // Get store's memory slice | |
168 int alias_idx = C->get_alias_index(_igvn.type(n->in(MemNode::Address))->is_ptr()); | |
169 | |
170 // Get memory-phi anti-dep loads will be using | |
171 Node *memphi = n->in(MemNode::Memory); | |
172 assert( memphi->is_Phi(), "" ); | |
173 // Hoist any anti-dep load to the splitting block; | |
174 // it will then "split-up". | |
175 for (DUIterator_Fast imax,i = memphi->fast_outs(imax); i < imax; i++) { | |
176 Node *load = memphi->fast_out(i); | |
177 if( load->is_Load() && alias_idx == C->get_alias_index(_igvn.type(load->in(MemNode::Address))->is_ptr()) ) | |
178 set_ctrl(load,blk1); | |
179 } | |
180 } | |
181 | |
182 // Found some other Node; must clone it up | |
183 #ifndef PRODUCT | |
184 if( PrintOpto && VerifyLoopOptimizations ) { | |
185 tty->print("Cloning up: "); | |
186 n->dump(); | |
187 } | |
188 #endif | |
189 | |
1273
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
190 // ConvI2L may have type information on it which becomes invalid if |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
191 // it moves up in the graph so change any clones so widen the type |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
192 // to TypeLong::INT when pushing it up. |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
193 const Type* rtype = NULL; |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
194 if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::INT) { |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
195 rtype = TypeLong::INT; |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
196 } |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
197 |
0 | 198 // Now actually split-up this guy. One copy per control path merging. |
199 Node *phi = PhiNode::make_blank(blk1, n); | |
200 for( uint j = 1; j < blk1->req(); j++ ) { | |
201 Node *x = n->clone(); | |
1273
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
202 // Widen the type of the ConvI2L when pushing up. |
877a14af58e1
6663854: assert(n != __null,"Bad immediate dominator info.") in C2 with -Xcomp
never
parents:
1172
diff
changeset
|
203 if (rtype != NULL) x->as_Type()->set_type(rtype); |
0 | 204 if( n->in(0) && n->in(0) == blk1 ) |
205 x->set_req( 0, blk1->in(j) ); | |
206 for( uint i = 1; i < n->req(); i++ ) { | |
207 Node *m = n->in(i); | |
208 if( get_ctrl(m) == blk1 ) { | |
209 assert( m->in(0) == blk1, "" ); | |
210 x->set_req( i, m->in(j) ); | |
211 } | |
212 } | |
213 register_new_node( x, blk1->in(j) ); | |
214 phi->init_req( j, x ); | |
215 } | |
216 // Announce phi to optimizer | |
217 register_new_node(phi, blk1); | |
218 | |
219 // Remove cloned-up value from optimizer; use phi instead | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
220 _igvn.replace_node( n, phi ); |
0 | 221 |
222 // (There used to be a self-recursive call to split_up() here, | |
223 // but it is not needed. All necessary forward walking is done | |
224 // by do_split_if() below.) | |
225 | |
226 return true; | |
227 } | |
228 | |
229 //------------------------------register_new_node------------------------------ | |
230 void PhaseIdealLoop::register_new_node( Node *n, Node *blk ) { | |
1172 | 231 assert(!n->is_CFG(), "must be data node"); |
0 | 232 _igvn.register_new_node_with_optimizer(n); |
233 set_ctrl(n, blk); | |
234 IdealLoopTree *loop = get_loop(blk); | |
235 if( !loop->_child ) | |
236 loop->_body.push(n); | |
237 } | |
238 | |
239 //------------------------------small_cache------------------------------------ | |
240 struct small_cache : public Dict { | |
241 | |
242 small_cache() : Dict( cmpkey, hashptr ) {} | |
243 Node *probe( Node *use_blk ) { return (Node*)((*this)[use_blk]); } | |
244 void lru_insert( Node *use_blk, Node *new_def ) { Insert(use_blk,new_def); } | |
245 }; | |
246 | |
247 //------------------------------spinup----------------------------------------- | |
248 // "Spin up" the dominator tree, starting at the use site and stopping when we | |
249 // find the post-dominating point. | |
250 | |
251 // We must be at the merge point which post-dominates 'new_false' and | |
252 // 'new_true'. Figure out which edges into the RegionNode eventually lead up | |
253 // to false and which to true. Put in a PhiNode to merge values; plug in | |
254 // the appropriate false-arm or true-arm values. If some path leads to the | |
255 // original IF, then insert a Phi recursively. | |
256 Node *PhaseIdealLoop::spinup( Node *iff_dom, Node *new_false, Node *new_true, Node *use_blk, Node *def, small_cache *cache ) { | |
257 if (use_blk->is_top()) // Handle dead uses | |
258 return use_blk; | |
259 Node *prior_n = (Node*)0xdeadbeef; | |
260 Node *n = use_blk; // Get path input | |
261 assert( use_blk != iff_dom, "" ); | |
262 // Here's the "spinup" the dominator tree loop. Do a cache-check | |
263 // along the way, in case we've come this way before. | |
264 while( n != iff_dom ) { // Found post-dominating point? | |
265 prior_n = n; | |
266 n = idom(n); // Search higher | |
267 Node *s = cache->probe( prior_n ); // Check cache | |
268 if( s ) return s; // Cache hit! | |
269 } | |
270 | |
271 Node *phi_post; | |
272 if( prior_n == new_false || prior_n == new_true ) { | |
273 phi_post = def->clone(); | |
274 phi_post->set_req(0, prior_n ); | |
275 register_new_node(phi_post, prior_n); | |
276 } else { | |
277 // This method handles both control uses (looking for Regions) or data | |
278 // uses (looking for Phis). If looking for a control use, then we need | |
279 // to insert a Region instead of a Phi; however Regions always exist | |
280 // previously (the hash_find_insert below would always hit) so we can | |
281 // return the existing Region. | |
282 if( def->is_CFG() ) { | |
283 phi_post = prior_n; // If looking for CFG, return prior | |
284 } else { | |
285 assert( def->is_Phi(), "" ); | |
286 assert( prior_n->is_Region(), "must be a post-dominating merge point" ); | |
287 | |
288 // Need a Phi here | |
289 phi_post = PhiNode::make_blank(prior_n, def); | |
290 // Search for both true and false on all paths till find one. | |
291 for( uint i = 1; i < phi_post->req(); i++ ) // For all paths | |
292 phi_post->init_req( i, spinup( iff_dom, new_false, new_true, prior_n->in(i), def, cache ) ); | |
293 Node *t = _igvn.hash_find_insert(phi_post); | |
294 if( t ) { // See if we already have this one | |
295 // phi_post will not be used, so kill it | |
296 _igvn.remove_dead_node(phi_post); | |
297 phi_post->destruct(); | |
298 phi_post = t; | |
299 } else { | |
300 register_new_node( phi_post, prior_n ); | |
301 } | |
302 } | |
303 } | |
304 | |
305 // Update cache everywhere | |
306 prior_n = (Node*)0xdeadbeef; // Reset IDOM walk | |
307 n = use_blk; // Get path input | |
308 // Spin-up the idom tree again, basically doing path-compression. | |
309 // Insert cache entries along the way, so that if we ever hit this | |
310 // point in the IDOM tree again we'll stop immediately on a cache hit. | |
311 while( n != iff_dom ) { // Found post-dominating point? | |
312 prior_n = n; | |
313 n = idom(n); // Search higher | |
314 cache->lru_insert( prior_n, phi_post ); // Fill cache | |
315 } // End of while not gone high enough | |
316 | |
317 return phi_post; | |
318 } | |
319 | |
320 //------------------------------find_use_block--------------------------------- | |
321 // Find the block a USE is in. Normally USE's are in the same block as the | |
322 // using instruction. For Phi-USE's, the USE is in the predecessor block | |
323 // along the corresponding path. | |
324 Node *PhaseIdealLoop::find_use_block( Node *use, Node *def, Node *old_false, Node *new_false, Node *old_true, Node *new_true ) { | |
325 // CFG uses are their own block | |
326 if( use->is_CFG() ) | |
327 return use; | |
328 | |
329 if( use->is_Phi() ) { // Phi uses in prior block | |
330 // Grab the first Phi use; there may be many. | |
605 | 331 // Each will be handled as a separate iteration of |
0 | 332 // the "while( phi->outcnt() )" loop. |
333 uint j; | |
334 for( j = 1; j < use->req(); j++ ) | |
335 if( use->in(j) == def ) | |
336 break; | |
337 assert( j < use->req(), "def should be among use's inputs" ); | |
338 return use->in(0)->in(j); | |
339 } | |
340 // Normal (non-phi) use | |
341 Node *use_blk = get_ctrl(use); | |
342 // Some uses are directly attached to the old (and going away) | |
343 // false and true branches. | |
344 if( use_blk == old_false ) { | |
345 use_blk = new_false; | |
346 set_ctrl(use, new_false); | |
347 } | |
348 if( use_blk == old_true ) { | |
349 use_blk = new_true; | |
350 set_ctrl(use, new_true); | |
351 } | |
352 | |
353 if (use_blk == NULL) { // He's dead, Jim | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
354 _igvn.replace_node(use, C->top()); |
0 | 355 } |
356 | |
357 return use_blk; | |
358 } | |
359 | |
360 //------------------------------handle_use------------------------------------- | |
361 // Handle uses of the merge point. Basically, split-if makes the merge point | |
362 // go away so all uses of the merge point must go away as well. Most block | |
363 // local uses have already been split-up, through the merge point. Uses from | |
364 // far below the merge point can't always be split up (e.g., phi-uses are | |
365 // pinned) and it makes too much stuff live. Instead we use a path-based | |
366 // solution to move uses down. | |
367 // | |
368 // If the use is along the pre-split-CFG true branch, then the new use will | |
369 // be from the post-split-CFG true merge point. Vice-versa for the false | |
370 // path. Some uses will be along both paths; then we sink the use to the | |
371 // post-dominating location; we may need to insert a Phi there. | |
372 void PhaseIdealLoop::handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true ) { | |
373 | |
374 Node *use_blk = find_use_block(use,def,old_false,new_false,old_true,new_true); | |
375 if( !use_blk ) return; // He's dead, Jim | |
376 | |
377 // Walk up the dominator tree until I hit either the old IfFalse, the old | |
378 // IfTrue or the old If. Insert Phis where needed. | |
379 Node *new_def = spinup( region_dom, new_false, new_true, use_blk, def, cache ); | |
380 | |
381 // Found where this USE goes. Re-point him. | |
382 uint i; | |
383 for( i = 0; i < use->req(); i++ ) | |
384 if( use->in(i) == def ) | |
385 break; | |
386 assert( i < use->req(), "def should be among use's inputs" ); | |
387 _igvn.hash_delete(use); | |
388 use->set_req(i, new_def); | |
389 _igvn._worklist.push(use); | |
390 } | |
391 | |
392 //------------------------------do_split_if------------------------------------ | |
393 // Found an If getting its condition-code input from a Phi in the same block. | |
394 // Split thru the Region. | |
395 void PhaseIdealLoop::do_split_if( Node *iff ) { | |
396 #ifndef PRODUCT | |
397 if( PrintOpto && VerifyLoopOptimizations ) | |
398 tty->print_cr("Split-if"); | |
399 #endif | |
400 C->set_major_progress(); | |
401 Node *region = iff->in(0); | |
402 Node *region_dom = idom(region); | |
403 | |
404 // We are going to clone this test (and the control flow with it) up through | |
405 // the incoming merge point. We need to empty the current basic block. | |
406 // Clone any instructions which must be in this block up through the merge | |
407 // point. | |
408 DUIterator i, j; | |
409 bool progress = true; | |
410 while (progress) { | |
411 progress = false; | |
412 for (i = region->outs(); region->has_out(i); i++) { | |
413 Node* n = region->out(i); | |
414 if( n == region ) continue; | |
415 // The IF to be split is OK. | |
416 if( n == iff ) continue; | |
417 if( !n->is_Phi() ) { // Found pinned memory op or such | |
418 if (split_up(n, region, iff)) { | |
419 i = region->refresh_out_pos(i); | |
420 progress = true; | |
421 } | |
422 continue; | |
423 } | |
424 assert( n->in(0) == region, "" ); | |
425 | |
426 // Recursively split up all users of a Phi | |
427 for (j = n->outs(); n->has_out(j); j++) { | |
428 Node* m = n->out(j); | |
429 // If m is dead, throw it away, and declare progress | |
430 if (_nodes[m->_idx] == NULL) { | |
431 _igvn.remove_dead_node(m); | |
432 // fall through | |
433 } | |
434 else if (m != iff && split_up(m, region, iff)) { | |
435 // fall through | |
436 } else { | |
437 continue; | |
438 } | |
439 // Something unpredictable changed. | |
440 // Tell the iterators to refresh themselves, and rerun the loop. | |
441 i = region->refresh_out_pos(i); | |
442 j = region->refresh_out_pos(j); | |
443 progress = true; | |
444 } | |
445 } | |
446 } | |
447 | |
448 // Now we have no instructions in the block containing the IF. | |
449 // Split the IF. | |
450 Node *new_iff = split_thru_region( iff, region ); | |
451 | |
452 // Replace both uses of 'new_iff' with Regions merging True/False | |
453 // paths. This makes 'new_iff' go dead. | |
454 Node *old_false, *old_true; | |
455 Node *new_false, *new_true; | |
456 for (DUIterator_Last j2min, j2 = iff->last_outs(j2min); j2 >= j2min; --j2) { | |
457 Node *ifp = iff->last_out(j2); | |
458 assert( ifp->Opcode() == Op_IfFalse || ifp->Opcode() == Op_IfTrue, "" ); | |
459 ifp->set_req(0, new_iff); | |
460 Node *ifpx = split_thru_region( ifp, region ); | |
461 | |
462 // Replace 'If' projection of a Region with a Region of | |
463 // 'If' projections. | |
464 ifpx->set_req(0, ifpx); // A TRUE RegionNode | |
465 | |
466 // Setup dominator info | |
467 set_idom(ifpx, region_dom, dom_depth(region_dom) + 1); | |
468 | |
469 // Check for splitting loop tails | |
470 if( get_loop(iff)->tail() == ifp ) | |
471 get_loop(iff)->_tail = ifpx; | |
472 | |
473 // Replace in the graph with lazy-update mechanism | |
474 new_iff->set_req(0, new_iff); // hook self so it does not go dead | |
475 lazy_replace_proj( ifp, ifpx ); | |
476 new_iff->set_req(0, region); | |
477 | |
478 // Record bits for later xforms | |
479 if( ifp->Opcode() == Op_IfFalse ) { | |
480 old_false = ifp; | |
481 new_false = ifpx; | |
482 } else { | |
483 old_true = ifp; | |
484 new_true = ifpx; | |
485 } | |
486 } | |
487 _igvn.remove_dead_node(new_iff); | |
488 // Lazy replace IDOM info with the region's dominator | |
489 lazy_replace( iff, region_dom ); | |
490 | |
491 // Now make the original merge point go dead, by handling all its uses. | |
492 small_cache region_cache; | |
493 // Preload some control flow in region-cache | |
494 region_cache.lru_insert( new_false, new_false ); | |
495 region_cache.lru_insert( new_true , new_true ); | |
496 // Now handle all uses of the splitting block | |
497 for (DUIterator_Last kmin, k = region->last_outs(kmin); k >= kmin; --k) { | |
498 Node* phi = region->last_out(k); | |
499 if( !phi->in(0) ) { // Dead phi? Remove it | |
500 _igvn.remove_dead_node(phi); | |
501 continue; | |
502 } | |
503 assert( phi->in(0) == region, "" ); | |
504 if( phi == region ) { // Found the self-reference | |
505 phi->set_req(0, NULL); | |
506 continue; // Break the self-cycle | |
507 } | |
508 // Expected common case: Phi hanging off of Region | |
509 if( phi->is_Phi() ) { | |
510 // Need a per-def cache. Phi represents a def, so make a cache | |
511 small_cache phi_cache; | |
512 | |
513 // Inspect all Phi uses to make the Phi go dead | |
514 for (DUIterator_Last lmin, l = phi->last_outs(lmin); l >= lmin; --l) { | |
515 Node* use = phi->last_out(l); | |
516 // Compute the new DEF for this USE. New DEF depends on the path | |
517 // taken from the original DEF to the USE. The new DEF may be some | |
518 // collection of PHI's merging values from different paths. The Phis | |
519 // inserted depend only on the location of the USE. We use a | |
520 // 2-element cache to handle multiple uses from the same block. | |
521 handle_use( use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true ); | |
522 } // End of while phi has uses | |
523 | |
524 // Because handle_use might relocate region->_out, | |
525 // we must refresh the iterator. | |
526 k = region->last_outs(kmin); | |
527 | |
528 // Remove the dead Phi | |
529 _igvn.remove_dead_node( phi ); | |
530 | |
531 } else { | |
532 // Random memory op guarded by Region. Compute new DEF for USE. | |
533 handle_use( phi, region, ®ion_cache, region_dom, new_false, new_true, old_false, old_true ); | |
534 } | |
535 | |
536 } // End of while merge point has phis | |
537 | |
538 // Any leftover bits in the splitting block must not have depended on local | |
539 // Phi inputs (these have already been split-up). Hence it's safe to hoist | |
540 // these guys to the dominating point. | |
541 lazy_replace( region, region_dom ); | |
542 #ifndef PRODUCT | |
543 if( VerifyLoopOptimizations ) verify(); | |
544 #endif | |
545 } |