This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [dataflow]: PATCH: fix regressions on IA64/PPC, add more debug points.


Ok to check in.

kenny.

Seongbae Park wrote:
> Bootstrapped and regression tested on x86, x86-64, PPC and ia64.
> This patch clears up all dataflow branch regressions on above platforms,
> except a few extra regressions on x86 (32bit) due to a latent bug
> which Ken Zadeck is already working on.
>
>
> 2006-12-01  Seongbae Park <seongbae.park@gmail.com>
>
>        * dbgcnt.def: New counters
>        * postreload-gcse.c (delete_redundant_insns_1): New
>        debug counter point.
>        * postreload.c (reload_cse_move2add, gate_handle_postreload):
>        New debug counter point.
>        * auto-inc-dec.c (move_notes): Removed.
>        (move_dead_notes): New function.
>        (attempt_change): Call move_dead_notes(). Add missing
> dependency check.
>        * haifa-sched.c (schedule_block): New debug counter point.
>        * cse.c (delete_trivially_dead_insns): New debug counter point.
>        * gcse.c (pre_delete): New debug counter point.
>        * Makefile.in: Adding dependency on DBGCNT_H.
>        * sched-rgn.c (schedule_region): New debug counter point.
>        * dce.c (delete_corresponding_reg_equal_notes): New function
>        (delete_unmarked_insns): Call
> delete_corresponding_reg_equal_notes.
>
> ------------------------------------------------------------------------
>
> Index: gcc/dbgcnt.def
> ===================================================================
> --- gcc/dbgcnt.def	(revision 119428)
> +++ gcc/dbgcnt.def	(working copy)
> @@ -74,3 +74,10 @@ DEBUG_COUNTER (sched2_func)
>  DEBUG_COUNTER (local_alloc_for_sched)
>  DEBUG_COUNTER (split_for_sched2)
>  DEBUG_COUNTER (ia64_sched2)
> +DEBUG_COUNTER (pre_insn)
> +DEBUG_COUNTER (sched_block)
> +DEBUG_COUNTER (sched_insn)
> +DEBUG_COUNTER (gcse2_delete)
> +DEBUG_COUNTER (cse2_move2add)
> +DEBUG_COUNTER (delete_trivial_dead)
> +DEBUG_COUNTER (postreload_cse)
> Index: gcc/postreload-gcse.c
> ===================================================================
> --- gcc/postreload-gcse.c	(revision 119428)
> +++ gcc/postreload-gcse.c	(working copy)
> @@ -46,6 +46,7 @@ Software Foundation, 51 Franklin Street,
>  #include "target.h"
>  #include "timevar.h"
>  #include "tree-pass.h"
> +#include "dbgcnt.h"
>  
>  /* The following code implements gcse after reload, the purpose of this
>     pass is to cleanup redundant loads generated by reload and other
> @@ -1290,7 +1291,7 @@ delete_redundant_insns_1 (void **slot, v
>  
>    for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
>      {
> -      if (occr->deleted_p)
> +      if (occr->deleted_p && dbg_cnt (gcse2_delete))
>  	{
>  	  delete_insn (occr->insn);
>  	  stats.insns_deleted++;
> Index: gcc/postreload.c
> ===================================================================
> --- gcc/postreload.c	(revision 119428)
> +++ gcc/postreload.c	(working copy)
> @@ -47,6 +47,7 @@ Software Foundation, 51 Franklin Street,
>  #include "timevar.h"
>  #include "tree-pass.h"
>  #include "df.h"
> +#include "dbgcnt.h"
>  
>  static int reload_cse_noop_set_p (rtx);
>  static void reload_cse_simplify (rtx, rtx);
> @@ -1227,7 +1228,8 @@ reload_cse_move2add (rtx first)
>  	  /* Check if we have valid information on the contents of this
>  	     register in the mode of REG.  */
>  	  if (reg_set_luid[regno] > move2add_last_label_luid
> -	      && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno]))
> +	      && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno])
> +              && dbg_cnt (cse2_move2add))
>  	    {
>  	      /* Try to transform (set (REGX) (CONST_INT A))
>  				  ...
> @@ -1574,6 +1576,9 @@ gate_handle_postreload (void)
>  static unsigned int
>  rest_of_handle_postreload (void)
>  {
> +  if (!dbg_cnt (postreload_cse))
> +    return 0;
> +
>    /* Do a very simple CSE pass over just the hard registers.  */
>    reload_cse_regs (get_insns ());
>    /* Reload_cse_regs can eliminate potentially-trapping MEMs.
> Index: gcc/auto-inc-dec.c
> ===================================================================
> --- gcc/auto-inc-dec.c	(revision 119428)
> +++ gcc/auto-inc-dec.c	(working copy)
> @@ -452,39 +452,34 @@ static rtx * reg_next_def = NULL;
>  static struct df *df = NULL;
>  
>  
> -/* Move notes that match PATTERN to TO_INSN from FROM_INSN.  If
> -   PATTERN is NULL, move all notes.  */
> +/* Move dead note that match PATTERN to TO_INSN from FROM_INSN.  We do
> +   not really care about moving any other notes from the inc or add
> +   insn.  Moving the REG_EQUAL and REG_EQUIV is clearly wrong and it
> +   does not appear that there are any other kinds of relavant notes.  */
>  
>  static void 
> -move_notes (rtx to_insn, rtx from_insn, rtx pattern)
> +move_dead_notes (rtx to_insn, rtx from_insn, rtx pattern)
>  {
>    rtx note; 
>    rtx next_note;
>    rtx prev_note = NULL;
>  
> -  if (pattern)
> -    for (note = REG_NOTES (from_insn); note; note = next_note)
> -      {
> -	next_note = XEXP (note, 1);
> -	
> -	if (pattern == XEXP (note, 0))
> -	  {
> -	    XEXP (note, 1) = REG_NOTES (to_insn);
> -	    REG_NOTES (to_insn) = note;
> -	    if (prev_note)
> -	      XEXP (prev_note, 1) = next_note;
> -	    else
> -	      REG_NOTES (from_insn) = next_note;
> -	  }
> -	else prev_note = note;
> -      }
> -  else
> -    for (note = REG_NOTES (from_insn); note; note = next_note)
> -      {
> -	next_note = XEXP (note, 1);
> -	XEXP (note, 1) = REG_NOTES (to_insn);
> -	REG_NOTES (to_insn) = note;
> -      }
> +  for (note = REG_NOTES (from_insn); note; note = next_note)
> +    {
> +      next_note = XEXP (note, 1);
> +      
> +      if ((REG_NOTE_KIND(note) == REG_DEAD)
> +	  && pattern == XEXP (note, 0))
> +	{
> +	  XEXP (note, 1) = REG_NOTES (to_insn);
> +	  REG_NOTES (to_insn) = note;
> +	  if (prev_note)
> +	    XEXP (prev_note, 1) = next_note;
> +	  else
> +	    REG_NOTES (from_insn) = next_note;
> +	}
> +      else prev_note = note;
> +    }
>  }
>  
>  
> @@ -565,9 +560,9 @@ attempt_change (rtx new_addr_pat, rtx in
>    switch (inc_insn.form)
>      {
>      case FORM_PRE_ADD:
> -      move_notes (mem_insn.insn, inc_insn.insn, NULL);
>        mov_insn = insert_move_insn_before (mem_insn.insn, 
>  					  inc_insn.reg_res, inc_insn.reg0);
> +      move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
>  
>        regno = REGNO (inc_insn.reg_res);
>        reg_next_def [regno] = mov_insn;
> @@ -583,7 +578,6 @@ attempt_change (rtx new_addr_pat, rtx in
>  
>        /* Fallthru.  */
>      case FORM_PRE_INC:
> -      move_notes (mem_insn.insn, inc_insn.insn, NULL);
>        regno = REGNO (inc_insn.reg_res);
>        reg_next_def [regno] = mem_insn.insn;
>        reg_next_use [regno] = NULL;
> @@ -593,9 +587,7 @@ attempt_change (rtx new_addr_pat, rtx in
>      case FORM_POST_ADD:
>        mov_insn = insert_move_insn_before (mem_insn.insn, 
>  					  inc_insn.reg_res, inc_insn.reg0);
> -      move_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
> -      move_notes (mem_insn.insn, inc_insn.insn, inc_insn.reg1);
> -      move_notes (mem_insn.insn, inc_insn.insn, inc_insn.reg_res);
> +      move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
>  
>        /* Do not move anything to the mov insn because the instruction
>  	 pointer for the main iteration has not yet hit that.  It is
> @@ -1096,7 +1088,20 @@ find_inc (bool first_try)
>  	{
>  	  if (dump_file)
>  	    fprintf (dump_file, 
> -		     "result of inc is assigned to between mem and inc insns.\n");
> +		     "result of add is assigned to between mem and inc insns.\n");
> +	  return false;
> +	}
> +
> +      other_insn = get_next_ref (REGNO (inc_insn.reg_res), 
> +				 BASIC_BLOCK (BLOCK_NUM (mem_insn.insn)), 
> +				 reg_next_use);
> +      if (other_insn 
> +	  && (other_insn != inc_insn.insn)
> +	  && (DF_INSN_LUID (df, inc_insn.insn) > DF_INSN_LUID (df, other_insn)))
> +	{
> +	  if (dump_file)
> +	    fprintf (dump_file, 
> +		     "result of add is used between mem and inc insns.\n");
>  	  return false;
>  	}
>  
> Index: gcc/haifa-sched.c
> ===================================================================
> --- gcc/haifa-sched.c	(revision 119428)
> +++ gcc/haifa-sched.c	(working copy)
> @@ -144,6 +144,7 @@ Software Foundation, 51 Franklin Street,
>  #include "target.h"
>  #include "output.h"
>  #include "params.h"
> +#include "dbgcnt.h"
>  
>  #ifdef INSN_SCHEDULING
>  
> @@ -2294,8 +2295,6 @@ schedule_block (basic_block *target_bb, 
>  		 there's nothing better to do (ready list is empty) but
>  		 there are still vacant dispatch slots in the current cycle.  */
>  	      if (sched_verbose >= 6)
> -		fprintf(sched_dump,";;\t\tSecond chance\n");
> -	      memcpy (temp_state, curr_state, dfa_state_size);
>  	      if (early_queue_to_ready (temp_state, &ready))
>  		ready_sort (&ready);
>  	    }
> @@ -2305,6 +2304,23 @@ schedule_block (basic_block *target_bb, 
>  	      || !(*current_sched_info->schedule_more_p) ())
>  	    break;
>  
> +          if (dbg_cnt (sched_insn) == false)
> +            {
> +              insn = NEXT_INSN (last_scheduled_insn); 
> +              while ((*current_sched_info->schedule_more_p) ())
> +                {
> +                  (*current_sched_info->begin_schedule_ready) (insn,
> +                                                               last_scheduled_insn);
> +                  if (QUEUE_INDEX (insn) >= 0)
> +                    queue_remove (insn);
> +                  last_scheduled_insn = insn;
> +                  insn = NEXT_INSN (insn);
> +                }
> +              while (ready.n_ready)
> +                ready_remove_first (&ready);
> +              goto bail_out;
> +            }
> +
>  	  /* Select and remove the insn from the ready list.  */
>  	  if (sort_p)
>  	    {
> @@ -2462,6 +2478,7 @@ schedule_block (basic_block *target_bb, 
>  	}
>      }
>  
> +bail_out:
>    /* Debug info.  */
>    if (sched_verbose)
>      {
> Index: gcc/cse.c
> ===================================================================
> --- gcc/cse.c	(revision 119428)
> +++ gcc/cse.c	(working copy)
> @@ -44,6 +44,7 @@ Software Foundation, 51 Franklin Street,
>  #include "params.h"
>  #include "rtlhooks-def.h"
>  #include "tree-pass.h"
> +#include "dbgcnt.h"
>  
>  /* The basic idea of common subexpression elimination is to go
>     through the code, keeping a record of expressions that would
> @@ -6541,7 +6542,7 @@ delete_trivially_dead_insns (rtx insns, 
>        /* If this is a dead insn, delete it and show registers in it aren't
>  	 being used.  */
>  
> -      if (! live_insn)
> +      if (! live_insn && dbg_cnt (delete_trivial_dead))
>  	{
>  	  count_reg_usage (insn, counts, NULL_RTX, -1);
>  	  delete_insn_and_edges (insn);
> Index: gcc/gcse.c
> ===================================================================
> --- gcc/gcse.c	(revision 119428)
> +++ gcc/gcse.c	(working copy)
> @@ -171,6 +171,7 @@ Software Foundation, 51 Franklin Street,
>  #include "timevar.h"
>  #include "tree-pass.h"
>  #include "hashtab.h"
> +#include "dbgcnt.h"
>  
>  /* Propagate flow information through back edges and thus enable PRE's
>     moving loop invariant calculations out of loops.
> @@ -4437,7 +4438,8 @@ pre_delete (void)
>  
>  	    /* We only delete insns that have a single_set.  */
>  	    if (TEST_BIT (pre_delete_map[bb->index], indx)
> -		&& (set = single_set (insn)) != 0)
> +		&& (set = single_set (insn)) != 0
> +                && dbg_cnt (pre_insn))
>  	      {
>  		/* Create a pseudo-reg to store the result of reaching
>  		   expressions into.  Get the mode for the new pseudo from
> Index: gcc/Makefile.in
> ===================================================================
> --- gcc/Makefile.in	(revision 119428)
> +++ gcc/Makefile.in	(working copy)
> @@ -2342,7 +2342,8 @@ cselib.o : cselib.c $(CONFIG_H) $(SYSTEM
>  cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
>     hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
>     output.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \
> -   except.h $(TARGET_H) $(PARAMS_H) rtlhooks-def.h tree-pass.h $(REAL_H)
> +   except.h $(TARGET_H) $(PARAMS_H) rtlhooks-def.h tree-pass.h $(REAL_H) \
> +   $(DBGCNT_H)
>  dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
>     $(TREE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(DF_H) cselib.h \
>     $(DBGCNT_H) dce.h timevar.h tree-pass.h
> @@ -2359,7 +2360,7 @@ gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) 
>     $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \
>     $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
>     $(TM_P_H) $(PARAMS_H) except.h gt-gcse.h $(TREE_H) cselib.h $(TIMEVAR_H) \
> -   intl.h $(OBSTACK_H) tree-pass.h
> +   intl.h $(OBSTACK_H) tree-pass.h $(DBGCNT_H)
>  resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
>     coretypes.h $(TM_H) $(REGS_H) $(FLAGS_H) output.h $(RESOURCE_H) $(DF_H) \
>     $(FUNCTION_H) toplev.h $(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H)
> @@ -2536,7 +2537,7 @@ postreload-gcse.o : postreload-gcse.c $(
>     $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
>     $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
>     $(TM_P_H) except.h $(TREE_H) $(TARGET_H) $(HASHTAB_H) intl.h $(OBSTACK_H) \
> -   $(PARAMS_H) $(TIMEVAR_H) tree-pass.h $(REAL_H)
> +   $(PARAMS_H) $(TIMEVAR_H) tree-pass.h $(REAL_H) $(DBGCNT_H)
>  caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
>     $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
>     addresses.h $(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H)
> @@ -2577,7 +2578,7 @@ modulo-sched.o : modulo-sched.c $(DDG_H)
>  haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
>     $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
>     $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H) output.h \
> -   $(PARAMS_H)
> +   $(PARAMS_H) $(DBGCNT_H)
>  sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>     $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
>     $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h cselib.h \
> Index: gcc/sched-rgn.c
> ===================================================================
> --- gcc/sched-rgn.c	(revision 119428)
> +++ gcc/sched-rgn.c	(working copy)
> @@ -2800,9 +2800,16 @@ schedule_region (int rgn)
>        current_sched_info->queue_must_finish_empty = current_nr_blocks == 1;
>  
>        curr_bb = first_bb;
> -      schedule_block (&curr_bb, rgn_n_insns);
> -      gcc_assert (EBB_FIRST_BB (bb) == first_bb);
> -      sched_rgn_n_insns += sched_n_insns;
> +      if (dbg_cnt (sched_block))
> +        {
> +          schedule_block (&curr_bb, rgn_n_insns);
> +          gcc_assert (EBB_FIRST_BB (bb) == first_bb);
> +          sched_rgn_n_insns += sched_n_insns;
> +        }
> +      else
> +        {
> +          sched_rgn_n_insns += rgn_n_insns;
> +        }
>  
>        /* Clean up.  */
>        if (current_nr_blocks > 1)
> Index: gcc/dce.c
> ===================================================================
> --- gcc/dce.c	(revision 119428)
> +++ gcc/dce.c	(working copy)
> @@ -213,6 +213,46 @@ init_dce (bool fast)
>  }
>  
>  
> +/* Delete all REG_EQUAL notes of the registers INSN writes,
> +   to prevent bad dangling REG_EQUAL notes. */
> +
> +static void
> +delete_corresponding_reg_equal_notes (rtx insn)
> +{
> +  struct df_ref *def;
> +  for (def = DF_INSN_DEFS (dce_df, insn); def; def = DF_REF_NEXT_REF (def))
> +    {
> +      struct df_ref *eq_use = DF_REG_EQ_USE_CHAIN (dce_df, DF_REF_REGNO (def));
> +
> +      if (eq_use)
> +        {
> +          rtx *insns = alloca (sizeof(rtx) 
> +                               * DF_REG_EQ_USE_COUNT (dce_df, DF_REF_REGNO (def)));
> +          rtx *p_insn = insns;
> +          do
> +            {
> +              rtx note;
> +              if (DF_REF_INSN (eq_use) != insn
> +                  && (note = find_reg_note (DF_REF_INSN (eq_use), 
> +                                            REG_EQUAL, NULL_RTX)) != NULL)
> +                {
> +                  remove_note (DF_REF_INSN (eq_use), note);
> +                  /* We can't rescan while iterating over EQ_USE chain,
> +                     because rescanning invalidates EQ_USE chain. 
> +                     Instead, we just keep the record of the insns. */
> +                  *p_insn++ = DF_REF_INSN (eq_use);
> +                }
> +            }
> +          while ((eq_use = DF_REF_NEXT_REG (eq_use)) != NULL);
> +
> +          /* Now rescan insns that have REG_EQUAL note removed.  */
> +          while (--p_insn >= insns)
> +            df_insn_rescan (*p_insn);
> +        }
> +    }
> +}
> +
> +
>  /* Delete every instruction that hasn't been marked.  Clear the insn from DCE_DF if
>     DF_DELETE is true.  */
>  
> @@ -232,6 +272,11 @@ delete_unmarked_insns (void)
>  	  if (dump_file)
>  	    fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));
>  	  /* XXX: This may need to be changed to delete_insn_and_edges */
> +
> +          /* Before we delete the insn, we have to delete
> +             REG_EQUAL of the destination regs of the deleted insn
> +             to prevent dangling REG_EQUAL. */
> +          delete_corresponding_reg_equal_notes (insn);
>  	  delete_insn (insn);
>  	  something_changed = true;
>  	}
>   


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]