This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [ast-optimizer-branch]: CFG improvements [patch]
- To: law at redhat dot com
- Subject: Re: [ast-optimizer-branch]: CFG improvements [patch]
- From: Diego Novillo <dnovillo at redhat dot com>
- Date: Mon, 13 Aug 2001 12:08:22 -0400
- Cc: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>, gcc-patches at gcc dot gnu dot org, Nathan Sidwell <nathan at codesourcery dot com>
- Organization: Red Hat Canada
- References: <20010811213954.A27476@tornado.cygnus.com> <2647.997683491@localhost.localdomain>
On Mon, 13 Aug 2001, Jeff Law wrote:
> In message <20010811213954.A27476@tornado.cygnus.com>you write:
> > On Fri, 10 Aug 2001, Dan Nicolaescu wrote:
> >
> > >
> > > > 2001-08-10 Diego Novillo <dnovillo@redhat.com>
> > > >
> > > > * basic-block.h (basic_block): Add new field 'reachable'.
> > > > (expunge_block): Declare.
> > >
> > > One suggestion: you could steal one bit from `loop_depth' in that
> > > structure and use it for `reachable', that would avoid increasing the
> > > size of struct basic_block_def
> > >
> > Ugh. I suppose. I'm not really fond of hacks like this one,
> > they eventually come back to haunt you.
> >
> > I was thinking more along the lines of having an 'flags' field
> > like we do in edges. We may want to add more flags in the future
> > (although I can't think of a meaningful example right now).
> >
> > I'll go with the flow here. What do folks think? Should we add
> > a 'flags' field or piggyback flags like this one on unused bits
> > in the structure?
> I'd prefer a flags field similar to what we do with edges.
>
> jeff
OK. I withdraw the original patch and propose this one instead.
It adds a 'flags' field to the basic block structure.
Bootstrapped and regression tested on i686.
Diego.
* basic-block.h (basic_block): Add new field 'flags'.
(BB_REACHABLE): Define.
(expunge_block): Declare.
* flow.c (ENTRY_BLOCK_PTR): Initialize field 'flags'.
(EXIT_BLOCK_PTR): Ditto.
(expunge_block): Remove static declaration.
(cleanup_cfg): Clear bb->aux on every basic block.
(find_unreachable_blocks): Set BB_REACHABLE bit in bb->flags when
computing reachability.
(delete_unreachable_blocks): Delete block b if b->flags has
BB_REACHABLE unset.
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.111
diff -d -p -d -c -p -r1.111 basic-block.h
*** basic-block.h 2001/08/06 06:39:20 1.111
--- basic-block.h 2001/08/13 14:37:08
*************** typedef struct basic_block_def {
*** 218,227 ****
--- 218,233 ----
/* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */
int frequency;
+
+ /* Various flags. See BB_* below. */
+ int flags;
} *basic_block;
#define BB_FREQ_MAX 10000
+ /* Masks for basic_block.flags. */
+ #define BB_REACHABLE 1
+
/* Number of basic blocks in the current function. */
extern int n_basic_blocks;
*************** extern void debug_regset PARAMS ((regse
*** 609,614 ****
--- 615,621 ----
extern void allocate_reg_life_data PARAMS ((void));
extern void allocate_bb_life_data PARAMS ((void));
extern void find_unreachable_blocks PARAMS ((void));
+ extern void expunge_block PARAMS ((basic_block));
extern void delete_noop_moves PARAMS ((rtx));
extern rtx last_loop_beg_note PARAMS ((rtx));
extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.461
diff -d -p -d -c -p -r1.461 flow.c
*** flow.c 2001/08/08 22:06:47 1.461
--- flow.c 2001/08/13 14:37:09
*************** struct basic_block_def entry_exit_blocks
*** 208,214 ****
ENTRY_BLOCK, /* index */
0, /* loop_depth */
0, /* count */
! 0 /* frequency */
},
{
NULL, /* head */
--- 208,215 ----
ENTRY_BLOCK, /* index */
0, /* loop_depth */
0, /* count */
! 0, /* frequency */
! 0 /* flags */
},
{
NULL, /* head */
*************** struct basic_block_def entry_exit_blocks
*** 225,231 ****
EXIT_BLOCK, /* index */
0, /* loop_depth */
0, /* count */
! 0 /* frequency */
}
};
--- 226,233 ----
EXIT_BLOCK, /* index */
0, /* loop_depth */
0, /* count */
! 0, /* frequency */
! 0 /* flags */
}
};
*************** static void commit_one_edge_insertion PA
*** 383,389 ****
static void delete_unreachable_blocks PARAMS ((void));
static int can_delete_note_p PARAMS ((rtx));
- static void expunge_block PARAMS ((basic_block));
static int can_delete_label_p PARAMS ((rtx));
static int tail_recursion_label_p PARAMS ((rtx));
static int merge_blocks_move_predecessor_nojumps PARAMS ((basic_block,
--- 385,390 ----
*************** void
*** 1030,1035 ****
--- 1031,1038 ----
cleanup_cfg (mode)
int mode;
{
+ int i;
+
timevar_push (TV_CLEANUP_CFG);
delete_unreachable_blocks ();
if (try_optimize_cfg (mode))
*************** cleanup_cfg (mode)
*** 1040,1045 ****
--- 1043,1052 ----
free_EXPR_LIST_list (&label_value_list);
free_EXPR_LIST_list (&tail_recursion_label_list);
timevar_pop (TV_CLEANUP_CFG);
+
+ /* Clear bb->aux on all basic blocks. */
+ for (i = 0; i < n_basic_blocks; ++i)
+ BASIC_BLOCK (i)->aux = NULL;
}
/* Create a new basic block consisting of the instructions between
*************** flow_call_edges_add (blocks)
*** 2640,2647 ****
return blocks_split;
}
! /* Find unreachable blocks. An unreachable block will have NULL in
! block->aux, a non-NULL value indicates the block is reachable. */
void
find_unreachable_blocks ()
--- 2647,2655 ----
return blocks_split;
}
! /* Find unreachable blocks. An unreachable block will have 0 in
! the reachable bit in block->flags. A non-zero value indicates the
! block is reachable. */
void
find_unreachable_blocks ()
*************** find_unreachable_blocks ()
*** 2653,2662 ****
n = n_basic_blocks;
tos = worklist = (basic_block *) xmalloc (sizeof (basic_block) * n);
! /* Use basic_block->aux as a marker. Clear them all. */
for (i = 0; i < n; ++i)
! BASIC_BLOCK (i)->aux = NULL;
/* Add our starting points to the worklist. Almost always there will
be only one. It isn't inconcievable that we might one day directly
--- 2661,2670 ----
n = n_basic_blocks;
tos = worklist = (basic_block *) xmalloc (sizeof (basic_block) * n);
! /* Clear all the reachability flags. */
for (i = 0; i < n; ++i)
! BASIC_BLOCK (i)->flags &= ~BB_REACHABLE;
/* Add our starting points to the worklist. Almost always there will
be only one. It isn't inconcievable that we might one day directly
*************** find_unreachable_blocks ()
*** 2666,2673 ****
{
*tos++ = e->dest;
! /* Mark the block with a handy non-null value. */
! e->dest->aux = e;
}
/* Iterate: find everything reachable from what we've already seen. */
--- 2674,2681 ----
{
*tos++ = e->dest;
! /* Mark the block reachable. */
! e->dest->flags |= BB_REACHABLE;
}
/* Iterate: find everything reachable from what we've already seen. */
*************** find_unreachable_blocks ()
*** 2677,2686 ****
basic_block b = *--tos;
for (e = b->succ; e; e = e->succ_next)
! if (!e->dest->aux)
{
*tos++ = e->dest;
! e->dest->aux = e;
}
}
--- 2685,2694 ----
basic_block b = *--tos;
for (e = b->succ; e; e = e->succ_next)
! if (!(e->dest->flags & BB_REACHABLE))
{
*tos++ = e->dest;
! e->dest->flags |= BB_REACHABLE;
}
}
*************** delete_unreachable_blocks ()
*** 2703,2712 ****
{
basic_block b = BASIC_BLOCK (i);
! if (b->aux != NULL)
! /* This block was found. Tidy up the mark. */
! b->aux = NULL;
! else
flow_delete_block (b);
}
--- 2711,2717 ----
{
basic_block b = BASIC_BLOCK (i);
! if (!(b->flags & BB_REACHABLE))
flow_delete_block (b);
}
*************** flow_delete_block (b)
*** 2842,2848 ****
/* Remove block B from the basic block array and compact behind it. */
! static void
expunge_block (b)
basic_block b;
{
--- 2847,2853 ----
/* Remove block B from the basic block array and compact behind it. */
! void
expunge_block (b)
basic_block b;
{