Mercurial > hg > truffle
annotate src/share/vm/opto/phaseX.hpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | d092d1b31229 |
children | b2ee5dc63353 |
rev | line source |
---|---|
0 | 1 /* |
6842
b9a9ed0f8eeb
7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents:
6272
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1489
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:
1489
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_PHASEX_HPP |
26 #define SHARE_VM_OPTO_PHASEX_HPP | |
27 | |
28 #include "libadt/dict.hpp" | |
29 #include "libadt/vectset.hpp" | |
30 #include "memory/resourceArea.hpp" | |
31 #include "opto/memnode.hpp" | |
32 #include "opto/node.hpp" | |
33 #include "opto/phase.hpp" | |
34 #include "opto/type.hpp" | |
35 | |
0 | 36 class Compile; |
37 class ConINode; | |
38 class ConLNode; | |
39 class Node; | |
40 class Type; | |
41 class PhaseTransform; | |
42 class PhaseGVN; | |
43 class PhaseIterGVN; | |
44 class PhaseCCP; | |
45 class PhasePeephole; | |
46 class PhaseRegAlloc; | |
47 | |
48 | |
49 //----------------------------------------------------------------------------- | |
50 // Expandable closed hash-table of nodes, initialized to NULL. | |
51 // Note that the constructor just zeros things | |
52 // Storage is reclaimed when the Arena's lifetime is over. | |
53 class NodeHash : public StackObj { | |
54 protected: | |
55 Arena *_a; // Arena to allocate in | |
56 uint _max; // Size of table (power of 2) | |
57 uint _inserts; // For grow and debug, count of hash_inserts | |
58 uint _insert_limit; // 'grow' when _inserts reaches _insert_limit | |
59 Node **_table; // Hash table of Node pointers | |
60 Node *_sentinel; // Replaces deleted entries in hash table | |
61 | |
62 public: | |
63 NodeHash(uint est_max_size); | |
64 NodeHash(Arena *arena, uint est_max_size); | |
65 NodeHash(NodeHash *use_this_state); | |
66 #ifdef ASSERT | |
67 ~NodeHash(); // Unlock all nodes upon destruction of table. | |
68 void operator=(const NodeHash&); // Unlock all nodes upon replacement of table. | |
69 #endif | |
70 Node *hash_find(const Node*);// Find an equivalent version in hash table | |
71 Node *hash_find_insert(Node*);// If not in table insert else return found node | |
72 void hash_insert(Node*); // Insert into hash table | |
73 bool hash_delete(const Node*);// Replace with _sentinel in hash table | |
74 void check_grow() { | |
75 _inserts++; | |
76 if( _inserts == _insert_limit ) { grow(); } | |
77 assert( _inserts <= _insert_limit, "hash table overflow"); | |
78 assert( _inserts < _max, "hash table overflow" ); | |
79 } | |
80 static uint round_up(uint); // Round up to nearest power of 2 | |
81 void grow(); // Grow _table to next power of 2 and rehash | |
82 // Return 75% of _max, rounded up. | |
83 uint insert_limit() const { return _max - (_max>>2); } | |
84 | |
85 void clear(); // Set all entries to NULL, keep storage. | |
86 // Size of hash table | |
87 uint size() const { return _max; } | |
88 // Return Node* at index in table | |
89 Node *at(uint table_index) { | |
90 assert(table_index < _max, "Must be within table"); | |
91 return _table[table_index]; | |
92 } | |
93 | |
94 void remove_useless_nodes(VectorSet &useful); // replace with sentinel | |
7473 | 95 void replace_with(NodeHash* nh); |
0 | 96 |
97 Node *sentinel() { return _sentinel; } | |
98 | |
99 #ifndef PRODUCT | |
100 Node *find_index(uint idx); // For debugging | |
101 void dump(); // For debugging, dump statistics | |
102 #endif | |
103 uint _grows; // For debugging, count of table grow()s | |
104 uint _look_probes; // For debugging, count of hash probes | |
105 uint _lookup_hits; // For debugging, count of hash_finds | |
106 uint _lookup_misses; // For debugging, count of hash_finds | |
107 uint _insert_probes; // For debugging, count of hash probes | |
108 uint _delete_probes; // For debugging, count of hash probes for deletes | |
109 uint _delete_hits; // For debugging, count of hash probes for deletes | |
110 uint _delete_misses; // For debugging, count of hash probes for deletes | |
111 uint _total_inserts; // For debugging, total inserts into hash table | |
112 uint _total_insert_probes; // For debugging, total probes while inserting | |
113 }; | |
114 | |
115 | |
116 //----------------------------------------------------------------------------- | |
117 // Map dense integer indices to Types. Uses classic doubling-array trick. | |
118 // Abstractly provides an infinite array of Type*'s, initialized to NULL. | |
119 // Note that the constructor just zeros things, and since I use Arena | |
120 // allocation I do not need a destructor to reclaim storage. | |
121 // Despite the general name, this class is customized for use by PhaseTransform. | |
122 class Type_Array : public StackObj { | |
123 Arena *_a; // Arena to allocate in | |
124 uint _max; | |
125 const Type **_types; | |
126 void grow( uint i ); // Grow array node to fit | |
127 const Type *operator[] ( uint i ) const // Lookup, or NULL for not mapped | |
128 { return (i<_max) ? _types[i] : (Type*)NULL; } | |
129 friend class PhaseTransform; | |
130 public: | |
131 Type_Array(Arena *a) : _a(a), _max(0), _types(0) {} | |
132 Type_Array(Type_Array *ta) : _a(ta->_a), _max(ta->_max), _types(ta->_types) { } | |
133 const Type *fast_lookup(uint i) const{assert(i<_max,"oob");return _types[i];} | |
134 // Extend the mapping: index i maps to Type *n. | |
135 void map( uint i, const Type *n ) { if( i>=_max ) grow(i); _types[i] = n; } | |
136 uint Size() const { return _max; } | |
137 #ifndef PRODUCT | |
138 void dump() const; | |
139 #endif | |
140 }; | |
141 | |
142 | |
143 //------------------------------PhaseRemoveUseless----------------------------- | |
144 // Remove useless nodes from GVN hash-table, worklist, and graph | |
145 class PhaseRemoveUseless : public Phase { | |
146 protected: | |
147 Unique_Node_List _useful; // Nodes reachable from root | |
148 // list is allocated from current resource area | |
149 public: | |
150 PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist ); | |
151 | |
152 Unique_Node_List *get_useful() { return &_useful; } | |
153 }; | |
154 | |
155 | |
156 //------------------------------PhaseTransform--------------------------------- | |
157 // Phases that analyze, then transform. Constructing the Phase object does any | |
158 // global or slow analysis. The results are cached later for a fast | |
159 // transformation pass. When the Phase object is deleted the cached analysis | |
160 // results are deleted. | |
161 class PhaseTransform : public Phase { | |
162 protected: | |
163 Arena* _arena; | |
164 Node_Array _nodes; // Map old node indices to new nodes. | |
165 Type_Array _types; // Map old node indices to Types. | |
166 | |
167 // ConNode caches: | |
168 enum { _icon_min = -1 * HeapWordSize, | |
169 _icon_max = 16 * HeapWordSize, | |
170 _lcon_min = _icon_min, | |
171 _lcon_max = _icon_max, | |
172 _zcon_max = (uint)T_CONFLICT | |
173 }; | |
174 ConINode* _icons[_icon_max - _icon_min + 1]; // cached jint constant nodes | |
175 ConLNode* _lcons[_lcon_max - _lcon_min + 1]; // cached jlong constant nodes | |
176 ConNode* _zcons[_zcon_max + 1]; // cached is_zero_type nodes | |
177 void init_con_caches(); | |
178 | |
179 // Support both int and long caches because either might be an intptr_t, | |
180 // so they show up frequently in address computations. | |
181 | |
182 public: | |
183 PhaseTransform( PhaseNumber pnum ); | |
184 PhaseTransform( Arena *arena, PhaseNumber pnum ); | |
185 PhaseTransform( PhaseTransform *phase, PhaseNumber pnum ); | |
186 | |
187 Arena* arena() { return _arena; } | |
188 Type_Array& types() { return _types; } | |
189 // _nodes is used in varying ways by subclasses, which define local accessors | |
190 | |
191 public: | |
192 // Get a previously recorded type for the node n. | |
193 // This type must already have been recorded. | |
194 // If you want the type of a very new (untransformed) node, | |
195 // you must use type_or_null, and test the result for NULL. | |
196 const Type* type(const Node* n) const { | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6144
diff
changeset
|
197 assert(n != NULL, "must not be null"); |
0 | 198 const Type* t = _types.fast_lookup(n->_idx); |
199 assert(t != NULL, "must set before get"); | |
200 return t; | |
201 } | |
202 // Get a previously recorded type for the node n, | |
203 // or else return NULL if there is none. | |
204 const Type* type_or_null(const Node* n) const { | |
205 return _types.fast_lookup(n->_idx); | |
206 } | |
207 // Record a type for a node. | |
208 void set_type(const Node* n, const Type *t) { | |
209 assert(t != NULL, "type must not be null"); | |
210 _types.map(n->_idx, t); | |
211 } | |
212 // Record an initial type for a node, the node's bottom type. | |
213 void set_type_bottom(const Node* n) { | |
214 // Use this for initialization when bottom_type() (or better) is not handy. | |
215 // Usually the initialization shoudl be to n->Value(this) instead, | |
216 // or a hand-optimized value like Type::MEMORY or Type::CONTROL. | |
217 assert(_types[n->_idx] == NULL, "must set the initial type just once"); | |
218 _types.map(n->_idx, n->bottom_type()); | |
219 } | |
220 // Make sure the types array is big enough to record a size for the node n. | |
221 // (In product builds, we never want to do range checks on the types array!) | |
222 void ensure_type_or_null(const Node* n) { | |
223 if (n->_idx >= _types.Size()) | |
224 _types.map(n->_idx, NULL); // Grow the types array as needed. | |
225 } | |
226 | |
227 // Utility functions: | |
228 const TypeInt* find_int_type( Node* n); | |
229 const TypeLong* find_long_type(Node* n); | |
230 jint find_int_con( Node* n, jint value_if_unknown) { | |
231 const TypeInt* t = find_int_type(n); | |
232 return (t != NULL && t->is_con()) ? t->get_con() : value_if_unknown; | |
233 } | |
234 jlong find_long_con(Node* n, jlong value_if_unknown) { | |
235 const TypeLong* t = find_long_type(n); | |
236 return (t != NULL && t->is_con()) ? t->get_con() : value_if_unknown; | |
237 } | |
238 | |
239 // Make an idealized constant, i.e., one of ConINode, ConPNode, ConFNode, etc. | |
240 // Same as transform(ConNode::make(t)). | |
241 ConNode* makecon(const Type* t); | |
242 virtual ConNode* uncached_makecon(const Type* t) // override in PhaseValues | |
243 { ShouldNotCallThis(); return NULL; } | |
244 | |
245 // Fast int or long constant. Same as TypeInt::make(i) or TypeLong::make(l). | |
246 ConINode* intcon(jint i); | |
247 ConLNode* longcon(jlong l); | |
248 | |
249 // Fast zero or null constant. Same as makecon(Type::get_zero_type(bt)). | |
250 ConNode* zerocon(BasicType bt); | |
251 | |
252 // Return a node which computes the same function as this node, but | |
253 // in a faster or cheaper fashion. | |
254 virtual Node *transform( Node *n ) = 0; | |
255 | |
256 // Return whether two Nodes are equivalent. | |
257 // Must not be recursive, since the recursive version is built from this. | |
258 // For pessimistic optimizations this is simply pointer equivalence. | |
259 bool eqv(const Node* n1, const Node* n2) const { return n1 == n2; } | |
260 | |
261 // For pessimistic passes, the return type must monotonically narrow. | |
262 // For optimistic passes, the return type must monotonically widen. | |
263 // It is possible to get into a "death march" in either type of pass, | |
264 // where the types are continually moving but it will take 2**31 or | |
265 // more steps to converge. This doesn't happen on most normal loops. | |
266 // | |
267 // Here is an example of a deadly loop for an optimistic pass, along | |
268 // with a partial trace of inferred types: | |
269 // x = phi(0,x'); L: x' = x+1; if (x' >= 0) goto L; | |
270 // 0 1 join([0..max], 1) | |
271 // [0..1] [1..2] join([0..max], [1..2]) | |
272 // [0..2] [1..3] join([0..max], [1..3]) | |
273 // ... ... ... | |
274 // [0..max] [min]u[1..max] join([0..max], [min..max]) | |
275 // [0..max] ==> fixpoint | |
276 // We would have proven, the hard way, that the iteration space is all | |
277 // non-negative ints, with the loop terminating due to 32-bit overflow. | |
278 // | |
279 // Here is the corresponding example for a pessimistic pass: | |
280 // x = phi(0,x'); L: x' = x-1; if (x' >= 0) goto L; | |
281 // int int join([0..max], int) | |
282 // [0..max] [-1..max-1] join([0..max], [-1..max-1]) | |
283 // [0..max-1] [-1..max-2] join([0..max], [-1..max-2]) | |
284 // ... ... ... | |
285 // [0..1] [-1..0] join([0..max], [-1..0]) | |
286 // 0 -1 join([0..max], -1) | |
287 // 0 == fixpoint | |
288 // We would have proven, the hard way, that the iteration space is {0}. | |
289 // (Usually, other optimizations will make the "if (x >= 0)" fold up | |
290 // before we get into trouble. But not always.) | |
291 // | |
292 // It's a pleasant thing to observe that the pessimistic pass | |
293 // will make short work of the optimistic pass's deadly loop, | |
294 // and vice versa. That is a good example of the complementary | |
295 // purposes of the CCP (optimistic) vs. GVN (pessimistic) phases. | |
296 // | |
297 // In any case, only widen or narrow a few times before going to the | |
298 // correct flavor of top or bottom. | |
299 // | |
300 // This call only needs to be made once as the data flows around any | |
301 // given cycle. We do it at Phis, and nowhere else. | |
302 // The types presented are the new type of a phi (computed by PhiNode::Value) | |
303 // and the previously computed type, last time the phi was visited. | |
304 // | |
305 // The third argument is upper limit for the saturated value, | |
306 // if the phase wishes to widen the new_type. | |
307 // If the phase is narrowing, the old type provides a lower limit. | |
308 // Caller guarantees that old_type and new_type are no higher than limit_type. | |
309 virtual const Type* saturate(const Type* new_type, const Type* old_type, | |
310 const Type* limit_type) const | |
311 { ShouldNotCallThis(); return NULL; } | |
312 | |
313 #ifndef PRODUCT | |
314 void dump_old2new_map() const; | |
315 void dump_new( uint new_lidx ) const; | |
316 void dump_types() const; | |
317 void dump_nodes_and_types(const Node *root, uint depth, bool only_ctrl = true); | |
318 void dump_nodes_and_types_recur( const Node *n, uint depth, bool only_ctrl, VectorSet &visited); | |
319 | |
320 uint _count_progress; // For profiling, count transforms that make progress | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1080
diff
changeset
|
321 void set_progress() { ++_count_progress; assert( allow_progress(),"No progress allowed during verification"); } |
0 | 322 void clear_progress() { _count_progress = 0; } |
323 uint made_progress() const { return _count_progress; } | |
324 | |
325 uint _count_transforms; // For profiling, count transforms performed | |
326 void set_transforms() { ++_count_transforms; } | |
327 void clear_transforms() { _count_transforms = 0; } | |
328 uint made_transforms() const{ return _count_transforms; } | |
329 | |
330 bool _allow_progress; // progress not allowed during verification pass | |
331 void set_allow_progress(bool allow) { _allow_progress = allow; } | |
332 bool allow_progress() { return _allow_progress; } | |
333 #endif | |
334 }; | |
335 | |
336 //------------------------------PhaseValues------------------------------------ | |
337 // Phase infrastructure to support values | |
338 class PhaseValues : public PhaseTransform { | |
339 protected: | |
340 NodeHash _table; // Hash table for value-numbering | |
341 | |
342 public: | |
343 PhaseValues( Arena *arena, uint est_max_size ); | |
344 PhaseValues( PhaseValues *pt ); | |
345 PhaseValues( PhaseValues *ptv, const char *dummy ); | |
346 NOT_PRODUCT( ~PhaseValues(); ) | |
347 virtual PhaseIterGVN *is_IterGVN() { return 0; } | |
348 | |
349 // Some Ideal and other transforms delete --> modify --> insert values | |
350 bool hash_delete(Node *n) { return _table.hash_delete(n); } | |
351 void hash_insert(Node *n) { _table.hash_insert(n); } | |
352 Node *hash_find_insert(Node *n){ return _table.hash_find_insert(n); } | |
353 Node *hash_find(const Node *n) { return _table.hash_find(n); } | |
354 | |
355 // Used after parsing to eliminate values that are no longer in program | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
356 void remove_useless_nodes(VectorSet &useful) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
357 _table.remove_useless_nodes(useful); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
358 // this may invalidate cached cons so reset the cache |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
359 init_con_caches(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
948
diff
changeset
|
360 } |
0 | 361 |
362 virtual ConNode* uncached_makecon(const Type* t); // override from PhaseTransform | |
363 | |
364 virtual const Type* saturate(const Type* new_type, const Type* old_type, | |
365 const Type* limit_type) const | |
366 { return new_type; } | |
367 | |
368 #ifndef PRODUCT | |
369 uint _count_new_values; // For profiling, count new values produced | |
370 void inc_new_values() { ++_count_new_values; } | |
371 void clear_new_values() { _count_new_values = 0; } | |
372 uint made_new_values() const { return _count_new_values; } | |
373 #endif | |
374 }; | |
375 | |
376 | |
377 //------------------------------PhaseGVN--------------------------------------- | |
378 // Phase for performing local, pessimistic GVN-style optimizations. | |
379 class PhaseGVN : public PhaseValues { | |
380 public: | |
381 PhaseGVN( Arena *arena, uint est_max_size ) : PhaseValues( arena, est_max_size ) {} | |
382 PhaseGVN( PhaseGVN *gvn ) : PhaseValues( gvn ) {} | |
383 PhaseGVN( PhaseGVN *gvn, const char *dummy ) : PhaseValues( gvn, dummy ) {} | |
384 | |
385 // Return a node which computes the same function as this node, but | |
386 // in a faster or cheaper fashion. | |
387 Node *transform( Node *n ); | |
388 Node *transform_no_reclaim( Node *n ); | |
389 | |
7473 | 390 void replace_with(PhaseGVN* gvn) { |
391 _table.replace_with(&gvn->_table); | |
392 _types = gvn->_types; | |
393 } | |
394 | |
0 | 395 // Check for a simple dead loop when a data node references itself. |
396 DEBUG_ONLY(void dead_loop_check(Node *n);) | |
397 }; | |
398 | |
399 //------------------------------PhaseIterGVN----------------------------------- | |
400 // Phase for iteratively performing local, pessimistic GVN-style optimizations. | |
401 // and ideal transformations on the graph. | |
402 class PhaseIterGVN : public PhaseGVN { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
403 private: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
404 bool _delay_transform; // When true simply register the node when calling transform |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
405 // instead of actually optimizing it |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
406 |
0 | 407 // Idealize old Node 'n' with respect to its inputs and its value |
408 virtual Node *transform_old( Node *a_node ); | |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
409 |
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
410 // Subsume users of node 'old' into node 'nn' |
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
411 void subsume_node( Node *old, Node *nn ); |
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
412 |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
6144
diff
changeset
|
413 Node_Stack _stack; // Stack used to avoid recursion |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
6144
diff
changeset
|
414 |
0 | 415 protected: |
416 | |
417 // Idealize new Node 'n' with respect to its inputs and its value | |
418 virtual Node *transform( Node *a_node ); | |
419 | |
420 // Warm up hash table, type table and initial worklist | |
421 void init_worklist( Node *a_root ); | |
422 | |
423 virtual const Type* saturate(const Type* new_type, const Type* old_type, | |
424 const Type* limit_type) const; | |
425 // Usually returns new_type. Returns old_type if new_type is only a slight | |
426 // improvement, such that it would take many (>>10) steps to reach 2**32. | |
427 | |
428 public: | |
429 PhaseIterGVN( PhaseIterGVN *igvn ); // Used by CCP constructor | |
430 PhaseIterGVN( PhaseGVN *gvn ); // Used after Parser | |
431 PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ); // Used after +VerifyOpto | |
432 | |
433 virtual PhaseIterGVN *is_IterGVN() { return this; } | |
434 | |
435 Unique_Node_List _worklist; // Iterative worklist | |
436 | |
437 // Given def-use info and an initial worklist, apply Node::Ideal, | |
438 // Node::Value, Node::Identity, hash-based value numbering, Node::Ideal_DU | |
439 // and dominator info to a fixed point. | |
440 void optimize(); | |
441 | |
442 // Register a new node with the iter GVN pass without transforming it. | |
443 // Used when we need to restructure a Region/Phi area and all the Regions | |
444 // and Phis need to complete this one big transform before any other | |
445 // transforms can be triggered on the region. | |
446 // Optional 'orig' is an earlier version of this node. | |
447 // It is significant only for debugging and profiling. | |
448 Node* register_new_node_with_optimizer(Node* n, Node* orig = NULL); | |
449 | |
6244
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
6144
diff
changeset
|
450 // Kill a globally dead Node. All uses are also globally dead and are |
611e8a669a2c
7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents:
6144
diff
changeset
|
451 // aggressively trimmed. |
0 | 452 void remove_globally_dead_node( Node *dead ); |
453 | |
454 // Kill all inputs to a dead node, recursively making more dead nodes. | |
455 // The Node must be dead locally, i.e., have no uses. | |
456 void remove_dead_node( Node *dead ) { | |
457 assert(dead->outcnt() == 0 && !dead->is_top(), "node must be dead"); | |
458 remove_globally_dead_node(dead); | |
459 } | |
460 | |
461 // Add users of 'n' to worklist | |
462 void add_users_to_worklist0( Node *n ); | |
463 void add_users_to_worklist ( Node *n ); | |
464 | |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
0
diff
changeset
|
465 // Replace old node with new one. |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
0
diff
changeset
|
466 void replace_node( Node *old, Node *nn ) { |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
0
diff
changeset
|
467 add_users_to_worklist(old); |
1621
6027dddc26c6
6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents:
1552
diff
changeset
|
468 hash_delete(old); // Yank from hash before hacking edges |
73
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
0
diff
changeset
|
469 subsume_node(old, nn); |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
0
diff
changeset
|
470 } |
a8880a78d355
6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents:
0
diff
changeset
|
471 |
6144
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
472 // Delayed node rehash: remove a node from the hash table and rehash it during |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
473 // next optimizing pass |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
474 void rehash_node_delayed(Node* n) { |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
475 hash_delete(n); |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
476 _worklist.push(n); |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
477 } |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
478 |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
479 // Replace ith edge of "n" with "in" |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
480 void replace_input_of(Node* n, int i, Node* in) { |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
481 rehash_node_delayed(n); |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
482 n->set_req(i, in); |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
483 } |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
484 |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
485 // Delete ith edge of "n" |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
486 void delete_input_of(Node* n, int i) { |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
487 rehash_node_delayed(n); |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
488 n->del_req(i); |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
489 } |
5e990493719e
7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents:
4778
diff
changeset
|
490 |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
196
diff
changeset
|
491 bool delay_transform() const { return _delay_transform; } |
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
196
diff
changeset
|
492 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
493 void set_delay_transform(bool delay) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
494 _delay_transform = delay; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
495 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
73
diff
changeset
|
496 |
2445 | 497 // Clone loop predicates. Defined in loopTransform.cpp. |
3345 | 498 Node* clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check); |
2445 | 499 // Create a new if below new_entry for the predicate to be cloned |
500 ProjNode* create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, | |
501 Deoptimization::DeoptReason reason); | |
502 | |
0 | 503 #ifndef PRODUCT |
504 protected: | |
505 // Sub-quadratic implementation of VerifyIterativeGVN. | |
6846 | 506 julong _verify_counter; |
507 julong _verify_full_passes; | |
0 | 508 enum { _verify_window_size = 30 }; |
509 Node* _verify_window[_verify_window_size]; | |
510 void verify_step(Node* n); | |
511 #endif | |
512 }; | |
513 | |
514 //------------------------------PhaseCCP--------------------------------------- | |
515 // Phase for performing global Conditional Constant Propagation. | |
516 // Should be replaced with combined CCP & GVN someday. | |
517 class PhaseCCP : public PhaseIterGVN { | |
518 // Non-recursive. Use analysis to transform single Node. | |
519 virtual Node *transform_once( Node *n ); | |
520 | |
521 public: | |
522 PhaseCCP( PhaseIterGVN *igvn ); // Compute conditional constants | |
523 NOT_PRODUCT( ~PhaseCCP(); ) | |
524 | |
525 // Worklist algorithm identifies constants | |
526 void analyze(); | |
527 // Recursive traversal of program. Used analysis to modify program. | |
528 virtual Node *transform( Node *n ); | |
529 // Do any transformation after analysis | |
530 void do_transform(); | |
531 | |
532 virtual const Type* saturate(const Type* new_type, const Type* old_type, | |
533 const Type* limit_type) const; | |
534 // Returns new_type->widen(old_type), which increments the widen bits until | |
535 // giving up with TypeInt::INT or TypeLong::LONG. | |
536 // Result is clipped to limit_type if necessary. | |
537 | |
538 #ifndef PRODUCT | |
539 static uint _total_invokes; // For profiling, count invocations | |
540 void inc_invokes() { ++PhaseCCP::_total_invokes; } | |
541 | |
542 static uint _total_constants; // For profiling, count constants found | |
543 uint _count_constants; | |
544 void clear_constants() { _count_constants = 0; } | |
545 void inc_constants() { ++_count_constants; } | |
546 uint count_constants() const { return _count_constants; } | |
547 | |
548 static void print_statistics(); | |
549 #endif | |
550 }; | |
551 | |
552 | |
553 //------------------------------PhasePeephole---------------------------------- | |
554 // Phase for performing peephole optimizations on register allocated basic blocks. | |
555 class PhasePeephole : public PhaseTransform { | |
556 PhaseRegAlloc *_regalloc; | |
557 PhaseCFG &_cfg; | |
558 // Recursive traversal of program. Pure function is unused in this phase | |
559 virtual Node *transform( Node *n ); | |
560 | |
561 public: | |
562 PhasePeephole( PhaseRegAlloc *regalloc, PhaseCFG &cfg ); | |
563 NOT_PRODUCT( ~PhasePeephole(); ) | |
564 | |
565 // Do any transformation after analysis | |
566 void do_transform(); | |
567 | |
568 #ifndef PRODUCT | |
569 static uint _total_peepholes; // For profiling, count peephole rules applied | |
570 uint _count_peepholes; | |
571 void clear_peepholes() { _count_peepholes = 0; } | |
572 void inc_peepholes() { ++_count_peepholes; } | |
573 uint count_peepholes() const { return _count_peepholes; } | |
574 | |
575 static void print_statistics(); | |
576 #endif | |
577 }; | |
1972 | 578 |
579 #endif // SHARE_VM_OPTO_PHASEX_HPP |