src/share/vm/opto/ifg.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 8065618_7u Sdiff src/share/vm/opto

src/share/vm/opto/ifg.cpp

Print this page
rev 5451 : 8065618: C2 RA incorrectly removes kill projections
Summary: Don't remove KILL projections if their "defining" nodes have SCMemProj projection (memory side effects).
Reviewed-by: iveresov, roland
rev 5452 : 8066649: 8u backport for 8065618 is incorrect
Summary: The new code in 8u backport should guard the execution of the following code instead of return.
Reviewed-by: iveresov


 554     uint j;
 555     for( j = last_inst + 1; j > 1; j-- ) {
 556       Node *n = b->_nodes[j - 1];
 557 
 558       // Get value being defined
 559       uint r = n2lidx(n);
 560 
 561       // Some special values do not allocate
 562       if( r ) {
 563         // A DEF normally costs block frequency; rematerialized values are
 564         // removed from the DEF sight, so LOWER costs here.
 565         lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq;
 566 
 567         // If it is not live, then this instruction is dead.  Probably caused
 568         // by spilling and rematerialization.  Who cares why, yank this baby.
 569         if( !liveout.member(r) && n->Opcode() != Op_SafePoint ) {
 570           Node *def = n->in(0);
 571           if( !n->is_Proj() ||
 572               // Could also be a flags-projection of a dead ADD or such.
 573               (n2lidx(def) && !liveout.member(n2lidx(def)) ) ) {



















 574             b->_nodes.remove(j - 1);
 575             if( lrgs(r)._def == n ) lrgs(r)._def = 0;
 576             n->disconnect_inputs(NULL, C);
 577             _cfg._bbs.map(n->_idx,NULL);
 578             n->replace_by(C->top());
 579             // Since yanking a Node from block, high pressure moves up one
 580             hrp_index[0]--;
 581             hrp_index[1]--;
 582             continue;
 583           }

 584 
 585           // Fat-projections kill many registers which cannot be used to
 586           // hold live ranges.
 587           if( lrgs(r)._fat_proj ) {
 588             // Count the int-only registers
 589             RegMask itmp = lrgs(r).mask();
 590             itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
 591             int iregs = itmp.Size();
 592 #ifdef EXACT_PRESSURE
 593             if( pressure[0]+iregs > b->_reg_pressure )
 594               b->_reg_pressure = pressure[0]+iregs;
 595 #endif
 596             if( pressure[0]       <= (uint)INTPRESSURE &&
 597                 pressure[0]+iregs >  (uint)INTPRESSURE ) {
 598 #ifndef EXACT_PRESSURE
 599               b->_reg_pressure = (uint)INTPRESSURE+1;
 600 #endif
 601               hrp_index[0] = j-1;
 602             }
 603             // Count the float-only registers




 554     uint j;
 555     for( j = last_inst + 1; j > 1; j-- ) {
 556       Node *n = b->_nodes[j - 1];
 557 
 558       // Get value being defined
 559       uint r = n2lidx(n);
 560 
 561       // Some special values do not allocate
 562       if( r ) {
 563         // A DEF normally costs block frequency; rematerialized values are
 564         // removed from the DEF sight, so LOWER costs here.
 565         lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq;
 566 
 567         // If it is not live, then this instruction is dead.  Probably caused
 568         // by spilling and rematerialization.  Who cares why, yank this baby.
 569         if( !liveout.member(r) && n->Opcode() != Op_SafePoint ) {
 570           Node *def = n->in(0);
 571           if( !n->is_Proj() ||
 572               // Could also be a flags-projection of a dead ADD or such.
 573               (n2lidx(def) && !liveout.member(n2lidx(def)) ) ) {
 574             bool remove = true;
 575             if (n->is_MachProj()) {
 576               // Don't remove KILL projections if their "defining" nodes have
 577               // memory effects (have SCMemProj projection node) -
 578               // they are not dead even when their result is not used.
 579               // For example, compareAndSwapL (and other CAS) and EncodeISOArray nodes.
 580               // The method add_input_to_liveout() keeps such nodes alive (put them on liveout list)
 581               // when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed
 582               // in block in such order that KILL MachProj nodes are processed first.
 583               uint cnt = def->outcnt();
 584               for (uint i = 0; i < cnt; i++) {
 585                 Node* proj = def->raw_out(i);
 586                 if (proj->Opcode() == Op_SCMemProj) {
 587                   remove = false;
 588                   break;
 589                 }
 590               }
 591             }
 592             if (remove) {
 593               b->_nodes.remove(j - 1);
 594               if( lrgs(r)._def == n ) lrgs(r)._def = 0;
 595               n->disconnect_inputs(NULL, C);
 596               _cfg._bbs.map(n->_idx,NULL);
 597               n->replace_by(C->top());
 598               // Since yanking a Node from block, high pressure moves up one
 599               hrp_index[0]--;
 600               hrp_index[1]--;
 601               continue;
 602             }
 603           }
 604 
 605           // Fat-projections kill many registers which cannot be used to
 606           // hold live ranges.
 607           if( lrgs(r)._fat_proj ) {
 608             // Count the int-only registers
 609             RegMask itmp = lrgs(r).mask();
 610             itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
 611             int iregs = itmp.Size();
 612 #ifdef EXACT_PRESSURE
 613             if( pressure[0]+iregs > b->_reg_pressure )
 614               b->_reg_pressure = pressure[0]+iregs;
 615 #endif
 616             if( pressure[0]       <= (uint)INTPRESSURE &&
 617                 pressure[0]+iregs >  (uint)INTPRESSURE ) {
 618 #ifndef EXACT_PRESSURE
 619               b->_reg_pressure = (uint)INTPRESSURE+1;
 620 #endif
 621               hrp_index[0] = j-1;
 622             }
 623             // Count the float-only registers


src/share/vm/opto/ifg.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File