@@ -210,8 +210,6 @@ static int sms_order_nodes (ddg_ptr, int, int *, int *);
210
210
static void set_node_sched_params (ddg_ptr );
211
211
static partial_schedule_ptr sms_schedule_by_order (ddg_ptr , int , int , int * );
212
212
static void permute_partial_schedule (partial_schedule_ptr , rtx_insn * );
213
- static void generate_prolog_epilog (partial_schedule_ptr , class loop * ,
214
- rtx , rtx );
215
213
static int calculate_stage_count (partial_schedule_ptr , int );
216
214
static void calculate_must_precede_follow (ddg_node_ptr , int , int ,
217
215
int , int , sbitmap , sbitmap , sbitmap );
@@ -391,30 +389,40 @@ doloop_register_get (rtx_insn *head, rtx_insn *tail)
391
389
this constant. Otherwise return 0. */
392
390
static rtx_insn *
393
391
const_iteration_count (rtx count_reg , basic_block pre_header ,
394
- int64_t * count )
392
+ int64_t * count , bool * adjust_inplace )
395
393
{
396
394
rtx_insn * insn ;
397
395
rtx_insn * head , * tail ;
398
396
397
+ * adjust_inplace = false;
398
+ bool read_after = false;
399
+
399
400
if (! pre_header )
400
401
return NULL ;
401
402
402
403
get_ebb_head_tail (pre_header , pre_header , & head , & tail );
403
404
404
405
for (insn = tail ; insn != PREV_INSN (head ); insn = PREV_INSN (insn ))
405
- if (NONDEBUG_INSN_P (insn ) && single_set ( insn ) &&
406
- rtx_equal_p ( count_reg , SET_DEST (single_set (insn ))))
406
+ if (single_set (insn ) && rtx_equal_p ( count_reg ,
407
+ SET_DEST (single_set (insn ))))
407
408
{
408
409
rtx pat = single_set (insn );
409
410
410
411
if (CONST_INT_P (SET_SRC (pat )))
411
412
{
412
413
* count = INTVAL (SET_SRC (pat ));
414
+ * adjust_inplace = !read_after ;
413
415
return insn ;
414
416
}
415
417
416
418
return NULL ;
417
419
}
420
+ else if (NONDEBUG_INSN_P (insn ) && reg_mentioned_p (count_reg , insn ))
421
+ {
422
+ read_after = true;
423
+ if (reg_set_p (count_reg , insn ))
424
+ break ;
425
+ }
418
426
419
427
return NULL ;
420
428
}
@@ -1126,7 +1134,7 @@ duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
1126
1134
/* Generate the instructions (including reg_moves) for prolog & epilog. */
1127
1135
static void
1128
1136
generate_prolog_epilog (partial_schedule_ptr ps , class loop * loop ,
1129
- rtx count_reg , rtx count_init )
1137
+ rtx count_reg , bool adjust_init )
1130
1138
{
1131
1139
int i ;
1132
1140
int last_stage = PS_STAGE_COUNT (ps ) - 1 ;
@@ -1135,12 +1143,12 @@ generate_prolog_epilog (partial_schedule_ptr ps, class loop *loop,
1135
1143
/* Generate the prolog, inserting its insns on the loop-entry edge. */
1136
1144
start_sequence ();
1137
1145
1138
- if (! count_init )
1146
+ if (adjust_init )
1139
1147
{
1140
1148
/* Generate instructions at the beginning of the prolog to
1141
- adjust the loop count by STAGE_COUNT. If loop count is constant
1142
- (count_init) , this constant is adjusted by STAGE_COUNT in
1143
- generate_prolog_epilog function. */
1149
+ adjust the loop count by STAGE_COUNT. If loop count is constant
1150
+ and it not used anywhere in prologue , this constant is adjusted by
1151
+ STAGE_COUNT outside of generate_prolog_epilog function. */
1144
1152
rtx sub_reg = NULL_RTX ;
1145
1153
1146
1154
sub_reg = expand_simple_binop (GET_MODE (count_reg ), MINUS , count_reg ,
@@ -1528,7 +1536,8 @@ sms_schedule (void)
1528
1536
rtx_insn * count_init ;
1529
1537
int mii , rec_mii , stage_count , min_cycle ;
1530
1538
int64_t loop_count = 0 ;
1531
- bool opt_sc_p ;
1539
+ bool opt_sc_p , adjust_inplace = false;
1540
+ basic_block pre_header ;
1532
1541
1533
1542
if (! (g = g_arr [loop -> num ]))
1534
1543
continue ;
@@ -1569,19 +1578,13 @@ sms_schedule (void)
1569
1578
}
1570
1579
1571
1580
1572
- /* In case of th loop have doloop register it gets special
1573
- handling. */
1574
- count_init = NULL ;
1575
- if ((count_reg = doloop_register_get (head , tail )))
1576
- {
1577
- basic_block pre_header ;
1578
-
1579
- pre_header = loop_preheader_edge (loop )-> src ;
1580
- count_init = const_iteration_count (count_reg , pre_header ,
1581
- & loop_count );
1582
- }
1581
+ count_reg = doloop_register_get (head , tail );
1583
1582
gcc_assert (count_reg );
1584
1583
1584
+ pre_header = loop_preheader_edge (loop )-> src ;
1585
+ count_init = const_iteration_count (count_reg , pre_header , & loop_count ,
1586
+ & adjust_inplace );
1587
+
1585
1588
if (dump_file && count_init )
1586
1589
{
1587
1590
fprintf (dump_file , "SMS const-doloop " );
@@ -1701,9 +1704,20 @@ sms_schedule (void)
1701
1704
print_partial_schedule (ps , dump_file );
1702
1705
}
1703
1706
1704
- /* case the BCT count is not known , Do loop-versioning */
1705
- if (count_reg && ! count_init )
1707
+ if (count_init )
1708
+ {
1709
+ if (adjust_inplace )
1710
+ {
1711
+ /* When possible, set new iteration count of loop kernel in
1712
+ place. Otherwise, generate_prolog_epilog creates an insn
1713
+ to adjust. */
1714
+ SET_SRC (single_set (count_init )) = GEN_INT (loop_count
1715
+ - stage_count + 1 );
1716
+ }
1717
+ }
1718
+ else
1706
1719
{
1720
+ /* case the BCT count is not known , Do loop-versioning */
1707
1721
rtx comp_rtx = gen_rtx_GT (VOIDmode , count_reg ,
1708
1722
gen_int_mode (stage_count ,
1709
1723
GET_MODE (count_reg )));
@@ -1713,12 +1727,7 @@ sms_schedule (void)
1713
1727
loop_version (loop , comp_rtx , & condition_bb ,
1714
1728
prob , prob .invert (),
1715
1729
prob , prob .invert (), true);
1716
- }
1717
-
1718
- /* Set new iteration count of loop kernel. */
1719
- if (count_reg && count_init )
1720
- SET_SRC (single_set (count_init )) = GEN_INT (loop_count
1721
- - stage_count + 1 );
1730
+ }
1722
1731
1723
1732
/* Now apply the scheduled kernel to the RTL of the loop. */
1724
1733
permute_partial_schedule (ps , g -> closing_branch -> first_note );
@@ -1735,7 +1744,7 @@ sms_schedule (void)
1735
1744
if (dump_file )
1736
1745
print_node_sched_params (dump_file , g -> num_nodes , ps );
1737
1746
/* Generate prolog and epilog. */
1738
- generate_prolog_epilog (ps , loop , count_reg , count_init );
1747
+ generate_prolog_epilog (ps , loop , count_reg , ! adjust_inplace );
1739
1748
break ;
1740
1749
}
1741
1750
0 commit comments