Commit 5ece9746 by Jeffrey A Law Committed by Jeff Law

haifa-sched.c (build_jmp_edges): Delete dead function.

        * haifa-sched.c (build_jmp_edges): Delete dead function.
        (build_control_flow): Use cfg routines from flow.c
        (schedule_insns): Remove debugging code accidentally checked
        in earlier today.
        * basic-block.h: Add external integer list structures, typdefs,
        accessor macros and function declarations.  Simlarly for
        basic block pred/succ support and simple bitmap stuff.
        * flow.c: Add functions for integer list, basic block pred/succ
        support and simple bitmap support.
        (compute_dominators): New function to compute dominators and
        post dominators.
        (find_basic_blocks): Split into two functions.
        (life_analysis): Likewise.
        (flow_analysis): Removed.  Now handled by calling find_basic_blocks,
        the life_analysis from toplev.c
        * toplev.c (rest_of_compilation): Call find_basic_blocks, then
        life_analysis instead of flow_analysis.

Co-Authored-By: Doug Evans <devans@cygnus.com>

From-SVN: r18421
parent ac9b3c97
Thu Mar 5 23:24:50 1998 Jeffrey A Law (law@cygnus.com)
Doug Evans (devans@cygnus.com)
* haifa-sched.c (build_jmp_edges): Delete dead function.
(build_control_flow): Use cfg routines from flow.c
(schedule_insns): Remove debugging code accidentally checked
in earlier today.
* basic-block.h: Add external integer list structures, typdefs,
accessor macros and function declarations. Simlarly for
basic block pred/succ support and simple bitmap stuff.
* flow.c: Add functions for integer list, basic block pred/succ
support and simple bitmap support.
(compute_dominators): New function to compute dominators and
post dominators.
(find_basic_blocks): Split into two functions.
(life_analysis): Likewise.
(flow_analysis): Removed. Now handled by calling find_basic_blocks,
the life_analysis from toplev.c
* toplev.c (rest_of_compilation): Call find_basic_blocks, then
life_analysis instead of flow_analysis.
Thu Mar 5 23:06:26 1998 J"orn Rennecke <amylaar@cygnus.co.uk> Thu Mar 5 23:06:26 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* jump.c (jump_optimize): Call mark_jump_label also for deleted * jump.c (jump_optimize): Call mark_jump_label also for deleted
......
...@@ -128,3 +128,124 @@ extern regset regs_live_at_setjmp; ...@@ -128,3 +128,124 @@ extern regset regs_live_at_setjmp;
#define REG_BLOCK_GLOBAL -2 #define REG_BLOCK_GLOBAL -2
#define REG_BASIC_BLOCK(N) (reg_n_info[(N)].basic_block) #define REG_BASIC_BLOCK(N) (reg_n_info[(N)].basic_block)
/* List of integers.
These are used for storing things like predecessors, etc.
This scheme isn't very space efficient, especially on 64 bit machines.
The interface is designed so that the implementation can be replaced with
something more efficient if desirable. */
typedef struct int_list {
struct int_list *next;
int val;
} int_list;
typedef int_list *int_list_ptr;
/* Integer list elements are allocated in blocks to reduce the frequency
of calls to malloc and to reduce the associated space overhead. */
typedef struct int_list_block {
struct int_list_block *next;
int nodes_left;
#define INT_LIST_NODES_IN_BLK 500
struct int_list nodes[INT_LIST_NODES_IN_BLK];
} int_list_block;
/* Given a pointer to the list, return pointer to first element. */
#define INT_LIST_FIRST(il) (il)
/* Given a pointer to a list element, return pointer to next element. */
#define INT_LIST_NEXT(p) ((p)->next)
/* Return non-zero if P points to the end of the list. */
#define INT_LIST_END(p) ((p) == NULL)
/* Return element pointed to by P. */
#define INT_LIST_VAL(p) ((p)->val)
#define INT_LIST_SET_VAL(p, new_val) ((p)->val = (new_val))
extern void free_int_list PROTO ((int_list_block **));
/* Stuff for recording basic block info. */
#define BLOCK_HEAD(B) basic_block_head[(B)]
#define BLOCK_END(B) basic_block_end[(B)]
/* Special block numbers [markers] for entry and exit. */
#define ENTRY_BLOCK (-1)
#define EXIT_BLOCK (-2)
/* from flow.c */
extern int *uid_block_number;
#define BLOCK_NUM(INSN) uid_block_number[INSN_UID (INSN)]
extern int compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
int *, int *));
extern void dump_bb_data PROTO ((FILE *, int_list_ptr *, int_list_ptr *));
extern void free_bb_mem PROTO ((void));
/* Simple bitmaps.
It's not clear yet whether using bitmap.[ch] will be a win.
It should be straightforward to convert so for now we keep things simple
while more important issues are dealt with. */
#define SBITMAP_ELT_BITS HOST_BITS_PER_WIDE_INT
#define SBITMAP_ELT_TYPE unsigned HOST_WIDE_INT
typedef struct simple_bitmap_def {
/* Number of bits. */
int n_bits;
/* Size in elements. */
int size;
/* Size in bytes. */
int bytes;
/* The elements. */
SBITMAP_ELT_TYPE elms[1];
} *sbitmap;
typedef SBITMAP_ELT_TYPE *sbitmap_ptr;
/* Return the set size needed for N elements. */
#define SBITMAP_SET_SIZE(n) (((n) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS)
/* set bit number bitno in the bitmap */
#define SET_BIT(bitmap, bitno) \
do { \
(bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] |= (SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS; \
} while (0)
/* test if bit number bitno in the bitmap is set */
#define TEST_BIT(bitmap, bitno) \
((bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] & ((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS))
/* reset bit number bitno in the bitmap */
#define RESET_BIT(bitmap, bitno) \
do { \
(bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] &= ~((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS); \
} while (0)
extern sbitmap sbitmap_alloc PROTO ((int));
extern sbitmap *sbitmap_vector_alloc PROTO ((int, int));
extern void sbitmap_copy PROTO ((sbitmap, sbitmap));
extern void sbitmap_zero PROTO ((sbitmap));
extern void sbitmap_ones PROTO ((sbitmap));
extern void sbitmap_vector_zero PROTO ((sbitmap *, int));
extern void sbitmap_vector_ones PROTO ((sbitmap *, int));
extern int sbitmap_union_of_diff PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
extern void sbitmap_difference PROTO ((sbitmap, sbitmap, sbitmap));
extern void sbitmap_not PROTO ((sbitmap, sbitmap));
extern int sbitmap_a_or_b_and_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
extern int sbitmap_a_and_b_or_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
extern int sbitmap_a_and_b PROTO ((sbitmap, sbitmap, sbitmap));
extern int sbitmap_a_or_b PROTO ((sbitmap, sbitmap, sbitmap));
extern void sbitmap_intersect_of_predsucc PROTO ((sbitmap, sbitmap *,
int, int_list_ptr *));
extern void sbitmap_intersect_of_predecessors PROTO ((sbitmap, sbitmap *, int,
int_list_ptr *));
extern void sbitmap_intersect_of_successors PROTO ((sbitmap, sbitmap *, int,
int_list_ptr *));
extern void sbitmap_union_of_predecessors PROTO ((sbitmap, sbitmap *, int,
int_list_ptr *));
...@@ -521,7 +521,6 @@ static char is_cfg_nonregular PROTO ((void)); ...@@ -521,7 +521,6 @@ static char is_cfg_nonregular PROTO ((void));
static int uses_reg_or_mem PROTO ((rtx)); static int uses_reg_or_mem PROTO ((rtx));
void debug_control_flow PROTO ((void)); void debug_control_flow PROTO ((void));
static void build_control_flow PROTO ((void)); static void build_control_flow PROTO ((void));
static void build_jmp_edges PROTO ((rtx, int));
static void new_edge PROTO ((int, int)); static void new_edge PROTO ((int, int));
...@@ -1310,105 +1309,60 @@ debug_control_flow () ...@@ -1310,105 +1309,60 @@ debug_control_flow ()
} }
/* build the control flow graph. (also set nr_edges accurately) */ /* Build the control flow graph and set nr_edges.
Instead of trying to build a cfg ourselves, we rely on flow to
do it for us. Stamp out useless code (and bug) duplication. */
static void static void
build_control_flow () build_control_flow ()
{ {
int i; int i, j;
int_list_ptr *s_preds;
int_list_ptr *s_succs;
int_list_ptr succ;
int *num_preds;
int *num_succs;
/* The scheduler runs after flow; therefore, we can't blindly call
back into find_basic_blocks since doing so could invalidate the
info in basic_block_live_at_start.
Consider a block consisting entirely of dead stores; after life
analysis it would be a block of NOTE_INSN_DELETED notes. If
we call find_basic_blocks again, then the block would be removed
entirely and invalidate our the register live information.
We could (should?) recompute register live information. Doing
so may even be beneficial. */
s_preds = (int_list_ptr *) alloca (n_basic_blocks * sizeof (int_list_ptr));
s_succs = (int_list_ptr *) alloca (n_basic_blocks * sizeof (int_list_ptr));
num_preds = (int *) alloca (n_basic_blocks * sizeof (int));
num_succs = (int *) alloca (n_basic_blocks * sizeof (int));
compute_preds_succs (s_preds, s_succs, num_preds, num_succs);
nr_edges = 0; nr_edges = 0;
for (i = 0; i < n_basic_blocks; i++) for (i = 0; i < n_basic_blocks; i++)
{ for (succ = s_succs[i]; succ; succ = succ->next)
rtx insn; {
if (INT_LIST_VAL (succ) != EXIT_BLOCK)
insn = basic_block_end[i]; new_edge (i, INT_LIST_VAL (succ));
if (GET_CODE (insn) == JUMP_INSN) }
{
build_jmp_edges (PATTERN (insn), i);
}
for (insn = PREV_INSN (basic_block_head[i]);
insn && GET_CODE (insn) == NOTE; insn = PREV_INSN (insn))
;
/* build fallthrough edges */
if (!insn && i != 0)
new_edge (i - 1, i);
else if (insn && GET_CODE (insn) != BARRIER)
new_edge (i - 1, i);
}
/* increment by 1, since edge 0 is unused. */ /* increment by 1, since edge 0 is unused. */
nr_edges++; nr_edges++;
/* For now. This will move as more and more of haifa is converted
to using the cfg code in flow.c */
free_bb_mem ();
} }
/* construct edges in the control flow graph, from 'source' block, to /* Record an edge in the control flow graph from SOURCE to TARGET.
blocks refered to by 'pattern'. */
static
void
build_jmp_edges (pattern, source)
rtx pattern;
int source;
{
register RTX_CODE code;
register int i;
register char *fmt;
code = GET_CODE (pattern);
if (code == LABEL_REF)
{
register rtx label = XEXP (pattern, 0);
register int target;
/* This can happen as a result of a syntax error
and a diagnostic has already been printed. */
if (INSN_UID (label) == 0)
return;
target = INSN_BLOCK (label);
new_edge (source, target);
return;
}
/* proper handling of ADDR_DIFF_VEC: do not add a non-existing edge
from the block containing the branch-on-table, to itself. */
if (code == ADDR_VEC
|| code == ADDR_DIFF_VEC)
{
int diff_vec_p = GET_CODE (pattern) == ADDR_DIFF_VEC;
int len = XVECLEN (pattern, diff_vec_p);
int k;
for (k = 0; k < len; k++)
{
rtx tem = XVECEXP (pattern, diff_vec_p, k);
build_jmp_edges (tem, source);
}
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
build_jmp_edges (XEXP (pattern, i), source);
if (fmt[i] == 'E')
{
register int j;
for (j = 0; j < XVECLEN (pattern, i); j++)
build_jmp_edges (XVECEXP (pattern, i, j), source);
}
}
}
/* construct an edge in the control flow graph, from 'source' to 'target'. */ In theory, this is redundant with the s_succs computed above, but
we have not converted all of haifa to use information from the
integer lists. */
static void static void
new_edge (source, target) new_edge (source, target)
...@@ -8718,8 +8672,6 @@ schedule_insns (dump_file) ...@@ -8718,8 +8672,6 @@ schedule_insns (dump_file)
emit_note_after (NOTE_INSN_DELETED, basic_block_end[n_basic_blocks - 1]); emit_note_after (NOTE_INSN_DELETED, basic_block_end[n_basic_blocks - 1]);
/* Schedule every region in the subroutine */ /* Schedule every region in the subroutine */
fprintf(stderr, "HELLO: nr_regions=%d max_reg_num=%d\n",
(int)nr_regions, (int)max_reg_num());
for (rgn = 0; rgn < nr_regions; rgn++) for (rgn = 0; rgn < nr_regions; rgn++)
{ {
schedule_region (rgn); schedule_region (rgn);
......
...@@ -3381,8 +3381,13 @@ rest_of_compilation (decl) ...@@ -3381,8 +3381,13 @@ rest_of_compilation (decl)
/* Do control and data flow analysis, /* Do control and data flow analysis,
and write some of the results to dump file. */ and write some of the results to dump file. */
TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (), TIMEVAR
rtl_dump_file)); (flow_time,
{
find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
life_analysis (insns, max_reg_num (), rtl_dump_file);
});
if (warn_uninitialized) if (warn_uninitialized)
{ {
uninitialized_vars_warning (DECL_INITIAL (decl)); uninitialized_vars_warning (DECL_INITIAL (decl));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment