--- old/src/share/vm/opto/live.cpp 2015-09-10 19:30:37.058466800 -0700 +++ new/src/share/vm/opto/live.cpp 2015-09-10 19:30:36.819442900 -0700 @@ -41,7 +41,14 @@ // block is put on the worklist. // The locally live-in stuff is computed once and added to predecessor // live-out sets. This separate compilation is done in the outer loop below. -PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) { +PhaseLive::PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena, bool keep_deltas) + : Phase(LIVE), + _cfg(cfg), + _names(names), + _arena(arena), + _live(0), + _livein(0), + _keep_deltas(keep_deltas) { } void PhaseLive::compute(uint maxlrg) { @@ -56,6 +63,13 @@ _live[i].initialize(_maxlrg); } + if (_keep_deltas) { + _livein = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks()); + for (i = 0; i < _cfg.number_of_blocks(); i++) { + _livein[i].initialize(_maxlrg); + } + } + // Init the sparse arrays for delta-sets. ResourceMark rm; // Nuke temp storage on exit @@ -124,7 +138,10 @@ // PhiNode uses go in the live-out set of prior blocks. for (uint k = i; k > 0; k--) { - add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass); + Node *phi = block->get_node(k - 1); + if (l < phi->req()) { + add_liveout(p, _names.at(phi->in(l)->_idx), first_pass); + } } } freeset(block); @@ -200,8 +217,11 @@ } // Free an IndexSet from a block. -void PhaseLive::freeset( const Block *p ) { +void PhaseLive::freeset( Block *p ) { IndexSet *f = _deltas[p->_pre_order-1]; + if ( _keep_deltas ) { + add_livein(p, f); + } f->set_next(_free_IndexSet); _free_IndexSet = f; // Drop onto free list _deltas[p->_pre_order-1] = NULL; @@ -249,10 +269,23 @@ } } +// Add a vector of live-in values to a given blocks live-in set. +void PhaseLive::add_livein(Block *p, IndexSet *lo) { + IndexSet *livein = &_livein[p->_pre_order-1]; + IndexSetIterator elements(lo); + uint r; + while ((r = elements.next()) != 0) { + livein->insert(r); // Then add to live-in set + } +} + #ifndef PRODUCT // Dump the live-out set for a block void PhaseLive::dump( const Block *b ) const { tty->print("Block %d: ",b->_pre_order); + if ( _keep_deltas ) { + tty->print("LiveIn: "); _livein[b->_pre_order-1].dump(); + } tty->print("LiveOut: "); _live[b->_pre_order-1].dump(); uint cnt = b->number_of_nodes(); for( uint i=0; i