annotate src/share/vm/opto/phaseX.cpp @ 1721:413ad0331a0c

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