===================================================================
***************
+ /* { dg-do compile } */
+ /* { dg-options "-O1 -mtune=amdfam10 -fexpensive-optimizations -fgcse -foptimize-register-move -freorder-blocks -fschedule-insns2 -funswitch-loops -fgcse-las -fselective-scheduling2 -fsel-sched-pipelining -funroll-all-loops" } */
+
+ typedef char uint8_t;
+ typedef uint32_t;
+ typedef vo_frame_t;
+ struct vo_frame_s
+ {
+ uint8_t base[3];
+ int pitches[3];};
+ typedef struct
+ {
+ void
+ (*proc_macro_block)
+ (void);
+ }
+ xine_xvmc_t;
+ typedef struct
+ {
+ uint8_t ref[2][3];
+ int pmv;
+ }
+ motion_t;
+ typedef struct
+ {
+ uint32_t bitstream_buf;
+ int bitstream_bits;
+ uint8_t * bitstream_ptr;
+ uint8_t dest[3];
+ int pitches[3];
+ int offset;
+ motion_t b_motion;
+ motion_t f_motion;
+ int v_offset;
+ int coded_picture_width;
+ int picture_structure;
+ struct vo_frame_s *current_frame;}
+ picture_t;
+ typedef struct
+ {
+ int xvmc_last_slice_code;}
+ mpeg2dec_accel_t;
+ static bitstream_init (picture_t * picture, void *start)
+ {
+ picture->bitstream_ptr = start;
+ }
+ static slice_xvmc_init (picture_t * picture, int code)
+ {
+ int offset;
+ struct vo_frame_s *forward_reference_frame;
+ offset = picture->picture_structure == 2;
+ picture->pitches[0] = picture->current_frame->pitches[0];
+ picture->pitches[1] = picture->current_frame->pitches[1];
+ if (picture)
+ picture->f_motion.ref
+ [0]
+ [0]
+ = forward_reference_frame->base + (offset ? picture->pitches[0] : 0);
+ picture->f_motion.ref[0][1] = (offset);
+ if (picture->picture_structure)
+ picture->pitches[0] <<= picture->pitches[1] <<= 1;
+ offset = 0;
+ while (1)
+ {
+ if (picture->bitstream_buf >= 0x08000000)
+ break;
+ switch (picture->bitstream_buf >> 12)
+ {
+ case 8:
+ offset += 33;
+ picture->bitstream_buf
+ |=
+ picture->bitstream_ptr[1] << picture->bitstream_bits;
+ }
+ }
+ picture->offset = (offset);
+ while (picture->offset - picture->coded_picture_width >= 0)
+ {
+ picture->offset -= picture->coded_picture_width;
+ if (picture->current_frame)
+ {
+ picture->dest[0] += picture->pitches[0];
+ picture->dest[1] += picture->pitches[1];
+ }
+ picture->v_offset += 16;
+ }
+ }
+
+ void
+ mpeg2_xvmc_slice
+ (mpeg2dec_accel_t * accel, picture_t * picture, int code, uint8_t buffer,int mba_inc)
+ {
+ xine_xvmc_t * xvmc = bitstream_init (picture, buffer);
+ slice_xvmc_init (picture, code);
+ while (1)
+ {
+ if (picture)
+ break;
+ switch (picture->bitstream_buf)
+ {
+ case 8:
+ mba_inc += accel->xvmc_last_slice_code = code;
+ xvmc->proc_macro_block ();
+ while (mba_inc)
+ ;
+ }
+ }
+ }
===================================================================
***************
+ /* { dg-do compile } */
+ /* { dg-options "-O3 -march=amdfam10 -fselective-scheduling2 -fsel-sched-pipelining -funroll-all-loops" } */
+
+ struct S
+ {
+ struct
+ {
+ int i;
+ } **p;
+ int x;
+ int y;
+ };
+
+ extern int baz (void);
+ extern int bar (void *, int, int);
+
+ void
+ foo (struct S *s)
+ {
+ int i;
+ for (i = 0; i < s->x; i++)
+ bar (s->p[i], baz (), s->y);
+ for (i = 0; i < s->x; i++)
+ s->p[i]->i++;
+ }
===================================================================
***************
+ /* { dg-do compile } */
+ /* { dg-options "-mtune=amdfam10 -O3 -fpeel-loops -fselective-scheduling2 -fsel-sched-pipelining -fPIC" } */
+
+ static int FIR_Tab_16[16][16];
+
+ void
+ V_Pass_Avrg_16_C_ref (int *Dst, int *Src, int W, int BpS, int Rnd)
+ {
+ while (W-- > 0)
+ {
+ int i, k;
+ int Sums[16] = { };
+ for (i = 0; i < 16; ++i)
+ for (k = 0; k < 16; ++k)
+ Sums[k] += FIR_Tab_16[i][k] * Src[i];
+ for (i = 0; i < 16; ++i)
+ Dst[i] = Sums[i] + Src[i];
+ }
+ }
===================================================================
***************
+ /* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+ /* { dg-options "-O3 -fschedule-insns -fschedule-insns2 -fselective-scheduling2 -fsel-sched-pipelining -funroll-loops -fprefetch-loop-arrays" } */
+
+ void main1 (float *pa, float *pc)
+ {
+ int i;
+ float b[256];
+ float c[256];
+ for (i = 0; i < 256; i++)
+ b[i] = c[i] = pc[i];
+ for (i = 0; i < 256; i++)
+ pa[i] = b[i] * c[i];
+ }
===================================================================
***************
+ /* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+ /* { dg-options "-O1 -freorder-blocks -fschedule-insns2 -funswitch-loops -fselective-scheduling2 -fsel-sched-pipelining -funroll-all-loops" } */
+ void
+ foo1 (int *s)
+ {
+ s[0] = s[1];
+ while (s[6] - s[8])
+ {
+ s[6] -= s[8];
+ if (s[8] || s[0])
+ {
+ s[3] += s[0];
+ s[4] += s[1];
+ }
+ s[7]++;
+ }
+ }
===================================================================
***************
+ /* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+ /* { dg-options "-Os -fselective-scheduling2 -fsel-sched-pipelining -fprofile-generate" } */
+
+ static inline void
+ bmp_iter_next (int *bi, int *bit_no)
+ {
+ *bi >>= 1;
+ *bit_no += 1;
+ }
+
+ int bmp_iter_set (int *bi, int *bit_no);
+ void bitmap_initialize_stat (int, ...);
+ void bitmap_clear (void);
+
+ void
+ df_md_alloc (int bi, int bb_index, void *bb_info)
+ {
+ for (; bmp_iter_set (&bi, &bb_index); bmp_iter_next (&bi, &bb_index))
+
+ if (bb_info)
+ bitmap_clear ();
+ else
+ bitmap_initialize_stat (0);
+ }
===================================================================
*************** sel_dfa_new_cycle (insn_t insn, fence_t
}
/* Invoke reorder* target hooks on the ready list. Return the number of insns
! we can issue. FENCE is the current fence. */
static int
! invoke_reorder_hooks (fence_t fence)
{
int issue_more;
! bool ran_hook = false;
/* Call the reorder hook at the beginning of the cycle, and call
the reorder2 hook in the middle of the cycle. */
}
/* Invoke reorder* target hooks on the ready list. Return the number of insns
! we can issue. FENCE is the current fence. Write true in *PRAN_HOOK whether
! we have actually run any hook. */
static int
! invoke_reorder_hooks (fence_t fence, bool *pran_hook)
{
int issue_more;
!
! *pran_hook = false;
/* Call the reorder hook at the beginning of the cycle, and call
the reorder2 hook in the middle of the cycle. */
*************** invoke_reorder_hooks (fence_t fence)
if (pipelining_p)
++ready.n_ready;
! ran_hook = true;
}
else
/* Initialize can_issue_more for variable_issue. */
if (pipelining_p)
++ready.n_ready;
! *pran_hook = true;
}
else
/* Initialize can_issue_more for variable_issue. */
*************** invoke_reorder_hooks (fence_t fence)
++ready.n_ready;
}
! ran_hook = true;
}
else
issue_more = FENCE_ISSUE_MORE (fence);
/* Ensure that ready list and vec_av_set are in line with each other,
i.e. vec_av_set[i] == ready_element (&ready, i). */
! if (issue_more && ran_hook)
{
int i, j, n;
rtx *arr = ready.vec;
++ready.n_ready;
}
! *pran_hook = true;
}
else
issue_more = FENCE_ISSUE_MORE (fence);
/* Ensure that ready list and vec_av_set are in line with each other,
i.e. vec_av_set[i] == ready_element (&ready, i). */
! if (issue_more && *pran_hook)
{
int i, j, n;
rtx *arr = ready.vec;
*************** get_expr_cost (expr_t expr, fence_t fenc
}
/* Find the best insn for scheduling, either via max_issue or just take
! the most prioritized available. */
static int
! choose_best_insn (fence_t fence, int privileged_n, int *index)
{
int can_issue = 0;
}
/* Find the best insn for scheduling, either via max_issue or just take
! the most prioritized available. FENCE is the current fence,
! PRIVILEGED_N is the number of privileged insns for max_issue call,
! RAN_HOOK indicates that any preparational hooks were run.
! Write in *INDEX the number of selected instruction or -1 if neither
! instruction of the ready list can be selected. */
static int
! choose_best_insn (fence_t fence, int privileged_n, bool ran_hook, int *index)
{
int can_issue = 0;
*************** choose_best_insn (fence_t fence, int pri
if (get_expr_cost (expr, fence) < 1)
{
can_issue = can_issue_more;
+ if (!ran_hook && !can_issue)
+ can_issue = 1;
*index = i;
if (sched_verbose >= 2)
*************** choose_best_insn (fence_t fence, int pri
/* Choose the best expr from *AV_VLIW_PTR and a suitable register for it.
BNDS and FENCE are current boundaries and scheduling fence respectively.
Return the expr found and NULL if nothing can be issued atm.
! Write to PNEED_STALL the number of cycles to stall if no expr was found. */
static expr_t
find_best_expr (av_set_t *av_vliw_ptr, blist_t bnds, fence_t fence,
int *pneed_stall)
{
expr_t best;
/* Choose the best insn for scheduling via:
1) sorting the ready list based on priority;
/* Choose the best expr from *AV_VLIW_PTR and a suitable register for it.
BNDS and FENCE are current boundaries and scheduling fence respectively.
Return the expr found and NULL if nothing can be issued atm.
! Write to PNEED_STALL the number of cycles to stall if no expr was found.
! The positive number of cycles means a data dependency stall, while
! the negative one means a functional stall (DFA stall). */
static expr_t
find_best_expr (av_set_t *av_vliw_ptr, blist_t bnds, fence_t fence,
int *pneed_stall)
{
expr_t best;
+ bool ran_hook;
/* Choose the best insn for scheduling via:
1) sorting the ready list based on priority;
*************** find_best_expr (av_set_t *av_vliw_ptr, b
{
int privileged_n, index;
! can_issue_more = invoke_reorder_hooks (fence);
! if (can_issue_more > 0)
{
/* Try choosing the best insn until we find one that is could be
scheduled due to liveness restrictions on its destination register.
{
int privileged_n, index;
! can_issue_more = invoke_reorder_hooks (fence, &ran_hook);
! if (can_issue_more > 0 || !ran_hook)
{
/* Try choosing the best insn until we find one that is could be
scheduled due to liveness restrictions on its destination register.
*************** find_best_expr (av_set_t *av_vliw_ptr, b
in the order of their priority. */
invoke_dfa_lookahead_guard ();
privileged_n = calculate_privileged_insns ();
! can_issue_more = choose_best_insn (fence, privileged_n, &index);
if (can_issue_more)
best = find_expr_for_ready (index, true);
}
in the order of their priority. */
invoke_dfa_lookahead_guard ();
privileged_n = calculate_privileged_insns ();
! can_issue_more = choose_best_insn (fence, privileged_n, ran_hook, &index);
if (can_issue_more)
best = find_expr_for_ready (index, true);
}
*************** find_best_expr (av_set_t *av_vliw_ptr, b
if (can_issue_more == 0)
{
best = NULL;
! *pneed_stall = 1;
}
}
if (can_issue_more == 0)
{
best = NULL;
! *pneed_stall = -1;
}
}
*************** find_best_expr (av_set_t *av_vliw_ptr, b
{
can_issue_more = invoke_aftermath_hooks (fence, EXPR_INSN_RTX (best),
can_issue_more);
! if (can_issue_more == 0)
! *pneed_stall = 1;
}
if (sched_verbose >= 2)
{
can_issue_more = invoke_aftermath_hooks (fence, EXPR_INSN_RTX (best),
can_issue_more);
! if (targetm.sched.variable_issue
! && can_issue_more == 0)
! *pneed_stall = -1;
}
if (sched_verbose >= 2)
*************** advance_state_on_fence (fence_t fence, i
gcc_assert (res < 0);
if (memcmp (temp_state, FENCE_STATE (fence), dfa_state_size))
! {
! FENCE_ISSUED_INSNS (fence)++;
!
! /* We should never issue more than issue_rate insns. */
! if (FENCE_ISSUED_INSNS (fence) > issue_rate)
! gcc_unreachable ();
! }
}
else
{
gcc_assert (res < 0);
if (memcmp (temp_state, FENCE_STATE (fence), dfa_state_size))
! FENCE_ISSUED_INSNS (fence)++;
}
else
{
*************** schedule_expr_on_boundary (bnd_t bnd, ex
return insn;
}
! /* Stall for N cycles on FENCE. */
static void
stall_for_cycles (fence_t fence, int n)
{
int could_more;
! could_more = n > 1 || FENCE_ISSUED_INSNS (fence) < issue_rate;
while (n--)
advance_one_cycle (fence);
if (could_more)
return insn;
}
! /* Stall for N cycles on FENCE. N > 0 means we want a stall because
! of an unsatisfied data dependence, N < 0 means the DFA stall.
! The difference is that we need to set the AFTER_STALL_P bit only
! for a data dependence stall. */
static void
stall_for_cycles (fence_t fence, int n)
{
int could_more;
! if (n > 0)
! could_more = 1;
! else
! n = -n;
while (n--)
advance_one_cycle (fence);
if (could_more)
*************** fill_insns (fence_t fence, int seqno, il
blist_t *bnds_tailp1, *bndsp;
expr_t expr_vliw;
int need_stall;
! int was_stall = 0, scheduled_insns = 0, stall_iterations = 0;
int max_insns = pipelining_p ? issue_rate : 2 * issue_rate;
int max_stall = pipelining_p ? 1 : 3;
bool last_insn_was_debug = false;
blist_t *bnds_tailp1, *bndsp;
expr_t expr_vliw;
int need_stall;
! int was_stall = 0, scheduled_insns = 0;
int max_insns = pipelining_p ? issue_rate : 2 * issue_rate;
int max_stall = pipelining_p ? 1 : 3;
bool last_insn_was_debug = false;
*************** fill_insns (fence_t fence, int seqno, il
do
{
expr_vliw = find_best_expr (&av_vliw, bnds, fence, &need_stall);
! if (!expr_vliw && need_stall)
{
/* All expressions required a stall. Do not recompute av sets
as we'll get the same answer (modulo the insns between
the fence and its boundary, which will not be available for
! pipelining). */
! gcc_assert (! expr_vliw && stall_iterations < 2);
! was_stall++;
! /* If we are going to stall for too long, break to recompute av
sets and bring more insns for pipelining. */
! if (need_stall <= 3)
stall_for_cycles (fence, need_stall);
else
{
do
{
expr_vliw = find_best_expr (&av_vliw, bnds, fence, &need_stall);
! if (! expr_vliw && need_stall != 0)
{
/* All expressions required a stall. Do not recompute av sets
as we'll get the same answer (modulo the insns between
the fence and its boundary, which will not be available for
! pipelining).
! If we are going to stall for too long, break to recompute av
sets and bring more insns for pipelining. */
! was_stall++;
! if (need_stall < 0 || need_stall <= 3)
stall_for_cycles (fence, need_stall);
else
{
*************** fill_insns (fence_t fence, int seqno, il
}
}
}
! while (! expr_vliw && need_stall);
/* Now either we've selected expr_vliw or we have nothing to schedule. */
if (!expr_vliw)
}
}
}
! while (! expr_vliw && need_stall != 0);
/* Now either we've selected expr_vliw or we have nothing to schedule. */
if (!expr_vliw)
*************** init_seqno_1 (basic_block bb, sbitmap vi
init_seqno_1 (succ, visited_bbs, blocks_to_reschedule);
}
+ else if (blocks_to_reschedule)
+ bitmap_set_bit (forced_ebb_heads, succ->index);
}
for (insn = BB_END (bb); insn != note; insn = PREV_INSN (insn))
*************** reset_sched_cycles_in_current_ebb (void)
}
haifa_clock += i;
+ if (sched_verbose >= 2)
+ sel_print ("haifa clock: %d\n", haifa_clock);
}
else
gcc_assert (haifa_cost == 0);
*************** reset_sched_cycles_in_current_ebb (void)
{
sel_print ("advance_state (dfa_new_cycle)\n");
debug_state (curr_state);
+ sel_print ("haifa clock: %d\n", haifa_clock + 1);
}
}
*************** reset_sched_cycles_in_current_ebb (void)
cost = state_transition (curr_state, insn);
if (sched_verbose >= 2)
! debug_state (curr_state);
!
gcc_assert (cost < 0);
}
cost = state_transition (curr_state, insn);
if (sched_verbose >= 2)
! {
! sel_print ("scheduled insn %d, clock %d\n", INSN_UID (insn),
! haifa_clock + 1);
! debug_state (curr_state);
! }
gcc_assert (cost < 0);
}
*************** sel_sched_region_1 (void)
continue;
}
! if (bitmap_clear_bit (blocks_to_reschedule, bb->index))
{
flist_tail_init (new_fences);
continue;
}
! if (bitmap_bit_p (blocks_to_reschedule, bb->index))
{
flist_tail_init (new_fences);