Mercurial > hg > truffle
annotate src/share/vm/opto/phaseX.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | 30f42e691e70 |
children | 6f3fd5150b67 |
rev | line source |
---|---|
0 | 1 /* |
6842
b9a9ed0f8eeb
7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents:
6804
diff
changeset
|
2 * Copyright (c) 1997, 2012, 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:
1017
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1017
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:
1017
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "memory/allocation.inline.hpp" | |
27 #include "opto/block.hpp" | |
28 #include "opto/callnode.hpp" | |
29 #include "opto/cfgnode.hpp" | |
30 #include "opto/connode.hpp" | |
31 #include "opto/idealGraphPrinter.hpp" | |
32 #include "opto/loopnode.hpp" | |
33 #include "opto/machnode.hpp" | |
34 #include "opto/opcodes.hpp" | |
35 #include "opto/phaseX.hpp" | |
36 #include "opto/regalloc.hpp" | |
37 #include "opto/rootnode.hpp" | |
0 | 38 |
39 //============================================================================= | |
40 #define NODE_HASH_MINIMUM_SIZE 255 | |
41 //------------------------------NodeHash--------------------------------------- | |
42 NodeHash::NodeHash(uint est_max_size) : | |
43 _max( round_up(est_max_size < NODE_HASH_MINIMUM_SIZE ? NODE_HASH_MINIMUM_SIZE : est_max_size) ), | |
44 _a(Thread::current()->resource_area()), | |
45 _table( NEW_ARENA_ARRAY( _a , Node* , _max ) ), // (Node**)_a->Amalloc(_max * sizeof(Node*)) ), | |
46 _inserts(0), _insert_limit( insert_limit() ), | |
47 _look_probes(0), _lookup_hits(0), _lookup_misses(0), | |
48 _total_insert_probes(0), _total_inserts(0), | |
49 _insert_probes(0), _grows(0) { | |
50 // _sentinel must be in the current node space | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6244
diff
changeset
|
51 _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control); |
0 | 52 memset(_table,0,sizeof(Node*)*_max); |
53 } | |
54 | |
55 //------------------------------NodeHash--------------------------------------- | |
56 NodeHash::NodeHash(Arena *arena, uint est_max_size) : | |
57 _max( round_up(est_max_size < NODE_HASH_MINIMUM_SIZE ? NODE_HASH_MINIMUM_SIZE : est_max_size) ), | |
58 _a(arena), | |
59 _table( NEW_ARENA_ARRAY( _a , Node* , _max ) ), | |
60 _inserts(0), _insert_limit( insert_limit() ), | |
61 _look_probes(0), _lookup_hits(0), _lookup_misses(0), | |
62 _delete_probes(0), _delete_hits(0), _delete_misses(0), | |
63 _total_insert_probes(0), _total_inserts(0), | |
64 _insert_probes(0), _grows(0) { | |
65 // _sentinel must be in the current node space | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6244
diff
changeset
|
66 _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control); |
0 | 67 memset(_table,0,sizeof(Node*)*_max); |
68 } | |
69 | |
70 //------------------------------NodeHash--------------------------------------- | |
71 NodeHash::NodeHash(NodeHash *nh) { | |
72 debug_only(_table = (Node**)badAddress); // interact correctly w/ operator= | |
73 // just copy in all the fields | |
74 *this = *nh; | |
75 // nh->_sentinel must be in the current node space | |
76 } | |
77 | |
7473 | 78 void NodeHash::replace_with(NodeHash *nh) { |
79 debug_only(_table = (Node**)badAddress); // interact correctly w/ operator= | |
80 // just copy in all the fields | |
81 *this = *nh; | |
82 // nh->_sentinel must be in the current node space | |
83 } | |
84 | |
0 | 85 //------------------------------hash_find-------------------------------------- |
86 // Find in hash table | |
87 Node *NodeHash::hash_find( const Node *n ) { | |
88 // ((Node*)n)->set_hash( n->hash() ); | |
89 uint hash = n->hash(); | |
90 if (hash == Node::NO_HASH) { | |
91 debug_only( _lookup_misses++ ); | |
92 return NULL; | |
93 } | |
94 uint key = hash & (_max-1); | |
95 uint stride = key | 0x01; | |
96 debug_only( _look_probes++ ); | |
97 Node *k = _table[key]; // Get hashed value | |
98 if( !k ) { // ?Miss? | |
99 debug_only( _lookup_misses++ ); | |
100 return NULL; // Miss! | |
101 } | |
102 | |
103 int op = n->Opcode(); | |
104 uint req = n->req(); | |
105 while( 1 ) { // While probing hash table | |
106 if( k->req() == req && // Same count of inputs | |
107 k->Opcode() == op ) { // Same Opcode | |
108 for( uint i=0; i<req; i++ ) | |
109 if( n->in(i)!=k->in(i)) // Different inputs? | |
110 goto collision; // "goto" is a speed hack... | |
111 if( n->cmp(*k) ) { // Check for any special bits | |
112 debug_only( _lookup_hits++ ); | |
113 return k; // Hit! | |
114 } | |
115 } | |
116 collision: | |
117 debug_only( _look_probes++ ); | |
118 key = (key + stride/*7*/) & (_max-1); // Stride through table with relative prime | |
119 k = _table[key]; // Get hashed value | |
120 if( !k ) { // ?Miss? | |
121 debug_only( _lookup_misses++ ); | |
122 return NULL; // Miss! | |
123 } | |
124 } | |
125 ShouldNotReachHere(); | |
126 return NULL; | |
127 } | |
128 | |
129 //------------------------------hash_find_insert------------------------------- | |
130 // Find in hash table, insert if not already present | |
131 // Used to preserve unique entries in hash table | |
132 Node *NodeHash::hash_find_insert( Node *n ) { | |
133 // n->set_hash( ); | |
134 uint hash = n->hash(); | |
135 if (hash == Node::NO_HASH) { | |
136 debug_only( _lookup_misses++ ); | |
137 return NULL; | |
138 } | |
139 uint key = hash & (_max-1); | |
140 uint stride = key | 0x01; // stride must be relatively prime to table siz | |
141 uint first_sentinel = 0; // replace a sentinel if seen. | |
142 debug_only( _look_probes++ ); | |
143 Node *k = _table[key]; // Get hashed value | |
144 if( !k ) { // ?Miss? | |
145 debug_only( _lookup_misses++ ); | |
146 _table[key] = n; // Insert into table! | |
147 debug_only(n->enter_hash_lock()); // Lock down the node while in the table. | |
148 check_grow(); // Grow table if insert hit limit | |
149 return NULL; // Miss! | |
150 } | |
151 else if( k == _sentinel ) { | |
152 first_sentinel = key; // Can insert here | |
153 } | |
154 | |
155 int op = n->Opcode(); | |
156 uint req = n->req(); | |
157 while( 1 ) { // While probing hash table | |
158 if( k->req() == req && // Same count of inputs | |
159 k->Opcode() == op ) { // Same Opcode | |
160 for( uint i=0; i<req; i++ ) | |
161 if( n->in(i)!=k->in(i)) // Different inputs? | |
162 goto collision; // "goto" is a speed hack... | |
163 if( n->cmp(*k) ) { // Check for any special bits | |
164 debug_only( _lookup_hits++ ); | |
165 return k; // Hit! | |
166 } | |
167 } | |
168 collision: | |
169 debug_only( _look_probes++ ); | |
170 key = (key + stride) & (_max-1); // Stride through table w/ relative prime | |
171 k = _table[key]; // Get hashed value | |
172 if( !k ) { // ?Miss? | |
173 debug_only( _lookup_misses++ ); | |
174 key = (first_sentinel == 0) ? key : first_sentinel; // ?saw sentinel? | |
175 _table[key] = n; // Insert into table! | |
176 debug_only(n->enter_hash_lock()); // Lock down the node while in the table. | |
177 check_grow(); // Grow table if insert hit limit | |
178 return NULL; // Miss! | |
179 } | |
180 else if( first_sentinel == 0 && k == _sentinel ) { | |
181 first_sentinel = key; // Can insert here | |
182 } | |
183 | |
184 } | |
185 ShouldNotReachHere(); | |
186 return NULL; | |
187 } | |
188 | |
189 //------------------------------hash_insert------------------------------------ | |
190 // Insert into hash table | |
191 void NodeHash::hash_insert( Node *n ) { | |
192 // // "conflict" comments -- print nodes that conflict | |
193 // bool conflict = false; | |
194 // n->set_hash(); | |
195 uint hash = n->hash(); | |
196 if (hash == Node::NO_HASH) { | |
197 return; | |
198 } | |
199 check_grow(); | |
200 uint key = hash & (_max-1); | |
201 uint stride = key | 0x01; | |
202 | |
203 while( 1 ) { // While probing hash table | |
204 debug_only( _insert_probes++ ); | |
205 Node *k = _table[key]; // Get hashed value | |
206 if( !k || (k == _sentinel) ) break; // Found a slot | |
207 assert( k != n, "already inserted" ); | |
208 // if( PrintCompilation && PrintOptoStatistics && Verbose ) { tty->print(" conflict: "); k->dump(); conflict = true; } | |
209 key = (key + stride) & (_max-1); // Stride through table w/ relative prime | |
210 } | |
211 _table[key] = n; // Insert into table! | |
212 debug_only(n->enter_hash_lock()); // Lock down the node while in the table. | |
213 // if( conflict ) { n->dump(); } | |
214 } | |
215 | |
216 //------------------------------hash_delete------------------------------------ | |
605 | 217 // Replace in hash table with sentinel |
0 | 218 bool NodeHash::hash_delete( const Node *n ) { |
219 Node *k; | |
220 uint hash = n->hash(); | |
221 if (hash == Node::NO_HASH) { | |
222 debug_only( _delete_misses++ ); | |
223 return false; | |
224 } | |
225 uint key = hash & (_max-1); | |
226 uint stride = key | 0x01; | |
227 debug_only( uint counter = 0; ); | |
605 | 228 for( ; /* (k != NULL) && (k != _sentinel) */; ) { |
0 | 229 debug_only( counter++ ); |
230 debug_only( _delete_probes++ ); | |
231 k = _table[key]; // Get hashed value | |
232 if( !k ) { // Miss? | |
233 debug_only( _delete_misses++ ); | |
234 #ifdef ASSERT | |
235 if( VerifyOpto ) { | |
236 for( uint i=0; i < _max; i++ ) | |
237 assert( _table[i] != n, "changed edges with rehashing" ); | |
238 } | |
239 #endif | |
240 return false; // Miss! Not in chain | |
241 } | |
242 else if( n == k ) { | |
243 debug_only( _delete_hits++ ); | |
244 _table[key] = _sentinel; // Hit! Label as deleted entry | |
245 debug_only(((Node*)n)->exit_hash_lock()); // Unlock the node upon removal from table. | |
246 return true; | |
247 } | |
248 else { | |
249 // collision: move through table with prime offset | |
250 key = (key + stride/*7*/) & (_max-1); | |
251 assert( counter <= _insert_limit, "Cycle in hash-table"); | |
252 } | |
253 } | |
254 ShouldNotReachHere(); | |
255 return false; | |
256 } | |
257 | |
258 //------------------------------round_up--------------------------------------- | |
259 // Round up to nearest power of 2 | |
260 uint NodeHash::round_up( uint x ) { | |
261 x += (x>>2); // Add 25% slop | |
262 if( x <16 ) return 16; // Small stuff | |
263 uint i=16; | |
264 while( i < x ) i <<= 1; // Double to fit | |
265 return i; // Return hash table size | |
266 } | |
267 | |
268 //------------------------------grow------------------------------------------- | |
269 // Grow _table to next power of 2 and insert old entries | |
270 void NodeHash::grow() { | |
271 // Record old state | |
272 uint old_max = _max; | |
273 Node **old_table = _table; | |
274 // Construct new table with twice the space | |
275 _grows++; | |
276 _total_inserts += _inserts; | |
277 _total_insert_probes += _insert_probes; | |
278 _inserts = 0; | |
279 _insert_probes = 0; | |
280 _max = _max << 1; | |
281 _table = NEW_ARENA_ARRAY( _a , Node* , _max ); // (Node**)_a->Amalloc( _max * sizeof(Node*) ); | |
282 memset(_table,0,sizeof(Node*)*_max); | |
283 _insert_limit = insert_limit(); | |
284 // Insert old entries into the new table | |
285 for( uint i = 0; i < old_max; i++ ) { | |
286 Node *m = *old_table++; | |
287 if( !m || m == _sentinel ) continue; | |
288 debug_only(m->exit_hash_lock()); // Unlock the node upon removal from old table. | |
289 hash_insert(m); | |
290 } | |
291 } | |
292 | |
293 //------------------------------clear------------------------------------------ | |
294 // Clear all entries in _table to NULL but keep storage | |
295 void NodeHash::clear() { | |
296 #ifdef ASSERT | |
297 // Unlock all nodes upon removal from table. | |
298 for (uint i = 0; i < _max; i++) { | |
299 Node* n = _table[i]; | |
300 if (!n || n == _sentinel) continue; | |
301 n->exit_hash_lock(); | |
302 } | |
303 #endif | |
304 | |
305 memset( _table, 0, _max * sizeof(Node*) ); | |
306 } | |
307 | |
308 //-----------------------remove_useless_nodes---------------------------------- | |
309 // Remove useless nodes from value table, | |
310 // implementation does not depend on hash function | |
311 void NodeHash::remove_useless_nodes(VectorSet &useful) { | |
312 | |
313 // Dead nodes in the hash table inherited from GVN should not replace | |
314 // existing nodes, remove dead nodes. | |
315 uint max = size(); | |
316 Node *sentinel_node = sentinel(); | |
317 for( uint i = 0; i < max; ++i ) { | |
318 Node *n = at(i); | |
319 if(n != NULL && n != sentinel_node && !useful.test(n->_idx)) { | |
320 debug_only(n->exit_hash_lock()); // Unlock the node when removed | |
321 _table[i] = sentinel_node; // Replace with placeholder | |
322 } | |
323 } | |
324 } | |
325 | |
326 #ifndef PRODUCT | |
327 //------------------------------dump------------------------------------------- | |
328 // Dump statistics for the hash table | |
329 void NodeHash::dump() { | |
330 _total_inserts += _inserts; | |
331 _total_insert_probes += _insert_probes; | |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3958
diff
changeset
|
332 if (PrintCompilation && PrintOptoStatistics && Verbose && (_inserts > 0)) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3958
diff
changeset
|
333 if (WizardMode) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3958
diff
changeset
|
334 for (uint i=0; i<_max; i++) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3958
diff
changeset
|
335 if (_table[i]) |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3958
diff
changeset
|
336 tty->print("%d/%d/%d ",i,_table[i]->hash()&(_max-1),_table[i]->_idx); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3958
diff
changeset
|
337 } |
0 | 338 } |
339 tty->print("\nGVN Hash stats: %d grows to %d max_size\n", _grows, _max); | |
340 tty->print(" %d/%d (%8.1f%% full)\n", _inserts, _max, (double)_inserts/_max*100.0); | |
341 tty->print(" %dp/(%dh+%dm) (%8.2f probes/lookup)\n", _look_probes, _lookup_hits, _lookup_misses, (double)_look_probes/(_lookup_hits+_lookup_misses)); | |
342 tty->print(" %dp/%di (%8.2f probes/insert)\n", _total_insert_probes, _total_inserts, (double)_total_insert_probes/_total_inserts); | |
343 // sentinels increase lookup cost, but not insert cost | |
344 assert((_lookup_misses+_lookup_hits)*4+100 >= _look_probes, "bad hash function"); | |
345 assert( _inserts+(_inserts>>3) < _max, "table too full" ); | |
346 assert( _inserts*3+100 >= _insert_probes, "bad hash function" ); | |
347 } | |
348 } | |
349 | |
350 Node *NodeHash::find_index(uint idx) { // For debugging | |
351 // Find an entry by its index value | |
352 for( uint i = 0; i < _max; i++ ) { | |
353 Node *m = _table[i]; | |
354 if( !m || m == _sentinel ) continue; | |
355 if( m->_idx == (uint)idx ) return m; | |
356 } | |
357 return NULL; | |
358 } | |
359 #endif | |
360 | |
361 #ifdef ASSERT | |
362 NodeHash::~NodeHash() { | |
363 // Unlock all nodes upon destruction of table. | |
364 if (_table != (Node**)badAddress) clear(); | |
365 } | |
366 | |
367 void NodeHash::operator=(const NodeHash& nh) { | |
368 // Unlock all nodes upon replacement of table. | |
369 if (&nh == this) return; | |
370 if (_table != (Node**)badAddress) clear(); | |
371 memcpy(this, &nh, sizeof(*this)); | |
372 // Do not increment hash_lock counts again. | |
373 // Instead, be sure we never again use the source table. | |
374 ((NodeHash*)&nh)->_table = (Node**)badAddress; | |
375 } | |
376 | |
377 | |
378 #endif | |
379 | |
380 | |
381 //============================================================================= | |
382 //------------------------------PhaseRemoveUseless----------------------------- | |
383 // 1) Use a breadthfirst walk to collect useful nodes reachable from root. | |
384 PhaseRemoveUseless::PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist ) : Phase(Remove_Useless), | |
385 _useful(Thread::current()->resource_area()) { | |
386 | |
387 // Implementation requires 'UseLoopSafepoints == true' and an edge from root | |
388 // to each SafePointNode at a backward branch. Inserted in add_safepoint(). | |
389 if( !UseLoopSafepoints || !OptoRemoveUseless ) return; | |
390 | |
391 // Identify nodes that are reachable from below, useful. | |
392 C->identify_useful_nodes(_useful); | |
7196
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6842
diff
changeset
|
393 // Update dead node list |
2aff40cb4703
7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents:
6842
diff
changeset
|
394 C->update_dead_node_list(_useful); |
0 | 395 |
396 // Remove all useless nodes from PhaseValues' recorded types | |
397 // Must be done before disconnecting nodes to preserve hash-table-invariant | |
398 gvn->remove_useless_nodes(_useful.member_set()); | |
399 | |
400 // Remove all useless nodes from future worklist | |
401 worklist->remove_useless_nodes(_useful.member_set()); | |
402 | |
403 // Disconnect 'useless' nodes that are adjacent to useful nodes | |
404 C->remove_useless_nodes(_useful); | |
405 | |
406 // Remove edges from "root" to each SafePoint at a backward branch. | |
407 // They were inserted during parsing (see add_safepoint()) to make infinite | |
408 // loops without calls or exceptions visible to root, i.e., useful. | |
409 Node *root = C->root(); | |
410 if( root != NULL ) { | |
411 for( uint i = root->req(); i < root->len(); ++i ) { | |
412 Node *n = root->in(i); | |
413 if( n != NULL && n->is_SafePoint() ) { | |
414 root->rm_prec(i); | |
415 --i; | |
416 } | |
417 } | |
418 } | |
419 } | |
420 | |
421 | |
422 //============================================================================= | |
423 //------------------------------PhaseTransform--------------------------------- | |
424 PhaseTransform::PhaseTransform( PhaseNumber pnum ) : Phase(pnum), | |
425 _arena(Thread::current()->resource_area()), | |
426 _nodes(_arena), | |
427 _types(_arena) | |
428 { | |
429 init_con_caches(); | |
430 #ifndef PRODUCT | |
431 clear_progress(); | |
432 clear_transforms(); | |
433 set_allow_progress(true); | |
434 #endif | |
435 // Force allocation for currently existing nodes | |
436 _types.map(C->unique(), NULL); | |
437 } | |
438 | |
439 //------------------------------PhaseTransform--------------------------------- | |
440 PhaseTransform::PhaseTransform( Arena *arena, PhaseNumber pnum ) : Phase(pnum), | |
441 _arena(arena), | |
442 _nodes(arena), | |
443 _types(arena) | |
444 { | |
445 init_con_caches(); | |
446 #ifndef PRODUCT | |
447 clear_progress(); | |
448 clear_transforms(); | |
449 set_allow_progress(true); | |
450 #endif | |
451 // Force allocation for currently existing nodes | |
452 _types.map(C->unique(), NULL); | |
453 } | |
454 | |
455 //------------------------------PhaseTransform--------------------------------- | |
456 // Initialize with previously generated type information | |
457 PhaseTransform::PhaseTransform( PhaseTransform *pt, PhaseNumber pnum ) : Phase(pnum), | |
458 _arena(pt->_arena), | |
459 _nodes(pt->_nodes), | |
460 _types(pt->_types) | |
461 { | |
462 init_con_caches(); | |
463 #ifndef PRODUCT | |
464 clear_progress(); | |
465 clear_transforms(); | |
466 set_allow_progress(true); | |
467 #endif | |
468 } | |
469 | |
470 void PhaseTransform::init_con_caches() { | |
471 memset(_icons,0,sizeof(_icons)); | |
472 memset(_lcons,0,sizeof(_lcons)); | |
473 memset(_zcons,0,sizeof(_zcons)); | |
474 } | |
475 | |
476 | |
477 //--------------------------------find_int_type-------------------------------- | |
478 const TypeInt* PhaseTransform::find_int_type(Node* n) { | |
479 if (n == NULL) return NULL; | |
480 // Call type_or_null(n) to determine node's type since we might be in | |
481 // parse phase and call n->Value() may return wrong type. | |
482 // (For example, a phi node at the beginning of loop parsing is not ready.) | |
483 const Type* t = type_or_null(n); | |
484 if (t == NULL) return NULL; | |
485 return t->isa_int(); | |
486 } | |
487 | |
488 | |
489 //-------------------------------find_long_type-------------------------------- | |
490 const TypeLong* PhaseTransform::find_long_type(Node* n) { | |
491 if (n == NULL) return NULL; | |
492 // (See comment above on type_or_null.) | |
493 const Type* t = type_or_null(n); | |
494 if (t == NULL) return NULL; | |
495 return t->isa_long(); | |
496 } | |
497 | |
498 | |
499 #ifndef PRODUCT | |
500 void PhaseTransform::dump_old2new_map() const { | |
501 _nodes.dump(); | |
502 } | |
503 | |
504 void PhaseTransform::dump_new( uint nidx ) const { | |
505 for( uint i=0; i<_nodes.Size(); i++ ) | |
506 if( _nodes[i] && _nodes[i]->_idx == nidx ) { | |
507 _nodes[i]->dump(); | |
508 tty->cr(); | |
509 tty->print_cr("Old index= %d",i); | |
510 return; | |
511 } | |
512 tty->print_cr("Node %d not found in the new indices", nidx); | |
513 } | |
514 | |
515 //------------------------------dump_types------------------------------------- | |
516 void PhaseTransform::dump_types( ) const { | |
517 _types.dump(); | |
518 } | |
519 | |
520 //------------------------------dump_nodes_and_types--------------------------- | |
521 void PhaseTransform::dump_nodes_and_types(const Node *root, uint depth, bool only_ctrl) { | |
522 VectorSet visited(Thread::current()->resource_area()); | |
523 dump_nodes_and_types_recur( root, depth, only_ctrl, visited ); | |
524 } | |
525 | |
526 //------------------------------dump_nodes_and_types_recur--------------------- | |
527 void PhaseTransform::dump_nodes_and_types_recur( const Node *n, uint depth, bool only_ctrl, VectorSet &visited) { | |
528 if( !n ) return; | |
529 if( depth == 0 ) return; | |
530 if( visited.test_set(n->_idx) ) return; | |
531 for( uint i=0; i<n->len(); i++ ) { | |
532 if( only_ctrl && !(n->is_Region()) && i != TypeFunc::Control ) continue; | |
533 dump_nodes_and_types_recur( n->in(i), depth-1, only_ctrl, visited ); | |
534 } | |
535 n->dump(); | |
536 if (type_or_null(n) != NULL) { | |
537 tty->print(" "); type(n)->dump(); tty->cr(); | |
538 } | |
539 } | |
540 | |
541 #endif | |
542 | |
543 | |
544 //============================================================================= | |
545 //------------------------------PhaseValues------------------------------------ | |
546 // Set minimum table size to "255" | |
547 PhaseValues::PhaseValues( Arena *arena, uint est_max_size ) : PhaseTransform(arena, GVN), _table(arena, est_max_size) { | |
548 NOT_PRODUCT( clear_new_values(); ) | |
549 } | |
550 | |
551 //------------------------------PhaseValues------------------------------------ | |
552 // Set minimum table size to "255" | |
553 PhaseValues::PhaseValues( PhaseValues *ptv ) : PhaseTransform( ptv, GVN ), | |
554 _table(&ptv->_table) { | |
555 NOT_PRODUCT( clear_new_values(); ) | |
556 } | |
557 | |
558 //------------------------------PhaseValues------------------------------------ | |
559 // Used by +VerifyOpto. Clear out hash table but copy _types array. | |
560 PhaseValues::PhaseValues( PhaseValues *ptv, const char *dummy ) : PhaseTransform( ptv, GVN ), | |
561 _table(ptv->arena(),ptv->_table.size()) { | |
562 NOT_PRODUCT( clear_new_values(); ) | |
563 } | |
564 | |
565 //------------------------------~PhaseValues----------------------------------- | |
566 #ifndef PRODUCT | |
567 PhaseValues::~PhaseValues() { | |
568 _table.dump(); | |
569 | |
570 // Statistics for value progress and efficiency | |
571 if( PrintCompilation && Verbose && WizardMode ) { | |
572 tty->print("\n%sValues: %d nodes ---> %d/%d (%d)", | |
573 is_IterGVN() ? "Iter" : " ", C->unique(), made_progress(), made_transforms(), made_new_values()); | |
574 if( made_transforms() != 0 ) { | |
575 tty->print_cr(" ratio %f", made_progress()/(float)made_transforms() ); | |
576 } else { | |
577 tty->cr(); | |
578 } | |
579 } | |
580 } | |
581 #endif | |
582 | |
583 //------------------------------makecon---------------------------------------- | |
584 ConNode* PhaseTransform::makecon(const Type *t) { | |
585 assert(t->singleton(), "must be a constant"); | |
586 assert(!t->empty() || t == Type::TOP, "must not be vacuous range"); | |
587 switch (t->base()) { // fast paths | |
588 case Type::Half: | |
589 case Type::Top: return (ConNode*) C->top(); | |
590 case Type::Int: return intcon( t->is_int()->get_con() ); | |
591 case Type::Long: return longcon( t->is_long()->get_con() ); | |
592 } | |
593 if (t->is_zero_type()) | |
594 return zerocon(t->basic_type()); | |
595 return uncached_makecon(t); | |
596 } | |
597 | |
598 //--------------------------uncached_makecon----------------------------------- | |
599 // Make an idealized constant - one of ConINode, ConPNode, etc. | |
600 ConNode* PhaseValues::uncached_makecon(const Type *t) { | |
601 assert(t->singleton(), "must be a constant"); | |
602 ConNode* x = ConNode::make(C, t); | |
603 ConNode* k = (ConNode*)hash_find_insert(x); // Value numbering | |
604 if (k == NULL) { | |
605 set_type(x, t); // Missed, provide type mapping | |
606 GrowableArray<Node_Notes*>* nna = C->node_note_array(); | |
607 if (nna != NULL) { | |
608 Node_Notes* loc = C->locate_node_notes(nna, x->_idx, true); | |
609 loc->clear(); // do not put debug info on constants | |
610 } | |
611 } else { | |
612 x->destruct(); // Hit, destroy duplicate constant | |
613 x = k; // use existing constant | |
614 } | |
615 return x; | |
616 } | |
617 | |
618 //------------------------------intcon----------------------------------------- | |
619 // Fast integer constant. Same as "transform(new ConINode(TypeInt::make(i)))" | |
620 ConINode* PhaseTransform::intcon(int i) { | |
621 // Small integer? Check cache! Check that cached node is not dead | |
622 if (i >= _icon_min && i <= _icon_max) { | |
623 ConINode* icon = _icons[i-_icon_min]; | |
624 if (icon != NULL && icon->in(TypeFunc::Control) != NULL) | |
625 return icon; | |
626 } | |
627 ConINode* icon = (ConINode*) uncached_makecon(TypeInt::make(i)); | |
628 assert(icon->is_Con(), ""); | |
629 if (i >= _icon_min && i <= _icon_max) | |
630 _icons[i-_icon_min] = icon; // Cache small integers | |
631 return icon; | |
632 } | |
633 | |
634 //------------------------------longcon---------------------------------------- | |
635 // Fast long constant. | |
636 ConLNode* PhaseTransform::longcon(jlong l) { | |
637 // Small integer? Check cache! Check that cached node is not dead | |
638 if (l >= _lcon_min && l <= _lcon_max) { | |
639 ConLNode* lcon = _lcons[l-_lcon_min]; | |
640 if (lcon != NULL && lcon->in(TypeFunc::Control) != NULL) | |
641 return lcon; | |
642 } | |
643 ConLNode* lcon = (ConLNode*) uncached_makecon(TypeLong::make(l)); | |
644 assert(lcon->is_Con(), ""); | |
645 if (l >= _lcon_min && l <= _lcon_max) | |
646 _lcons[l-_lcon_min] = lcon; // Cache small integers | |
647 return lcon; | |
648 } | |
649 | |
650 //------------------------------zerocon----------------------------------------- | |
651 // Fast zero or null constant. Same as "transform(ConNode::make(Type::get_zero_type(bt)))" | |
652 ConNode* PhaseTransform::zerocon(BasicType bt) { | |
653 assert((uint)bt <= _zcon_max, "domain check"); | |
654 ConNode* zcon = _zcons[bt]; | |
655 if (zcon != NULL && zcon->in(TypeFunc::Control) != NULL) | |
656 return zcon; | |
657 zcon = (ConNode*) uncached_makecon(Type::get_zero_type(bt)); | |
658 _zcons[bt] = zcon; | |
659 return zcon; | |
660 } | |
661 | |
662 | |
663 | |
664 //============================================================================= | |
665 //------------------------------transform-------------------------------------- | |
666 // Return a node which computes the same function as this node, but in a | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
667 // faster or cheaper fashion. |
0 | 668 Node *PhaseGVN::transform( Node *n ) { |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
669 return transform_no_reclaim(n); |
0 | 670 } |
671 | |
672 //------------------------------transform-------------------------------------- | |
673 // Return a node which computes the same function as this node, but | |
674 // in a faster or cheaper fashion. | |
675 Node *PhaseGVN::transform_no_reclaim( Node *n ) { | |
676 NOT_PRODUCT( set_transforms(); ) | |
677 | |
678 // Apply the Ideal call in a loop until it no longer applies | |
679 Node *k = n; | |
680 NOT_PRODUCT( uint loop_count = 0; ) | |
681 while( 1 ) { | |
682 Node *i = k->Ideal(this, /*can_reshape=*/false); | |
683 if( !i ) break; | |
684 assert( i->_idx >= k->_idx, "Idealize should return new nodes, use Identity to return old nodes" ); | |
685 k = i; | |
686 assert(loop_count++ < K, "infinite loop in PhaseGVN::transform"); | |
687 } | |
688 NOT_PRODUCT( if( loop_count != 0 ) { set_progress(); } ) | |
689 | |
690 | |
691 // If brand new node, make space in type array. | |
692 ensure_type_or_null(k); | |
693 | |
694 // Since I just called 'Value' to compute the set of run-time values | |
695 // for this Node, and 'Value' is non-local (and therefore expensive) I'll | |
696 // cache Value. Later requests for the local phase->type of this Node can | |
697 // use the cached Value instead of suffering with 'bottom_type'. | |
698 const Type *t = k->Value(this); // Get runtime Value set | |
699 assert(t != NULL, "value sanity"); | |
700 if (type_or_null(k) != t) { | |
701 #ifndef PRODUCT | |
702 // Do not count initial visit to node as a transformation | |
703 if (type_or_null(k) == NULL) { | |
704 inc_new_values(); | |
705 set_progress(); | |
706 } | |
707 #endif | |
708 set_type(k, t); | |
709 // If k is a TypeNode, capture any more-precise type permanently into Node | |
710 k->raise_bottom_type(t); | |
711 } | |
712 | |
713 if( t->singleton() && !k->is_Con() ) { | |
714 NOT_PRODUCT( set_progress(); ) | |
715 return makecon(t); // Turn into a constant | |
716 } | |
717 | |
718 // Now check for Identities | |
719 Node *i = k->Identity(this); // Look for a nearby replacement | |
720 if( i != k ) { // Found? Return replacement! | |
721 NOT_PRODUCT( set_progress(); ) | |
722 return i; | |
723 } | |
724 | |
725 // Global Value Numbering | |
726 i = hash_find_insert(k); // Insert if new | |
727 if( i && (i != k) ) { | |
728 // Return the pre-existing node | |
729 NOT_PRODUCT( set_progress(); ) | |
730 return i; | |
731 } | |
732 | |
733 // Return Idealized original | |
734 return k; | |
735 } | |
736 | |
737 #ifdef ASSERT | |
738 //------------------------------dead_loop_check-------------------------------- | |
605 | 739 // Check for a simple dead loop when a data node references itself directly |
0 | 740 // or through an other data node excluding cons and phis. |
741 void PhaseGVN::dead_loop_check( Node *n ) { | |
742 // Phi may reference itself in a loop | |
743 if (n != NULL && !n->is_dead_loop_safe() && !n->is_CFG()) { | |
744 // Do 2 levels check and only data inputs. | |
745 bool no_dead_loop = true; | |
746 uint cnt = n->req(); | |
747 for (uint i = 1; i < cnt && no_dead_loop; i++) { | |
748 Node *in = n->in(i); | |
749 if (in == n) { | |
750 no_dead_loop = false; | |
751 } else if (in != NULL && !in->is_dead_loop_safe()) { | |
752 uint icnt = in->req(); | |
753 for (uint j = 1; j < icnt && no_dead_loop; j++) { | |
754 if (in->in(j) == n || in->in(j) == in) | |
755 no_dead_loop = false; | |
756 } | |
757 } | |
758 } | |
759 if (!no_dead_loop) n->dump(3); | |
760 assert(no_dead_loop, "dead loop detected"); | |
761 } | |
762 } | |
763 #endif | |
764 | |
765 //============================================================================= | |
766 //------------------------------PhaseIterGVN----------------------------------- | |
767 // Initialize hash table to fresh and clean for +VerifyOpto | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
768 PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ) : PhaseGVN(igvn,dummy), _worklist( ), |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
769 _stack(C->unique() >> 1), |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
770 _delay_transform(false) { |
0 | 771 } |
772 | |
773 //------------------------------PhaseIterGVN----------------------------------- | |
774 // Initialize with previous PhaseIterGVN info; used by PhaseCCP | |
775 PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn ) : PhaseGVN(igvn), | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
776 _worklist( igvn->_worklist ), |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
777 _stack( igvn->_stack ), |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
778 _delay_transform(igvn->_delay_transform) |
0 | 779 { |
780 } | |
781 | |
782 //------------------------------PhaseIterGVN----------------------------------- | |
783 // Initialize with previous PhaseGVN info from Parser | |
784 PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn), | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
785 _worklist(*C->for_igvn()), |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
786 _stack(C->unique() >> 1), |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
787 _delay_transform(false) |
0 | 788 { |
789 uint max; | |
790 | |
791 // Dead nodes in the hash table inherited from GVN were not treated as | |
792 // roots during def-use info creation; hence they represent an invisible | |
793 // use. Clear them out. | |
794 max = _table.size(); | |
795 for( uint i = 0; i < max; ++i ) { | |
796 Node *n = _table.at(i); | |
797 if(n != NULL && n != _table.sentinel() && n->outcnt() == 0) { | |
798 if( n->is_top() ) continue; | |
799 assert( false, "Parse::remove_useless_nodes missed this node"); | |
800 hash_delete(n); | |
801 } | |
802 } | |
803 | |
804 // Any Phis or Regions on the worklist probably had uses that could not | |
805 // make more progress because the uses were made while the Phis and Regions | |
806 // were in half-built states. Put all uses of Phis and Regions on worklist. | |
807 max = _worklist.size(); | |
808 for( uint j = 0; j < max; j++ ) { | |
809 Node *n = _worklist.at(j); | |
810 uint uop = n->Opcode(); | |
811 if( uop == Op_Phi || uop == Op_Region || | |
812 n->is_Type() || | |
813 n->is_Mem() ) | |
814 add_users_to_worklist(n); | |
815 } | |
816 } | |
817 | |
818 | |
819 #ifndef PRODUCT | |
820 void PhaseIterGVN::verify_step(Node* n) { | |
821 _verify_window[_verify_counter % _verify_window_size] = n; | |
822 ++_verify_counter; | |
823 ResourceMark rm; | |
824 ResourceArea *area = Thread::current()->resource_area(); | |
825 VectorSet old_space(area), new_space(area); | |
826 if (C->unique() < 1000 || | |
827 0 == _verify_counter % (C->unique() < 10000 ? 10 : 100)) { | |
828 ++_verify_full_passes; | |
829 Node::verify_recur(C->root(), -1, old_space, new_space); | |
830 } | |
831 const int verify_depth = 4; | |
832 for ( int i = 0; i < _verify_window_size; i++ ) { | |
833 Node* n = _verify_window[i]; | |
834 if ( n == NULL ) continue; | |
835 if( n->in(0) == NodeSentinel ) { // xform_idom | |
836 _verify_window[i] = n->in(1); | |
837 --i; continue; | |
838 } | |
839 // Typical fanout is 1-2, so this call visits about 6 nodes. | |
840 Node::verify_recur(n, verify_depth, old_space, new_space); | |
841 } | |
842 } | |
843 #endif | |
844 | |
845 | |
846 //------------------------------init_worklist---------------------------------- | |
847 // Initialize worklist for each node. | |
848 void PhaseIterGVN::init_worklist( Node *n ) { | |
849 if( _worklist.member(n) ) return; | |
850 _worklist.push(n); | |
851 uint cnt = n->req(); | |
852 for( uint i =0 ; i < cnt; i++ ) { | |
853 Node *m = n->in(i); | |
854 if( m ) init_worklist(m); | |
855 } | |
856 } | |
857 | |
858 //------------------------------optimize--------------------------------------- | |
859 void PhaseIterGVN::optimize() { | |
860 debug_only(uint num_processed = 0;); | |
861 #ifndef PRODUCT | |
862 { | |
863 _verify_counter = 0; | |
864 _verify_full_passes = 0; | |
865 for ( int i = 0; i < _verify_window_size; i++ ) { | |
866 _verify_window[i] = NULL; | |
867 } | |
868 } | |
869 #endif | |
870 | |
1826
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
871 #ifdef ASSERT |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
872 Node* prev = NULL; |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
873 uint rep_cnt = 0; |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
874 #endif |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
875 uint loop_count = 0; |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
876 |
0 | 877 // Pull from worklist; transform node; |
878 // If node has changed: update edge info and put uses on worklist. | |
879 while( _worklist.size() ) { | |
3958
075ea0ed9e7c
7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents:
1972
diff
changeset
|
880 if (C->check_node_count(NodeLimitFudgeFactor * 2, |
075ea0ed9e7c
7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents:
1972
diff
changeset
|
881 "out of nodes optimizing method")) { |
075ea0ed9e7c
7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents:
1972
diff
changeset
|
882 return; |
075ea0ed9e7c
7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents:
1972
diff
changeset
|
883 } |
0 | 884 Node *n = _worklist.pop(); |
1826
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
885 if (++loop_count >= K * C->unique()) { |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
886 debug_only(n->dump(4);) |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
887 assert(false, "infinite loop in PhaseIterGVN::optimize"); |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
888 C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize"); |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
889 return; |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
890 } |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
891 #ifdef ASSERT |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
892 if (n == prev) { |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
893 if (++rep_cnt > 3) { |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
894 n->dump(4); |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
895 assert(false, "loop in Ideal transformation"); |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
896 } |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
897 } else { |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
898 rep_cnt = 0; |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
899 } |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
900 prev = n; |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1621
diff
changeset
|
901 #endif |
0 | 902 if (TraceIterativeGVN && Verbose) { |
903 tty->print(" Pop "); | |
904 NOT_PRODUCT( n->dump(); ) | |
905 debug_only(if( (num_processed++ % 100) == 0 ) _worklist.print_set();) | |
906 } | |
907 | |
908 if (n->outcnt() != 0) { | |
909 | |
910 #ifndef PRODUCT | |
911 uint wlsize = _worklist.size(); | |
912 const Type* oldtype = type_or_null(n); | |
913 #endif //PRODUCT | |
914 | |
915 Node *nn = transform_old(n); | |
916 | |
917 #ifndef PRODUCT | |
918 if (TraceIterativeGVN) { | |
919 const Type* newtype = type_or_null(n); | |
920 if (nn != n) { | |
921 // print old node | |
922 tty->print("< "); | |
923 if (oldtype != newtype && oldtype != NULL) { | |
924 oldtype->dump(); | |
925 } | |
926 do { tty->print("\t"); } while (tty->position() < 16); | |
927 tty->print("<"); | |
928 n->dump(); | |
929 } | |
930 if (oldtype != newtype || nn != n) { | |
931 // print new node and/or new type | |
932 if (oldtype == NULL) { | |
933 tty->print("* "); | |
934 } else if (nn != n) { | |
935 tty->print("> "); | |
936 } else { | |
937 tty->print("= "); | |
938 } | |
939 if (newtype == NULL) { | |
940 tty->print("null"); | |
941 } else { | |
942 newtype->dump(); | |
943 } | |
944 do { tty->print("\t"); } while (tty->position() < 16); | |
945 nn->dump(); | |
946 } | |
947 if (Verbose && wlsize < _worklist.size()) { | |
948 tty->print(" Push {"); | |
949 while (wlsize != _worklist.size()) { | |
950 Node* pushed = _worklist.at(wlsize++); | |
951 tty->print(" %d", pushed->_idx); | |
952 } | |
953 tty->print_cr(" }"); | |
954 } | |
955 } | |
956 if( VerifyIterativeGVN && nn != n ) { | |
957 verify_step((Node*) NULL); // ignore n, it might be subsumed | |
958 } | |
959 #endif | |
960 } else if (!n->is_top()) { | |
961 remove_dead_node(n); | |
962 } | |
963 } | |
964 | |
965 #ifndef PRODUCT | |
966 C->verify_graph_edges(); | |
967 if( VerifyOpto && allow_progress() ) { | |
968 // Must turn off allow_progress to enable assert and break recursion | |
969 C->root()->verify(); | |
970 { // Check if any progress was missed using IterGVN | |
971 // Def-Use info enables transformations not attempted in wash-pass | |
972 // e.g. Region/Phi cleanup, ... | |
973 // Null-check elision -- may not have reached fixpoint | |
974 // do not propagate to dominated nodes | |
975 ResourceMark rm; | |
976 PhaseIterGVN igvn2(this,"Verify"); // Fresh and clean! | |
977 // Fill worklist completely | |
978 igvn2.init_worklist(C->root()); | |
979 | |
980 igvn2.set_allow_progress(false); | |
981 igvn2.optimize(); | |
982 igvn2.set_allow_progress(true); | |
983 } | |
984 } | |
985 if ( VerifyIterativeGVN && PrintOpto ) { | |
986 if ( _verify_counter == _verify_full_passes ) | |
987 tty->print_cr("VerifyIterativeGVN: %d transforms and verify passes", | |
988 _verify_full_passes); | |
989 else | |
990 tty->print_cr("VerifyIterativeGVN: %d transforms, %d full verify passes", | |
991 _verify_counter, _verify_full_passes); | |
992 } | |
993 #endif | |
994 } | |
995 | |
996 | |
997 //------------------register_new_node_with_optimizer--------------------------- | |
998 // Register a new node with the optimizer. Update the types array, the def-use | |
999 // info. Put on worklist. | |
1000 Node* PhaseIterGVN::register_new_node_with_optimizer(Node* n, Node* orig) { | |
1001 set_type_bottom(n); | |
1002 _worklist.push(n); | |
1003 if (orig != NULL) C->copy_node_notes_to(n, orig); | |
1004 return n; | |
1005 } | |
1006 | |
1007 //------------------------------transform-------------------------------------- | |
1008 // Non-recursive: idealize Node 'n' with respect to its inputs and its value | |
1009 Node *PhaseIterGVN::transform( Node *n ) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
1010 if (_delay_transform) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
1011 // Register the node but don't optimize for now |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
1012 register_new_node_with_optimizer(n); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
1013 return n; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
1014 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
65
diff
changeset
|
1015 |
0 | 1016 // If brand new node, make space in type array, and give it a type. |
1017 ensure_type_or_null(n); | |
1018 if (type_or_null(n) == NULL) { | |
1019 set_type_bottom(n); | |
1020 } | |
1021 | |
1022 return transform_old(n); | |
1023 } | |
1024 | |
1025 //------------------------------transform_old---------------------------------- | |
1026 Node *PhaseIterGVN::transform_old( Node *n ) { | |
1027 #ifndef PRODUCT | |
1028 debug_only(uint loop_count = 0;); | |
1029 set_transforms(); | |
1030 #endif | |
1031 // Remove 'n' from hash table in case it gets modified | |
1032 _table.hash_delete(n); | |
1033 if( VerifyIterativeGVN ) { | |
1034 assert( !_table.find_index(n->_idx), "found duplicate entry in table"); | |
1035 } | |
1036 | |
1037 // Apply the Ideal call in a loop until it no longer applies | |
1038 Node *k = n; | |
1039 DEBUG_ONLY(dead_loop_check(k);) | |
305 | 1040 DEBUG_ONLY(bool is_new = (k->outcnt() == 0);) |
0 | 1041 Node *i = k->Ideal(this, /*can_reshape=*/true); |
305 | 1042 assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); |
0 | 1043 #ifndef PRODUCT |
1044 if( VerifyIterativeGVN ) | |
1045 verify_step(k); | |
1046 if( i && VerifyOpto ) { | |
1047 if( !allow_progress() ) { | |
1048 if (i->is_Add() && i->outcnt() == 1) { | |
1049 // Switched input to left side because this is the only use | |
1050 } else if( i->is_If() && (i->in(0) == NULL) ) { | |
1051 // This IF is dead because it is dominated by an equivalent IF When | |
1052 // dominating if changed, info is not propagated sparsely to 'this' | |
1053 // Propagating this info further will spuriously identify other | |
1054 // progress. | |
1055 return i; | |
1056 } else | |
1057 set_progress(); | |
1058 } else | |
1059 set_progress(); | |
1060 } | |
1061 #endif | |
1062 | |
1063 while( i ) { | |
1064 #ifndef PRODUCT | |
1065 debug_only( if( loop_count >= K ) i->dump(4); ) | |
1066 assert(loop_count < K, "infinite loop in PhaseIterGVN::transform"); | |
1067 debug_only( loop_count++; ) | |
1068 #endif | |
1069 assert((i->_idx >= k->_idx) || i->is_top(), "Idealize should return new nodes, use Identity to return old nodes"); | |
1070 // Made a change; put users of original Node on worklist | |
1071 add_users_to_worklist( k ); | |
1072 // Replacing root of transform tree? | |
1073 if( k != i ) { | |
1074 // Make users of old Node now use new. | |
1075 subsume_node( k, i ); | |
1076 k = i; | |
1077 } | |
1078 DEBUG_ONLY(dead_loop_check(k);) | |
1079 // Try idealizing again | |
305 | 1080 DEBUG_ONLY(is_new = (k->outcnt() == 0);) |
0 | 1081 i = k->Ideal(this, /*can_reshape=*/true); |
305 | 1082 assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes"); |
0 | 1083 #ifndef PRODUCT |
1084 if( VerifyIterativeGVN ) | |
1085 verify_step(k); | |
1086 if( i && VerifyOpto ) set_progress(); | |
1087 #endif | |
1088 } | |
1089 | |
1090 // If brand new node, make space in type array. | |
1091 ensure_type_or_null(k); | |
1092 | |
1093 // See what kind of values 'k' takes on at runtime | |
1094 const Type *t = k->Value(this); | |
1095 assert(t != NULL, "value sanity"); | |
1096 | |
1097 // Since I just called 'Value' to compute the set of run-time values | |
1098 // for this Node, and 'Value' is non-local (and therefore expensive) I'll | |
1099 // cache Value. Later requests for the local phase->type of this Node can | |
1100 // use the cached Value instead of suffering with 'bottom_type'. | |
1101 if (t != type_or_null(k)) { | |
1102 NOT_PRODUCT( set_progress(); ) | |
1103 NOT_PRODUCT( inc_new_values();) | |
1104 set_type(k, t); | |
1105 // If k is a TypeNode, capture any more-precise type permanently into Node | |
1106 k->raise_bottom_type(t); | |
1107 // Move users of node to worklist | |
1108 add_users_to_worklist( k ); | |
1109 } | |
1110 | |
1111 // If 'k' computes a constant, replace it with a constant | |
1112 if( t->singleton() && !k->is_Con() ) { | |
1113 NOT_PRODUCT( set_progress(); ) | |
1114 Node *con = makecon(t); // Make a constant | |
1115 add_users_to_worklist( k ); | |
1116 subsume_node( k, con ); // Everybody using k now uses con | |
1117 return con; | |
1118 } | |
1119 | |
1120 // Now check for Identities | |
1121 i = k->Identity(this); // Look for a nearby replacement | |
1122 if( i != k ) { // Found? Return replacement! | |
1123 NOT_PRODUCT( set_progress(); ) | |
1124 add_users_to_worklist( k ); | |
1125 subsume_node( k, i ); // Everybody using k now uses i | |
1126 return i; | |
1127 } | |
1128 | |
1129 // Global Value Numbering | |
1130 i = hash_find_insert(k); // Check for pre-existing node | |
1131 if( i && (i != k) ) { | |
1132 // Return the pre-existing node if it isn't dead | |
1133 NOT_PRODUCT( set_progress(); ) | |
1134 add_users_to_worklist( k ); | |
1135 subsume_node( k, i ); // Everybody using k now uses i | |
1136 return i; | |
1137 } | |
1138 | |
1139 // Return Idealized original | |
1140 return k; | |
1141 } | |
1142 | |
1143 //---------------------------------saturate------------------------------------ | |
1144 const Type* PhaseIterGVN::saturate(const Type* new_type, const Type* old_type, | |
1145 const Type* limit_type) const { | |
1146 return new_type->narrow(old_type); | |
1147 } | |
1148 | |
1149 //------------------------------remove_globally_dead_node---------------------- | |
1150 // Kill a globally dead Node. All uses are also globally dead and are | |
1151 // aggressively trimmed. | |
1152 void PhaseIterGVN::remove_globally_dead_node( Node *dead ) { | |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1153 enum DeleteProgress { |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1154 PROCESS_INPUTS, |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1155 PROCESS_OUTPUTS |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1156 }; |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1157 assert(_stack.is_empty(), "not empty"); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1158 _stack.push(dead, PROCESS_INPUTS); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1159 |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1160 while (_stack.is_nonempty()) { |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1161 dead = _stack.node(); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1162 uint progress_state = _stack.index(); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1163 assert(dead != C->root(), "killing root, eh?"); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1164 assert(!dead->is_top(), "add check for top when pushing"); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1165 NOT_PRODUCT( set_progress(); ) |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1166 if (progress_state == PROCESS_INPUTS) { |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1167 // After following inputs, continue to outputs |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1168 _stack.set_index(PROCESS_OUTPUTS); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1169 if (!dead->is_Con()) { // Don't kill cons but uses |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1170 bool recurse = false; |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1171 // Remove from hash table |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1172 _table.hash_delete( dead ); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1173 // Smash all inputs to 'dead', isolating him completely |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1174 for (uint i = 0; i < dead->req(); i++) { |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1175 Node *in = dead->in(i); |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1176 if (in != NULL && in != C->top()) { // Points to something? |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1177 int nrep = dead->replace_edge(in, NULL); // Kill edges |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1178 assert((nrep > 0), "sanity"); |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1179 if (in->outcnt() == 0) { // Made input go dead? |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1180 _stack.push(in, PROCESS_INPUTS); // Recursively remove |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1181 recurse = true; |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1182 } else if (in->outcnt() == 1 && |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1183 in->has_special_unique_user()) { |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1184 _worklist.push(in->unique_out()); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1185 } else if (in->outcnt() <= 2 && dead->is_Phi()) { |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1186 if (in->Opcode() == Op_Region) { |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1187 _worklist.push(in); |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1188 } else if (in->is_Store()) { |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1189 DUIterator_Fast imax, i = in->fast_outs(imax); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1190 _worklist.push(in->fast_out(i)); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1191 i++; |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1192 if (in->outcnt() == 2) { |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1193 _worklist.push(in->fast_out(i)); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1194 i++; |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1195 } |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1196 assert(!(i < imax), "sanity"); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1197 } |
0 | 1198 } |
8116
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1199 if (ReduceFieldZeroing && dead->is_Load() && i == MemNode::Memory && |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1200 in->is_Proj() && in->in(0) != NULL && in->in(0)->is_Initialize()) { |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1201 // A Load that directly follows an InitializeNode is |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1202 // going away. The Stores that follow are candidates |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1203 // again to be captured by the InitializeNode. |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1204 for (DUIterator_Fast jmax, j = in->fast_outs(jmax); j < jmax; j++) { |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1205 Node *n = in->fast_out(j); |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1206 if (n->is_Store()) { |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1207 _worklist.push(n); |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1208 } |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1209 } |
6931f425c517
8007294: ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution
roland
parents:
8048
diff
changeset
|
1210 } |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1211 } // if (in != NULL && in != C->top()) |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1212 } // for (uint i = 0; i < dead->req(); i++) |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1213 if (recurse) { |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1214 continue; |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1215 } |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1216 } // if (!dead->is_Con()) |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1217 } // if (progress_state == PROCESS_INPUTS) |
0 | 1218 |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1219 // Aggressively kill globally dead uses |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1220 // (Rather than pushing all the outs at once, we push one at a time, |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1221 // plus the parent to resume later, because of the indefinite number |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1222 // of edge deletions per loop trip.) |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1223 if (dead->outcnt() > 0) { |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1224 // Recursively remove output edges |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1225 _stack.push(dead->raw_out(0), PROCESS_INPUTS); |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1226 } else { |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1227 // Finished disconnecting all input and output edges. |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
4064
diff
changeset
|
1228 _stack.pop(); |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1229 // Remove dead node from iterative worklist |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1230 _worklist.remove(dead); |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1231 // Constant node that has no out-edges and has only one in-edge from |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1232 // root is usually dead. However, sometimes reshaping walk makes |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1233 // it reachable by adding use edges. So, we will NOT count Con nodes |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1234 // as dead to be conservative about the dead node count at any |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1235 // given time. |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1236 if (!dead->is_Con()) { |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1237 C->record_dead_node(dead->_idx); |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1238 } |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1239 if (dead->is_macro()) { |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1240 C->remove_macro_node(dead); |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1241 } |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1242 if (dead->is_expensive()) { |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1243 C->remove_expensive_node(dead); |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1244 } |
0 | 1245 } |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
8116
diff
changeset
|
1246 } // while (_stack.is_nonempty()) |
0 | 1247 } |
1248 | |
1249 //------------------------------subsume_node----------------------------------- | |
1250 // Remove users from node 'old' and add them to node 'nn'. | |
1251 void PhaseIterGVN::subsume_node( Node *old, Node *nn ) { | |
1252 assert( old != hash_find(old), "should already been removed" ); | |
1253 assert( old != C->top(), "cannot subsume top node"); | |
1254 // Copy debug or profile information to the new version: | |
1255 C->copy_node_notes_to(nn, old); | |
1256 // Move users of node 'old' to node 'nn' | |
1257 for (DUIterator_Last imin, i = old->last_outs(imin); i >= imin; ) { | |
1258 Node* use = old->last_out(i); // for each use... | |
1259 // use might need re-hashing (but it won't if it's a new node) | |
1260 bool is_in_table = _table.hash_delete( use ); | |
1261 // Update use-def info as well | |
1262 // We remove all occurrences of old within use->in, | |
1263 // so as to avoid rehashing any node more than once. | |
1264 // The hash table probe swamps any outer loop overhead. | |
1265 uint num_edges = 0; | |
1266 for (uint jmax = use->len(), j = 0; j < jmax; j++) { | |
1267 if (use->in(j) == old) { | |
1268 use->set_req(j, nn); | |
1269 ++num_edges; | |
1270 } | |
1271 } | |
1272 // Insert into GVN hash table if unique | |
1273 // If a duplicate, 'use' will be cleaned up when pulled off worklist | |
1274 if( is_in_table ) { | |
1275 hash_find_insert(use); | |
1276 } | |
1277 i -= num_edges; // we deleted 1 or more copies of this edge | |
1278 } | |
1279 | |
1280 // Smash all inputs to 'old', isolating him completely | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6244
diff
changeset
|
1281 Node *temp = new (C) Node(1); |
0 | 1282 temp->init_req(0,nn); // Add a use to nn to prevent him from dying |
1283 remove_dead_node( old ); | |
1284 temp->del_req(0); // Yank bogus edge | |
1285 #ifndef PRODUCT | |
1286 if( VerifyIterativeGVN ) { | |
1287 for ( int i = 0; i < _verify_window_size; i++ ) { | |
1288 if ( _verify_window[i] == old ) | |
1289 _verify_window[i] = nn; | |
1290 } | |
1291 } | |
1292 #endif | |
1293 _worklist.remove(temp); // this can be necessary | |
1294 temp->destruct(); // reuse the _idx of this little guy | |
1295 } | |
1296 | |
1297 //------------------------------add_users_to_worklist-------------------------- | |
1298 void PhaseIterGVN::add_users_to_worklist0( Node *n ) { | |
1299 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { | |
1300 _worklist.push(n->fast_out(i)); // Push on worklist | |
1301 } | |
1302 } | |
1303 | |
1304 void PhaseIterGVN::add_users_to_worklist( Node *n ) { | |
1305 add_users_to_worklist0(n); | |
1306 | |
1307 // Move users of node to worklist | |
1308 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { | |
1309 Node* use = n->fast_out(i); // Get use | |
1310 | |
1311 if( use->is_Multi() || // Multi-definer? Push projs on worklist | |
1312 use->is_Store() ) // Enable store/load same address | |
1313 add_users_to_worklist0(use); | |
1314 | |
1315 // If we changed the receiver type to a call, we need to revisit | |
1316 // the Catch following the call. It's looking for a non-NULL | |
1317 // receiver to know when to enable the regular fall-through path | |
1318 // in addition to the NullPtrException path. | |
1319 if (use->is_CallDynamicJava() && n == use->in(TypeFunc::Parms)) { | |
1320 Node* p = use->as_CallDynamicJava()->proj_out(TypeFunc::Control); | |
1321 if (p != NULL) { | |
1322 add_users_to_worklist0(p); | |
1323 } | |
1324 } | |
1325 | |
1326 if( use->is_Cmp() ) { // Enable CMP/BOOL optimization | |
1327 add_users_to_worklist(use); // Put Bool on worklist | |
1328 // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the | |
1329 // phi merging either 0 or 1 onto the worklist | |
1330 if (use->outcnt() > 0) { | |
1331 Node* bol = use->raw_out(0); | |
1332 if (bol->outcnt() > 0) { | |
1333 Node* iff = bol->raw_out(0); | |
1334 if (iff->outcnt() == 2) { | |
1335 Node* ifproj0 = iff->raw_out(0); | |
1336 Node* ifproj1 = iff->raw_out(1); | |
1337 if (ifproj0->outcnt() > 0 && ifproj1->outcnt() > 0) { | |
1338 Node* region0 = ifproj0->raw_out(0); | |
1339 Node* region1 = ifproj1->raw_out(0); | |
1340 if( region0 == region1 ) | |
1341 add_users_to_worklist0(region0); | |
1342 } | |
1343 } | |
1344 } | |
1345 } | |
1346 } | |
1347 | |
1348 uint use_op = use->Opcode(); | |
1349 // If changed Cast input, check Phi users for simple cycles | |
65 | 1350 if( use->is_ConstraintCast() || use->is_CheckCastPP() ) { |
0 | 1351 for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { |
1352 Node* u = use->fast_out(i2); | |
1353 if (u->is_Phi()) | |
1354 _worklist.push(u); | |
1355 } | |
1356 } | |
1357 // If changed LShift inputs, check RShift users for useless sign-ext | |
1358 if( use_op == Op_LShiftI ) { | |
1359 for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { | |
1360 Node* u = use->fast_out(i2); | |
1361 if (u->Opcode() == Op_RShiftI) | |
1362 _worklist.push(u); | |
1363 } | |
1364 } | |
1365 // If changed AddP inputs, check Stores for loop invariant | |
1366 if( use_op == Op_AddP ) { | |
1367 for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { | |
1368 Node* u = use->fast_out(i2); | |
1369 if (u->is_Mem()) | |
1370 _worklist.push(u); | |
1371 } | |
1372 } | |
1373 // If changed initialization activity, check dependent Stores | |
1374 if (use_op == Op_Allocate || use_op == Op_AllocateArray) { | |
1375 InitializeNode* init = use->as_Allocate()->initialization(); | |
1376 if (init != NULL) { | |
1377 Node* imem = init->proj_out(TypeFunc::Memory); | |
1378 if (imem != NULL) add_users_to_worklist0(imem); | |
1379 } | |
1380 } | |
1381 if (use_op == Op_Initialize) { | |
1382 Node* imem = use->as_Initialize()->proj_out(TypeFunc::Memory); | |
1383 if (imem != NULL) add_users_to_worklist0(imem); | |
1384 } | |
1385 } | |
1386 } | |
1387 | |
1388 //============================================================================= | |
1389 #ifndef PRODUCT | |
1390 uint PhaseCCP::_total_invokes = 0; | |
1391 uint PhaseCCP::_total_constants = 0; | |
1392 #endif | |
1393 //------------------------------PhaseCCP--------------------------------------- | |
1394 // Conditional Constant Propagation, ala Wegman & Zadeck | |
1395 PhaseCCP::PhaseCCP( PhaseIterGVN *igvn ) : PhaseIterGVN(igvn) { | |
1396 NOT_PRODUCT( clear_constants(); ) | |
1397 assert( _worklist.size() == 0, "" ); | |
1398 // Clear out _nodes from IterGVN. Must be clear to transform call. | |
1399 _nodes.clear(); // Clear out from IterGVN | |
1400 analyze(); | |
1401 } | |
1402 | |
1403 #ifndef PRODUCT | |
1404 //------------------------------~PhaseCCP-------------------------------------- | |
1405 PhaseCCP::~PhaseCCP() { | |
1406 inc_invokes(); | |
1407 _total_constants += count_constants(); | |
1408 } | |
1409 #endif | |
1410 | |
1411 | |
1412 #ifdef ASSERT | |
1413 static bool ccp_type_widens(const Type* t, const Type* t0) { | |
1414 assert(t->meet(t0) == t, "Not monotonic"); | |
1415 switch (t->base() == t0->base() ? t->base() : Type::Top) { | |
1416 case Type::Int: | |
1417 assert(t0->isa_int()->_widen <= t->isa_int()->_widen, "widen increases"); | |
1418 break; | |
1419 case Type::Long: | |
1420 assert(t0->isa_long()->_widen <= t->isa_long()->_widen, "widen increases"); | |
1421 break; | |
1422 } | |
1423 return true; | |
1424 } | |
1425 #endif //ASSERT | |
1426 | |
1427 //------------------------------analyze---------------------------------------- | |
1428 void PhaseCCP::analyze() { | |
1429 // Initialize all types to TOP, optimistic analysis | |
1430 for (int i = C->unique() - 1; i >= 0; i--) { | |
1431 _types.map(i,Type::TOP); | |
1432 } | |
1433 | |
1434 // Push root onto worklist | |
1435 Unique_Node_List worklist; | |
1436 worklist.push(C->root()); | |
1437 | |
1438 // Pull from worklist; compute new value; push changes out. | |
1439 // This loop is the meat of CCP. | |
1440 while( worklist.size() ) { | |
1441 Node *n = worklist.pop(); | |
1442 const Type *t = n->Value(this); | |
1443 if (t != type(n)) { | |
1444 assert(ccp_type_widens(t, type(n)), "ccp type must widen"); | |
1445 #ifndef PRODUCT | |
1446 if( TracePhaseCCP ) { | |
1447 t->dump(); | |
1448 do { tty->print("\t"); } while (tty->position() < 16); | |
1449 n->dump(); | |
1450 } | |
1451 #endif | |
1452 set_type(n, t); | |
1453 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { | |
1454 Node* m = n->fast_out(i); // Get user | |
1455 if( m->is_Region() ) { // New path to Region? Must recheck Phis too | |
1456 for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { | |
1457 Node* p = m->fast_out(i2); // Propagate changes to uses | |
1458 if( p->bottom_type() != type(p) ) // If not already bottomed out | |
1459 worklist.push(p); // Propagate change to user | |
1460 } | |
1461 } | |
605 | 1462 // If we changed the receiver type to a call, we need to revisit |
0 | 1463 // the Catch following the call. It's looking for a non-NULL |
1464 // receiver to know when to enable the regular fall-through path | |
1465 // in addition to the NullPtrException path | |
1466 if (m->is_Call()) { | |
1467 for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { | |
1468 Node* p = m->fast_out(i2); // Propagate changes to uses | |
1469 if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1) | |
1470 worklist.push(p->unique_out()); | |
1471 } | |
1472 } | |
1473 if( m->bottom_type() != type(m) ) // If not already bottomed out | |
1474 worklist.push(m); // Propagate change to user | |
1475 } | |
1476 } | |
1477 } | |
1478 } | |
1479 | |
1480 //------------------------------do_transform----------------------------------- | |
1481 // Top level driver for the recursive transformer | |
1482 void PhaseCCP::do_transform() { | |
1483 // Correct leaves of new-space Nodes; they point to old-space. | |
1484 C->set_root( transform(C->root())->as_Root() ); | |
1485 assert( C->top(), "missing TOP node" ); | |
1486 assert( C->root(), "missing root" ); | |
1487 } | |
1488 | |
1489 //------------------------------transform-------------------------------------- | |
1490 // Given a Node in old-space, clone him into new-space. | |
1491 // Convert any of his old-space children into new-space children. | |
1492 Node *PhaseCCP::transform( Node *n ) { | |
1493 Node *new_node = _nodes[n->_idx]; // Check for transformed node | |
1494 if( new_node != NULL ) | |
1495 return new_node; // Been there, done that, return old answer | |
1496 new_node = transform_once(n); // Check for constant | |
1497 _nodes.map( n->_idx, new_node ); // Flag as having been cloned | |
1498 | |
1499 // Allocate stack of size _nodes.Size()/2 to avoid frequent realloc | |
1500 GrowableArray <Node *> trstack(C->unique() >> 1); | |
1501 | |
1502 trstack.push(new_node); // Process children of cloned node | |
1503 while ( trstack.is_nonempty() ) { | |
1504 Node *clone = trstack.pop(); | |
1505 uint cnt = clone->req(); | |
1506 for( uint i = 0; i < cnt; i++ ) { // For all inputs do | |
1507 Node *input = clone->in(i); | |
1508 if( input != NULL ) { // Ignore NULLs | |
1509 Node *new_input = _nodes[input->_idx]; // Check for cloned input node | |
1510 if( new_input == NULL ) { | |
1511 new_input = transform_once(input); // Check for constant | |
1512 _nodes.map( input->_idx, new_input );// Flag as having been cloned | |
1513 trstack.push(new_input); | |
1514 } | |
1515 assert( new_input == clone->in(i), "insanity check"); | |
1516 } | |
1517 } | |
1518 } | |
1519 return new_node; | |
1520 } | |
1521 | |
1522 | |
1523 //------------------------------transform_once--------------------------------- | |
1524 // For PhaseCCP, transformation is IDENTITY unless Node computed a constant. | |
1525 Node *PhaseCCP::transform_once( Node *n ) { | |
1526 const Type *t = type(n); | |
1527 // Constant? Use constant Node instead | |
1528 if( t->singleton() ) { | |
1529 Node *nn = n; // Default is to return the original constant | |
1530 if( t == Type::TOP ) { | |
1531 // cache my top node on the Compile instance | |
1532 if( C->cached_top_node() == NULL || C->cached_top_node()->in(0) == NULL ) { | |
1533 C->set_cached_top_node( ConNode::make(C, Type::TOP) ); | |
1534 set_type(C->top(), Type::TOP); | |
1535 } | |
1536 nn = C->top(); | |
1537 } | |
1538 if( !n->is_Con() ) { | |
1539 if( t != Type::TOP ) { | |
1540 nn = makecon(t); // ConNode::make(t); | |
1541 NOT_PRODUCT( inc_constants(); ) | |
1542 } else if( n->is_Region() ) { // Unreachable region | |
1543 // Note: nn == C->top() | |
1544 n->set_req(0, NULL); // Cut selfreference | |
1545 // Eagerly remove dead phis to avoid phis copies creation. | |
1546 for (DUIterator i = n->outs(); n->has_out(i); i++) { | |
1547 Node* m = n->out(i); | |
1548 if( m->is_Phi() ) { | |
1549 assert(type(m) == Type::TOP, "Unreachable region should not have live phis."); | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
1550 replace_node(m, nn); |
0 | 1551 --i; // deleted this phi; rescan starting with next position |
1552 } | |
1553 } | |
1554 } | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
1555 replace_node(n,nn); // Update DefUse edges for new constant |
0 | 1556 } |
1557 return nn; | |
1558 } | |
1559 | |
1560 // If x is a TypeNode, capture any more-precise type permanently into Node | |
1561 if (t != n->bottom_type()) { | |
1562 hash_delete(n); // changing bottom type may force a rehash | |
1563 n->raise_bottom_type(t); | |
1564 _worklist.push(n); // n re-enters the hash table via the worklist | |
1565 } | |
1566 | |
1567 // Idealize graph using DU info. Must clone() into new-space. | |
1568 // DU info is generally used to show profitability, progress or safety | |
1569 // (but generally not needed for correctness). | |
1570 Node *nn = n->Ideal_DU_postCCP(this); | |
1571 | |
1572 // TEMPORARY fix to ensure that 2nd GVN pass eliminates NULL checks | |
1573 switch( n->Opcode() ) { | |
1574 case Op_FastLock: // Revisit FastLocks for lock coarsening | |
1575 case Op_If: | |
1576 case Op_CountedLoopEnd: | |
1577 case Op_Region: | |
1578 case Op_Loop: | |
1579 case Op_CountedLoop: | |
1580 case Op_Conv2B: | |
1581 case Op_Opaque1: | |
1582 case Op_Opaque2: | |
1583 _worklist.push(n); | |
1584 break; | |
1585 default: | |
1586 break; | |
1587 } | |
1588 if( nn ) { | |
1589 _worklist.push(n); | |
1590 // Put users of 'n' onto worklist for second igvn transform | |
1591 add_users_to_worklist(n); | |
1592 return nn; | |
1593 } | |
1594 | |
1595 return n; | |
1596 } | |
1597 | |
1598 //---------------------------------saturate------------------------------------ | |
1599 const Type* PhaseCCP::saturate(const Type* new_type, const Type* old_type, | |
1600 const Type* limit_type) const { | |
1009
03b336640699
6885584: A particular class structure causes large allocation spike for jit
never
parents:
927
diff
changeset
|
1601 const Type* wide_type = new_type->widen(old_type, limit_type); |
0 | 1602 if (wide_type != new_type) { // did we widen? |
1603 // If so, we may have widened beyond the limit type. Clip it back down. | |
1604 new_type = wide_type->filter(limit_type); | |
1605 } | |
1606 return new_type; | |
1607 } | |
1608 | |
1609 //------------------------------print_statistics------------------------------- | |
1610 #ifndef PRODUCT | |
1611 void PhaseCCP::print_statistics() { | |
1612 tty->print_cr("CCP: %d constants found: %d", _total_invokes, _total_constants); | |
1613 } | |
1614 #endif | |
1615 | |
1616 | |
1617 //============================================================================= | |
1618 #ifndef PRODUCT | |
1619 uint PhasePeephole::_total_peepholes = 0; | |
1620 #endif | |
1621 //------------------------------PhasePeephole---------------------------------- | |
1622 // Conditional Constant Propagation, ala Wegman & Zadeck | |
1623 PhasePeephole::PhasePeephole( PhaseRegAlloc *regalloc, PhaseCFG &cfg ) | |
1624 : PhaseTransform(Peephole), _regalloc(regalloc), _cfg(cfg) { | |
1625 NOT_PRODUCT( clear_peepholes(); ) | |
1626 } | |
1627 | |
1628 #ifndef PRODUCT | |
1629 //------------------------------~PhasePeephole--------------------------------- | |
1630 PhasePeephole::~PhasePeephole() { | |
1631 _total_peepholes += count_peepholes(); | |
1632 } | |
1633 #endif | |
1634 | |
1635 //------------------------------transform-------------------------------------- | |
1636 Node *PhasePeephole::transform( Node *n ) { | |
1637 ShouldNotCallThis(); | |
1638 return NULL; | |
1639 } | |
1640 | |
1641 //------------------------------do_transform----------------------------------- | |
1642 void PhasePeephole::do_transform() { | |
1643 bool method_name_not_printed = true; | |
1644 | |
1645 // Examine each basic block | |
1646 for( uint block_number = 1; block_number < _cfg._num_blocks; ++block_number ) { | |
1647 Block *block = _cfg._blocks[block_number]; | |
1648 bool block_not_printed = true; | |
1649 | |
1650 // and each instruction within a block | |
1651 uint end_index = block->_nodes.size(); | |
1652 // block->end_idx() not valid after PhaseRegAlloc | |
1653 for( uint instruction_index = 1; instruction_index < end_index; ++instruction_index ) { | |
1654 Node *n = block->_nodes.at(instruction_index); | |
1655 if( n->is_Mach() ) { | |
1656 MachNode *m = n->as_Mach(); | |
1657 int deleted_count = 0; | |
1658 // check for peephole opportunities | |
1659 MachNode *m2 = m->peephole( block, instruction_index, _regalloc, deleted_count, C ); | |
1660 if( m2 != NULL ) { | |
1661 #ifndef PRODUCT | |
1662 if( PrintOptoPeephole ) { | |
1663 // Print method, first time only | |
1664 if( C->method() && method_name_not_printed ) { | |
1665 C->method()->print_short_name(); tty->cr(); | |
1666 method_name_not_printed = false; | |
1667 } | |
1668 // Print this block | |
1669 if( Verbose && block_not_printed) { | |
1670 tty->print_cr("in block"); | |
1671 block->dump(); | |
1672 block_not_printed = false; | |
1673 } | |
1674 // Print instructions being deleted | |
1675 for( int i = (deleted_count - 1); i >= 0; --i ) { | |
1676 block->_nodes.at(instruction_index-i)->as_Mach()->format(_regalloc); tty->cr(); | |
1677 } | |
1678 tty->print_cr("replaced with"); | |
1679 // Print new instruction | |
1680 m2->format(_regalloc); | |
1681 tty->print("\n\n"); | |
1682 } | |
1683 #endif | |
1684 // Remove old nodes from basic block and update instruction_index | |
1685 // (old nodes still exist and may have edges pointing to them | |
1686 // as register allocation info is stored in the allocator using | |
1687 // the node index to live range mappings.) | |
1688 uint safe_instruction_index = (instruction_index - deleted_count); | |
1689 for( ; (instruction_index > safe_instruction_index); --instruction_index ) { | |
1690 block->_nodes.remove( instruction_index ); | |
1691 } | |
1692 // install new node after safe_instruction_index | |
1693 block->_nodes.insert( safe_instruction_index + 1, m2 ); | |
1694 end_index = block->_nodes.size() - 1; // Recompute new block size | |
1695 NOT_PRODUCT( inc_peepholes(); ) | |
1696 } | |
1697 } | |
1698 } | |
1699 } | |
1700 } | |
1701 | |
1702 //------------------------------print_statistics------------------------------- | |
1703 #ifndef PRODUCT | |
1704 void PhasePeephole::print_statistics() { | |
1705 tty->print_cr("Peephole: peephole rules applied: %d", _total_peepholes); | |
1706 } | |
1707 #endif | |
1708 | |
1709 | |
1710 //============================================================================= | |
1711 //------------------------------set_req_X-------------------------------------- | |
1712 void Node::set_req_X( uint i, Node *n, PhaseIterGVN *igvn ) { | |
1713 assert( is_not_dead(n), "can not use dead node"); | |
1714 assert( igvn->hash_find(this) != this, "Need to remove from hash before changing edges" ); | |
1715 Node *old = in(i); | |
1716 set_req(i, n); | |
1717 | |
1718 // old goes dead? | |
1719 if( old ) { | |
1720 switch (old->outcnt()) { | |
927
662f330d7275
6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents:
605
diff
changeset
|
1721 case 0: |
662f330d7275
6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents:
605
diff
changeset
|
1722 // Put into the worklist to kill later. We do not kill it now because the |
662f330d7275
6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents:
605
diff
changeset
|
1723 // recursive kill will delete the current node (this) if dead-loop exists |
0 | 1724 if (!old->is_top()) |
927
662f330d7275
6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents:
605
diff
changeset
|
1725 igvn->_worklist.push( old ); |
0 | 1726 break; |
1727 case 1: | |
1728 if( old->is_Store() || old->has_special_unique_user() ) | |
1729 igvn->add_users_to_worklist( old ); | |
1730 break; | |
1731 case 2: | |
1732 if( old->is_Store() ) | |
1733 igvn->add_users_to_worklist( old ); | |
1734 if( old->Opcode() == Op_Region ) | |
1735 igvn->_worklist.push(old); | |
1736 break; | |
1737 case 3: | |
1738 if( old->Opcode() == Op_Region ) { | |
1739 igvn->_worklist.push(old); | |
1740 igvn->add_users_to_worklist( old ); | |
1741 } | |
1742 break; | |
1743 default: | |
1744 break; | |
1745 } | |
1746 } | |
1747 | |
1748 } | |
1749 | |
1750 //-------------------------------replace_by----------------------------------- | |
1751 // Using def-use info, replace one node for another. Follow the def-use info | |
1752 // to all users of the OLD node. Then make all uses point to the NEW node. | |
1753 void Node::replace_by(Node *new_node) { | |
1754 assert(!is_top(), "top node has no DU info"); | |
1755 for (DUIterator_Last imin, i = last_outs(imin); i >= imin; ) { | |
1756 Node* use = last_out(i); | |
1757 uint uses_found = 0; | |
1758 for (uint j = 0; j < use->len(); j++) { | |
1759 if (use->in(j) == this) { | |
1760 if (j < use->req()) | |
1761 use->set_req(j, new_node); | |
1762 else use->set_prec(j, new_node); | |
1763 uses_found++; | |
1764 } | |
1765 } | |
1766 i -= uses_found; // we deleted 1 or more copies of this edge | |
1767 } | |
1768 } | |
1769 | |
1770 //============================================================================= | |
1771 //----------------------------------------------------------------------------- | |
1772 void Type_Array::grow( uint i ) { | |
1773 if( !_max ) { | |
1774 _max = 1; | |
1775 _types = (const Type**)_a->Amalloc( _max * sizeof(Type*) ); | |
1776 _types[0] = NULL; | |
1777 } | |
1778 uint old = _max; | |
1779 while( i >= _max ) _max <<= 1; // Double to fit | |
1780 _types = (const Type**)_a->Arealloc( _types, old*sizeof(Type*),_max*sizeof(Type*)); | |
1781 memset( &_types[old], 0, (_max-old)*sizeof(Type*) ); | |
1782 } | |
1783 | |
1784 //------------------------------dump------------------------------------------- | |
1785 #ifndef PRODUCT | |
1786 void Type_Array::dump() const { | |
1787 uint max = Size(); | |
1788 for( uint i = 0; i < max; i++ ) { | |
1789 if( _types[i] != NULL ) { | |
1790 tty->print(" %d\t== ", i); _types[i]->dump(); tty->cr(); | |
1791 } | |
1792 } | |
1793 } | |
1794 #endif |