delete_null_pointer_checks vs cfg optimization

law@redhat.com law@redhat.com
Fri Jun 14 09:24:00 GMT 2002


Bootstrapped and regression tested i686-pc-linux-gnu.  Installed into the 
mainline sources.

	* gcse.c (delete_null_pointer_checks_1): Inform caller if any
	null pointer checks were eliminated.  Update prototype.
	(delete_null_pointer_checks): Similarly.
	* rtl.h (delete_null_pointer_checks): Update prototype.
	* toplev.c (rest_of_compilation): Only run cleanup_cfg if
	delete_null_pointer_checks deletes one or more null
	pointer checks.  Do not run cleanup_cfg before gcse, the
	CFG is accurate and optimized at that point..


Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.204
diff -c -3 -p -r1.204 gcse.c
*** gcse.c	11 Jun 2002 19:58:04 -0000	1.204
--- gcse.c	14 Jun 2002 14:46:00 -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 int 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
*** 5473,5479 ****
     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,
  			      nonnull_avout, npi)
       unsigned int *block_reg;
--- 5473,5479 ----
     NPI.  NONNULL_AVIN and NONNULL_AVOUT are pre-allocated sbitmaps;
     they are not our responsibility to free.  */
  
! static int
  delete_null_pointer_checks_1 (block_reg, nonnull_avin,
  			      nonnull_avout, npi)
       unsigned int *block_reg;
*************** delete_null_pointer_checks_1 (block_reg,
*** 5484,5489 ****
--- 5484,5490 ----
    basic_block bb, current_block;
    sbitmap *nonnull_local = npi->nonnull_local;
    sbitmap *nonnull_killed = npi->nonnull_killed;
+   int something_changed = 0;
  
    /* 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,
*** 5605,5610 ****
--- 5606,5612 ----
  	  emit_barrier_after (new_jump);
  	}
  
+       something_changed = 1;
        delete_insn (last_insn);
        if (compare_and_branch == 2)
  	delete_insn (earliest);
*************** delete_null_pointer_checks_1 (block_reg,
*** 5615,5620 ****
--- 5617,5624 ----
  	 block.)  */
        block_reg[bb->index] = 0;
      }
+ 
+   return something_changed;
  }
  
  /* Find EQ/NE comparisons against zero which can be (indirectly) evaluated
*************** delete_null_pointer_checks_1 (block_reg,
*** 5641,5647 ****
  
     This could probably be integrated with global cprop with a little work.  
*/
  
! void
  delete_null_pointer_checks (f)
       rtx f ATTRIBUTE_UNUSED;
  {
--- 5645,5651 ----
  
     This could probably be integrated with global cprop with a little work.  
*/
  
! int
  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
--- 5656,5666 ----
    int regs_per_pass;
    int max_reg;
    struct null_pointer_info npi;
+   int something_changed = 0;
  
    /* If we have only a single block, then there's nothing to do.  */
    if (n_basic_blocks <= 1)
!     return 0;
  
    /* 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.  */
--- 5671,5677 ----
       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 0;
  
    /* 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.  */
--- 5724,5733 ----
      {
        npi.min_reg = reg;
        npi.max_reg = MIN (reg + regs_per_pass, max_reg);
!       something_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 ****
--- 5738,5745 ----
    sbitmap_vector_free (npi.nonnull_killed);
    sbitmap_vector_free (nonnull_avin);
    sbitmap_vector_free (nonnull_avout);
+ 
+   return something_changed;
  }
  
  /* Code Hoisting variables and subroutines.  */
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.360
diff -c -3 -p -r1.360 rtl.h
*** rtl.h	13 Jun 2002 16:14:54 -0000	1.360
--- rtl.h	14 Jun 2002 14:46:04 -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 int delete_null_pointer_checks	PARAMS ((rtx));
  
  /* In regmove.c */
  #ifdef BUFSIZ
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.651
diff -c -3 -p -r1.651 toplev.c
*** toplev.c	13 Jun 2002 17:20:01 -0000	1.651
--- toplev.c	14 Jun 2002 14:46:11 -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);
      }
  
*************** rest_of_compilation (decl)
*** 2775,2787 ****
        if (tem || optimize > 1)
  	cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
        /* Try to identify useless null pointer tests and delete them.  */
!       if (flag_delete_null_pointer_checks || flag_thread_jumps)
  	{
  	  timevar_push (TV_JUMP);
  
  	  if (flag_delete_null_pointer_checks)
! 	    delete_null_pointer_checks (insns);
! 	  /* CFG is no longer maintained up-to-date.  */
  	  timevar_pop (TV_JUMP);
  	}
  
--- 2775,2787 ----
        if (tem || optimize > 1)
  	cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
        /* Try to identify useless null pointer tests and delete them.  */
!       if (flag_delete_null_pointer_checks)
  	{
  	  timevar_push (TV_JUMP);
  
  	  if (flag_delete_null_pointer_checks)
! 	    if (delete_null_pointer_checks (insns))
! 	      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
  	  timevar_pop (TV_JUMP);
  	}
  
*************** rest_of_compilation (decl)
*** 2814,2820 ****
        timevar_push (TV_GCSE);
        open_dump_file (DFI_gcse, decl);
  
-       cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
        tem = gcse_main (insns, rtl_dump_file);
        rebuild_jump_labels (insns);
        delete_trivially_dead_insns (insns, max_reg_num ());
--- 2814,2819 ----






More information about the Gcc-patches mailing list