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