//------------------------------compute_separating_interferences--------------- // Factored code from copy_copy that computes extra interferences from // lengthening a live range by double-coalescing. uint PhaseConservativeCoalesce::compute_separating_interferences(Node *dst_copy, Node *src_copy, Block *b, uint bindex, RegMask &rm, uint reg_degree, uint rm_size, uint lr1, uint lr2 ) { assert(!lrgs(lr1)._fat_proj, "cannot coalesce fat_proj"); assert(!lrgs(lr2)._fat_proj, "cannot coalesce fat_proj"); Node *prev_copy = dst_copy->in(dst_copy->is_Copy()); Block *b2 = b; uint bindex2 = bindex; while( 1 ) { // Find previous instruction bindex2--; // Chain backwards 1 instruction while( bindex2 == 0 ) { // At block start, find prior block assert( b2->num_preds() == 2, "cannot double coalesce across c-flow" ); b2 = _phc._cfg._bbs[b2->pred(1)->_idx]; bindex2 = b2->end_idx()-1; } // Get prior instruction assert(bindex2 < b2->_nodes.size(), "index out of bounds"); Node *x = b2->_nodes[bindex2]; if( x == prev_copy ) { // Previous copy in copy chain? if( prev_copy == src_copy)// Found end of chain and all interferences break; // So break out of loop // Else work back one in copy chain prev_copy = prev_copy->in(prev_copy->is_Copy()); } else { // Else collect interferences uint lidx = _phc.Find(x); // Found another def of live-range being stretched? if( lidx == lr1 ) return max_juint; if( lidx == lr2 ) return max_juint; // If we attempt to coalesce across a bound def if( lrgs(lidx).is_bound() ) { // Do not let the coalesced LRG expect to get the bound color rm.SUBTRACT( lrgs(lidx).mask() ); // Recompute rm_size rm_size = rm.Size(); //if( rm._flags ) rm_size += 1000000; if( reg_degree >= rm_size ) return max_juint; } if( rm.overlap(lrgs(lidx).mask()) ) { // Insert lidx into union LRG; returns TRUE if actually inserted if( _ulr.insert(lidx) ) { // Infinite-stack neighbors do not alter colorability, as they // can always color to some other color. if( !lrgs(lidx).mask().is_AllStack() ) { // If this coalesce will make any new neighbor uncolorable, // do not coalesce. if( lrgs(lidx).just_lo_degree() ) return max_juint; // Bump our degree if( ++reg_degree >= rm_size ) return max_juint; } // End of if not infinite-stack neighbor } // End of if actually inserted } // End of if live range overlaps } // End of else collect interferences for 1 node } // End of while forever, scan back for interferences return reg_degree; }
uint IndexSet::lrg_union(uint lr1, uint lr2, const uint fail_degree, const PhaseIFG *ifg, const RegMask &mask ) { IndexSet *one = ifg->neighbors(lr1); IndexSet *two = ifg->neighbors(lr2); LRG &lrg1 = ifg->lrgs(lr1); LRG &lrg2 = ifg->lrgs(lr2); #ifdef ASSERT assert(_max_elements == one->_max_elements, "max element mismatch"); check_watch("union destination"); one->check_watch("union source"); two->check_watch("union source"); #endif // Compute the degree of the combined live-range. The combined // live-range has the union of the original live-ranges' neighbors set as // well as the neighbors of all intermediate copies, minus those neighbors // that can not use the intersected allowed-register-set. // Copy the larger set. Insert the smaller set into the larger. if (two->count() > one->count()) { IndexSet *temp = one; one = two; two = temp; } clear(); // Used to compute degree of register-only interferences. Infinite-stack // neighbors do not alter colorability, as they can always color to some // other color. (A variant of the Briggs assertion) uint reg_degree = 0; uint element; // Load up the combined interference set with the neighbors of one IndexSetIterator elements(one); while ((element = elements.next()) != 0) { LRG &lrg = ifg->lrgs(element); if (mask.overlap(lrg.mask())) { insert(element); if( !lrg.mask().is_AllStack() ) { reg_degree += lrg1.compute_degree(lrg); if( reg_degree >= fail_degree ) return reg_degree; } else { // !!!!! Danger! No update to reg_degree despite having a neighbor. // A variant of the Briggs assertion. // Not needed if I simplify during coalesce, ala George/Appel. assert( lrg.lo_degree(), "" ); } } } // Add neighbors of two as well IndexSetIterator elements2(two); while ((element = elements2.next()) != 0) { LRG &lrg = ifg->lrgs(element); if (mask.overlap(lrg.mask())) { if (insert(element)) { if( !lrg.mask().is_AllStack() ) { reg_degree += lrg2.compute_degree(lrg); if( reg_degree >= fail_degree ) return reg_degree; } else { // !!!!! Danger! No update to reg_degree despite having a neighbor. // A variant of the Briggs assertion. // Not needed if I simplify during coalesce, ala George/Appel. assert( lrg.lo_degree(), "" ); } } } } return reg_degree; }