Large gcse.c patch

Jeffrey A Law law@hurl.cygnus.com
Wed Mar 10 21:29:00 GMT 1999


Another gcse.c cleanup patch.  Rather large this time.  3-stages on the x86.

It's amazing how much code can change in a year.


        * gcse.c: More comments, whitespace and similar fixes.
        (dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
        (dump_pre_data, compute_cprop_local_properties): Likewise.
        (one_classic_gcse_pass): Lose unused argument.  All callers changed.
        (compute_hash_table, compute_expr_hash_table): Likewise.
        (compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
        (cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
        All callers changed.  Only alter jumps if ALTER_JUMPS is nonzero.
        Lose unused argument.
        (gcse_main): Always run a cprop pass after finishing global cse.
        (compute_local_properties): New function.
        (hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
        (compute_cprop_data): Use compute_local_properties.

Index: gcse.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/gcse.c,v
retrieving revision 1.31
diff -c -3 -p -r1.31 gcse.c
*** gcse.c	1999/03/10 20:18:59	1.31
--- gcse.c	1999/03/11 05:22:25
*************** static sbitmap *rd_kill, *rd_gen, *reach
*** 509,514 ****
--- 509,515 ----
  
  /* for available exprs */
  static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
+ 
  
  static void compute_can_copy	  PROTO ((void));
  
*************** static char *grealloc		 PROTO ((char *, 
*** 517,524 ****
  static char *gcse_alloc	       PROTO ((unsigned long));
  static void alloc_gcse_mem	    PROTO ((rtx));
  static void free_gcse_mem	     PROTO ((void));
- extern void dump_cuid_table	   PROTO ((FILE *));
- 
  static void alloc_reg_set_mem	 PROTO ((int));
  static void free_reg_set_mem	  PROTO ((void));
  static void record_one_set	    PROTO ((int, rtx));
--- 518,523 ----
*************** static void hash_scan_insn	    PROTO ((r
*** 529,606 ****
  static void hash_scan_set	     PROTO ((rtx, rtx, int));
  static void hash_scan_clobber	 PROTO ((rtx, rtx));
  static void hash_scan_call	    PROTO ((rtx, rtx));
- static void maybe_set_rd_gen	  PROTO ((int, rtx));
  static int want_to_gcse_p	     PROTO ((rtx));
  static int oprs_unchanged_p	   PROTO ((rtx, rtx, int));
  static int oprs_anticipatable_p       PROTO ((rtx, rtx));
  static int oprs_available_p	   PROTO ((rtx, rtx));
! static void insert_expr_in_table      PROTO ((rtx, enum machine_mode, rtx, int, int));
  static void insert_set_in_table       PROTO ((rtx, rtx));
! static unsigned int hash_expr	 PROTO ((rtx, enum machine_mode, int *, int));
  static unsigned int hash_expr_1       PROTO ((rtx, enum machine_mode, int *));
  static unsigned int hash_set	  PROTO ((int, int));
  static int expr_equiv_p	       PROTO ((rtx, rtx));
  static void record_last_reg_set_info  PROTO ((rtx, int));
  static void record_last_mem_set_info  PROTO ((rtx));
  static void record_last_set_info      PROTO ((rtx, rtx));
! static void compute_hash_table	PROTO ((rtx, int));
  static void alloc_set_hash_table      PROTO ((int));
  static void free_set_hash_table       PROTO ((void));
! static void compute_set_hash_table    PROTO ((rtx));
  static void alloc_expr_hash_table     PROTO ((int));
  static void free_expr_hash_table      PROTO ((void));
! static void compute_expr_hash_table   PROTO ((rtx));
  static void dump_hash_table	   PROTO ((FILE *, const char *, struct expr **, int, int));
  static struct expr *lookup_expr       PROTO ((rtx));
  static struct expr *lookup_set	PROTO ((int, rtx));
  static struct expr *next_set	  PROTO ((int, struct expr *));
  static void reset_opr_set_tables      PROTO ((void));
  static int oprs_not_set_p	     PROTO ((rtx, rtx));
! static void mark_call		 PROTO ((rtx, rtx));
  static void mark_set		  PROTO ((rtx, rtx));
  static void mark_clobber	      PROTO ((rtx, rtx));
  static void mark_oprs_set	     PROTO ((rtx));
  
- static void alloc_rd_mem	      PROTO ((int, int));
- static void free_rd_mem	       PROTO ((void));
- static void compute_kill_rd	   PROTO ((void));
- static void handle_rd_kill_set	PROTO ((rtx, int, int));
- static void compute_rd		PROTO ((void));
- extern void dump_rd_table	     PROTO ((FILE *, char *, sbitmap *));
- 
- static void alloc_avail_expr_mem      PROTO ((int, int));
- static void free_avail_expr_mem       PROTO ((void));
- static void compute_ae_gen	    PROTO ((void));
- static void compute_ae_kill	   PROTO ((void));
- static int expr_killed_p	      PROTO ((rtx, int));
- static void compute_available	 PROTO ((void));
- 
- static int expr_reaches_here_p	PROTO ((struct occr *, struct expr *,
- 					      int, int, char *));
- static rtx computing_insn	     PROTO ((struct expr *, rtx));
- static int def_reaches_here_p	 PROTO ((rtx, rtx));
- static int can_disregard_other_sets   PROTO ((struct reg_set **, rtx, int));
- static int handle_avail_expr	  PROTO ((rtx, struct expr *));
- static int classic_gcse	       PROTO ((void));
- static int one_classic_gcse_pass      PROTO ((rtx, int));
- 
  static void alloc_cprop_mem	   PROTO ((int, int));
  static void free_cprop_mem	    PROTO ((void));
- extern void dump_cprop_data	   PROTO ((FILE *));
  static void compute_transp	    PROTO ((rtx, int, sbitmap *, int));
! static void compute_cprop_local_properties PROTO ((void));
  static void compute_cprop_avinout     PROTO ((void));
  static void compute_cprop_data	PROTO ((void));
  static void find_used_regs	    PROTO ((rtx));
  static int try_replace_reg	    PROTO ((rtx, rtx, rtx));
  static struct expr *find_avail_set    PROTO ((int, rtx));
! static int cprop_insn		 PROTO ((rtx));
! static int cprop		      PROTO ((void));
! static int one_cprop_pass	     PROTO ((rtx, int));
  
  static void alloc_pre_mem	     PROTO ((int, int));
  static void free_pre_mem	      PROTO ((void));
- extern void dump_pre_data	     PROTO ((FILE *));
  static void compute_pre_local_properties PROTO ((void));
  static void compute_pre_avinout       PROTO ((void));
  static void compute_pre_antinout      PROTO ((void));
--- 528,582 ----
  static void hash_scan_set	     PROTO ((rtx, rtx, int));
  static void hash_scan_clobber	 PROTO ((rtx, rtx));
  static void hash_scan_call	    PROTO ((rtx, rtx));
  static int want_to_gcse_p	     PROTO ((rtx));
  static int oprs_unchanged_p	   PROTO ((rtx, rtx, int));
  static int oprs_anticipatable_p       PROTO ((rtx, rtx));
  static int oprs_available_p	   PROTO ((rtx, rtx));
! static void insert_expr_in_table      PROTO ((rtx, enum machine_mode,
! 					      rtx, int, int));
  static void insert_set_in_table       PROTO ((rtx, rtx));
! static unsigned int hash_expr	 PROTO ((rtx, enum machine_mode,
! 					 int *, int));
  static unsigned int hash_expr_1       PROTO ((rtx, enum machine_mode, int *));
  static unsigned int hash_set	  PROTO ((int, int));
  static int expr_equiv_p	       PROTO ((rtx, rtx));
  static void record_last_reg_set_info  PROTO ((rtx, int));
  static void record_last_mem_set_info  PROTO ((rtx));
  static void record_last_set_info      PROTO ((rtx, rtx));
! static void compute_hash_table	PROTO ((int));
  static void alloc_set_hash_table      PROTO ((int));
  static void free_set_hash_table       PROTO ((void));
! static void compute_set_hash_table    PROTO ((void));
  static void alloc_expr_hash_table     PROTO ((int));
  static void free_expr_hash_table      PROTO ((void));
! static void compute_expr_hash_table   PROTO ((void));
  static void dump_hash_table	   PROTO ((FILE *, const char *, struct expr **, int, int));
  static struct expr *lookup_expr       PROTO ((rtx));
  static struct expr *lookup_set	PROTO ((int, rtx));
  static struct expr *next_set	  PROTO ((int, struct expr *));
  static void reset_opr_set_tables      PROTO ((void));
  static int oprs_not_set_p	     PROTO ((rtx, rtx));
! static void mark_call		 PROTO ((rtx));
  static void mark_set		  PROTO ((rtx, rtx));
  static void mark_clobber	      PROTO ((rtx, rtx));
  static void mark_oprs_set	     PROTO ((rtx));
  
  static void alloc_cprop_mem	   PROTO ((int, int));
  static void free_cprop_mem	    PROTO ((void));
  static void compute_transp	    PROTO ((rtx, int, sbitmap *, int));
! static void compute_local_properties  PROTO ((sbitmap *, sbitmap *,
! 					      sbitmap *, int));
  static void compute_cprop_avinout     PROTO ((void));
  static void compute_cprop_data	PROTO ((void));
  static void find_used_regs	    PROTO ((rtx));
  static int try_replace_reg	    PROTO ((rtx, rtx, rtx));
  static struct expr *find_avail_set    PROTO ((int, rtx));
! static int cprop_insn		 PROTO ((rtx, int));
! static int cprop		      PROTO ((int));
! static int one_cprop_pass	     PROTO ((int, int));
  
  static void alloc_pre_mem	     PROTO ((int, int));
  static void free_pre_mem	      PROTO ((void));
  static void compute_pre_local_properties PROTO ((void));
  static void compute_pre_avinout       PROTO ((void));
  static void compute_pre_antinout      PROTO ((void));
*************** static void pre_insert_copy_insn      PR
*** 615,623 ****
  static void pre_insert_copies	 PROTO ((void));
  static int pre_delete		 PROTO ((void));
  static int pre_gcse		   PROTO ((void));
! static int one_pre_gcse_pass	  PROTO ((rtx, int));
  
  static void add_label_notes	      PROTO ((rtx, rtx));
  
  /* Entry point for global common subexpression elimination.
     F is the first instruction in the function.  */
--- 591,620 ----
  static void pre_insert_copies	 PROTO ((void));
  static int pre_delete		 PROTO ((void));
  static int pre_gcse		   PROTO ((void));
! static int one_pre_gcse_pass	  PROTO ((int));
  
  static void add_label_notes	      PROTO ((rtx, rtx));
+ 
+ static void alloc_rd_mem	      PROTO ((int, int));
+ static void free_rd_mem	       PROTO ((void));
+ static void handle_rd_kill_set	PROTO ((rtx, int, int));
+ static void compute_kill_rd	   PROTO ((void));
+ static void compute_rd		PROTO ((void));
+ static void alloc_avail_expr_mem      PROTO ((int, int));
+ static void free_avail_expr_mem       PROTO ((void));
+ static void compute_ae_gen	    PROTO ((void));
+ static int expr_killed_p	      PROTO ((rtx, int));
+ static void compute_ae_kill	   PROTO ((void));
+ static void compute_available	 PROTO ((void));
+ static int expr_reaches_here_p	PROTO ((struct occr *, struct expr *,
+ 					      int, int, char *));
+ static rtx computing_insn	     PROTO ((struct expr *, rtx));
+ static int def_reaches_here_p	 PROTO ((rtx, rtx));
+ static int can_disregard_other_sets   PROTO ((struct reg_set **, rtx, int));
+ static int handle_avail_expr	  PROTO ((rtx, struct expr *));
+ static int classic_gcse	       PROTO ((void));
+ static int one_classic_gcse_pass      PROTO ((int));
+ 
  
  /* Entry point for global common subexpression elimination.
     F is the first instruction in the function.  */
*************** gcse_main (f, file)
*** 635,650 ****
    /* Point to release obstack data from for each pass.  */
    char *gcse_obstack_bottom;
  
!   run_jump_opt_after_gcse = 0;
! 
!   /* It's impossible to construct a correct control flow graph in the
!      presense of setjmp, so just punt to be safe.  */
    if (current_function_calls_setjmp)
      return 0;
     
    /* For calling dump_foo fns from gdb.  */
    debug_stderr = stderr;
  
    max_gcse_regno = max_reg_num ();
    find_basic_blocks (f, max_gcse_regno, file);
  
--- 632,651 ----
    /* Point to release obstack data from for each pass.  */
    char *gcse_obstack_bottom;
  
!   /* We do not construct an accurate cfg in functions which call
!      setjmp, so just punt to be safe.  */
    if (current_function_calls_setjmp)
      return 0;
     
+   /* Assume that we do not need to run jump optimizations after gcse.  */
+   run_jump_opt_after_gcse = 0;
+ 
    /* For calling dump_foo fns from gdb.  */
    debug_stderr = stderr;
+   gcse_file = file;
  
+   /* Identify the basic block information for this function, including
+      successors and predecessors.  */
    max_gcse_regno = max_reg_num ();
    find_basic_blocks (f, max_gcse_regno, file);
  
*************** gcse_main (f, file)
*** 665,672 ****
  
    gcc_obstack_init (&gcse_obstack);
  
-   gcse_file = file;
- 
    /* Allocate and compute predecessors/successors.  */
  
    s_preds = (int_list_ptr *) alloca (n_basic_blocks * sizeof (int_list_ptr));
--- 666,671 ----
*************** gcse_main (f, file)
*** 681,689 ****
  
    /* Record where pseudo-registers are set.
       This data is kept accurate during each pass.
!      ??? We could also record hard-reg and memory information here
       [since it's unchanging], however it is currently done during
!      hash table computation.  */
  
    alloc_reg_set_mem (max_gcse_regno);
    compute_sets (f);
--- 680,692 ----
  
    /* Record where pseudo-registers are set.
       This data is kept accurate during each pass.
!      ??? We could also record hard-reg information here
       [since it's unchanging], however it is currently done during
!      hash table computation.
! 
!      It may be tempting to compute MEM set information here too, but MEM
!      sets will be subject to code motion one day and thus we need to compute
!      information about memory sets when we build the hash tables.  */
  
    alloc_reg_set_mem (max_gcse_regno);
    compute_sets (f);
*************** gcse_main (f, file)
*** 708,719 ****
  
        alloc_gcse_mem (f);
  
!       changed = one_cprop_pass (f, pass + 1);
  
        if (optimize_size)
! 	changed |= one_classic_gcse_pass (f, pass + 1);
        else
! 	changed |= one_pre_gcse_pass (f, pass + 1);
  
        if (max_pass_bytes < bytes_used)
  	max_pass_bytes = bytes_used;
--- 711,724 ----
  
        alloc_gcse_mem (f);
  
!       /* Don't allow constant propagation to modify jumps
! 	 during this pass.  */
!       changed = one_cprop_pass (pass + 1, 0);
  
        if (optimize_size)
! 	changed |= one_classic_gcse_pass (pass + 1);
        else
! 	changed |= one_pre_gcse_pass (pass + 1);
  
        if (max_pass_bytes < bytes_used)
  	max_pass_bytes = bytes_used;
*************** gcse_main (f, file)
*** 729,742 ****
        pass++;
      }
  
!   /* If we're doing PRE, do one last pass of copy propagation.  */
!   if (! optimize_size)
!     {
!       max_gcse_regno = max_reg_num ();
!       alloc_gcse_mem (f);
!       one_cprop_pass (f, pass + 1);
!       free_gcse_mem ();
!     }
  
    if (file)
      {
--- 734,747 ----
        pass++;
      }
  
!   /* Do one last pass of copy propagation, including cprop into
!      conditional jumps.  */
! 
!   max_gcse_regno = max_reg_num ();
!   alloc_gcse_mem (f);
!   /* This time, go ahead and allow cprop to alter jumps.  */
!   one_cprop_pass (pass + 1, 1);
!   free_gcse_mem ();
  
    if (file)
      {
*************** free_gcse_mem ()
*** 899,921 ****
    free (mem_set_in_block);
  }
  
! void
! dump_cuid_table (file)
!      FILE *file;
  {
!   int i;
  
!   fprintf (file, "CUID table\n");
!   for (i = 0; i < max_cuid; i++)
      {
!       rtx insn = CUID_INSN (i);
!       if (i != 0 && i % 10 == 0)
! 	fprintf (file, "\n");
!       if (insn != NULL)
! 	fprintf (file, " %d", INSN_UID (insn));
      }
-   fprintf (file, "\n\n");
  }
  
  /* Register set information.
  
--- 904,1016 ----
    free (mem_set_in_block);
  }
  
! 
! /* Compute the local properties of each recorded expression.
!    Local properties are those that are defined by the block, irrespective
!    of other blocks.
! 
!    An expression is transparent in a block if its operands are not modified
!    in the block.
! 
!    An expression is computed (locally available) in a block if it is computed
!    at least once and expression would contain the same value if the
!    computation was moved to the end of the block.
! 
!    An expression is locally anticipatable in a block if it is computed at
!    least once and expression would contain the same value if the computation
!    was moved to the beginning of the block.
! 
!    We call this routine for cprop, pre and code hoisting.  They all
!    compute basically the same information and thus can easily share
!    this code.
! 
!    TRANSP, COMP, and ANTLOC are destination sbitmaps for recording
!    local properties.  If NULL, then it is not necessary to compute
!    or record that particular property.
! 
!    SETP controls which hash table to look at.  If zero, this routine
!    looks at the expr hash table; if nonzero this routine looks at
!    the set hash table.  */
!  
! static void
! compute_local_properties (transp, comp, antloc, setp)
!      sbitmap *transp;
!      sbitmap *comp;
!      sbitmap *antloc;
!      int setp;
  {
!   int i, hash_table_size;
!   struct expr **hash_table;
!   
!   /* Initialize any bitmaps that were passed in.  */
!   if (transp)
!     sbitmap_vector_ones (transp, n_basic_blocks);
!   if (comp)
!     sbitmap_vector_zero (comp, n_basic_blocks);
!   if (antloc)
!     sbitmap_vector_zero (antloc, n_basic_blocks);
! 
!   /* We use the same code for cprop, pre and hoisting.  For cprop
!      we care about the set hash table, for pre and hoisting we
!      care about the expr hash table.  */
!   hash_table_size = setp ? set_hash_table_size : expr_hash_table_size;
!   hash_table = setp ? set_hash_table : expr_hash_table;
  
!   for (i = 0; i < hash_table_size; i++)
      {
!       struct expr *expr;
! 
!       for (expr = hash_table[i]; expr != NULL; expr = expr->next_same_hash)
! 	{
! 	  struct occr *occr;
! 	  int indx = expr->bitmap_index;
! 
! 	  /* The expression is transparent in this block if it is not killed.
! 	     We start by assuming all are transparent [none are killed], and
! 	     then reset the bits for those that are.  */
! 
! 	  if (transp)
! 	    compute_transp (expr->expr, indx, transp, setp);
! 
! 	  /* The occurrences recorded in antic_occr are exactly those that
! 	     we want to set to non-zero in ANTLOC.  */
! 
! 	  if (antloc)
! 	    {
! 	      for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
! 		{
! 		  int bb = BLOCK_NUM (occr->insn);
! 		  SET_BIT (antloc[bb], indx);
! 
! 		  /* While we're scanning the table, this is a good place to
! 		     initialize this.  */
! 		  occr->deleted_p = 0;
! 		}
! 	    }
! 
! 	  /* The occurrences recorded in avail_occr are exactly those that
! 	     we want to set to non-zero in COMP.  */
! 	  if (comp)
! 	    {
! 	
! 	      for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
! 		{
! 		  int bb = BLOCK_NUM (occr->insn);
! 		  SET_BIT (comp[bb], indx);
! 
! 		  /* While we're scanning the table, this is a good place to
! 		     initialize this.  */
! 		  occr->copied_p = 0;
! 		}
! 	    }
! 
! 	  /* While we're scanning the table, this is a good place to
! 	     initialize this.  */
! 	  expr->reaching_reg = 0;
! 	}
      }
  }
+ 
  
  /* Register set information.
  
*************** static int *reg_last_set;
*** 1047,1064 ****
  static int mem_first_set;
  static int mem_last_set;
  
- /* Set the appropriate bit in `rd_gen' [the gen for reaching defs] if the
-    register set in this insn is not set after this insn in this block.  */
- 
- static void
- maybe_set_rd_gen (regno, insn)
-      int regno;
-      rtx insn;
- {
-   if (reg_last_set[regno] <= INSN_CUID (insn))
-     SET_BIT (rd_gen[BLOCK_NUM (insn)], INSN_CUID (insn));
- }
- 
  /* Perform a quick check whether X, the source of a set, is something
     we want to consider for GCSE.  */
  
--- 1142,1147 ----
*************** hash_scan_set (pat, insn, set_p)
*** 1787,1808 ****
  		       && oprs_available_p (pat, tmp))))
  	insert_set_in_table (pat, insn);
      }
- 
-   /* Check if first/last set in this block for classic gcse,
-      but not for copy/constant propagation.  */
-   if (optimize_size && !set_p)
-       
-     {
-       rtx dest = SET_DEST (pat);
- 
-       while (GET_CODE (dest) == SUBREG
- 	     || GET_CODE (dest) == ZERO_EXTRACT
- 	     || GET_CODE (dest) == SIGN_EXTRACT
- 	     || GET_CODE (dest) == STRICT_LOW_PART)
- 	dest = XEXP (dest, 0);
-       if (GET_CODE (dest) == REG)
- 	maybe_set_rd_gen (REGNO (dest), insn);
-     }
  }
  
  static void
--- 1870,1875 ----
*************** hash_scan_insn (insn, set_p, in_libcall_
*** 1857,1877 ****
  	    {
  	      if (GET_CODE (SET_SRC (x)) == CALL)
  		hash_scan_call (SET_SRC (x), insn);
- 
- 	      /* Check if first/last set in this block for classic
- 		 gcse, but not for constant/copy propagation.  */
- 	      if (optimize_size && !set_p)
- 		{
- 		  rtx dest = SET_DEST (x);
- 
- 		  while (GET_CODE (dest) == SUBREG
- 			 || GET_CODE (dest) == ZERO_EXTRACT
- 			 || GET_CODE (dest) == SIGN_EXTRACT
- 			 || GET_CODE (dest) == STRICT_LOW_PART)
- 		    dest = XEXP (dest, 0);
- 		  if (GET_CODE (dest) == REG)
- 		    maybe_set_rd_gen (REGNO (dest), insn);
- 		}
  	    }
  	  else if (GET_CODE (x) == CLOBBER)
  	    hash_scan_clobber (x, insn);
--- 1924,1929 ----
*************** record_last_set_info (dest, setter)
*** 1994,2001 ****
     SET_P is non-zero for computing the assignment hash table.  */
  
  static void
! compute_hash_table (f, set_p)
!      rtx f ATTRIBUTE_UNUSED;
       int set_p;
  {
    int bb;
--- 2046,2052 ----
     SET_P is non-zero for computing the assignment hash table.  */
  
  static void
! compute_hash_table (set_p)
       int set_p;
  {
    int bb;
*************** free_set_hash_table ()
*** 2130,2143 ****
  /* Compute the hash table for doing copy/const propagation.  */
  
  static void
! compute_set_hash_table (f)
!      rtx f;
  {
    /* Initialize count of number of entries in hash table.  */
    n_sets = 0;
    bzero ((char *) set_hash_table, set_hash_table_size * sizeof (struct expr *));
  
!   compute_hash_table (f, 1);
  }
  
  /* Allocate space for the expression hash table.
--- 2181,2193 ----
  /* Compute the hash table for doing copy/const propagation.  */
  
  static void
! compute_set_hash_table ()
  {
    /* Initialize count of number of entries in hash table.  */
    n_sets = 0;
    bzero ((char *) set_hash_table, set_hash_table_size * sizeof (struct expr *));
  
!   compute_hash_table (1);
  }
  
  /* Allocate space for the expression hash table.
*************** free_expr_hash_table ()
*** 2173,2186 ****
  /* Compute the hash table for doing GCSE.  */
  
  static void
! compute_expr_hash_table (f)
!      rtx f;
  {
    /* Initialize count of number of entries in hash table.  */
    n_exprs = 0;
    bzero ((char *) expr_hash_table, expr_hash_table_size * sizeof (struct expr *));
  
!   compute_hash_table (f, 0);
  }
  
  /* Expression tracking support.  */
--- 2223,2235 ----
  /* Compute the hash table for doing GCSE.  */
  
  static void
! compute_expr_hash_table ()
  {
    /* Initialize count of number of entries in hash table.  */
    n_exprs = 0;
    bzero ((char *) expr_hash_table, expr_hash_table_size * sizeof (struct expr *));
  
!   compute_hash_table (0);
  }
  
  /* Expression tracking support.  */
*************** repeat:
*** 2345,2352 ****
  /* Mark things set by a CALL.  */
  
  static void
! mark_call (pat, insn)
!      rtx pat ATTRIBUTE_UNUSED, insn;
  {
    mem_last_set = INSN_CUID (insn);
  }
--- 2394,2401 ----
  /* Mark things set by a CALL.  */
  
  static void
! mark_call (insn)
!      rtx insn;
  {
    mem_last_set = INSN_CUID (insn);
  }
*************** mark_set (pat, insn)
*** 2371,2377 ****
      mem_last_set = INSN_CUID (insn);
  
    if (GET_CODE (SET_SRC (pat)) == CALL)
!     mark_call (SET_SRC (pat), insn);
  }
  
  /* Record things set by a CLOBBER.  */
--- 2420,2426 ----
      mem_last_set = INSN_CUID (insn);
  
    if (GET_CODE (SET_SRC (pat)) == CALL)
!     mark_call (insn);
  }
  
  /* Record things set by a CLOBBER.  */
*************** mark_oprs_set (insn)
*** 2415,2428 ****
  	  else if (GET_CODE (x) == CLOBBER)
  	    mark_clobber (x, insn);
  	  else if (GET_CODE (x) == CALL)
! 	    mark_call (x, insn);
  	}
      }
    else if (GET_CODE (pat) == CLOBBER)
      mark_clobber (pat, insn);
    else if (GET_CODE (pat) == CALL)
!     mark_call (pat, insn);
  }
  
  /* Classic GCSE reaching definition support.  */
  
--- 2464,2478 ----
  	  else if (GET_CODE (x) == CLOBBER)
  	    mark_clobber (x, insn);
  	  else if (GET_CODE (x) == CALL)
! 	    mark_call (insn);
  	}
      }
    else if (GET_CODE (pat) == CLOBBER)
      mark_clobber (pat, insn);
    else if (GET_CODE (pat) == CALL)
!     mark_call (insn);
  }
+ 
  
  /* Classic GCSE reaching definition support.  */
  
*************** handle_rd_kill_set (insn, regno, bb)
*** 2474,2511 ****
      }
  }
  
- void
- dump_rd_table (file, title, bmap)
-      FILE *file;
-      char *title;
-      sbitmap *bmap;
- {
-   int bb,cuid,i,j,n;
- 
-   fprintf (file, "%s\n", title);
-   for (bb = 0; bb < n_basic_blocks; bb++)
-     {
-       fprintf (file, "BB %d\n", bb);
-       dump_sbitmap (file, bmap[bb]);
-       for (i = n = cuid = 0; i < bmap[bb]->size; i++)
- 	{
- 	  for (j = 0; j < SBITMAP_ELT_BITS; j++, cuid++)
- 	    {
- 	      if ((bmap[bb]->elms[i] & (1 << j)) != 0)
- 		{
- 		  if (n % 10 == 0)
- 		    fprintf (file, " ");
- 		  fprintf (file, " %d", INSN_UID (CUID_INSN (cuid)));
- 		  n++;
- 		}
- 	    }
- 	}
-       if (n != 0)
- 	fprintf (file, "\n");
-     }
-   fprintf (file, "\n");
- }
- 
  /* Compute the set of kill's for reaching definitions.  */
  
  static void
--- 2524,2529 ----
*************** compute_available ()
*** 2807,2814 ****
        changed = 0;
        for (bb = 1; bb < n_basic_blocks; bb++)
  	{
! 	  sbitmap_intersect_of_predecessors (ae_in[bb], ae_out,
! 					     bb, s_preds);
  	  changed |= sbitmap_union_of_diff (ae_out[bb], ae_gen[bb],
  					    ae_in[bb], ae_kill[bb]);
  	}
--- 2825,2831 ----
        changed = 0;
        for (bb = 1; bb < n_basic_blocks; bb++)
  	{
! 	  sbitmap_intersect_of_predecessors (ae_in[bb], ae_out, bb, s_preds);
  	  changed |= sbitmap_union_of_diff (ae_out[bb], ae_gen[bb],
  					    ae_in[bb], ae_kill[bb]);
  	}
*************** classic_gcse ()
*** 3263,3270 ****
     Return non-zero if a change was made.  */
  
  static int
! one_classic_gcse_pass (f, pass)
!      rtx f;
       int pass;
  {
    int changed = 0;
--- 3280,3286 ----
     Return non-zero if a change was made.  */
  
  static int
! one_classic_gcse_pass (pass)
       int pass;
  {
    int changed = 0;
*************** one_classic_gcse_pass (f, pass)
*** 3274,3280 ****
  
    alloc_expr_hash_table (max_cuid);
    alloc_rd_mem (n_basic_blocks, max_cuid);
!   compute_expr_hash_table (f);
    if (gcse_file)
      dump_hash_table (gcse_file, "Expression", expr_hash_table,
  		     expr_hash_table_size, n_exprs);
--- 3290,3296 ----
  
    alloc_expr_hash_table (max_cuid);
    alloc_rd_mem (n_basic_blocks, max_cuid);
!   compute_expr_hash_table ();
    if (gcse_file)
      dump_hash_table (gcse_file, "Expression", expr_hash_table,
  		     expr_hash_table_size, n_exprs);
*************** free_cprop_mem ()
*** 3341,3363 ****
    free (cprop_avout);
  }
  
- /* Dump copy/const propagation data.  */
- 
- void
- dump_cprop_data (file)
-      FILE *file;
- {
-   dump_sbitmap_vector (file, "CPROP partially locally available sets", "BB",
- 		       cprop_pavloc, n_basic_blocks);
-   dump_sbitmap_vector (file, "CPROP absolutely altered sets", "BB",
- 		       cprop_absaltered, n_basic_blocks);
- 
-   dump_sbitmap_vector (file, "CPROP available incoming sets", "BB",
- 		       cprop_avin, n_basic_blocks);
-   dump_sbitmap_vector (file, "CPROP available outgoing sets", "BB",
- 		       cprop_avout, n_basic_blocks);
- }
- 
  /* For each block, compute whether X is transparent.
     X is either an expression or an assignment [though we don't care which,
     for this context an assignment is treated as an expression].
--- 3357,3362 ----
*************** compute_transp (x, indx, bmap, set_p)
*** 3483,3525 ****
  	}
      }
  }
- 
- static void
- compute_cprop_local_properties ()
- {
-   int i;
- 
-   sbitmap_vector_zero (cprop_absaltered, n_basic_blocks);
-   sbitmap_vector_zero (cprop_pavloc, n_basic_blocks);
- 
-   for (i = 0; i < set_hash_table_size; i++)
-     {
-       struct expr *expr;
- 
-       for (expr = set_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
- 	{
- 	  struct occr *occr;
- 	  int indx = expr->bitmap_index;
- 
- 	  /* The assignment is absolutely altered if any operand is modified
- 	     by this block [excluding the assignment itself].
- 	     We start by assuming all are transparent [none are killed], and
- 	     then setting the bits for those that are.  */
- 
- 	  compute_transp (expr->expr, indx, cprop_absaltered, 1);
- 
- 	  /* The occurrences recorded in avail_occr are exactly those that
- 	     we want to set to non-zero in PAVLOC.  */
- 
- 	  for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
- 	    {
- 	      int bb = BLOCK_NUM (occr->insn);
- 	      SET_BIT (cprop_pavloc[bb], indx);
- 	    }
- 	}
-     }
- }
  
  static void
  compute_cprop_avinout ()
  {
--- 3482,3493 ----
  	}
      }
  }
  
+ /* Compute the available expressions at the start and end of each
+    basic block for cprop.  This particular dataflow equation is
+    used often enough that we might want to generalize it and make
+    as a subroutine for other global optimizations that need available
+    in/out information.  */
  static void
  compute_cprop_avinout ()
  {
*************** compute_cprop_avinout ()
*** 3536,3543 ****
        for (bb = 0; bb < n_basic_blocks; bb++)
  	{
  	  if (bb != 0)
! 	    sbitmap_intersect_of_predecessors (cprop_avin[bb], cprop_avout,
! 					       bb, s_preds);
  	  changed |= sbitmap_union_of_diff (cprop_avout[bb],
  					    cprop_pavloc[bb],
  					    cprop_avin[bb],
--- 3504,3511 ----
        for (bb = 0; bb < n_basic_blocks; bb++)
  	{
  	  if (bb != 0)
! 	    sbitmap_intersect_of_predecessors (cprop_avin[bb],
! 					       cprop_avout, bb, s_preds);
  	  changed |= sbitmap_union_of_diff (cprop_avout[bb],
  					    cprop_pavloc[bb],
  					    cprop_avin[bb],
*************** compute_cprop_avinout ()
*** 3556,3562 ****
  static void
  compute_cprop_data ()
  {
!   compute_cprop_local_properties ();
    compute_cprop_avinout ();
  }
  
--- 3524,3530 ----
  static void
  compute_cprop_data ()
  {
!   compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, 1);
    compute_cprop_avinout ();
  }
  
*************** find_avail_set (regno, insn)
*** 3700,3707 ****
     The result is non-zero if a change was made.  */
  
  static int
! cprop_insn (insn)
       rtx insn;
  {
    struct reg_use *reg_used;
    int changed = 0;
--- 3668,3676 ----
     The result is non-zero if a change was made.  */
  
  static int
! cprop_insn (insn, alter_jumps)
       rtx insn;
+      int alter_jumps;
  {
    struct reg_use *reg_used;
    int changed = 0;
*************** cprop_insn (insn)
*** 3775,3781 ****
  	     (set (pc) (if_then_else ...))
  
  	     Note this does not currently handle machines which use cc0.  */
! 	  else if (GET_CODE (insn) == JUMP_INSN && condjump_p (insn))
  	    {
  	      /* We want a copy of the JUMP_INSN so we can modify it
  		 in-place as needed without effecting the original.  */
--- 3744,3751 ----
  	     (set (pc) (if_then_else ...))
  
  	     Note this does not currently handle machines which use cc0.  */
! 	  else if (alter_jumps
! 		   && GET_CODE (insn) == JUMP_INSN && condjump_p (insn))
  	    {
  	      /* We want a copy of the JUMP_INSN so we can modify it
  		 in-place as needed without effecting the original.  */
*************** cprop_insn (insn)
*** 3880,3886 ****
     Return non-zero if a change was made.  */
  
  static int
! cprop ()
  {
    int bb, changed;
    rtx insn;
--- 3850,3857 ----
     Return non-zero if a change was made.  */
  
  static int
! cprop (alter_jumps)
!      int alter_jumps;
  {
    int bb, changed;
    rtx insn;
*************** cprop ()
*** 3900,3906 ****
  	{
  	  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  	    {
! 	      changed |= cprop_insn (insn);
  
  	      /* Keep track of everything modified by this insn.  */
  	      /* ??? Need to be careful w.r.t. mods done to INSN.  */
--- 3871,3877 ----
  	{
  	  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
  	    {
! 	      changed |= cprop_insn (insn, alter_jumps);
  
  	      /* Keep track of everything modified by this insn.  */
  	      /* ??? Need to be careful w.r.t. mods done to INSN.  */
*************** cprop ()
*** 3920,3928 ****
     PASS is the pass count.  */
  
  static int
! one_cprop_pass (f, pass)
!      rtx f;
       int pass;
  {
    int changed = 0;
  
--- 3891,3899 ----
     PASS is the pass count.  */
  
  static int
! one_cprop_pass (pass, alter_jumps)
       int pass;
+      int alter_jumps;
  {
    int changed = 0;
  
*************** one_cprop_pass (f, pass)
*** 3930,3936 ****
    copy_prop_count = 0;
  
    alloc_set_hash_table (max_cuid);
!   compute_set_hash_table (f);
    if (gcse_file)
      dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size,
  		     n_sets);
--- 3901,3907 ----
    copy_prop_count = 0;
  
    alloc_set_hash_table (max_cuid);
!   compute_set_hash_table ();
    if (gcse_file)
      dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size,
  		     n_sets);
*************** one_cprop_pass (f, pass)
*** 3938,3944 ****
      {
        alloc_cprop_mem (n_basic_blocks, n_sets);
        compute_cprop_data ();
!       changed = cprop ();
        free_cprop_mem ();
      }
    free_set_hash_table ();
--- 3909,3915 ----
      {
        alloc_cprop_mem (n_basic_blocks, n_sets);
        compute_cprop_data ();
!       changed = cprop (alter_jumps);
        free_cprop_mem ();
      }
    free_set_hash_table ();
*************** free_pre_mem ()
*** 4029,4069 ****
    free (pre_transpout);
  }
  
- /* Dump PRE data.  */
- 
- void
- dump_pre_data (file)
-      FILE *file;
- {
-   dump_sbitmap_vector (file, "PRE locally transparent expressions", "BB",
- 		       pre_transp, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE locally available expressions", "BB",
- 		       pre_comp, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE locally anticipatable expressions", "BB",
- 		       pre_antloc, n_basic_blocks);
- 
-   dump_sbitmap_vector (file, "PRE available incoming expressions", "BB",
- 		       pre_avin, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE available outgoing expressions", "BB",
- 		       pre_avout, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE anticipatable incoming expressions", "BB",
- 		       pre_antin, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE anticipatable outgoing expressions", "BB",
- 		       pre_antout, n_basic_blocks);
- 
-   dump_sbitmap_vector (file, "PRE partially available incoming expressions", "BB",
- 		       pre_pavin, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE partially available outgoing expressions", "BB",
- 		       pre_pavout, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE placement possible on incoming", "BB",
- 		       pre_ppin, n_basic_blocks);
-   dump_sbitmap_vector (file, "PRE placement possible on outgoing", "BB",
- 		       pre_ppout, n_basic_blocks);
- 
-   dump_sbitmap_vector (file, "PRE transparent on outgoing", "BB",
- 		       pre_transpout, n_basic_blocks);
- }
- 
  /* Compute the local properties of each recorded expression.
     Local properties are those that are defined by the block, irrespective
     of other blocks.
--- 4000,4005 ----
*************** pre_gcse ()
*** 4886,4893 ****
     Return non-zero if a change was made.  */
  
  static int
! one_pre_gcse_pass (f, pass)
!      rtx f;
       int pass;
  {
    int changed = 0;
--- 4822,4828 ----
     Return non-zero if a change was made.  */
  
  static int
! one_pre_gcse_pass (pass)
       int pass;
  {
    int changed = 0;
*************** one_pre_gcse_pass (f, pass)
*** 4896,4902 ****
    gcse_create_count = 0;
  
    alloc_expr_hash_table (max_cuid);
!   compute_expr_hash_table (f);
    if (gcse_file)
      dump_hash_table (gcse_file, "Expression", expr_hash_table,
  		     expr_hash_table_size, n_exprs);
--- 4831,4837 ----
    gcse_create_count = 0;
  
    alloc_expr_hash_table (max_cuid);
!   compute_expr_hash_table ();
    if (gcse_file)
      dump_hash_table (gcse_file, "Expression", expr_hash_table,
  		     expr_hash_table_size, n_exprs);


More information about the Gcc-patches mailing list