[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