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