@@ -639,6 +639,34 @@ void ShenandoahBarrierC2Support::verify(RootNode* root) {
639639}
640640#endif
641641
642+ bool ShenandoahBarrierC2Support::is_anti_dependent_load_at_control (PhaseIdealLoop* phase, Node* maybe_load, Node* store,
643+ Node* control) {
644+ return maybe_load->is_Load () && phase->C ->can_alias (store->adr_type (), phase->C ->get_alias_index (maybe_load->adr_type ())) &&
645+ phase->ctrl_or_self (maybe_load) == control;
646+ }
647+
648+ void ShenandoahBarrierC2Support::maybe_push_anti_dependent_loads (PhaseIdealLoop* phase, Node* maybe_store, Node* control, Unique_Node_List &wq) {
649+ if (!maybe_store->is_Store () && !maybe_store->is_LoadStore ()) {
650+ return ;
651+ }
652+ Node* mem = maybe_store->in (MemNode::Memory);
653+ for (DUIterator_Fast imax, i = mem->fast_outs (imax); i < imax; i++) {
654+ Node* u = mem->fast_out (i);
655+ if (is_anti_dependent_load_at_control (phase, u, maybe_store, control)) {
656+ wq.push (u);
657+ }
658+ }
659+ }
660+
661+ void ShenandoahBarrierC2Support::push_data_inputs_at_control (PhaseIdealLoop* phase, Node* n, Node* ctrl, Unique_Node_List &wq) {
662+ for (uint i = 0 ; i < n->req (); i++) {
663+ Node* in = n->in (i);
664+ if (in != nullptr && (ShenandoahIUBarrier ? (phase->ctrl_or_self (in) == ctrl) : (phase->has_ctrl (in) && phase->get_ctrl (in) == ctrl))) {
665+ wq.push (in);
666+ }
667+ }
668+ }
669+
642670bool ShenandoahBarrierC2Support::is_dominator_same_ctrl (Node* c, Node* d, Node* n, PhaseIdealLoop* phase) {
643671 // That both nodes have the same control is not sufficient to prove
644672 // domination, verify that there's no path from d to n
@@ -653,22 +681,9 @@ bool ShenandoahBarrierC2Support::is_dominator_same_ctrl(Node* c, Node* d, Node*
653681 if (m->is_Phi () && m->in (0 )->is_Loop ()) {
654682 assert (phase->ctrl_or_self (m->in (LoopNode::EntryControl)) != c, " following loop entry should lead to new control" );
655683 } else {
656- if (m->is_Store () || m->is_LoadStore ()) {
657- // Take anti-dependencies into account
658- Node* mem = m->in (MemNode::Memory);
659- for (DUIterator_Fast imax, i = mem->fast_outs (imax); i < imax; i++) {
660- Node* u = mem->fast_out (i);
661- if (u->is_Load () && phase->C ->can_alias (m->adr_type (), phase->C ->get_alias_index (u->adr_type ())) &&
662- phase->ctrl_or_self (u) == c) {
663- wq.push (u);
664- }
665- }
666- }
667- for (uint i = 0 ; i < m->req (); i++) {
668- if (m->in (i) != NULL && phase->ctrl_or_self (m->in (i)) == c) {
669- wq.push (m->in (i));
670- }
671- }
684+ // Take anti-dependencies into account
685+ maybe_push_anti_dependent_loads (phase, m, c, wq);
686+ push_data_inputs_at_control (phase, m, c, wq);
672687 }
673688 }
674689 return true ;
@@ -1020,7 +1035,20 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo
10201035 phase->register_new_node (val, ctrl);
10211036}
10221037
1023- void ShenandoahBarrierC2Support::fix_ctrl (Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase) {
1038+ void ShenandoahBarrierC2Support::collect_nodes_above_barrier (Unique_Node_List &nodes_above_barrier, PhaseIdealLoop* phase, Node* ctrl, Node* init_raw_mem) {
1039+ nodes_above_barrier.clear ();
1040+ if (phase->has_ctrl (init_raw_mem) && phase->get_ctrl (init_raw_mem) == ctrl && !init_raw_mem->is_Phi ()) {
1041+ nodes_above_barrier.push (init_raw_mem);
1042+ }
1043+ for (uint next = 0 ; next < nodes_above_barrier.size (); next++) {
1044+ Node* n = nodes_above_barrier.at (next);
1045+ // Take anti-dependencies into account
1046+ maybe_push_anti_dependent_loads (phase, n, ctrl, nodes_above_barrier);
1047+ push_data_inputs_at_control (phase, n, ctrl, nodes_above_barrier);
1048+ }
1049+ }
1050+
1051+ void ShenandoahBarrierC2Support::fix_ctrl (Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& nodes_above_barrier, uint last, PhaseIdealLoop* phase) {
10241052 Node* ctrl = phase->get_ctrl (barrier);
10251053 Node* init_raw_mem = fixer.find_mem (ctrl, barrier);
10261054
@@ -1031,30 +1059,17 @@ void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const Mem
10311059 // control will be after the expanded barrier. The raw memory (if
10321060 // its memory is control dependent on the barrier's input control)
10331061 // must stay above the barrier.
1034- uses_to_ignore.clear ();
1035- if (phase->has_ctrl (init_raw_mem) && phase->get_ctrl (init_raw_mem) == ctrl && !init_raw_mem->is_Phi ()) {
1036- uses_to_ignore.push (init_raw_mem);
1037- }
1038- for (uint next = 0 ; next < uses_to_ignore.size (); next++) {
1039- Node *n = uses_to_ignore.at (next);
1040- for (uint i = 0 ; i < n->req (); i++) {
1041- Node* in = n->in (i);
1042- if (in != NULL && phase->has_ctrl (in) && phase->get_ctrl (in) == ctrl) {
1043- uses_to_ignore.push (in);
1044- }
1045- }
1046- }
1062+ collect_nodes_above_barrier (nodes_above_barrier, phase, ctrl, init_raw_mem);
10471063 for (DUIterator_Fast imax, i = ctrl->fast_outs (imax); i < imax; i++) {
10481064 Node* u = ctrl->fast_out (i);
10491065 if (u->_idx < last &&
10501066 u != barrier &&
10511067 !u->depends_only_on_test () && // preserve dependency on test
1052- !uses_to_ignore .member (u) &&
1068+ !nodes_above_barrier .member (u) &&
10531069 (u->in (0 ) != ctrl || (!u->is_Region () && !u->is_Phi ())) &&
10541070 (ctrl->Opcode () != Op_CatchProj || u->Opcode () != Op_CreateEx)) {
10551071 Node* old_c = phase->ctrl_or_self (u);
1056- Node* c = old_c;
1057- if (c != ctrl ||
1072+ if (old_c != ctrl ||
10581073 is_dominator_same_ctrl (old_c, barrier, u, phase) ||
10591074 ShenandoahBarrierSetC2::is_shenandoah_state_load (u)) {
10601075 phase->igvn ().rehash_node_delayed (u);
@@ -1326,7 +1341,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
13261341
13271342 // Expand load-reference-barriers
13281343 MemoryGraphFixer fixer (Compile::AliasIdxRaw, true , phase);
1329- Unique_Node_List uses_to_ignore ;
1344+ Unique_Node_List nodes_above_barriers ;
13301345 for (int i = state->load_reference_barriers_count () - 1 ; i >= 0 ; i--) {
13311346 ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier (i);
13321347 uint last = phase->C ->unique ();
@@ -1423,7 +1438,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
14231438 Node* out_val = val_phi;
14241439 phase->register_new_node (val_phi, region);
14251440
1426- fix_ctrl (lrb, region, fixer, uses, uses_to_ignore , last, phase);
1441+ fix_ctrl (lrb, region, fixer, uses, nodes_above_barriers , last, phase);
14271442
14281443 ctrl = orig_ctrl;
14291444
@@ -1579,7 +1594,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
15791594 phase->register_control (region, loop, heap_stable_ctrl->in (0 ));
15801595 phase->register_new_node (phi, region);
15811596
1582- fix_ctrl (barrier, region, fixer, uses, uses_to_ignore , last, phase);
1597+ fix_ctrl (barrier, region, fixer, uses, nodes_above_barriers , last, phase);
15831598 for (uint next = 0 ; next < uses.size (); next++ ) {
15841599 Node *n = uses.at (next);
15851600 assert (phase->get_ctrl (n) == init_ctrl, " bad control" );
0 commit comments