Commit b5ce41ff by Jeffrey A Law Committed by Jeff Law

gcse.c: More comments, whitespace and similar fixes.

        * gcse.c: More comments, whitespace and similar fixes.
        (dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
        (dump_pre_data, compute_cprop_local_properties): Likewise.
        (one_classic_gcse_pass): Lose unused argument.  All callers changed.
        (compute_hash_table, compute_expr_hash_table): Likewise.
        (compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
        (cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
        All callers changed.  Only alter jumps if ALTER_JUMPS is nonzero.
        Lose unused argument.
        (gcse_main): Always run a cprop pass after finishing global cse.
        (compute_local_properties): New function.
        (hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
        (compute_cprop_data): Use compute_local_properties.

From-SVN: r25677
parent 878f32c3
...@@ -22,6 +22,20 @@ Wed Mar 10 23:11:19 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> ...@@ -22,6 +22,20 @@ Wed Mar 10 23:11:19 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
Wed Mar 10 20:28:29 1999 Jeffrey A Law (law@cygnus.com) Wed Mar 10 20:28:29 1999 Jeffrey A Law (law@cygnus.com)
* gcse.c: More comments, whitespace and similar fixes.
(dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete.
(dump_pre_data, compute_cprop_local_properties): Likewise.
(one_classic_gcse_pass): Lose unused argument. All callers changed.
(compute_hash_table, compute_expr_hash_table): Likewise.
(compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise.
(cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS.
All callers changed. Only alter jumps if ALTER_JUMPS is nonzero.
Lose unused argument.
(gcse_main): Always run a cprop pass after finishing global cse.
(compute_local_properties): New function.
(hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen.
(compute_cprop_data): Use compute_local_properties.
* gcse.c: Update various comments. * gcse.c: Update various comments.
(current_function_calls_longjmp): Delete declaration. (current_function_calls_longjmp): Delete declaration.
......
...@@ -510,6 +510,7 @@ static sbitmap *rd_kill, *rd_gen, *reaching_defs, *rd_out; ...@@ -510,6 +510,7 @@ static sbitmap *rd_kill, *rd_gen, *reaching_defs, *rd_out;
/* for available exprs */ /* for available exprs */
static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out; static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
static void compute_can_copy PROTO ((void)); static void compute_can_copy PROTO ((void));
static char *gmalloc PROTO ((unsigned int)); static char *gmalloc PROTO ((unsigned int));
...@@ -517,8 +518,6 @@ static char *grealloc PROTO ((char *, unsigned int)); ...@@ -517,8 +518,6 @@ static char *grealloc PROTO ((char *, unsigned int));
static char *gcse_alloc PROTO ((unsigned long)); static char *gcse_alloc PROTO ((unsigned long));
static void alloc_gcse_mem PROTO ((rtx)); static void alloc_gcse_mem PROTO ((rtx));
static void free_gcse_mem PROTO ((void)); static void free_gcse_mem PROTO ((void));
extern void dump_cuid_table PROTO ((FILE *));
static void alloc_reg_set_mem PROTO ((int)); static void alloc_reg_set_mem PROTO ((int));
static void free_reg_set_mem PROTO ((void)); static void free_reg_set_mem PROTO ((void));
static void record_one_set PROTO ((int, rtx)); static void record_one_set PROTO ((int, rtx));
...@@ -529,78 +528,55 @@ static void hash_scan_insn PROTO ((rtx, int, int)); ...@@ -529,78 +528,55 @@ static void hash_scan_insn PROTO ((rtx, int, int));
static void hash_scan_set PROTO ((rtx, rtx, int)); static void hash_scan_set PROTO ((rtx, rtx, int));
static void hash_scan_clobber PROTO ((rtx, rtx)); static void hash_scan_clobber PROTO ((rtx, rtx));
static void hash_scan_call PROTO ((rtx, rtx)); static void hash_scan_call PROTO ((rtx, rtx));
static void maybe_set_rd_gen PROTO ((int, rtx));
static int want_to_gcse_p PROTO ((rtx)); static int want_to_gcse_p PROTO ((rtx));
static int oprs_unchanged_p PROTO ((rtx, rtx, int)); static int oprs_unchanged_p PROTO ((rtx, rtx, int));
static int oprs_anticipatable_p PROTO ((rtx, rtx)); static int oprs_anticipatable_p PROTO ((rtx, rtx));
static int oprs_available_p PROTO ((rtx, rtx)); static int oprs_available_p PROTO ((rtx, rtx));
static void insert_expr_in_table PROTO ((rtx, enum machine_mode, rtx, int, int)); static void insert_expr_in_table PROTO ((rtx, enum machine_mode,
rtx, int, int));
static void insert_set_in_table PROTO ((rtx, rtx)); static void insert_set_in_table PROTO ((rtx, rtx));
static unsigned int hash_expr PROTO ((rtx, enum machine_mode, int *, int)); static unsigned int hash_expr PROTO ((rtx, enum machine_mode,
int *, int));
static unsigned int hash_expr_1 PROTO ((rtx, enum machine_mode, int *)); static unsigned int hash_expr_1 PROTO ((rtx, enum machine_mode, int *));
static unsigned int hash_set PROTO ((int, int)); static unsigned int hash_set PROTO ((int, int));
static int expr_equiv_p PROTO ((rtx, rtx)); static int expr_equiv_p PROTO ((rtx, rtx));
static void record_last_reg_set_info PROTO ((rtx, int)); static void record_last_reg_set_info PROTO ((rtx, int));
static void record_last_mem_set_info PROTO ((rtx)); static void record_last_mem_set_info PROTO ((rtx));
static void record_last_set_info PROTO ((rtx, rtx)); static void record_last_set_info PROTO ((rtx, rtx));
static void compute_hash_table PROTO ((rtx, int)); static void compute_hash_table PROTO ((int));
static void alloc_set_hash_table PROTO ((int)); static void alloc_set_hash_table PROTO ((int));
static void free_set_hash_table PROTO ((void)); static void free_set_hash_table PROTO ((void));
static void compute_set_hash_table PROTO ((rtx)); static void compute_set_hash_table PROTO ((void));
static void alloc_expr_hash_table PROTO ((int)); static void alloc_expr_hash_table PROTO ((int));
static void free_expr_hash_table PROTO ((void)); static void free_expr_hash_table PROTO ((void));
static void compute_expr_hash_table PROTO ((rtx)); static void compute_expr_hash_table PROTO ((void));
static void dump_hash_table PROTO ((FILE *, const char *, struct expr **, int, int)); static void dump_hash_table PROTO ((FILE *, const char *, struct expr **, int, int));
static struct expr *lookup_expr PROTO ((rtx)); static struct expr *lookup_expr PROTO ((rtx));
static struct expr *lookup_set PROTO ((int, rtx)); static struct expr *lookup_set PROTO ((int, rtx));
static struct expr *next_set PROTO ((int, struct expr *)); static struct expr *next_set PROTO ((int, struct expr *));
static void reset_opr_set_tables PROTO ((void)); static void reset_opr_set_tables PROTO ((void));
static int oprs_not_set_p PROTO ((rtx, rtx)); static int oprs_not_set_p PROTO ((rtx, rtx));
static void mark_call PROTO ((rtx, rtx)); static void mark_call PROTO ((rtx));
static void mark_set PROTO ((rtx, rtx)); static void mark_set PROTO ((rtx, rtx));
static void mark_clobber PROTO ((rtx, rtx)); static void mark_clobber PROTO ((rtx, rtx));
static void mark_oprs_set PROTO ((rtx)); static void mark_oprs_set PROTO ((rtx));
static void alloc_rd_mem PROTO ((int, int));
static void free_rd_mem PROTO ((void));
static void compute_kill_rd PROTO ((void));
static void handle_rd_kill_set PROTO ((rtx, int, int));
static void compute_rd PROTO ((void));
extern void dump_rd_table PROTO ((FILE *, char *, sbitmap *));
static void alloc_avail_expr_mem PROTO ((int, int));
static void free_avail_expr_mem PROTO ((void));
static void compute_ae_gen PROTO ((void));
static void compute_ae_kill PROTO ((void));
static int expr_killed_p PROTO ((rtx, int));
static void compute_available PROTO ((void));
static int expr_reaches_here_p PROTO ((struct occr *, struct expr *,
int, int, char *));
static rtx computing_insn PROTO ((struct expr *, rtx));
static int def_reaches_here_p PROTO ((rtx, rtx));
static int can_disregard_other_sets PROTO ((struct reg_set **, rtx, int));
static int handle_avail_expr PROTO ((rtx, struct expr *));
static int classic_gcse PROTO ((void));
static int one_classic_gcse_pass PROTO ((rtx, int));
static void alloc_cprop_mem PROTO ((int, int)); static void alloc_cprop_mem PROTO ((int, int));
static void free_cprop_mem PROTO ((void)); static void free_cprop_mem PROTO ((void));
extern void dump_cprop_data PROTO ((FILE *));
static void compute_transp PROTO ((rtx, int, sbitmap *, int)); static void compute_transp PROTO ((rtx, int, sbitmap *, int));
static void compute_cprop_local_properties PROTO ((void)); static void compute_local_properties PROTO ((sbitmap *, sbitmap *,
sbitmap *, int));
static void compute_cprop_avinout PROTO ((void)); static void compute_cprop_avinout PROTO ((void));
static void compute_cprop_data PROTO ((void)); static void compute_cprop_data PROTO ((void));
static void find_used_regs PROTO ((rtx)); static void find_used_regs PROTO ((rtx));
static int try_replace_reg PROTO ((rtx, rtx, rtx)); static int try_replace_reg PROTO ((rtx, rtx, rtx));
static struct expr *find_avail_set PROTO ((int, rtx)); static struct expr *find_avail_set PROTO ((int, rtx));
static int cprop_insn PROTO ((rtx)); static int cprop_insn PROTO ((rtx, int));
static int cprop PROTO ((void)); static int cprop PROTO ((int));
static int one_cprop_pass PROTO ((rtx, int)); static int one_cprop_pass PROTO ((int, int));
static void alloc_pre_mem PROTO ((int, int)); static void alloc_pre_mem PROTO ((int, int));
static void free_pre_mem PROTO ((void)); static void free_pre_mem PROTO ((void));
extern void dump_pre_data PROTO ((FILE *));
static void compute_pre_local_properties PROTO ((void)); static void compute_pre_local_properties PROTO ((void));
static void compute_pre_avinout PROTO ((void)); static void compute_pre_avinout PROTO ((void));
static void compute_pre_antinout PROTO ((void)); static void compute_pre_antinout PROTO ((void));
...@@ -615,10 +591,31 @@ static void pre_insert_copy_insn PROTO ((struct expr *, rtx)); ...@@ -615,10 +591,31 @@ static void pre_insert_copy_insn PROTO ((struct expr *, rtx));
static void pre_insert_copies PROTO ((void)); static void pre_insert_copies PROTO ((void));
static int pre_delete PROTO ((void)); static int pre_delete PROTO ((void));
static int pre_gcse PROTO ((void)); static int pre_gcse PROTO ((void));
static int one_pre_gcse_pass PROTO ((rtx, int)); static int one_pre_gcse_pass PROTO ((int));
static void add_label_notes PROTO ((rtx, rtx)); static void add_label_notes PROTO ((rtx, rtx));
static void alloc_rd_mem PROTO ((int, int));
static void free_rd_mem PROTO ((void));
static void handle_rd_kill_set PROTO ((rtx, int, int));
static void compute_kill_rd PROTO ((void));
static void compute_rd PROTO ((void));
static void alloc_avail_expr_mem PROTO ((int, int));
static void free_avail_expr_mem PROTO ((void));
static void compute_ae_gen PROTO ((void));
static int expr_killed_p PROTO ((rtx, int));
static void compute_ae_kill PROTO ((void));
static void compute_available PROTO ((void));
static int expr_reaches_here_p PROTO ((struct occr *, struct expr *,
int, int, char *));
static rtx computing_insn PROTO ((struct expr *, rtx));
static int def_reaches_here_p PROTO ((rtx, rtx));
static int can_disregard_other_sets PROTO ((struct reg_set **, rtx, int));
static int handle_avail_expr PROTO ((rtx, struct expr *));
static int classic_gcse PROTO ((void));
static int one_classic_gcse_pass PROTO ((int));
/* Entry point for global common subexpression elimination. /* Entry point for global common subexpression elimination.
F is the first instruction in the function. */ F is the first instruction in the function. */
...@@ -635,16 +632,20 @@ gcse_main (f, file) ...@@ -635,16 +632,20 @@ gcse_main (f, file)
/* Point to release obstack data from for each pass. */ /* Point to release obstack data from for each pass. */
char *gcse_obstack_bottom; char *gcse_obstack_bottom;
run_jump_opt_after_gcse = 0; /* We do not construct an accurate cfg in functions which call
setjmp, so just punt to be safe. */
/* It's impossible to construct a correct control flow graph in the
presense of setjmp, so just punt to be safe. */
if (current_function_calls_setjmp) if (current_function_calls_setjmp)
return 0; return 0;
/* Assume that we do not need to run jump optimizations after gcse. */
run_jump_opt_after_gcse = 0;
/* For calling dump_foo fns from gdb. */ /* For calling dump_foo fns from gdb. */
debug_stderr = stderr; debug_stderr = stderr;
gcse_file = file;
/* Identify the basic block information for this function, including
successors and predecessors. */
max_gcse_regno = max_reg_num (); max_gcse_regno = max_reg_num ();
find_basic_blocks (f, max_gcse_regno, file); find_basic_blocks (f, max_gcse_regno, file);
...@@ -665,8 +666,6 @@ gcse_main (f, file) ...@@ -665,8 +666,6 @@ gcse_main (f, file)
gcc_obstack_init (&gcse_obstack); gcc_obstack_init (&gcse_obstack);
gcse_file = file;
/* Allocate and compute predecessors/successors. */ /* Allocate and compute predecessors/successors. */
s_preds = (int_list_ptr *) alloca (n_basic_blocks * sizeof (int_list_ptr)); s_preds = (int_list_ptr *) alloca (n_basic_blocks * sizeof (int_list_ptr));
...@@ -681,9 +680,13 @@ gcse_main (f, file) ...@@ -681,9 +680,13 @@ gcse_main (f, file)
/* Record where pseudo-registers are set. /* Record where pseudo-registers are set.
This data is kept accurate during each pass. This data is kept accurate during each pass.
??? We could also record hard-reg and memory information here ??? We could also record hard-reg information here
[since it's unchanging], however it is currently done during [since it's unchanging], however it is currently done during
hash table computation. */ hash table computation.
It may be tempting to compute MEM set information here too, but MEM
sets will be subject to code motion one day and thus we need to compute
information about memory sets when we build the hash tables. */
alloc_reg_set_mem (max_gcse_regno); alloc_reg_set_mem (max_gcse_regno);
compute_sets (f); compute_sets (f);
...@@ -708,12 +711,14 @@ gcse_main (f, file) ...@@ -708,12 +711,14 @@ gcse_main (f, file)
alloc_gcse_mem (f); alloc_gcse_mem (f);
changed = one_cprop_pass (f, pass + 1); /* Don't allow constant propagation to modify jumps
during this pass. */
changed = one_cprop_pass (pass + 1, 0);
if (optimize_size) if (optimize_size)
changed |= one_classic_gcse_pass (f, pass + 1); changed |= one_classic_gcse_pass (pass + 1);
else else
changed |= one_pre_gcse_pass (f, pass + 1); changed |= one_pre_gcse_pass (pass + 1);
if (max_pass_bytes < bytes_used) if (max_pass_bytes < bytes_used)
max_pass_bytes = bytes_used; max_pass_bytes = bytes_used;
...@@ -729,14 +734,14 @@ gcse_main (f, file) ...@@ -729,14 +734,14 @@ gcse_main (f, file)
pass++; pass++;
} }
/* If we're doing PRE, do one last pass of copy propagation. */ /* Do one last pass of copy propagation, including cprop into
if (! optimize_size) conditional jumps. */
{
max_gcse_regno = max_reg_num (); max_gcse_regno = max_reg_num ();
alloc_gcse_mem (f); alloc_gcse_mem (f);
one_cprop_pass (f, pass + 1); /* This time, go ahead and allow cprop to alter jumps. */
one_cprop_pass (pass + 1, 1);
free_gcse_mem (); free_gcse_mem ();
}
if (file) if (file)
{ {
...@@ -899,24 +904,114 @@ free_gcse_mem () ...@@ -899,24 +904,114 @@ free_gcse_mem ()
free (mem_set_in_block); free (mem_set_in_block);
} }
void
dump_cuid_table (file) /* Compute the local properties of each recorded expression.
FILE *file; Local properties are those that are defined by the block, irrespective
of other blocks.
An expression is transparent in a block if its operands are not modified
in the block.
An expression is computed (locally available) in a block if it is computed
at least once and expression would contain the same value if the
computation was moved to the end of the block.
An expression is locally anticipatable in a block if it is computed at
least once and expression would contain the same value if the computation
was moved to the beginning of the block.
We call this routine for cprop, pre and code hoisting. They all
compute basically the same information and thus can easily share
this code.
TRANSP, COMP, and ANTLOC are destination sbitmaps for recording
local properties. If NULL, then it is not necessary to compute
or record that particular property.
SETP controls which hash table to look at. If zero, this routine
looks at the expr hash table; if nonzero this routine looks at
the set hash table. */
static void
compute_local_properties (transp, comp, antloc, setp)
sbitmap *transp;
sbitmap *comp;
sbitmap *antloc;
int setp;
{ {
int i; int i, hash_table_size;
struct expr **hash_table;
/* Initialize any bitmaps that were passed in. */
if (transp)
sbitmap_vector_ones (transp, n_basic_blocks);
if (comp)
sbitmap_vector_zero (comp, n_basic_blocks);
if (antloc)
sbitmap_vector_zero (antloc, n_basic_blocks);
/* We use the same code for cprop, pre and hoisting. For cprop
we care about the set hash table, for pre and hoisting we
care about the expr hash table. */
hash_table_size = setp ? set_hash_table_size : expr_hash_table_size;
hash_table = setp ? set_hash_table : expr_hash_table;
fprintf (file, "CUID table\n"); for (i = 0; i < hash_table_size; i++)
for (i = 0; i < max_cuid; i++)
{ {
rtx insn = CUID_INSN (i); struct expr *expr;
if (i != 0 && i % 10 == 0)
fprintf (file, "\n"); for (expr = hash_table[i]; expr != NULL; expr = expr->next_same_hash)
if (insn != NULL) {
fprintf (file, " %d", INSN_UID (insn)); struct occr *occr;
int indx = expr->bitmap_index;
/* The expression is transparent in this block if it is not killed.
We start by assuming all are transparent [none are killed], and
then reset the bits for those that are. */
if (transp)
compute_transp (expr->expr, indx, transp, setp);
/* The occurrences recorded in antic_occr are exactly those that
we want to set to non-zero in ANTLOC. */
if (antloc)
{
for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
{
int bb = BLOCK_NUM (occr->insn);
SET_BIT (antloc[bb], indx);
/* While we're scanning the table, this is a good place to
initialize this. */
occr->deleted_p = 0;
}
}
/* The occurrences recorded in avail_occr are exactly those that
we want to set to non-zero in COMP. */
if (comp)
{
for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
{
int bb = BLOCK_NUM (occr->insn);
SET_BIT (comp[bb], indx);
/* While we're scanning the table, this is a good place to
initialize this. */
occr->copied_p = 0;
}
}
/* While we're scanning the table, this is a good place to
initialize this. */
expr->reaching_reg = 0;
}
} }
fprintf (file, "\n\n");
} }
/* Register set information. /* Register set information.
`reg_set_table' records where each register is set or otherwise `reg_set_table' records where each register is set or otherwise
...@@ -1047,18 +1142,6 @@ static int *reg_last_set; ...@@ -1047,18 +1142,6 @@ static int *reg_last_set;
static int mem_first_set; static int mem_first_set;
static int mem_last_set; static int mem_last_set;
/* Set the appropriate bit in `rd_gen' [the gen for reaching defs] if the
register set in this insn is not set after this insn in this block. */
static void
maybe_set_rd_gen (regno, insn)
int regno;
rtx insn;
{
if (reg_last_set[regno] <= INSN_CUID (insn))
SET_BIT (rd_gen[BLOCK_NUM (insn)], INSN_CUID (insn));
}
/* Perform a quick check whether X, the source of a set, is something /* Perform a quick check whether X, the source of a set, is something
we want to consider for GCSE. */ we want to consider for GCSE. */
...@@ -1787,22 +1870,6 @@ hash_scan_set (pat, insn, set_p) ...@@ -1787,22 +1870,6 @@ hash_scan_set (pat, insn, set_p)
&& oprs_available_p (pat, tmp)))) && oprs_available_p (pat, tmp))))
insert_set_in_table (pat, insn); insert_set_in_table (pat, insn);
} }
/* Check if first/last set in this block for classic gcse,
but not for copy/constant propagation. */
if (optimize_size && !set_p)
{
rtx dest = SET_DEST (pat);
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
|| GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (GET_CODE (dest) == REG)
maybe_set_rd_gen (REGNO (dest), insn);
}
} }
static void static void
...@@ -1857,21 +1924,6 @@ hash_scan_insn (insn, set_p, in_libcall_block) ...@@ -1857,21 +1924,6 @@ hash_scan_insn (insn, set_p, in_libcall_block)
{ {
if (GET_CODE (SET_SRC (x)) == CALL) if (GET_CODE (SET_SRC (x)) == CALL)
hash_scan_call (SET_SRC (x), insn); hash_scan_call (SET_SRC (x), insn);
/* Check if first/last set in this block for classic
gcse, but not for constant/copy propagation. */
if (optimize_size && !set_p)
{
rtx dest = SET_DEST (x);
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
|| GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
if (GET_CODE (dest) == REG)
maybe_set_rd_gen (REGNO (dest), insn);
}
} }
else if (GET_CODE (x) == CLOBBER) else if (GET_CODE (x) == CLOBBER)
hash_scan_clobber (x, insn); hash_scan_clobber (x, insn);
...@@ -1994,8 +2046,7 @@ record_last_set_info (dest, setter) ...@@ -1994,8 +2046,7 @@ record_last_set_info (dest, setter)
SET_P is non-zero for computing the assignment hash table. */ SET_P is non-zero for computing the assignment hash table. */
static void static void
compute_hash_table (f, set_p) compute_hash_table (set_p)
rtx f ATTRIBUTE_UNUSED;
int set_p; int set_p;
{ {
int bb; int bb;
...@@ -2130,14 +2181,13 @@ free_set_hash_table () ...@@ -2130,14 +2181,13 @@ free_set_hash_table ()
/* Compute the hash table for doing copy/const propagation. */ /* Compute the hash table for doing copy/const propagation. */
static void static void
compute_set_hash_table (f) compute_set_hash_table ()
rtx f;
{ {
/* Initialize count of number of entries in hash table. */ /* Initialize count of number of entries in hash table. */
n_sets = 0; n_sets = 0;
bzero ((char *) set_hash_table, set_hash_table_size * sizeof (struct expr *)); bzero ((char *) set_hash_table, set_hash_table_size * sizeof (struct expr *));
compute_hash_table (f, 1); compute_hash_table (1);
} }
/* Allocate space for the expression hash table. /* Allocate space for the expression hash table.
...@@ -2173,14 +2223,13 @@ free_expr_hash_table () ...@@ -2173,14 +2223,13 @@ free_expr_hash_table ()
/* Compute the hash table for doing GCSE. */ /* Compute the hash table for doing GCSE. */
static void static void
compute_expr_hash_table (f) compute_expr_hash_table ()
rtx f;
{ {
/* Initialize count of number of entries in hash table. */ /* Initialize count of number of entries in hash table. */
n_exprs = 0; n_exprs = 0;
bzero ((char *) expr_hash_table, expr_hash_table_size * sizeof (struct expr *)); bzero ((char *) expr_hash_table, expr_hash_table_size * sizeof (struct expr *));
compute_hash_table (f, 0); compute_hash_table (0);
} }
/* Expression tracking support. */ /* Expression tracking support. */
...@@ -2345,8 +2394,8 @@ repeat: ...@@ -2345,8 +2394,8 @@ repeat:
/* Mark things set by a CALL. */ /* Mark things set by a CALL. */
static void static void
mark_call (pat, insn) mark_call (insn)
rtx pat ATTRIBUTE_UNUSED, insn; rtx insn;
{ {
mem_last_set = INSN_CUID (insn); mem_last_set = INSN_CUID (insn);
} }
...@@ -2371,7 +2420,7 @@ mark_set (pat, insn) ...@@ -2371,7 +2420,7 @@ mark_set (pat, insn)
mem_last_set = INSN_CUID (insn); mem_last_set = INSN_CUID (insn);
if (GET_CODE (SET_SRC (pat)) == CALL) if (GET_CODE (SET_SRC (pat)) == CALL)
mark_call (SET_SRC (pat), insn); mark_call (insn);
} }
/* Record things set by a CLOBBER. */ /* Record things set by a CLOBBER. */
...@@ -2415,15 +2464,16 @@ mark_oprs_set (insn) ...@@ -2415,15 +2464,16 @@ mark_oprs_set (insn)
else if (GET_CODE (x) == CLOBBER) else if (GET_CODE (x) == CLOBBER)
mark_clobber (x, insn); mark_clobber (x, insn);
else if (GET_CODE (x) == CALL) else if (GET_CODE (x) == CALL)
mark_call (x, insn); mark_call (insn);
} }
} }
else if (GET_CODE (pat) == CLOBBER) else if (GET_CODE (pat) == CLOBBER)
mark_clobber (pat, insn); mark_clobber (pat, insn);
else if (GET_CODE (pat) == CALL) else if (GET_CODE (pat) == CALL)
mark_call (pat, insn); mark_call (insn);
} }
/* Classic GCSE reaching definition support. */ /* Classic GCSE reaching definition support. */
/* Allocate reaching def variables. */ /* Allocate reaching def variables. */
...@@ -2474,38 +2524,6 @@ handle_rd_kill_set (insn, regno, bb) ...@@ -2474,38 +2524,6 @@ handle_rd_kill_set (insn, regno, bb)
} }
} }
void
dump_rd_table (file, title, bmap)
FILE *file;
char *title;
sbitmap *bmap;
{
int bb,cuid,i,j,n;
fprintf (file, "%s\n", title);
for (bb = 0; bb < n_basic_blocks; bb++)
{
fprintf (file, "BB %d\n", bb);
dump_sbitmap (file, bmap[bb]);
for (i = n = cuid = 0; i < bmap[bb]->size; i++)
{
for (j = 0; j < SBITMAP_ELT_BITS; j++, cuid++)
{
if ((bmap[bb]->elms[i] & (1 << j)) != 0)
{
if (n % 10 == 0)
fprintf (file, " ");
fprintf (file, " %d", INSN_UID (CUID_INSN (cuid)));
n++;
}
}
}
if (n != 0)
fprintf (file, "\n");
}
fprintf (file, "\n");
}
/* Compute the set of kill's for reaching definitions. */ /* Compute the set of kill's for reaching definitions. */
static void static void
...@@ -2807,8 +2825,7 @@ compute_available () ...@@ -2807,8 +2825,7 @@ compute_available ()
changed = 0; changed = 0;
for (bb = 1; bb < n_basic_blocks; bb++) for (bb = 1; bb < n_basic_blocks; bb++)
{ {
sbitmap_intersect_of_predecessors (ae_in[bb], ae_out, sbitmap_intersect_of_predecessors (ae_in[bb], ae_out, bb, s_preds);
bb, s_preds);
changed |= sbitmap_union_of_diff (ae_out[bb], ae_gen[bb], changed |= sbitmap_union_of_diff (ae_out[bb], ae_gen[bb],
ae_in[bb], ae_kill[bb]); ae_in[bb], ae_kill[bb]);
} }
...@@ -3263,8 +3280,7 @@ classic_gcse () ...@@ -3263,8 +3280,7 @@ classic_gcse ()
Return non-zero if a change was made. */ Return non-zero if a change was made. */
static int static int
one_classic_gcse_pass (f, pass) one_classic_gcse_pass (pass)
rtx f;
int pass; int pass;
{ {
int changed = 0; int changed = 0;
...@@ -3274,7 +3290,7 @@ one_classic_gcse_pass (f, pass) ...@@ -3274,7 +3290,7 @@ one_classic_gcse_pass (f, pass)
alloc_expr_hash_table (max_cuid); alloc_expr_hash_table (max_cuid);
alloc_rd_mem (n_basic_blocks, max_cuid); alloc_rd_mem (n_basic_blocks, max_cuid);
compute_expr_hash_table (f); compute_expr_hash_table ();
if (gcse_file) if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table, dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs); expr_hash_table_size, n_exprs);
...@@ -3341,23 +3357,6 @@ free_cprop_mem () ...@@ -3341,23 +3357,6 @@ free_cprop_mem ()
free (cprop_avout); free (cprop_avout);
} }
/* Dump copy/const propagation data. */
void
dump_cprop_data (file)
FILE *file;
{
dump_sbitmap_vector (file, "CPROP partially locally available sets", "BB",
cprop_pavloc, n_basic_blocks);
dump_sbitmap_vector (file, "CPROP absolutely altered sets", "BB",
cprop_absaltered, n_basic_blocks);
dump_sbitmap_vector (file, "CPROP available incoming sets", "BB",
cprop_avin, n_basic_blocks);
dump_sbitmap_vector (file, "CPROP available outgoing sets", "BB",
cprop_avout, n_basic_blocks);
}
/* For each block, compute whether X is transparent. /* For each block, compute whether X is transparent.
X is either an expression or an assignment [though we don't care which, X is either an expression or an assignment [though we don't care which,
for this context an assignment is treated as an expression]. for this context an assignment is treated as an expression].
...@@ -3484,42 +3483,11 @@ compute_transp (x, indx, bmap, set_p) ...@@ -3484,42 +3483,11 @@ compute_transp (x, indx, bmap, set_p)
} }
} }
static void /* Compute the available expressions at the start and end of each
compute_cprop_local_properties () basic block for cprop. This particular dataflow equation is
{ used often enough that we might want to generalize it and make
int i; as a subroutine for other global optimizations that need available
in/out information. */
sbitmap_vector_zero (cprop_absaltered, n_basic_blocks);
sbitmap_vector_zero (cprop_pavloc, n_basic_blocks);
for (i = 0; i < set_hash_table_size; i++)
{
struct expr *expr;
for (expr = set_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
{
struct occr *occr;
int indx = expr->bitmap_index;
/* The assignment is absolutely altered if any operand is modified
by this block [excluding the assignment itself].
We start by assuming all are transparent [none are killed], and
then setting the bits for those that are. */
compute_transp (expr->expr, indx, cprop_absaltered, 1);
/* The occurrences recorded in avail_occr are exactly those that
we want to set to non-zero in PAVLOC. */
for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
{
int bb = BLOCK_NUM (occr->insn);
SET_BIT (cprop_pavloc[bb], indx);
}
}
}
}
static void static void
compute_cprop_avinout () compute_cprop_avinout ()
{ {
...@@ -3536,8 +3504,8 @@ compute_cprop_avinout () ...@@ -3536,8 +3504,8 @@ compute_cprop_avinout ()
for (bb = 0; bb < n_basic_blocks; bb++) for (bb = 0; bb < n_basic_blocks; bb++)
{ {
if (bb != 0) if (bb != 0)
sbitmap_intersect_of_predecessors (cprop_avin[bb], cprop_avout, sbitmap_intersect_of_predecessors (cprop_avin[bb],
bb, s_preds); cprop_avout, bb, s_preds);
changed |= sbitmap_union_of_diff (cprop_avout[bb], changed |= sbitmap_union_of_diff (cprop_avout[bb],
cprop_pavloc[bb], cprop_pavloc[bb],
cprop_avin[bb], cprop_avin[bb],
...@@ -3556,7 +3524,7 @@ compute_cprop_avinout () ...@@ -3556,7 +3524,7 @@ compute_cprop_avinout ()
static void static void
compute_cprop_data () compute_cprop_data ()
{ {
compute_cprop_local_properties (); compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, 1);
compute_cprop_avinout (); compute_cprop_avinout ();
} }
...@@ -3700,8 +3668,9 @@ find_avail_set (regno, insn) ...@@ -3700,8 +3668,9 @@ find_avail_set (regno, insn)
The result is non-zero if a change was made. */ The result is non-zero if a change was made. */
static int static int
cprop_insn (insn) cprop_insn (insn, alter_jumps)
rtx insn; rtx insn;
int alter_jumps;
{ {
struct reg_use *reg_used; struct reg_use *reg_used;
int changed = 0; int changed = 0;
...@@ -3775,7 +3744,8 @@ cprop_insn (insn) ...@@ -3775,7 +3744,8 @@ cprop_insn (insn)
(set (pc) (if_then_else ...)) (set (pc) (if_then_else ...))
Note this does not currently handle machines which use cc0. */ Note this does not currently handle machines which use cc0. */
else if (GET_CODE (insn) == JUMP_INSN && condjump_p (insn)) else if (alter_jumps
&& GET_CODE (insn) == JUMP_INSN && condjump_p (insn))
{ {
/* We want a copy of the JUMP_INSN so we can modify it /* We want a copy of the JUMP_INSN so we can modify it
in-place as needed without effecting the original. */ in-place as needed without effecting the original. */
...@@ -3880,7 +3850,8 @@ cprop_insn (insn) ...@@ -3880,7 +3850,8 @@ cprop_insn (insn)
Return non-zero if a change was made. */ Return non-zero if a change was made. */
static int static int
cprop () cprop (alter_jumps)
int alter_jumps;
{ {
int bb, changed; int bb, changed;
rtx insn; rtx insn;
...@@ -3900,7 +3871,7 @@ cprop () ...@@ -3900,7 +3871,7 @@ cprop ()
{ {
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{ {
changed |= cprop_insn (insn); changed |= cprop_insn (insn, alter_jumps);
/* Keep track of everything modified by this insn. */ /* Keep track of everything modified by this insn. */
/* ??? Need to be careful w.r.t. mods done to INSN. */ /* ??? Need to be careful w.r.t. mods done to INSN. */
...@@ -3920,9 +3891,9 @@ cprop () ...@@ -3920,9 +3891,9 @@ cprop ()
PASS is the pass count. */ PASS is the pass count. */
static int static int
one_cprop_pass (f, pass) one_cprop_pass (pass, alter_jumps)
rtx f;
int pass; int pass;
int alter_jumps;
{ {
int changed = 0; int changed = 0;
...@@ -3930,7 +3901,7 @@ one_cprop_pass (f, pass) ...@@ -3930,7 +3901,7 @@ one_cprop_pass (f, pass)
copy_prop_count = 0; copy_prop_count = 0;
alloc_set_hash_table (max_cuid); alloc_set_hash_table (max_cuid);
compute_set_hash_table (f); compute_set_hash_table ();
if (gcse_file) if (gcse_file)
dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size, dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size,
n_sets); n_sets);
...@@ -3938,7 +3909,7 @@ one_cprop_pass (f, pass) ...@@ -3938,7 +3909,7 @@ one_cprop_pass (f, pass)
{ {
alloc_cprop_mem (n_basic_blocks, n_sets); alloc_cprop_mem (n_basic_blocks, n_sets);
compute_cprop_data (); compute_cprop_data ();
changed = cprop (); changed = cprop (alter_jumps);
free_cprop_mem (); free_cprop_mem ();
} }
free_set_hash_table (); free_set_hash_table ();
...@@ -4029,41 +4000,6 @@ free_pre_mem () ...@@ -4029,41 +4000,6 @@ free_pre_mem ()
free (pre_transpout); free (pre_transpout);
} }
/* Dump PRE data. */
void
dump_pre_data (file)
FILE *file;
{
dump_sbitmap_vector (file, "PRE locally transparent expressions", "BB",
pre_transp, n_basic_blocks);
dump_sbitmap_vector (file, "PRE locally available expressions", "BB",
pre_comp, n_basic_blocks);
dump_sbitmap_vector (file, "PRE locally anticipatable expressions", "BB",
pre_antloc, n_basic_blocks);
dump_sbitmap_vector (file, "PRE available incoming expressions", "BB",
pre_avin, n_basic_blocks);
dump_sbitmap_vector (file, "PRE available outgoing expressions", "BB",
pre_avout, n_basic_blocks);
dump_sbitmap_vector (file, "PRE anticipatable incoming expressions", "BB",
pre_antin, n_basic_blocks);
dump_sbitmap_vector (file, "PRE anticipatable outgoing expressions", "BB",
pre_antout, n_basic_blocks);
dump_sbitmap_vector (file, "PRE partially available incoming expressions", "BB",
pre_pavin, n_basic_blocks);
dump_sbitmap_vector (file, "PRE partially available outgoing expressions", "BB",
pre_pavout, n_basic_blocks);
dump_sbitmap_vector (file, "PRE placement possible on incoming", "BB",
pre_ppin, n_basic_blocks);
dump_sbitmap_vector (file, "PRE placement possible on outgoing", "BB",
pre_ppout, n_basic_blocks);
dump_sbitmap_vector (file, "PRE transparent on outgoing", "BB",
pre_transpout, n_basic_blocks);
}
/* Compute the local properties of each recorded expression. /* Compute the local properties of each recorded expression.
Local properties are those that are defined by the block, irrespective Local properties are those that are defined by the block, irrespective
of other blocks. of other blocks.
...@@ -4886,8 +4822,7 @@ pre_gcse () ...@@ -4886,8 +4822,7 @@ pre_gcse ()
Return non-zero if a change was made. */ Return non-zero if a change was made. */
static int static int
one_pre_gcse_pass (f, pass) one_pre_gcse_pass (pass)
rtx f;
int pass; int pass;
{ {
int changed = 0; int changed = 0;
...@@ -4896,7 +4831,7 @@ one_pre_gcse_pass (f, pass) ...@@ -4896,7 +4831,7 @@ one_pre_gcse_pass (f, pass)
gcse_create_count = 0; gcse_create_count = 0;
alloc_expr_hash_table (max_cuid); alloc_expr_hash_table (max_cuid);
compute_expr_hash_table (f); compute_expr_hash_table ();
if (gcse_file) if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table, dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs); expr_hash_table_size, n_exprs);
......
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