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