@@ -1287,10 +1287,12 @@ void PhaseIdealLoop::copy_skeleton_predicates_to_main_loop_helper(Node* predicat
1287
1287
// Clone the skeleton predicate twice and initialize one with the initial
1288
1288
// value of the loop induction variable. Leave the other predicate
1289
1289
// to be initialized when increasing the stride during loop unrolling.
1290
- prev_proj = clone_skeleton_predicate_for_main_loop (iff, opaque_init, NULL , predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
1290
+ prev_proj = clone_skeleton_predicate_for_main_or_post_loop (iff, opaque_init, NULL , predicate, uncommon_proj,
1291
+ current_proj, outer_loop, prev_proj);
1291
1292
assert (skeleton_predicate_has_opaque (prev_proj->in (0 )->as_If ()), " " );
1292
1293
1293
- prev_proj = clone_skeleton_predicate_for_main_loop (iff, init, stride, predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
1294
+ prev_proj = clone_skeleton_predicate_for_main_or_post_loop (iff, init, stride, predicate, uncommon_proj,
1295
+ current_proj, outer_loop, prev_proj);
1294
1296
assert (!skeleton_predicate_has_opaque (prev_proj->in (0 )->as_If ()), " " );
1295
1297
1296
1298
// Rewire any control inputs from the cloned skeleton predicates down to the main and post loop for data nodes that are part of the
@@ -1367,8 +1369,7 @@ bool PhaseIdealLoop::skeleton_predicate_has_opaque(IfNode* iff) {
1367
1369
// Clone the skeleton predicate bool for a main or unswitched loop:
1368
1370
// Main loop: Set new_init and new_stride nodes as new inputs.
1369
1371
// Unswitched loop: new_init and new_stride are both NULL. Clone OpaqueLoopInit and OpaqueLoopStride instead.
1370
- Node* PhaseIdealLoop::clone_skeleton_predicate_bool (Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj,
1371
- Node* control, IdealLoopTree* outer_loop) {
1372
+ Node* PhaseIdealLoop::clone_skeleton_predicate_bool (Node* iff, Node* new_init, Node* new_stride, Node* control) {
1372
1373
Node_Stack to_clone (2 );
1373
1374
to_clone.push (iff->in (1 ), 1 );
1374
1375
uint current = C->unique ();
@@ -1444,9 +1445,9 @@ Node* PhaseIdealLoop::clone_skeleton_predicate_bool(Node* iff, Node* new_init, N
1444
1445
1445
1446
// Clone a skeleton predicate for the main loop. new_init and new_stride are set as new inputs. Since the predicates cannot fail at runtime,
1446
1447
// Halt nodes are inserted instead of uncommon traps.
1447
- Node* PhaseIdealLoop::clone_skeleton_predicate_for_main_loop (Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj,
1448
- Node* control, IdealLoopTree* outer_loop, Node* input_proj) {
1449
- Node* result = clone_skeleton_predicate_bool (iff, new_init, new_stride, predicate, uncommon_proj, control, outer_loop );
1448
+ Node* PhaseIdealLoop::clone_skeleton_predicate_for_main_or_post_loop (Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj,
1449
+ Node* control, IdealLoopTree* outer_loop, Node* input_proj) {
1450
+ Node* result = clone_skeleton_predicate_bool (iff, new_init, new_stride, control);
1450
1451
Node* proj = predicate->clone ();
1451
1452
Node* other_proj = uncommon_proj->clone ();
1452
1453
Node* new_iff = iff->clone ();
@@ -1460,8 +1461,8 @@ Node* PhaseIdealLoop::clone_skeleton_predicate_for_main_loop(Node* iff, Node* ne
1460
1461
C->root ()->add_req (halt);
1461
1462
new_iff->set_req (0 , input_proj);
1462
1463
1463
- register_control (new_iff, outer_loop->_parent , input_proj);
1464
- register_control (proj, outer_loop->_parent , new_iff);
1464
+ register_control (new_iff, outer_loop == _ltree_root ? _ltree_root : outer_loop ->_parent , input_proj);
1465
+ register_control (proj, outer_loop == _ltree_root ? _ltree_root : outer_loop ->_parent , new_iff);
1465
1466
register_control (other_proj, _ltree_root, new_iff);
1466
1467
register_control (halt, _ltree_root, other_proj);
1467
1468
return proj;
@@ -1544,7 +1545,8 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n
1544
1545
// Add the post loop
1545
1546
const uint idx_before_pre_post = Compile::current ()->unique ();
1546
1547
CountedLoopNode *post_head = NULL ;
1547
- Node *main_exit = insert_post_loop (loop, old_new, main_head, main_end, incr, limit, post_head);
1548
+ Node* post_incr = incr;
1549
+ Node* main_exit = insert_post_loop (loop, old_new, main_head, main_end, post_incr, limit, post_head);
1548
1550
const uint idx_after_post_before_pre = Compile::current ()->unique ();
1549
1551
1550
1552
// ------------------------------
@@ -1643,6 +1645,7 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n
1643
1645
assert (post_head->in (1 )->is_IfProj (), " must be zero-trip guard If node projection of the post loop" );
1644
1646
copy_skeleton_predicates_to_main_loop (pre_head, castii, stride, outer_loop, outer_main_head, dd_main_head,
1645
1647
idx_before_pre_post, idx_after_post_before_pre, min_taken, post_head->in (1 ), old_new);
1648
+ copy_skeleton_predicates_to_post_loop (outer_main_head, post_head, post_incr, stride);
1646
1649
1647
1650
// Step B4: Shorten the pre-loop to run only 1 iteration (for now).
1648
1651
// RCE and alignment may change this later.
@@ -1765,6 +1768,7 @@ void PhaseIdealLoop::insert_vector_post_loop(IdealLoopTree *loop, Node_List &old
1765
1768
// In this case we throw away the result as we are not using it to connect anything else.
1766
1769
CountedLoopNode *post_head = NULL ;
1767
1770
insert_post_loop (loop, old_new, main_head, main_end, incr, limit, post_head);
1771
+ copy_skeleton_predicates_to_post_loop (main_head->skip_strip_mined (), post_head, incr, main_head->stride ());
1768
1772
1769
1773
// It's difficult to be precise about the trip-counts
1770
1774
// for post loops. They are usually very short,
@@ -1811,6 +1815,7 @@ void PhaseIdealLoop::insert_scalar_rced_post_loop(IdealLoopTree *loop, Node_List
1811
1815
// In this case we throw away the result as we are not using it to connect anything else.
1812
1816
CountedLoopNode *post_head = NULL ;
1813
1817
insert_post_loop (loop, old_new, main_head, main_end, incr, limit, post_head);
1818
+ copy_skeleton_predicates_to_post_loop (main_head->skip_strip_mined (), post_head, incr, main_head->stride ());
1814
1819
1815
1820
// It's difficult to be precise about the trip-counts
1816
1821
// for post loops. They are usually very short,
@@ -1827,9 +1832,9 @@ void PhaseIdealLoop::insert_scalar_rced_post_loop(IdealLoopTree *loop, Node_List
1827
1832
1828
1833
// ------------------------------insert_post_loop-------------------------------
1829
1834
// Insert post loops. Add a post loop to the given loop passed.
1830
- Node *PhaseIdealLoop::insert_post_loop (IdealLoopTree * loop, Node_List & old_new,
1831
- CountedLoopNode * main_head, CountedLoopEndNode * main_end,
1832
- Node * incr, Node * limit, CountedLoopNode *& post_head) {
1835
+ Node *PhaseIdealLoop::insert_post_loop (IdealLoopTree* loop, Node_List& old_new,
1836
+ CountedLoopNode* main_head, CountedLoopEndNode* main_end,
1837
+ Node*& incr, Node* limit, CountedLoopNode*& post_head) {
1833
1838
IfNode* outer_main_end = main_end;
1834
1839
IdealLoopTree* outer_loop = loop;
1835
1840
if (main_head->is_strip_mined ()) {
@@ -1913,8 +1918,8 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree *loop, Node_List &old_new,
1913
1918
}
1914
1919
1915
1920
// CastII for the new post loop:
1916
- Node* castii = cast_incr_before_loop (zer_opaq->in (1 ), zer_taken, post_head);
1917
- assert (castii != NULL , " no castII inserted" );
1921
+ incr = cast_incr_before_loop (zer_opaq->in (1 ), zer_taken, post_head);
1922
+ assert (incr != NULL , " no castII inserted" );
1918
1923
1919
1924
return new_main_exit;
1920
1925
}
@@ -1956,7 +1961,8 @@ void PhaseIdealLoop::update_main_loop_skeleton_predicates(Node* ctrl, CountedLoo
1956
1961
_igvn.replace_input_of (iff, 1 , iff->in (1 )->in (2 ));
1957
1962
} else {
1958
1963
// Add back predicates updated for the new stride.
1959
- prev_proj = clone_skeleton_predicate_for_main_loop (iff, init, max_value, entry, proj, ctrl, outer_loop, prev_proj);
1964
+ prev_proj = clone_skeleton_predicate_for_main_or_post_loop (iff, init, max_value, entry, proj, ctrl, outer_loop,
1965
+ prev_proj);
1960
1966
assert (!skeleton_predicate_has_opaque (prev_proj->in (0 )->as_If ()), " unexpected" );
1961
1967
}
1962
1968
}
@@ -1968,6 +1974,34 @@ void PhaseIdealLoop::update_main_loop_skeleton_predicates(Node* ctrl, CountedLoo
1968
1974
}
1969
1975
}
1970
1976
1977
+ void PhaseIdealLoop::copy_skeleton_predicates_to_post_loop (LoopNode* main_loop_head, CountedLoopNode* post_loop_head, Node* init, Node* stride) {
1978
+ // Go over the skeleton predicates of the main loop and make a copy for the post loop with its initial iv value and
1979
+ // stride as inputs.
1980
+ Node* post_loop_entry = post_loop_head->in (LoopNode::EntryControl);
1981
+ Node* main_loop_entry = main_loop_head->in (LoopNode::EntryControl);
1982
+ IdealLoopTree* post_loop = get_loop (post_loop_head);
1983
+
1984
+ Node* ctrl = main_loop_entry;
1985
+ Node* prev_proj = post_loop_entry;
1986
+ while (ctrl != NULL && ctrl->is_Proj () && ctrl->in (0 )->is_If ()) {
1987
+ IfNode* iff = ctrl->in (0 )->as_If ();
1988
+ ProjNode* proj = iff->proj_out (1 - ctrl->as_Proj ()->_con );
1989
+ if (proj->unique_ctrl_out ()->Opcode () != Op_Halt) {
1990
+ break ;
1991
+ }
1992
+ if (iff->in (1 )->Opcode () == Op_Opaque4 && skeleton_predicate_has_opaque (iff)) {
1993
+ prev_proj = clone_skeleton_predicate_for_main_or_post_loop (iff, init, stride, ctrl, proj, post_loop_entry,
1994
+ post_loop, prev_proj);
1995
+ assert (!skeleton_predicate_has_opaque (prev_proj->in (0 )->as_If ()), " unexpected" );
1996
+ }
1997
+ ctrl = ctrl->in (0 )->in (0 );
1998
+ }
1999
+ if (prev_proj != post_loop_entry) {
2000
+ _igvn.replace_input_of (post_loop_head, LoopNode::EntryControl, prev_proj);
2001
+ set_idom (post_loop_head, prev_proj, dom_depth (post_loop_head));
2002
+ }
2003
+ }
2004
+
1971
2005
// ------------------------------do_unroll--------------------------------------
1972
2006
// Unroll the loop body one step - make each trip do 2 iterations.
1973
2007
void PhaseIdealLoop::do_unroll (IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip) {
0 commit comments