[PATCH] Simplify rest_of_compilation logic

Matt Kraai kraai@alumni.cmu.edu
Thu Jun 13 11:38:00 GMT 2002


On Thu, Jun 13, 2002 at 10:03:27AM -0600, law@redhat.com wrote:
>  In message <Pine.LNX.4.33.0206130734590.11151-100000@www.eyesopen.com>, Roger 
> Sayle writes:
>  > A potential further improvement still would be to have the function
>  > delete_null_pointer_checks return a bool indicating that it actually
>  > modified one or more jumps, and use this in rest_of_compilation to
>  > determine whether it needs to call cleanup_cfg afterwards.
> Yes.  I actually thought the code did this, but looking at it now, it
> seems to not be the case.  It should be relatively simple to propagate
> out a return value to indicate if something was changed.

The following patch does so.  It compiles, but I cannot
bootstrap or regression test it since bootstrapping on PowerPC
is currently broken.

Matt

	* gcc/gcse.c (delete_null_pointer_checks_1): Return non-zero if a change
	is made.
	(delete_null_pointer_checks): Likewise.
	* rtl.h (delete_null_pointer_checks): Update prototype.
	* toplev.c (rest_of_compilation): Rerun cleanup_cfg only if a change was
	made.

Index: gcc/gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.204
diff -c -3 -p -r1.204 gcse.c
*** gcc/gcse.c	11 Jun 2002 19:58:04 -0000	1.204
--- gcc/gcse.c	13 Jun 2002 18:33:34 -0000
*************** static int handle_avail_expr	PARAMS ((rt
*** 658,664 ****
  static int classic_gcse		PARAMS ((void));
  static int one_classic_gcse_pass PARAMS ((int));
  static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
! static void delete_null_pointer_checks_1 PARAMS ((unsigned int *,
  						  sbitmap *, sbitmap *,
  						  struct null_pointer_info *));
  static rtx process_insert_insn	PARAMS ((struct expr *));
--- 658,664 ----
  static int classic_gcse		PARAMS ((void));
  static int one_classic_gcse_pass PARAMS ((int));
  static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
! static bool delete_null_pointer_checks_1 PARAMS ((unsigned int *,
  						  sbitmap *, sbitmap *,
  						  struct null_pointer_info *));
  static rtx process_insert_insn	PARAMS ((struct expr *));
*************** invalidate_nonnull_info (x, setter, data
*** 5471,5477 ****
  
  /* Do null-pointer check elimination for the registers indicated in
     NPI.  NONNULL_AVIN and NONNULL_AVOUT are pre-allocated sbitmaps;
!    they are not our responsibility to free.  */
  
  static void
  delete_null_pointer_checks_1 (block_reg, nonnull_avin,
--- 5471,5479 ----
  
  /* Do null-pointer check elimination for the registers indicated in
     NPI.  NONNULL_AVIN and NONNULL_AVOUT are pre-allocated sbitmaps;
!    they are not our responsibility to free.
! 
!    Return non-zero if a change was made.  */
  
  static void
  delete_null_pointer_checks_1 (block_reg, nonnull_avin,
*************** delete_null_pointer_checks_1 (block_reg,
*** 5484,5489 ****
--- 5486,5492 ----
    basic_block bb, current_block;
    sbitmap *nonnull_local = npi->nonnull_local;
    sbitmap *nonnull_killed = npi->nonnull_killed;
+   bool changed = false;
  
    /* Compute local properties, nonnull and killed.  A register will have
       the nonnull property if at the end of the current block its value is
*************** delete_null_pointer_checks_1 (block_reg,
*** 5614,5620 ****
--- 5617,5627 ----
  	 invalid here; we deleted the last instruction in the
  	 block.)  */
        block_reg[bb->index] = 0;
+ 
+       changed = true;
      }
+ 
+   return changed;
  }
  
  /* Find EQ/NE comparisons against zero which can be (indirectly) evaluated
*************** delete_null_pointer_checks_1 (block_reg,
*** 5639,5647 ****
     optimization opportunities of this nature to appear after the first CSE
     pass.
  
!    This could probably be integrated with global cprop with a little work.  */
  
! void
  delete_null_pointer_checks (f)
       rtx f ATTRIBUTE_UNUSED;
  {
--- 5646,5656 ----
     optimization opportunities of this nature to appear after the first CSE
     pass.
  
!    This could probably be integrated with global cprop with a little work.
  
!    Return non-zero if a change was made.  */
! 
! bool
  delete_null_pointer_checks (f)
       rtx f ATTRIBUTE_UNUSED;
  {
*************** delete_null_pointer_checks (f)
*** 5652,5661 ****
    int regs_per_pass;
    int max_reg;
    struct null_pointer_info npi;
  
    /* If we have only a single block, then there's nothing to do.  */
    if (n_basic_blocks <= 1)
!     return;
  
    /* Trying to perform global optimizations on flow graphs which have
       a high connectivity will take a long time and is unlikely to be
--- 5661,5671 ----
    int regs_per_pass;
    int max_reg;
    struct null_pointer_info npi;
+   bool changed = false;
  
    /* If we have only a single block, then there's nothing to do.  */
    if (n_basic_blocks <= 1)
!     return false;
  
    /* Trying to perform global optimizations on flow graphs which have
       a high connectivity will take a long time and is unlikely to be
*************** delete_null_pointer_checks (f)
*** 5666,5672 ****
       a couple switch statements.  So we require a relatively large number
       of basic blocks and the ratio of edges to blocks to be high.  */
    if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
!     return;
  
    /* We need four bitmaps, each with a bit for each register in each
       basic block.  */
--- 5676,5682 ----
       a couple switch statements.  So we require a relatively large number
       of basic blocks and the ratio of edges to blocks to be high.  */
    if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
!     return false;
  
    /* We need four bitmaps, each with a bit for each register in each
       basic block.  */
*************** delete_null_pointer_checks (f)
*** 5719,5726 ****
      {
        npi.min_reg = reg;
        npi.max_reg = MIN (reg + regs_per_pass, max_reg);
!       delete_null_pointer_checks_1 (block_reg, nonnull_avin,
! 				    nonnull_avout, &npi);
      }
  
    /* Free the table of registers compared at the end of every block.  */
--- 5729,5736 ----
      {
        npi.min_reg = reg;
        npi.max_reg = MIN (reg + regs_per_pass, max_reg);
!       changed |= delete_null_pointer_checks_1 (block_reg, nonnull_avin,
! 					       nonnull_avout, &npi);
      }
  
    /* Free the table of registers compared at the end of every block.  */
*************** delete_null_pointer_checks (f)
*** 5731,5736 ****
--- 5741,5748 ----
    sbitmap_vector_free (npi.nonnull_killed);
    sbitmap_vector_free (nonnull_avin);
    sbitmap_vector_free (nonnull_avout);
+ 
+   return changed;
  }
  
  /* Code Hoisting variables and subroutines.  */
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.651
diff -c -3 -p -r1.651 toplev.c
*** gcc/toplev.c	13 Jun 2002 17:20:01 -0000	1.651
--- gcc/toplev.c	13 Jun 2002 18:33:34 -0000
*************** rest_of_compilation (decl)
*** 2729,2737 ****
        if (rtl_dump_file)
  	dump_flow_info (rtl_dump_file);
  
!       delete_null_pointer_checks (insns);
  
-       cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
        close_dump_file (DFI_null, print_rtl_with_bb, insns);
      }
  
--- 2729,2737 ----
        if (rtl_dump_file)
  	dump_flow_info (rtl_dump_file);
  
!       if (delete_null_pointer_checks (insns))
! 	cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
  
        close_dump_file (DFI_null, print_rtl_with_bb, insns);
      }
  
Index: gcc/rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.360
diff -c -3 -p -r1.360 rtl.h
*** gcc/rtl.h	13 Jun 2002 16:14:54 -0000	1.360
--- gcc/rtl.h	13 Jun 2002 18:33:35 -0000
*************** extern void reg_scan			PARAMS ((rtx, uns
*** 2035,2041 ****
  extern void reg_scan_update		PARAMS ((rtx, rtx, unsigned int));
  extern void fix_register		PARAMS ((const char *, int, int));
  
! extern void delete_null_pointer_checks	PARAMS ((rtx));
  
  /* In regmove.c */
  #ifdef BUFSIZ
--- 2035,2041 ----
  extern void reg_scan_update		PARAMS ((rtx, rtx, unsigned int));
  extern void fix_register		PARAMS ((const char *, int, int));
  
! extern bool delete_null_pointer_checks	PARAMS ((rtx));
  
  /* In regmove.c */
  #ifdef BUFSIZ
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20020613/83effd55/attachment.sig>


More information about the Gcc-patches mailing list