@@ -639,6 +639,34 @@ void ShenandoahBarrierC2Support::verify(RootNode* root) {
639
639
}
640
640
#endif
641
641
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
+
642
670
bool ShenandoahBarrierC2Support::is_dominator_same_ctrl (Node* c, Node* d, Node* n, PhaseIdealLoop* phase) {
643
671
// That both nodes have the same control is not sufficient to prove
644
672
// 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*
653
681
if (m->is_Phi () && m->in (0 )->is_Loop ()) {
654
682
assert (phase->ctrl_or_self (m->in (LoopNode::EntryControl)) != c, " following loop entry should lead to new control" );
655
683
} 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) != nullptr && 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);
672
687
}
673
688
}
674
689
return true ;
@@ -1020,7 +1035,20 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo
1020
1035
phase->register_new_node (val, ctrl);
1021
1036
}
1022
1037
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) {
1024
1052
Node* ctrl = phase->get_ctrl (barrier);
1025
1053
Node* init_raw_mem = fixer.find_mem (ctrl, barrier);
1026
1054
@@ -1031,30 +1059,17 @@ void ShenandoahBarrierC2Support::fix_ctrl(Node* barrier, Node* region, const Mem
1031
1059
// control will be after the expanded barrier. The raw memory (if
1032
1060
// its memory is control dependent on the barrier's input control)
1033
1061
// 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 != nullptr && 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);
1047
1063
for (DUIterator_Fast imax, i = ctrl->fast_outs (imax); i < imax; i++) {
1048
1064
Node* u = ctrl->fast_out (i);
1049
1065
if (u->_idx < last &&
1050
1066
u != barrier &&
1051
1067
!u->depends_only_on_test () && // preserve dependency on test
1052
- !uses_to_ignore .member (u) &&
1068
+ !nodes_above_barrier .member (u) &&
1053
1069
(u->in (0 ) != ctrl || (!u->is_Region () && !u->is_Phi ())) &&
1054
1070
(ctrl->Opcode () != Op_CatchProj || u->Opcode () != Op_CreateEx)) {
1055
1071
Node* old_c = phase->ctrl_or_self (u);
1056
- Node* c = old_c;
1057
- if (c != ctrl ||
1072
+ if (old_c != ctrl ||
1058
1073
is_dominator_same_ctrl (old_c, barrier, u, phase) ||
1059
1074
ShenandoahBarrierSetC2::is_shenandoah_state_load (u)) {
1060
1075
phase->igvn ().rehash_node_delayed (u);
@@ -1334,7 +1349,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
1334
1349
1335
1350
// Expand load-reference-barriers
1336
1351
MemoryGraphFixer fixer (Compile::AliasIdxRaw, true , phase);
1337
- Unique_Node_List uses_to_ignore ;
1352
+ Unique_Node_List nodes_above_barriers ;
1338
1353
for (int i = state->load_reference_barriers_count () - 1 ; i >= 0 ; i--) {
1339
1354
ShenandoahLoadReferenceBarrierNode* lrb = state->load_reference_barrier (i);
1340
1355
uint last = phase->C ->unique ();
@@ -1429,7 +1444,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
1429
1444
Node* out_val = val_phi;
1430
1445
phase->register_new_node (val_phi, region);
1431
1446
1432
- fix_ctrl (lrb, region, fixer, uses, uses_to_ignore , last, phase);
1447
+ fix_ctrl (lrb, region, fixer, uses, nodes_above_barriers , last, phase);
1433
1448
1434
1449
ctrl = orig_ctrl;
1435
1450
@@ -1585,7 +1600,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
1585
1600
phase->register_control (region, loop, heap_stable_ctrl->in (0 ));
1586
1601
phase->register_new_node (phi, region);
1587
1602
1588
- fix_ctrl (barrier, region, fixer, uses, uses_to_ignore , last, phase);
1603
+ fix_ctrl (barrier, region, fixer, uses, nodes_above_barriers , last, phase);
1589
1604
for (uint next = 0 ; next < uses.size (); next++ ) {
1590
1605
Node *n = uses.at (next);
1591
1606
assert (phase->get_ctrl (n) == init_ctrl, " bad control" );
0 commit comments