@@ -540,6 +540,28 @@ static Block* memory_early_block(Node* load, Block* early, const PhaseCFG* cfg)
540540 return early;
541541}
542542
543+ // This function is used by insert_anti_dependences to find unrelated loads for stores in implicit null checks.
544+ bool PhaseCFG::unrelated_load_in_store_null_block (Node* store, Node* load) {
545+ // We expect an anti-dependence edge from 'load' to 'store', except when
546+ // implicit_null_check() has hoisted 'store' above its early block to
547+ // perform an implicit null check, and 'load' is placed in the null
548+ // block. In this case it is safe to ignore the anti-dependence, as the
549+ // null block is only reached if 'store' tries to write to null object and
550+ // 'load' read from non-null object (there is preceding check for that)
551+ // These objects can't be the same.
552+ Block* store_block = get_block_for_node (store);
553+ Block* load_block = get_block_for_node (load);
554+ Node* end = store_block->end ();
555+ if (end->is_MachNullCheck () && (end->in (1 ) == store) && store_block->dominates (load_block)) {
556+ Node* if_true = end->find_out_with (Op_IfTrue);
557+ assert (if_true != NULL , " null check without null projection" );
558+ Node* null_block_region = if_true->find_out_with (Op_Region);
559+ assert (null_block_region != NULL , " null check without null region" );
560+ return get_block_for_node (null_block_region) == load_block;
561+ }
562+ return false ;
563+ }
564+
543565// --------------------------insert_anti_dependences---------------------------
544566// A load may need to witness memory that nearby stores can overwrite.
545567// For each nearby store, either insert an "anti-dependence" edge
@@ -793,7 +815,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
793815 // will find him on the non_early_stores list and stick him
794816 // with a precedence edge.
795817 // (But, don't bother if LCA is already raised all the way.)
796- if (LCA != early) {
818+ if (LCA != early && ! unrelated_load_in_store_null_block (store, load) ) {
797819 store_block->set_raise_LCA_mark (load_index);
798820 must_raise_LCA = true ;
799821 non_early_stores.push (store);
@@ -804,23 +826,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
804826 // Add an anti-dep edge, and squeeze 'load' into the highest block.
805827 assert (store != load->find_exact_control (load->in (0 )), " dependence cycle found" );
806828 if (verify) {
807- #ifdef ASSERT
808- // We expect an anti-dependence edge from 'load' to 'store', except when
809- // implicit_null_check() has hoisted 'store' above its early block to
810- // perform an implicit null check, and 'load' is placed in the null
811- // block. In this case it is safe to ignore the anti-dependence, as the
812- // null block is only reached if 'store' tries to write to null.
813- Block* store_null_block = NULL ;
814- Node* store_null_check = store->find_out_with (Op_MachNullCheck);
815- if (store_null_check != NULL ) {
816- Node* if_true = store_null_check->find_out_with (Op_IfTrue);
817- assert (if_true != NULL , " null check without null projection" );
818- Node* null_block_region = if_true->find_out_with (Op_Region);
819- assert (null_block_region != NULL , " null check without null region" );
820- store_null_block = get_block_for_node (null_block_region);
821- }
822- #endif
823- assert (LCA == store_null_block || store->find_edge (load) != -1 ,
829+ assert (store->find_edge (load) != -1 || unrelated_load_in_store_null_block (store, load),
824830 " missing precedence edge" );
825831 } else {
826832 store->add_prec (load);
0 commit comments