189 } |
189 } |
190 #endif |
190 #endif |
191 |
191 |
192 // Get an IndexSet for a block. Return existing one, if any. Make a new |
192 // Get an IndexSet for a block. Return existing one, if any. Make a new |
193 // empty one if a prior one does not exist. |
193 // empty one if a prior one does not exist. |
194 IndexSet *PhaseLive::getset( Block *p ) { |
194 IndexSet *PhaseLive::getset(Block *p) { |
195 IndexSet *delta = _deltas[p->_pre_order-1]; |
195 IndexSet *delta = _deltas[p->_pre_order-1]; |
196 if( !delta ) // Not on worklist? |
196 if (!delta) { // Not on worklist? |
197 // Get a free set; flag as being on worklist |
197 // Get a free set; flag as being on worklist |
198 delta = _deltas[p->_pre_order-1] = getfreeset(); |
198 delta = _deltas[p->_pre_order-1] = getfreeset(); |
|
199 } |
199 return delta; // Return set of new live-out items |
200 return delta; // Return set of new live-out items |
200 } |
201 } |
201 |
202 |
202 // Pull from free list, or allocate. Internal allocation on the returned set |
203 // Pull from free list, or allocate. Internal allocation on the returned set |
203 // is always from thread local storage. |
204 // is always from thread local storage. |
204 IndexSet *PhaseLive::getfreeset( ) { |
205 IndexSet *PhaseLive::getfreeset() { |
205 IndexSet *f = _free_IndexSet; |
206 IndexSet *f = _free_IndexSet; |
206 if( !f ) { |
207 if (!f) { |
207 f = new IndexSet; |
208 f = new IndexSet; |
208 // f->set_arena(Thread::current()->resource_area()); |
|
209 f->initialize(_maxlrg, Thread::current()->resource_area()); |
209 f->initialize(_maxlrg, Thread::current()->resource_area()); |
210 } else { |
210 } else { |
211 // Pull from free list |
211 // Pull from free list |
212 _free_IndexSet = f->next(); |
212 _free_IndexSet = f->next(); |
213 //f->_cnt = 0; // Reset to empty |
|
214 // f->set_arena(Thread::current()->resource_area()); |
|
215 f->initialize(_maxlrg, Thread::current()->resource_area()); |
213 f->initialize(_maxlrg, Thread::current()->resource_area()); |
216 } |
214 } |
217 return f; |
215 return f; |
218 } |
216 } |
219 |
217 |
220 // Free an IndexSet from a block. |
218 // Free an IndexSet from a block. |
221 void PhaseLive::freeset( Block *p ) { |
219 void PhaseLive::freeset(Block *p) { |
222 IndexSet *f = _deltas[p->_pre_order-1]; |
220 IndexSet *f = _deltas[p->_pre_order-1]; |
223 if ( _keep_deltas ) { |
221 if (_keep_deltas) { |
224 add_livein(p, f); |
222 add_livein(p, f); |
225 } |
223 } |
226 f->set_next(_free_IndexSet); |
224 f->set_next(_free_IndexSet); |
227 _free_IndexSet = f; // Drop onto free list |
225 _free_IndexSet = f; // Drop onto free list |
228 _deltas[p->_pre_order-1] = NULL; |
226 _deltas[p->_pre_order-1] = NULL; |
229 } |
227 } |
230 |
228 |
231 // Add a live-out value to a given blocks live-out set. If it is new, then |
229 // Add a live-out value to a given blocks live-out set. If it is new, then |
232 // also add it to the delta set and stick the block on the worklist. |
230 // also add it to the delta set and stick the block on the worklist. |
233 void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) { |
231 void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) { |
234 IndexSet *live = &_live[p->_pre_order-1]; |
232 IndexSet *live = &_live[p->_pre_order-1]; |
235 if( live->insert(r) ) { // If actually inserted... |
233 if (live->insert(r)) { // If actually inserted... |
236 // We extended the live-out set. See if the value is generated locally. |
234 // We extended the live-out set. See if the value is generated locally. |
237 // If it is not, then we must extend the live-in set. |
235 // If it is not, then we must extend the live-in set. |
238 if( !_defs[p->_pre_order-1].member( r ) ) { |
236 if (!_defs[p->_pre_order-1].member(r)) { |
239 if( !_deltas[p->_pre_order-1] && // Not on worklist? |
237 if (!_deltas[p->_pre_order-1] && // Not on worklist? |
240 first_pass.test(p->_pre_order) ) |
238 first_pass.test(p->_pre_order)) { |
241 _worklist->push(p); // Actually go on worklist if already 1st pass |
239 _worklist->push(p); // Actually go on worklist if already 1st pass |
|
240 } |
242 getset(p)->insert(r); |
241 getset(p)->insert(r); |
243 } |
242 } |
244 } |
243 } |
245 } |
244 } |
246 |
245 |
247 // Add a vector of live-out values to a given blocks live-out set. |
246 // Add a vector of live-out values to a given blocks live-out set. |
248 void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) { |
247 void PhaseLive::add_liveout(Block *p, IndexSet *lo, VectorSet &first_pass) { |
249 IndexSet *live = &_live[p->_pre_order-1]; |
248 IndexSet *live = &_live[p->_pre_order-1]; |
250 IndexSet *defs = &_defs[p->_pre_order-1]; |
249 IndexSet *defs = &_defs[p->_pre_order-1]; |
251 IndexSet *on_worklist = _deltas[p->_pre_order-1]; |
250 IndexSet *on_worklist = _deltas[p->_pre_order-1]; |
252 IndexSet *delta = on_worklist ? on_worklist : getfreeset(); |
251 IndexSet *delta = on_worklist ? on_worklist : getfreeset(); |
253 |
252 |
254 IndexSetIterator elements(lo); |
253 if (!lo->is_empty()) { |
255 uint r; |
254 IndexSetIterator elements(lo); |
256 while ((r = elements.next()) != 0) { |
255 uint r; |
257 if( live->insert(r) && // If actually inserted... |
256 while ((r = elements.next()) != 0) { |
258 !defs->member( r ) ) // and not defined locally |
257 if (live->insert(r) && // If actually inserted... |
259 delta->insert(r); // Then add to live-in set |
258 !defs->member(r)) { // and not defined locally |
260 } |
259 delta->insert(r); // Then add to live-in set |
261 |
260 } |
262 if( delta->count() ) { // If actually added things |
261 } |
|
262 } |
|
263 |
|
264 if (delta->count()) { // If actually added things |
263 _deltas[p->_pre_order-1] = delta; // Flag as on worklist now |
265 _deltas[p->_pre_order-1] = delta; // Flag as on worklist now |
264 if( !on_worklist && // Not on worklist? |
266 if (!on_worklist && // Not on worklist? |
265 first_pass.test(p->_pre_order) ) |
267 first_pass.test(p->_pre_order)) { |
266 _worklist->push(p); // Actually go on worklist if already 1st pass |
268 _worklist->push(p); // Actually go on worklist if already 1st pass |
|
269 } |
267 } else { // Nothing there; just free it |
270 } else { // Nothing there; just free it |
268 delta->set_next(_free_IndexSet); |
271 delta->set_next(_free_IndexSet); |
269 _free_IndexSet = delta; // Drop onto free list |
272 _free_IndexSet = delta; // Drop onto free list |
270 } |
273 } |
271 } |
274 } |
272 |
275 |
273 // Add a vector of live-in values to a given blocks live-in set. |
276 // Add a vector of live-in values to a given blocks live-in set. |
274 void PhaseLive::add_livein(Block *p, IndexSet *lo) { |
277 void PhaseLive::add_livein(Block *p, IndexSet *lo) { |
275 IndexSet *livein = &_livein[p->_pre_order-1]; |
278 IndexSet *livein = &_livein[p->_pre_order-1]; |
276 IndexSetIterator elements(lo); |
279 if (!livein->is_empty()) { |
277 uint r; |
280 IndexSetIterator elements(lo); |
278 while ((r = elements.next()) != 0) { |
281 uint r; |
279 livein->insert(r); // Then add to live-in set |
282 while ((r = elements.next()) != 0) { |
|
283 livein->insert(r); // Then add to live-in set |
|
284 } |
280 } |
285 } |
281 } |
286 } |
282 |
287 |
283 #ifndef PRODUCT |
288 #ifndef PRODUCT |
284 // Dump the live-out set for a block |
289 // Dump the live-out set for a block |
285 void PhaseLive::dump( const Block *b ) const { |
290 void PhaseLive::dump(const Block *b) const { |
286 tty->print("Block %d: ",b->_pre_order); |
291 tty->print("Block %d: ",b->_pre_order); |
287 if ( _keep_deltas ) { |
292 if (_keep_deltas) { |
288 tty->print("LiveIn: "); _livein[b->_pre_order-1].dump(); |
293 tty->print("LiveIn: "); _livein[b->_pre_order-1].dump(); |
289 } |
294 } |
290 tty->print("LiveOut: "); _live[b->_pre_order-1].dump(); |
295 tty->print("LiveOut: "); _live[b->_pre_order-1].dump(); |
291 uint cnt = b->number_of_nodes(); |
296 uint cnt = b->number_of_nodes(); |
292 for( uint i=0; i<cnt; i++ ) { |
297 for (uint i = 0; i < cnt; i++) { |
293 tty->print("L%d/", _names.at(b->get_node(i)->_idx)); |
298 tty->print("L%d/", _names.at(b->get_node(i)->_idx)); |
294 b->get_node(i)->dump(); |
299 b->get_node(i)->dump(); |
295 } |
300 } |
296 tty->print("\n"); |
301 tty->print("\n"); |
297 } |
302 } |
298 |
303 |
299 // Verify that base pointers and derived pointers are still sane. |
304 // Verify that base pointers and derived pointers are still sane. |
300 void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const { |
305 void PhaseChaitin::verify_base_ptrs(ResourceArea *a) const { |
301 #ifdef ASSERT |
306 #ifdef ASSERT |
302 Unique_Node_List worklist(a); |
307 Unique_Node_List worklist(a); |
303 for (uint i = 0; i < _cfg.number_of_blocks(); i++) { |
308 for (uint i = 0; i < _cfg.number_of_blocks(); i++) { |
304 Block* block = _cfg.get_block(i); |
309 Block* block = _cfg.get_block(i); |
305 for (uint j = block->end_idx() + 1; j > 1; j--) { |
310 for (uint j = block->end_idx() + 1; j > 1; j--) { |
320 bool is_derived = ((idx - jvms->oopoff()) & 1) == 0; |
325 bool is_derived = ((idx - jvms->oopoff()) & 1) == 0; |
321 // search upwards through spills and spill phis for AddP |
326 // search upwards through spills and spill phis for AddP |
322 worklist.clear(); |
327 worklist.clear(); |
323 worklist.push(check); |
328 worklist.push(check); |
324 uint k = 0; |
329 uint k = 0; |
325 while( k < worklist.size() ) { |
330 while (k < worklist.size()) { |
326 check = worklist.at(k); |
331 check = worklist.at(k); |
327 assert(check,"Bad base or derived pointer"); |
332 assert(check,"Bad base or derived pointer"); |
328 // See PhaseChaitin::find_base_for_derived() for all cases. |
333 // See PhaseChaitin::find_base_for_derived() for all cases. |
329 int isc = check->is_Copy(); |
334 int isc = check->is_Copy(); |
330 if( isc ) { |
335 if (isc) { |
331 worklist.push(check->in(isc)); |
336 worklist.push(check->in(isc)); |
332 } else if( check->is_Phi() ) { |
337 } else if (check->is_Phi()) { |
333 for (uint m = 1; m < check->req(); m++) |
338 for (uint m = 1; m < check->req(); m++) |
334 worklist.push(check->in(m)); |
339 worklist.push(check->in(m)); |
335 } else if( check->is_Con() ) { |
340 } else if (check->is_Con()) { |
336 if (is_derived) { |
341 if (is_derived) { |
337 // Derived is NULL+offset |
342 // Derived is NULL+offset |
338 assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer"); |
343 assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer"); |
339 } else { |
344 } else { |
340 assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer"); |
345 assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer"); |