Tue, 02 Dec 2014 12:08:41 -0800
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
src/share/vm/opto/ifg.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/ifg.cpp Tue Dec 02 18:09:39 2014 +0000 1.2 +++ b/src/share/vm/opto/ifg.cpp Tue Dec 02 12:08:41 2014 -0800 1.3 @@ -541,6 +541,22 @@ 1.4 if( !n->is_Proj() || 1.5 // Could also be a flags-projection of a dead ADD or such. 1.6 (_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) { 1.7 + if (n->is_MachProj()) { 1.8 + // Don't remove KILL projections if their "defining" nodes have 1.9 + // memory effects (have SCMemProj projection node) - 1.10 + // they are not dead even when their result is not used. 1.11 + // For example, compareAndSwapL (and other CAS) and EncodeISOArray nodes. 1.12 + // The method add_input_to_liveout() keeps such nodes alive (put them on liveout list) 1.13 + // when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed 1.14 + // in block in such order that KILL MachProj nodes are processed first. 1.15 + uint cnt = def->outcnt(); 1.16 + for (uint i = 0; i < cnt; i++) { 1.17 + Node* proj = def->raw_out(i); 1.18 + if (proj->Opcode() == Op_SCMemProj) { 1.19 + return false; 1.20 + } 1.21 + } 1.22 + } 1.23 block->remove_node(j - 1); 1.24 if (lrgs(r)._def == n) { 1.25 lrgs(r)._def = 0;