Message ID | 20100730142651.GR18378@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
On Fri, 30 Jul 2010, Jakub Jelinek wrote: > Hi! > > As shown in these two PRs, postreload.c wasn't properly skipping > debug stmts. It seems that such skipping of DEBUG_INSNs in a loop > calling {prev,next}_nonnote_insn is very common though, > so this patch introduces functions for that and adjusts places > which do something like that by hand, plus adds it to the two needed > places in postreload.c. > In fact, one of these functions was already preexisting, but only as static > in combine.c. > > Bootstrapped/regtested on x86_64-linux and i686-linux, Kazu has tested > it on SH as well. Ok for trunk? 4.5 after 4.5.1 is released? Ok. Thanks, Richard. > 2010-07-30 Jakub Jelinek <jakub@redhat.com> > > PR debug/45055 > PR rtl-optimization/45137 > * rtl.h (prev_nonnote_nondebug_insn, next_nonnote_nondebug_insn): New > prototypes. > * emit-rtl.c (prev_nonnote_nondebug_insn, next_nonnote_nondebug_insn): > New functions. > * combine.c (next_nonnote_nondebug_insn): Removed. > * ifcvt.c (noce_process_if_block): Use prev_nonnote_nondebug_insn. > * haifa-sched.c (queue_to_ready): Use next_nonnote_nondebug_insn. > * sched-deps.c (sched_analyze_insn): Likewise. > (fixup_sched_groups, deps_start_bb): Use prev_nonnote_nondebug_insn. > * rtlanal.c (canonicalize_condition): Likewise. > * postreload.c (reload_combine_recognize_pattern): Likewise. > (reload_cse_move2add): Use next_nonnote_nondebug_insn. > > * gcc.dg/pr45055.c: New test. > > --- gcc/rtl.h.jj 2010-07-29 17:46:42.000000000 +0200 > +++ gcc/rtl.h 2010-07-30 13:28:44.000000000 +0200 > @@ -1693,6 +1693,8 @@ extern rtx next_nonnote_insn (rtx); > extern rtx next_nonnote_insn_bb (rtx); > extern rtx prev_nondebug_insn (rtx); > extern rtx next_nondebug_insn (rtx); > +extern rtx prev_nonnote_nondebug_insn (rtx); > +extern rtx next_nonnote_nondebug_insn (rtx); > extern rtx prev_real_insn (rtx); > extern rtx next_real_insn (rtx); > extern rtx prev_active_insn (rtx); > --- gcc/emit-rtl.c.jj 2010-07-16 17:55:08.000000000 +0200 > +++ gcc/emit-rtl.c 2010-07-30 13:15:52.000000000 +0200 > @@ -3135,6 +3135,38 @@ prev_nondebug_insn (rtx insn) > return insn; > } > > +/* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN. > + This routine does not look inside SEQUENCEs. */ > + > +rtx > +next_nonnote_nondebug_insn (rtx insn) > +{ > + while (insn) > + { > + insn = NEXT_INSN (insn); > + if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn))) > + break; > + } > + > + return insn; > +} > + > +/* Return the previous insn before INSN that is not a NOTE nor DEBUG_INSN. > + This routine does not look inside SEQUENCEs. */ > + > +rtx > +prev_nonnote_nondebug_insn (rtx insn) > +{ > + while (insn) > + { > + insn = PREV_INSN (insn); > + if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn))) > + break; > + } > + > + return insn; > +} > + > /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN; > or 0, if there is none. This routine does not look inside > SEQUENCEs. */ > --- gcc/combine.c.jj 2010-07-29 17:16:14.000000000 +0200 > +++ gcc/combine.c 2010-07-30 13:37:04.000000000 +0200 > @@ -12654,29 +12654,6 @@ reg_bitfield_target_p (rtx x, rtx body) > > return 0; > } > - > -/* Return the next insn after INSN that is neither a NOTE nor a > - DEBUG_INSN. This routine does not look inside SEQUENCEs. */ > - > -static rtx > -next_nonnote_nondebug_insn (rtx insn) > -{ > - while (insn) > - { > - insn = NEXT_INSN (insn); > - if (insn == 0) > - break; > - if (NOTE_P (insn)) > - continue; > - if (DEBUG_INSN_P (insn)) > - continue; > - break; > - } > - > - return insn; > -} > - > - > > /* Given a chain of REG_NOTES originally from FROM_INSN, try to place them > as appropriate. I3 and I2 are the insns resulting from the combination > --- gcc/ifcvt.c.jj 2010-07-09 13:44:24.000000000 +0200 > +++ gcc/ifcvt.c 2010-07-30 13:31:37.000000000 +0200 > @@ -2368,9 +2368,7 @@ noce_process_if_block (struct noce_if_in > } > else > { > - insn_b = prev_nonnote_insn (if_info->cond_earliest); > - while (insn_b && DEBUG_INSN_P (insn_b)) > - insn_b = prev_nonnote_insn (insn_b); > + insn_b = prev_nonnote_nondebug_insn (if_info->cond_earliest); > /* We're going to be moving the evaluation of B down from above > COND_EARLIEST to JUMP. Make sure the relevant data is still > intact. */ > --- gcc/haifa-sched.c.jj 2010-07-09 13:44:24.000000000 +0200 > +++ gcc/haifa-sched.c 2010-07-30 13:30:36.000000000 +0200 > @@ -2003,13 +2003,9 @@ queue_to_ready (struct ready_list *ready > q_ptr = NEXT_Q (q_ptr); > > if (dbg_cnt (sched_insn) == false) > - { > - /* If debug counter is activated do not requeue insn next after > - last_scheduled_insn. */ > - skip_insn = next_nonnote_insn (last_scheduled_insn); > - while (skip_insn && DEBUG_INSN_P (skip_insn)) > - skip_insn = next_nonnote_insn (skip_insn); > - } > + /* If debug counter is activated do not requeue insn next after > + last_scheduled_insn. */ > + skip_insn = next_nonnote_nondebug_insn (last_scheduled_insn); > else > skip_insn = NULL_RTX; > > --- gcc/sched-deps.c.jj 2010-07-09 13:44:24.000000000 +0200 > +++ gcc/sched-deps.c 2010-07-30 13:34:37.000000000 +0200 > @@ -1521,9 +1521,7 @@ fixup_sched_groups (rtx insn) > > delete_all_dependences (insn); > > - prev_nonnote = prev_nonnote_insn (insn); > - while (DEBUG_INSN_P (prev_nonnote)) > - prev_nonnote = prev_nonnote_insn (prev_nonnote); > + prev_nonnote = prev_nonnote_nondebug_insn (insn); > if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote) > && ! sched_insns_conditions_mutex_p (insn, prev_nonnote)) > add_dependence (insn, prev_nonnote, REG_DEP_ANTI); > @@ -2699,9 +2697,7 @@ sched_analyze_insn (struct deps_desc *de > if (JUMP_P (insn)) > { > rtx next; > - next = next_nonnote_insn (insn); > - while (next && DEBUG_INSN_P (next)) > - next = next_nonnote_insn (next); > + next = next_nonnote_nondebug_insn (insn); > if (next && BARRIER_P (next)) > reg_pending_barrier = MOVE_BARRIER; > else > @@ -3370,10 +3366,8 @@ deps_start_bb (struct deps_desc *deps, r > hard registers correct. */ > if (! reload_completed && !LABEL_P (head)) > { > - rtx insn = prev_nonnote_insn (head); > + rtx insn = prev_nonnote_nondebug_insn (head); > > - while (insn && DEBUG_INSN_P (insn)) > - insn = prev_nonnote_insn (insn); > if (insn && CALL_P (insn)) > deps->in_post_call_group_p = post_call_initial; > } > --- gcc/postreload.c.jj 2010-07-28 10:36:00.000000000 +0200 > +++ gcc/postreload.c 2010-07-30 13:29:19.000000000 +0200 > @@ -1113,7 +1113,7 @@ reload_combine_recognize_pattern (rtx in > && last_label_ruid < reg_state[regno].use_ruid) > { > rtx base = XEXP (src, 1); > - rtx prev = prev_nonnote_insn (insn); > + rtx prev = prev_nonnote_nondebug_insn (insn); > rtx prev_set = prev ? single_set (prev) : NULL_RTX; > rtx index_reg = NULL_RTX; > rtx reg_sum = NULL_RTX; > @@ -1852,7 +1852,7 @@ reload_cse_move2add (rtx first) > && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), > reg_mode[REGNO (src)])) > { > - rtx next = next_nonnote_insn (insn); > + rtx next = next_nonnote_nondebug_insn (insn); > rtx set = NULL_RTX; > if (next) > set = single_set (next); > --- gcc/rtlanal.c.jj 2010-07-09 13:44:24.000000000 +0200 > +++ gcc/rtlanal.c 2010-07-30 13:33:20.000000000 +0200 > @@ -4756,9 +4756,7 @@ canonicalize_condition (rtx insn, rtx co > stop if it isn't a single set or if it has a REG_INC note because > we don't want to bother dealing with it. */ > > - do > - prev = prev_nonnote_insn (prev); > - while (prev && DEBUG_INSN_P (prev)); > + prev = prev_nonnote_nondebug_insn (prev); > > if (prev == 0 > || !NONJUMP_INSN_P (prev) > --- gcc/testsuite/gcc.dg/pr45055.c.jj 2010-07-30 13:45:47.000000000 +0200 > +++ gcc/testsuite/gcc.dg/pr45055.c 2010-07-30 13:45:15.000000000 +0200 > @@ -0,0 +1,41 @@ > +/* PR debug/45055 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -ftracer -fsched-pressure -funroll-loops -fschedule-insns -fcompare-debug" } */ > + > +int colormap[10]; > + > +extern int bar (); > + > +void > +foo (int *img, int fp, int y, int *ptr, int depth, int c, int t, int xm) > +{ > + int x, color, count; > + for (; y; y--) > + { > + if (depth) > + { > + count = bar (); > + for (x = xm; x; x--) > + { > + if (c != 1) > + count = color = -1; > + if (count == 0) > + color = count = bar (); > + if (color) > + t = bar (fp); > + *ptr++ = colormap[t]; > + } > + } > + switch (*img) > + { > + case 1: > + bar (); > + case 3: > + case -1: > + case -3: > + bar (); > + case -4: > + bar (); > + } > + } > +} > > Jakub > >
--- gcc/rtl.h.jj 2010-07-29 17:46:42.000000000 +0200 +++ gcc/rtl.h 2010-07-30 13:28:44.000000000 +0200 @@ -1693,6 +1693,8 @@ extern rtx next_nonnote_insn (rtx); extern rtx next_nonnote_insn_bb (rtx); extern rtx prev_nondebug_insn (rtx); extern rtx next_nondebug_insn (rtx); +extern rtx prev_nonnote_nondebug_insn (rtx); +extern rtx next_nonnote_nondebug_insn (rtx); extern rtx prev_real_insn (rtx); extern rtx next_real_insn (rtx); extern rtx prev_active_insn (rtx); --- gcc/emit-rtl.c.jj 2010-07-16 17:55:08.000000000 +0200 +++ gcc/emit-rtl.c 2010-07-30 13:15:52.000000000 +0200 @@ -3135,6 +3135,38 @@ prev_nondebug_insn (rtx insn) return insn; } +/* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN. + This routine does not look inside SEQUENCEs. */ + +rtx +next_nonnote_nondebug_insn (rtx insn) +{ + while (insn) + { + insn = NEXT_INSN (insn); + if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn))) + break; + } + + return insn; +} + +/* Return the previous insn before INSN that is not a NOTE nor DEBUG_INSN. + This routine does not look inside SEQUENCEs. */ + +rtx +prev_nonnote_nondebug_insn (rtx insn) +{ + while (insn) + { + insn = PREV_INSN (insn); + if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn))) + break; + } + + return insn; +} + /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN; or 0, if there is none. This routine does not look inside SEQUENCEs. */ --- gcc/combine.c.jj 2010-07-29 17:16:14.000000000 +0200 +++ gcc/combine.c 2010-07-30 13:37:04.000000000 +0200 @@ -12654,29 +12654,6 @@ reg_bitfield_target_p (rtx x, rtx body) return 0; } - -/* Return the next insn after INSN that is neither a NOTE nor a - DEBUG_INSN. This routine does not look inside SEQUENCEs. */ - -static rtx -next_nonnote_nondebug_insn (rtx insn) -{ - while (insn) - { - insn = NEXT_INSN (insn); - if (insn == 0) - break; - if (NOTE_P (insn)) - continue; - if (DEBUG_INSN_P (insn)) - continue; - break; - } - - return insn; -} - - /* Given a chain of REG_NOTES originally from FROM_INSN, try to place them as appropriate. I3 and I2 are the insns resulting from the combination --- gcc/ifcvt.c.jj 2010-07-09 13:44:24.000000000 +0200 +++ gcc/ifcvt.c 2010-07-30 13:31:37.000000000 +0200 @@ -2368,9 +2368,7 @@ noce_process_if_block (struct noce_if_in } else { - insn_b = prev_nonnote_insn (if_info->cond_earliest); - while (insn_b && DEBUG_INSN_P (insn_b)) - insn_b = prev_nonnote_insn (insn_b); + insn_b = prev_nonnote_nondebug_insn (if_info->cond_earliest); /* We're going to be moving the evaluation of B down from above COND_EARLIEST to JUMP. Make sure the relevant data is still intact. */ --- gcc/haifa-sched.c.jj 2010-07-09 13:44:24.000000000 +0200 +++ gcc/haifa-sched.c 2010-07-30 13:30:36.000000000 +0200 @@ -2003,13 +2003,9 @@ queue_to_ready (struct ready_list *ready q_ptr = NEXT_Q (q_ptr); if (dbg_cnt (sched_insn) == false) - { - /* If debug counter is activated do not requeue insn next after - last_scheduled_insn. */ - skip_insn = next_nonnote_insn (last_scheduled_insn); - while (skip_insn && DEBUG_INSN_P (skip_insn)) - skip_insn = next_nonnote_insn (skip_insn); - } + /* If debug counter is activated do not requeue insn next after + last_scheduled_insn. */ + skip_insn = next_nonnote_nondebug_insn (last_scheduled_insn); else skip_insn = NULL_RTX; --- gcc/sched-deps.c.jj 2010-07-09 13:44:24.000000000 +0200 +++ gcc/sched-deps.c 2010-07-30 13:34:37.000000000 +0200 @@ -1521,9 +1521,7 @@ fixup_sched_groups (rtx insn) delete_all_dependences (insn); - prev_nonnote = prev_nonnote_insn (insn); - while (DEBUG_INSN_P (prev_nonnote)) - prev_nonnote = prev_nonnote_insn (prev_nonnote); + prev_nonnote = prev_nonnote_nondebug_insn (insn); if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote) && ! sched_insns_conditions_mutex_p (insn, prev_nonnote)) add_dependence (insn, prev_nonnote, REG_DEP_ANTI); @@ -2699,9 +2697,7 @@ sched_analyze_insn (struct deps_desc *de if (JUMP_P (insn)) { rtx next; - next = next_nonnote_insn (insn); - while (next && DEBUG_INSN_P (next)) - next = next_nonnote_insn (next); + next = next_nonnote_nondebug_insn (insn); if (next && BARRIER_P (next)) reg_pending_barrier = MOVE_BARRIER; else @@ -3370,10 +3366,8 @@ deps_start_bb (struct deps_desc *deps, r hard registers correct. */ if (! reload_completed && !LABEL_P (head)) { - rtx insn = prev_nonnote_insn (head); + rtx insn = prev_nonnote_nondebug_insn (head); - while (insn && DEBUG_INSN_P (insn)) - insn = prev_nonnote_insn (insn); if (insn && CALL_P (insn)) deps->in_post_call_group_p = post_call_initial; } --- gcc/postreload.c.jj 2010-07-28 10:36:00.000000000 +0200 +++ gcc/postreload.c 2010-07-30 13:29:19.000000000 +0200 @@ -1113,7 +1113,7 @@ reload_combine_recognize_pattern (rtx in && last_label_ruid < reg_state[regno].use_ruid) { rtx base = XEXP (src, 1); - rtx prev = prev_nonnote_insn (insn); + rtx prev = prev_nonnote_nondebug_insn (insn); rtx prev_set = prev ? single_set (prev) : NULL_RTX; rtx index_reg = NULL_RTX; rtx reg_sum = NULL_RTX; @@ -1852,7 +1852,7 @@ reload_cse_move2add (rtx first) && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[REGNO (src)])) { - rtx next = next_nonnote_insn (insn); + rtx next = next_nonnote_nondebug_insn (insn); rtx set = NULL_RTX; if (next) set = single_set (next); --- gcc/rtlanal.c.jj 2010-07-09 13:44:24.000000000 +0200 +++ gcc/rtlanal.c 2010-07-30 13:33:20.000000000 +0200 @@ -4756,9 +4756,7 @@ canonicalize_condition (rtx insn, rtx co stop if it isn't a single set or if it has a REG_INC note because we don't want to bother dealing with it. */ - do - prev = prev_nonnote_insn (prev); - while (prev && DEBUG_INSN_P (prev)); + prev = prev_nonnote_nondebug_insn (prev); if (prev == 0 || !NONJUMP_INSN_P (prev) --- gcc/testsuite/gcc.dg/pr45055.c.jj 2010-07-30 13:45:47.000000000 +0200 +++ gcc/testsuite/gcc.dg/pr45055.c 2010-07-30 13:45:15.000000000 +0200 @@ -0,0 +1,41 @@ +/* PR debug/45055 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftracer -fsched-pressure -funroll-loops -fschedule-insns -fcompare-debug" } */ + +int colormap[10]; + +extern int bar (); + +void +foo (int *img, int fp, int y, int *ptr, int depth, int c, int t, int xm) +{ + int x, color, count; + for (; y; y--) + { + if (depth) + { + count = bar (); + for (x = xm; x; x--) + { + if (c != 1) + count = color = -1; + if (count == 0) + color = count = bar (); + if (color) + t = bar (fp); + *ptr++ = colormap[t]; + } + } + switch (*img) + { + case 1: + bar (); + case 3: + case -1: + case -3: + bar (); + case -4: + bar (); + } + } +}