Large gcse.c patch
Jeffrey A Law
law@hurl.cygnus.com
Wed Mar 10 21:29:00 GMT 1999
Another gcse.c cleanup patch. Rather large this time. 3-stages on the x86.
It's amazing how much code can change in a year.
* 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.
Index: gcse.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/gcse.c,v
retrieving revision 1.31
diff -c -3 -p -r1.31 gcse.c
*** gcse.c 1999/03/10 20:18:59 1.31
--- gcse.c 1999/03/11 05:22:25
*************** static sbitmap *rd_kill, *rd_gen, *reach
*** 509,514 ****
--- 509,515 ----
/* for available exprs */
static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
+
static void compute_can_copy PROTO ((void));
*************** static char *grealloc PROTO ((char *,
*** 517,524 ****
static char *gcse_alloc PROTO ((unsigned long));
static void alloc_gcse_mem PROTO ((rtx));
static void free_gcse_mem PROTO ((void));
- extern void dump_cuid_table PROTO ((FILE *));
-
static void alloc_reg_set_mem PROTO ((int));
static void free_reg_set_mem PROTO ((void));
static void record_one_set PROTO ((int, rtx));
--- 518,523 ----
*************** static void hash_scan_insn PROTO ((r
*** 529,606 ****
static void hash_scan_set PROTO ((rtx, rtx, int));
static void hash_scan_clobber 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 oprs_unchanged_p PROTO ((rtx, rtx, int));
static int oprs_anticipatable_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_set_in_table PROTO ((rtx, rtx));
! 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_set PROTO ((int, int));
static int expr_equiv_p PROTO ((rtx, rtx));
static void record_last_reg_set_info PROTO ((rtx, int));
static void record_last_mem_set_info PROTO ((rtx));
static void record_last_set_info PROTO ((rtx, rtx));
! static void compute_hash_table PROTO ((rtx, int));
static void alloc_set_hash_table PROTO ((int));
static void free_set_hash_table PROTO ((void));
! static void compute_set_hash_table PROTO ((rtx));
static void alloc_expr_hash_table PROTO ((int));
static void free_expr_hash_table PROTO ((void));
! static void compute_expr_hash_table PROTO ((rtx));
static void dump_hash_table PROTO ((FILE *, const char *, struct expr **, int, int));
static struct expr *lookup_expr PROTO ((rtx));
static struct expr *lookup_set PROTO ((int, rtx));
static struct expr *next_set PROTO ((int, struct expr *));
static void reset_opr_set_tables PROTO ((void));
static int oprs_not_set_p PROTO ((rtx, rtx));
! static void mark_call PROTO ((rtx, rtx));
static void mark_set PROTO ((rtx, rtx));
static void mark_clobber PROTO ((rtx, 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 free_cprop_mem PROTO ((void));
- extern void dump_cprop_data PROTO ((FILE *));
static void compute_transp PROTO ((rtx, int, sbitmap *, int));
! static void compute_cprop_local_properties PROTO ((void));
static void compute_cprop_avinout PROTO ((void));
static void compute_cprop_data PROTO ((void));
static void find_used_regs PROTO ((rtx));
static int try_replace_reg PROTO ((rtx, rtx, rtx));
static struct expr *find_avail_set PROTO ((int, rtx));
! static int cprop_insn PROTO ((rtx));
! static int cprop PROTO ((void));
! static int one_cprop_pass PROTO ((rtx, int));
static void alloc_pre_mem PROTO ((int, int));
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_avinout PROTO ((void));
static void compute_pre_antinout PROTO ((void));
--- 528,582 ----
static void hash_scan_set PROTO ((rtx, rtx, int));
static void hash_scan_clobber PROTO ((rtx, rtx));
static void hash_scan_call PROTO ((rtx, rtx));
static int want_to_gcse_p PROTO ((rtx));
static int oprs_unchanged_p PROTO ((rtx, rtx, int));
static int oprs_anticipatable_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_set_in_table PROTO ((rtx, rtx));
! 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_set PROTO ((int, int));
static int expr_equiv_p PROTO ((rtx, rtx));
static void record_last_reg_set_info PROTO ((rtx, int));
static void record_last_mem_set_info PROTO ((rtx));
static void record_last_set_info PROTO ((rtx, rtx));
! static void compute_hash_table PROTO ((int));
static void alloc_set_hash_table PROTO ((int));
static void free_set_hash_table PROTO ((void));
! static void compute_set_hash_table PROTO ((void));
static void alloc_expr_hash_table PROTO ((int));
static void free_expr_hash_table PROTO ((void));
! static void compute_expr_hash_table PROTO ((void));
static void dump_hash_table PROTO ((FILE *, const char *, struct expr **, int, int));
static struct expr *lookup_expr PROTO ((rtx));
static struct expr *lookup_set PROTO ((int, rtx));
static struct expr *next_set PROTO ((int, struct expr *));
static void reset_opr_set_tables PROTO ((void));
static int oprs_not_set_p PROTO ((rtx, rtx));
! static void mark_call PROTO ((rtx));
static void mark_set PROTO ((rtx, rtx));
static void mark_clobber PROTO ((rtx, rtx));
static void mark_oprs_set PROTO ((rtx));
static void alloc_cprop_mem PROTO ((int, int));
static void free_cprop_mem PROTO ((void));
static void compute_transp PROTO ((rtx, int, sbitmap *, int));
! static void compute_local_properties PROTO ((sbitmap *, sbitmap *,
! sbitmap *, int));
static void compute_cprop_avinout PROTO ((void));
static void compute_cprop_data PROTO ((void));
static void find_used_regs PROTO ((rtx));
static int try_replace_reg PROTO ((rtx, rtx, rtx));
static struct expr *find_avail_set PROTO ((int, rtx));
! static int cprop_insn PROTO ((rtx, int));
! static int cprop PROTO ((int));
! static int one_cprop_pass PROTO ((int, int));
static void alloc_pre_mem PROTO ((int, int));
static void free_pre_mem PROTO ((void));
static void compute_pre_local_properties PROTO ((void));
static void compute_pre_avinout PROTO ((void));
static void compute_pre_antinout PROTO ((void));
*************** static void pre_insert_copy_insn PR
*** 615,623 ****
static void pre_insert_copies PROTO ((void));
static int pre_delete PROTO ((void));
static int pre_gcse PROTO ((void));
! static int one_pre_gcse_pass PROTO ((rtx, int));
static void add_label_notes PROTO ((rtx, rtx));
/* Entry point for global common subexpression elimination.
F is the first instruction in the function. */
--- 591,620 ----
static void pre_insert_copies PROTO ((void));
static int pre_delete PROTO ((void));
static int pre_gcse PROTO ((void));
! static int one_pre_gcse_pass PROTO ((int));
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.
F is the first instruction in the function. */
*************** gcse_main (f, file)
*** 635,650 ****
/* Point to release obstack data from for each pass. */
char *gcse_obstack_bottom;
! run_jump_opt_after_gcse = 0;
!
! /* 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)
return 0;
/* For calling dump_foo fns from gdb. */
debug_stderr = stderr;
max_gcse_regno = max_reg_num ();
find_basic_blocks (f, max_gcse_regno, file);
--- 632,651 ----
/* Point to release obstack data from for each pass. */
char *gcse_obstack_bottom;
! /* We do not construct an accurate cfg in functions which call
! setjmp, so just punt to be safe. */
if (current_function_calls_setjmp)
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. */
debug_stderr = stderr;
+ gcse_file = file;
+ /* Identify the basic block information for this function, including
+ successors and predecessors. */
max_gcse_regno = max_reg_num ();
find_basic_blocks (f, max_gcse_regno, file);
*************** gcse_main (f, file)
*** 665,672 ****
gcc_obstack_init (&gcse_obstack);
- gcse_file = file;
-
/* Allocate and compute predecessors/successors. */
s_preds = (int_list_ptr *) alloca (n_basic_blocks * sizeof (int_list_ptr));
--- 666,671 ----
*************** gcse_main (f, file)
*** 681,689 ****
/* Record where pseudo-registers are set.
This data is kept accurate during each pass.
! ??? We could also record hard-reg and memory information here
[since it's unchanging], however it is currently done during
! hash table computation. */
alloc_reg_set_mem (max_gcse_regno);
compute_sets (f);
--- 680,692 ----
/* Record where pseudo-registers are set.
This data is kept accurate during each pass.
! ??? We could also record hard-reg information here
[since it's unchanging], however it is currently done during
! 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);
compute_sets (f);
*************** gcse_main (f, file)
*** 708,719 ****
alloc_gcse_mem (f);
! changed = one_cprop_pass (f, pass + 1);
if (optimize_size)
! changed |= one_classic_gcse_pass (f, pass + 1);
else
! changed |= one_pre_gcse_pass (f, pass + 1);
if (max_pass_bytes < bytes_used)
max_pass_bytes = bytes_used;
--- 711,724 ----
alloc_gcse_mem (f);
! /* Don't allow constant propagation to modify jumps
! during this pass. */
! changed = one_cprop_pass (pass + 1, 0);
if (optimize_size)
! changed |= one_classic_gcse_pass (pass + 1);
else
! changed |= one_pre_gcse_pass (pass + 1);
if (max_pass_bytes < bytes_used)
max_pass_bytes = bytes_used;
*************** gcse_main (f, file)
*** 729,742 ****
pass++;
}
! /* If we're doing PRE, do one last pass of copy propagation. */
! if (! optimize_size)
! {
! max_gcse_regno = max_reg_num ();
! alloc_gcse_mem (f);
! one_cprop_pass (f, pass + 1);
! free_gcse_mem ();
! }
if (file)
{
--- 734,747 ----
pass++;
}
! /* Do one last pass of copy propagation, including cprop into
! conditional jumps. */
!
! max_gcse_regno = max_reg_num ();
! alloc_gcse_mem (f);
! /* This time, go ahead and allow cprop to alter jumps. */
! one_cprop_pass (pass + 1, 1);
! free_gcse_mem ();
if (file)
{
*************** free_gcse_mem ()
*** 899,921 ****
free (mem_set_in_block);
}
! void
! dump_cuid_table (file)
! FILE *file;
{
! int i;
! fprintf (file, "CUID table\n");
! for (i = 0; i < max_cuid; i++)
{
! rtx insn = CUID_INSN (i);
! if (i != 0 && i % 10 == 0)
! fprintf (file, "\n");
! if (insn != NULL)
! fprintf (file, " %d", INSN_UID (insn));
}
- fprintf (file, "\n\n");
}
/* Register set information.
--- 904,1016 ----
free (mem_set_in_block);
}
!
! /* Compute the local properties of each recorded expression.
! 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, 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;
! for (i = 0; i < hash_table_size; i++)
{
! struct expr *expr;
!
! for (expr = hash_table[i]; expr != NULL; expr = expr->next_same_hash)
! {
! 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;
! }
}
}
+
/* Register set information.
*************** static int *reg_last_set;
*** 1047,1064 ****
static int mem_first_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
we want to consider for GCSE. */
--- 1142,1147 ----
*************** hash_scan_set (pat, insn, set_p)
*** 1787,1808 ****
&& oprs_available_p (pat, tmp))))
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
--- 1870,1875 ----
*************** hash_scan_insn (insn, set_p, in_libcall_
*** 1857,1877 ****
{
if (GET_CODE (SET_SRC (x)) == CALL)
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)
hash_scan_clobber (x, insn);
--- 1924,1929 ----
*************** record_last_set_info (dest, setter)
*** 1994,2001 ****
SET_P is non-zero for computing the assignment hash table. */
static void
! compute_hash_table (f, set_p)
! rtx f ATTRIBUTE_UNUSED;
int set_p;
{
int bb;
--- 2046,2052 ----
SET_P is non-zero for computing the assignment hash table. */
static void
! compute_hash_table (set_p)
int set_p;
{
int bb;
*************** free_set_hash_table ()
*** 2130,2143 ****
/* Compute the hash table for doing copy/const propagation. */
static void
! compute_set_hash_table (f)
! rtx f;
{
/* Initialize count of number of entries in hash table. */
n_sets = 0;
bzero ((char *) set_hash_table, set_hash_table_size * sizeof (struct expr *));
! compute_hash_table (f, 1);
}
/* Allocate space for the expression hash table.
--- 2181,2193 ----
/* Compute the hash table for doing copy/const propagation. */
static void
! compute_set_hash_table ()
{
/* Initialize count of number of entries in hash table. */
n_sets = 0;
bzero ((char *) set_hash_table, set_hash_table_size * sizeof (struct expr *));
! compute_hash_table (1);
}
/* Allocate space for the expression hash table.
*************** free_expr_hash_table ()
*** 2173,2186 ****
/* Compute the hash table for doing GCSE. */
static void
! compute_expr_hash_table (f)
! rtx f;
{
/* Initialize count of number of entries in hash table. */
n_exprs = 0;
bzero ((char *) expr_hash_table, expr_hash_table_size * sizeof (struct expr *));
! compute_hash_table (f, 0);
}
/* Expression tracking support. */
--- 2223,2235 ----
/* Compute the hash table for doing GCSE. */
static void
! compute_expr_hash_table ()
{
/* Initialize count of number of entries in hash table. */
n_exprs = 0;
bzero ((char *) expr_hash_table, expr_hash_table_size * sizeof (struct expr *));
! compute_hash_table (0);
}
/* Expression tracking support. */
*************** repeat:
*** 2345,2352 ****
/* Mark things set by a CALL. */
static void
! mark_call (pat, insn)
! rtx pat ATTRIBUTE_UNUSED, insn;
{
mem_last_set = INSN_CUID (insn);
}
--- 2394,2401 ----
/* Mark things set by a CALL. */
static void
! mark_call (insn)
! rtx insn;
{
mem_last_set = INSN_CUID (insn);
}
*************** mark_set (pat, insn)
*** 2371,2377 ****
mem_last_set = INSN_CUID (insn);
if (GET_CODE (SET_SRC (pat)) == CALL)
! mark_call (SET_SRC (pat), insn);
}
/* Record things set by a CLOBBER. */
--- 2420,2426 ----
mem_last_set = INSN_CUID (insn);
if (GET_CODE (SET_SRC (pat)) == CALL)
! mark_call (insn);
}
/* Record things set by a CLOBBER. */
*************** mark_oprs_set (insn)
*** 2415,2428 ****
else if (GET_CODE (x) == CLOBBER)
mark_clobber (x, insn);
else if (GET_CODE (x) == CALL)
! mark_call (x, insn);
}
}
else if (GET_CODE (pat) == CLOBBER)
mark_clobber (pat, insn);
else if (GET_CODE (pat) == CALL)
! mark_call (pat, insn);
}
/* Classic GCSE reaching definition support. */
--- 2464,2478 ----
else if (GET_CODE (x) == CLOBBER)
mark_clobber (x, insn);
else if (GET_CODE (x) == CALL)
! mark_call (insn);
}
}
else if (GET_CODE (pat) == CLOBBER)
mark_clobber (pat, insn);
else if (GET_CODE (pat) == CALL)
! mark_call (insn);
}
+
/* Classic GCSE reaching definition support. */
*************** handle_rd_kill_set (insn, regno, bb)
*** 2474,2511 ****
}
}
- 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. */
static void
--- 2524,2529 ----
*************** compute_available ()
*** 2807,2814 ****
changed = 0;
for (bb = 1; bb < n_basic_blocks; bb++)
{
! sbitmap_intersect_of_predecessors (ae_in[bb], ae_out,
! bb, s_preds);
changed |= sbitmap_union_of_diff (ae_out[bb], ae_gen[bb],
ae_in[bb], ae_kill[bb]);
}
--- 2825,2831 ----
changed = 0;
for (bb = 1; bb < n_basic_blocks; bb++)
{
! sbitmap_intersect_of_predecessors (ae_in[bb], ae_out, bb, s_preds);
changed |= sbitmap_union_of_diff (ae_out[bb], ae_gen[bb],
ae_in[bb], ae_kill[bb]);
}
*************** classic_gcse ()
*** 3263,3270 ****
Return non-zero if a change was made. */
static int
! one_classic_gcse_pass (f, pass)
! rtx f;
int pass;
{
int changed = 0;
--- 3280,3286 ----
Return non-zero if a change was made. */
static int
! one_classic_gcse_pass (pass)
int pass;
{
int changed = 0;
*************** one_classic_gcse_pass (f, pass)
*** 3274,3280 ****
alloc_expr_hash_table (max_cuid);
alloc_rd_mem (n_basic_blocks, max_cuid);
! compute_expr_hash_table (f);
if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs);
--- 3290,3296 ----
alloc_expr_hash_table (max_cuid);
alloc_rd_mem (n_basic_blocks, max_cuid);
! compute_expr_hash_table ();
if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs);
*************** free_cprop_mem ()
*** 3341,3363 ****
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.
X is either an expression or an assignment [though we don't care which,
for this context an assignment is treated as an expression].
--- 3357,3362 ----
*************** compute_transp (x, indx, bmap, set_p)
*** 3483,3525 ****
}
}
}
-
- static void
- compute_cprop_local_properties ()
- {
- int i;
-
- 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
compute_cprop_avinout ()
{
--- 3482,3493 ----
}
}
}
+ /* Compute the available expressions at the start and end of each
+ basic block for cprop. This particular dataflow equation is
+ used often enough that we might want to generalize it and make
+ as a subroutine for other global optimizations that need available
+ in/out information. */
static void
compute_cprop_avinout ()
{
*************** compute_cprop_avinout ()
*** 3536,3543 ****
for (bb = 0; bb < n_basic_blocks; bb++)
{
if (bb != 0)
! sbitmap_intersect_of_predecessors (cprop_avin[bb], cprop_avout,
! bb, s_preds);
changed |= sbitmap_union_of_diff (cprop_avout[bb],
cprop_pavloc[bb],
cprop_avin[bb],
--- 3504,3511 ----
for (bb = 0; bb < n_basic_blocks; bb++)
{
if (bb != 0)
! sbitmap_intersect_of_predecessors (cprop_avin[bb],
! cprop_avout, bb, s_preds);
changed |= sbitmap_union_of_diff (cprop_avout[bb],
cprop_pavloc[bb],
cprop_avin[bb],
*************** compute_cprop_avinout ()
*** 3556,3562 ****
static void
compute_cprop_data ()
{
! compute_cprop_local_properties ();
compute_cprop_avinout ();
}
--- 3524,3530 ----
static void
compute_cprop_data ()
{
! compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, 1);
compute_cprop_avinout ();
}
*************** find_avail_set (regno, insn)
*** 3700,3707 ****
The result is non-zero if a change was made. */
static int
! cprop_insn (insn)
rtx insn;
{
struct reg_use *reg_used;
int changed = 0;
--- 3668,3676 ----
The result is non-zero if a change was made. */
static int
! cprop_insn (insn, alter_jumps)
rtx insn;
+ int alter_jumps;
{
struct reg_use *reg_used;
int changed = 0;
*************** cprop_insn (insn)
*** 3775,3781 ****
(set (pc) (if_then_else ...))
Note this does not currently handle machines which use cc0. */
! else if (GET_CODE (insn) == JUMP_INSN && condjump_p (insn))
{
/* We want a copy of the JUMP_INSN so we can modify it
in-place as needed without effecting the original. */
--- 3744,3751 ----
(set (pc) (if_then_else ...))
Note this does not currently handle machines which use cc0. */
! 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
in-place as needed without effecting the original. */
*************** cprop_insn (insn)
*** 3880,3886 ****
Return non-zero if a change was made. */
static int
! cprop ()
{
int bb, changed;
rtx insn;
--- 3850,3857 ----
Return non-zero if a change was made. */
static int
! cprop (alter_jumps)
! int alter_jumps;
{
int bb, changed;
rtx insn;
*************** cprop ()
*** 3900,3906 ****
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
! changed |= cprop_insn (insn);
/* Keep track of everything modified by this insn. */
/* ??? Need to be careful w.r.t. mods done to INSN. */
--- 3871,3877 ----
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
! changed |= cprop_insn (insn, alter_jumps);
/* Keep track of everything modified by this insn. */
/* ??? Need to be careful w.r.t. mods done to INSN. */
*************** cprop ()
*** 3920,3928 ****
PASS is the pass count. */
static int
! one_cprop_pass (f, pass)
! rtx f;
int pass;
{
int changed = 0;
--- 3891,3899 ----
PASS is the pass count. */
static int
! one_cprop_pass (pass, alter_jumps)
int pass;
+ int alter_jumps;
{
int changed = 0;
*************** one_cprop_pass (f, pass)
*** 3930,3936 ****
copy_prop_count = 0;
alloc_set_hash_table (max_cuid);
! compute_set_hash_table (f);
if (gcse_file)
dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size,
n_sets);
--- 3901,3907 ----
copy_prop_count = 0;
alloc_set_hash_table (max_cuid);
! compute_set_hash_table ();
if (gcse_file)
dump_hash_table (gcse_file, "SET", set_hash_table, set_hash_table_size,
n_sets);
*************** one_cprop_pass (f, pass)
*** 3938,3944 ****
{
alloc_cprop_mem (n_basic_blocks, n_sets);
compute_cprop_data ();
! changed = cprop ();
free_cprop_mem ();
}
free_set_hash_table ();
--- 3909,3915 ----
{
alloc_cprop_mem (n_basic_blocks, n_sets);
compute_cprop_data ();
! changed = cprop (alter_jumps);
free_cprop_mem ();
}
free_set_hash_table ();
*************** free_pre_mem ()
*** 4029,4069 ****
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.
Local properties are those that are defined by the block, irrespective
of other blocks.
--- 4000,4005 ----
*************** pre_gcse ()
*** 4886,4893 ****
Return non-zero if a change was made. */
static int
! one_pre_gcse_pass (f, pass)
! rtx f;
int pass;
{
int changed = 0;
--- 4822,4828 ----
Return non-zero if a change was made. */
static int
! one_pre_gcse_pass (pass)
int pass;
{
int changed = 0;
*************** one_pre_gcse_pass (f, pass)
*** 4896,4902 ****
gcse_create_count = 0;
alloc_expr_hash_table (max_cuid);
! compute_expr_hash_table (f);
if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs);
--- 4831,4837 ----
gcse_create_count = 0;
alloc_expr_hash_table (max_cuid);
! compute_expr_hash_table ();
if (gcse_file)
dump_hash_table (gcse_file, "Expression", expr_hash_table,
expr_hash_table_size, n_exprs);
More information about the Gcc-patches
mailing list