This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] gcse global variables removal
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: Richard Henderson <rth at redhat dot com>, Jan Hubicka <jh at suse dot cz>,gcc-patches at gcc dot gnu dot org
- Date: Thu, 1 Aug 2002 21:30:45 +0200
- Subject: Re: [PATCH] gcse global variables removal
- References: <20020711215749.GA19903@atrey.karlin.mff.cuni.cz> <20020712070058.GD8709@atrey.karlin.mff.cuni.cz> <20020712215119.GA13832@atrey.karlin.mff.cuni.cz> <20020719183328.B15855@redhat.com> <20020722203502.GB17147@atrey.karlin.mff.cuni.cz> <20020724165942.C26512@redhat.com>
Hello,
here is the second part of the patch. It packs ae_* and rd_* into
structures and passes them around as parameters. It also joins
size and actual table of reg_set_table into single structure
(this is mostly a cosmetical change).
Zdenek Dvorak
* gcse.c (reg_set_table_size): Moved to ...
(struct reg_set_table): new type.
(reg_set_table): Type changed to struct reg_set_table.
(rd_kill, rd_gen, reaching_defs, rd_out): Moved to ...
(rd_global): new structure...
(struct rd): of this type.
(ae_kill, ae_gen, ae_in, ae_out): Moved to ...
(ae_global): new structure...
(struct ae): of this type.
(alloc_rd_mem, free_rd_mem, handle_rd_kill_set, compute_kill_rd,
compute_rd, def_reaches_here_p, can_disregard_other_sets,
handle_avail_expr, expr_reaches_here_p_work): Pass struct rd
argument explicitly.
(alloc_avail_expr_mem, free_avail_expr_mem, compute_ae_gen,
compute_ae_kill, expr_reaches_here_p, computing_insn,
handle_avail_expr): Pass struct ae argument explicitly.
(alloc_reg_set_mem, free_reg_set_mem, record_one_set,
mark_oprs_set, handle_rd_kill_set, handle_avail_expr,
compute_transp): Modified due to change of reg_set_table type.
(classic_gcse, one_classic_gcse_pass, alloc_pre_mem,
free_pre_mem, compute_pre_data, build_store_vectors,
free_store_memory, store_motion): Initialize and pass ae_global
and/or rd_global to other functions.
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.217
diff -c -3 -p -r1.217 gcse.c
*** gcse.c 1 Aug 2002 19:10:14 -0000 1.217
--- gcse.c 1 Aug 2002 19:17:22 -0000
*************** typedef struct reg_set
*** 443,454 ****
rtx insn;
} reg_set;
! static reg_set **reg_set_table;
!
! /* Size of `reg_set_table'.
! The table starts out at max_gcse_regno + slop, and is enlarged as
! necessary. */
! static int reg_set_table_size;
/* Amount to grow `reg_set_table' by when it's full. */
#define REG_SET_TABLE_SLOP 100
--- 443,453 ----
rtx insn;
} reg_set;
! static struct reg_set_table
! {
! reg_set **table;
! int size;
! } reg_set_table;
/* Amount to grow `reg_set_table' by when it's full. */
#define REG_SET_TABLE_SLOP 100
*************** static int copy_prop_count;
*** 527,540 ****
n_exprs - for available expressions
Thus we view the bitmaps as 2 dimensional arrays. i.e.
! rd_kill[block_num][cuid_num]
! ae_kill[block_num][expr_num] */
/* For reaching defs */
! static sbitmap *rd_kill, *rd_gen, *reaching_defs, *rd_out;
/* for available exprs */
! static sbitmap *ae_kill, *ae_gen, *ae_in, *ae_out;
/* Objects of this type are passed around by the null-pointer check
removal routines. */
--- 526,545 ----
n_exprs - for available expressions
Thus we view the bitmaps as 2 dimensional arrays. i.e.
! rd.kill[block_num][cuid_num]
! ae.kill[block_num][expr_num] */
/* For reaching defs */
! static struct rd
! {
! sbitmap *kill, *gen, *reaching_defs, *out;
! } rd_global;
/* for available exprs */
! static struct ae
! {
! sbitmap *kill, *gen, *in, *out;
! } ae_global;
/* Objects of this type are passed around by the null-pointer check
removal routines. */
*************** static int hoist_expr_reaches_here_p PAR
*** 637,658 ****
char *));
static void hoist_code PARAMS ((void));
static int one_code_hoisting_pass PARAMS ((void));
! static void alloc_rd_mem PARAMS ((int, int));
! static void free_rd_mem PARAMS ((void));
! static void handle_rd_kill_set PARAMS ((rtx, int, basic_block));
! static void compute_kill_rd PARAMS ((void));
! static void compute_rd PARAMS ((void));
! static void alloc_avail_expr_mem PARAMS ((int, int));
! static void free_avail_expr_mem PARAMS ((void));
! static void compute_ae_gen PARAMS ((struct hash_table *));
static int expr_killed_p PARAMS ((rtx, basic_block));
! static void compute_ae_kill PARAMS ((sbitmap *, sbitmap *, struct hash_table *));
static int expr_reaches_here_p PARAMS ((struct occr *, struct expr *,
! basic_block, int));
! static rtx computing_insn PARAMS ((struct expr *, rtx));
! static int def_reaches_here_p PARAMS ((rtx, rtx));
! static int can_disregard_other_sets PARAMS ((struct reg_set **, rtx, int));
! static int handle_avail_expr PARAMS ((rtx, struct expr *));
static int classic_gcse PARAMS ((void));
static int one_classic_gcse_pass PARAMS ((int));
static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
--- 642,665 ----
char *));
static void hoist_code PARAMS ((void));
static int one_code_hoisting_pass PARAMS ((void));
! static void alloc_rd_mem PARAMS ((int, int, struct rd *));
! static void free_rd_mem PARAMS ((struct rd *));
! static void handle_rd_kill_set PARAMS ((rtx, int, basic_block, struct rd *));
! static void compute_kill_rd PARAMS ((struct rd *));
! static void compute_rd PARAMS ((struct rd *));
! static void alloc_avail_expr_mem PARAMS ((int, int, struct ae *));
! static void free_avail_expr_mem PARAMS ((struct ae *));
! static void compute_ae_gen PARAMS ((struct ae *, struct hash_table *));
static int expr_killed_p PARAMS ((rtx, basic_block));
! static void compute_ae_kill PARAMS ((struct ae *, struct hash_table *));
static int expr_reaches_here_p PARAMS ((struct occr *, struct expr *,
! basic_block, int, struct ae *));
! static rtx computing_insn PARAMS ((struct expr *, rtx, struct ae *));
! static int def_reaches_here_p PARAMS ((rtx, rtx, struct rd *));
! static int can_disregard_other_sets PARAMS ((struct reg_set **, rtx, int,
! struct rd *));
! static int handle_avail_expr PARAMS ((rtx, struct expr *,
! struct ae *, struct rd *));
static int classic_gcse PARAMS ((void));
static int one_classic_gcse_pass PARAMS ((int));
static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
*************** static int delete_null_pointer_checks_1
*** 662,668 ****
static rtx process_insert_insn PARAMS ((struct expr *));
static int pre_edge_insert PARAMS ((struct edge_list *, struct expr **));
static int expr_reaches_here_p_work PARAMS ((struct occr *, struct expr *,
! basic_block, int, char *));
static int pre_expr_reaches_here_p_work PARAMS ((basic_block, struct expr *,
basic_block, char *));
static struct ls_expr * ldst_entry PARAMS ((rtx));
--- 669,676 ----
static rtx process_insert_insn PARAMS ((struct expr *));
static int pre_edge_insert PARAMS ((struct edge_list *, struct expr **));
static int expr_reaches_here_p_work PARAMS ((struct occr *, struct expr *,
! basic_block, int, char *,
! struct ae *));
static int pre_expr_reaches_here_p_work PARAMS ((basic_block, struct expr *,
basic_block, char *));
static struct ls_expr * ldst_entry PARAMS ((rtx));
*************** alloc_reg_set_mem (n_regs)
*** 1199,1208 ****
{
unsigned int n;
! reg_set_table_size = n_regs + REG_SET_TABLE_SLOP;
! n = reg_set_table_size * sizeof (struct reg_set *);
! reg_set_table = (struct reg_set **) gmalloc (n);
! memset ((char *) reg_set_table, 0, n);
gcc_obstack_init (®_set_obstack);
}
--- 1207,1216 ----
{
unsigned int n;
! reg_set_table.size = n_regs + REG_SET_TABLE_SLOP;
! n = reg_set_table.size * sizeof (struct reg_set *);
! reg_set_table.table = (struct reg_set **) gmalloc (n);
! memset ((char *) reg_set_table.table, 0, n);
gcc_obstack_init (®_set_obstack);
}
*************** alloc_reg_set_mem (n_regs)
*** 1210,1216 ****
static void
free_reg_set_mem ()
{
! free (reg_set_table);
obstack_free (®_set_obstack, NULL);
}
--- 1218,1224 ----
static void
free_reg_set_mem ()
{
! free (reg_set_table.table);
obstack_free (®_set_obstack, NULL);
}
*************** record_one_set (regno, insn)
*** 1225,1248 ****
struct reg_set *new_reg_info;
/* If the table isn't big enough, enlarge it. */
! if (regno >= reg_set_table_size)
{
int new_size = regno + REG_SET_TABLE_SLOP;
! reg_set_table
! = (struct reg_set **) grealloc ((char *) reg_set_table,
new_size * sizeof (struct reg_set *));
! memset ((char *) (reg_set_table + reg_set_table_size), 0,
! (new_size - reg_set_table_size) * sizeof (struct reg_set *));
! reg_set_table_size = new_size;
}
new_reg_info = (struct reg_set *) obstack_alloc (®_set_obstack,
sizeof (struct reg_set));
bytes_used += sizeof (struct reg_set);
new_reg_info->insn = insn;
! new_reg_info->next = reg_set_table[regno];
! reg_set_table[regno] = new_reg_info;
}
/* Called from compute_sets via note_stores to handle one SET or CLOBBER in
--- 1233,1256 ----
struct reg_set *new_reg_info;
/* If the table isn't big enough, enlarge it. */
! if (regno >= reg_set_table.size)
{
int new_size = regno + REG_SET_TABLE_SLOP;
! reg_set_table.table
! = (struct reg_set **) grealloc ((char *) reg_set_table.table,
new_size * sizeof (struct reg_set *));
! memset ((char *) (reg_set_table.table + reg_set_table.size), 0,
! (new_size - reg_set_table.size) * sizeof (struct reg_set *));
! reg_set_table.size = new_size;
}
new_reg_info = (struct reg_set *) obstack_alloc (®_set_obstack,
sizeof (struct reg_set));
bytes_used += sizeof (struct reg_set);
new_reg_info->insn = insn;
! new_reg_info->next = reg_set_table.table[regno];
! reg_set_table.table[regno] = new_reg_info;
}
/* Called from compute_sets via note_stores to handle one SET or CLOBBER in
*************** mark_oprs_set (insn)
*** 2891,2942 ****
/* Allocate reaching def variables. */
static void
! alloc_rd_mem (n_blocks, n_insns)
int n_blocks, n_insns;
{
! rd_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (rd_kill, n_blocks);
! rd_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (rd_gen, n_blocks);
! reaching_defs = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (reaching_defs, n_blocks);
! rd_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (rd_out, n_blocks);
}
!
/* Free reaching def variables. */
static void
! free_rd_mem ()
{
! sbitmap_vector_free (rd_kill);
! sbitmap_vector_free (rd_gen);
! sbitmap_vector_free (reaching_defs);
! sbitmap_vector_free (rd_out);
}
/* Add INSN to the kills of BB. REGNO, set in BB, is killed by INSN. */
static void
! handle_rd_kill_set (insn, regno, bb)
rtx insn;
int regno;
basic_block bb;
{
struct reg_set *this_reg;
! for (this_reg = reg_set_table[regno]; this_reg; this_reg = this_reg ->next)
if (BLOCK_NUM (this_reg->insn) != BLOCK_NUM (insn))
! SET_BIT (rd_kill[bb->index], INSN_CUID (this_reg->insn));
}
/* Compute the set of kill's for reaching definitions. */
static void
! compute_kill_rd ()
{
int cuid;
unsigned int regno;
--- 2899,2954 ----
/* Allocate reaching def variables. */
static void
! alloc_rd_mem (n_blocks, n_insns, rd)
int n_blocks, n_insns;
+ struct rd *rd;
{
! rd->kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (rd->kill, n_blocks);
! rd->gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (rd->gen, n_blocks);
! rd->reaching_defs = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (rd->reaching_defs, n_blocks);
! rd->out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
! sbitmap_vector_zero (rd->out, n_blocks);
}
!
/* Free reaching def variables. */
static void
! free_rd_mem (rd)
! struct rd *rd;
{
! sbitmap_vector_free (rd->kill);
! sbitmap_vector_free (rd->gen);
! sbitmap_vector_free (rd->reaching_defs);
! sbitmap_vector_free (rd->out);
}
/* Add INSN to the kills of BB. REGNO, set in BB, is killed by INSN. */
static void
! handle_rd_kill_set (insn, regno, bb, rd)
rtx insn;
int regno;
basic_block bb;
+ struct rd *rd;
{
struct reg_set *this_reg;
! for (this_reg = reg_set_table.table[regno]; this_reg; this_reg = this_reg ->next)
if (BLOCK_NUM (this_reg->insn) != BLOCK_NUM (insn))
! SET_BIT (rd->kill[bb->index], INSN_CUID (this_reg->insn));
}
/* Compute the set of kill's for reaching definitions. */
static void
! compute_kill_rd (rd)
! struct rd *rd;
{
int cuid;
unsigned int regno;
*************** compute_kill_rd ()
*** 2953,2959 ****
Set the bit in `kill' corresponding to that insn. */
FOR_EACH_BB (bb)
for (cuid = 0; cuid < max_cuid; cuid++)
! if (TEST_BIT (rd_gen[bb->index], cuid))
{
rtx insn = CUID_INSN (cuid);
rtx pat = PATTERN (insn);
--- 2965,2971 ----
Set the bit in `kill' corresponding to that insn. */
FOR_EACH_BB (bb)
for (cuid = 0; cuid < max_cuid; cuid++)
! if (TEST_BIT (rd->gen[bb->index], cuid))
{
rtx insn = CUID_INSN (cuid);
rtx pat = PATTERN (insn);
*************** compute_kill_rd ()
*** 2962,2968 ****
{
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
! handle_rd_kill_set (insn, regno, bb);
}
if (GET_CODE (pat) == PARALLEL)
--- 2974,2980 ----
{
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
! handle_rd_kill_set (insn, regno, bb, rd);
}
if (GET_CODE (pat) == PARALLEL)
*************** compute_kill_rd ()
*** 2975,2987 ****
&& GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == REG)
handle_rd_kill_set (insn,
REGNO (XEXP (XVECEXP (pat, 0, i), 0)),
! bb);
}
}
else if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == REG)
/* Each setting of this register outside of this block
must be marked in the set of kills in this block. */
! handle_rd_kill_set (insn, REGNO (SET_DEST (pat)), bb);
}
}
--- 2987,2999 ----
&& GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == REG)
handle_rd_kill_set (insn,
REGNO (XEXP (XVECEXP (pat, 0, i), 0)),
! bb, rd);
}
}
else if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == REG)
/* Each setting of this register outside of this block
must be marked in the set of kills in this block. */
! handle_rd_kill_set (insn, REGNO (SET_DEST (pat)), bb, rd);
}
}
*************** compute_kill_rd ()
*** 2991,3003 ****
expressions but applied to the gens and kills of reaching definitions. */
static void
! compute_rd ()
{
int changed, passes;
basic_block bb;
FOR_EACH_BB (bb)
! sbitmap_copy (rd_out[bb->index] /*dst*/, rd_gen[bb->index] /*src*/);
passes = 0;
changed = 1;
--- 3003,3016 ----
expressions but applied to the gens and kills of reaching definitions. */
static void
! compute_rd (rd)
! struct rd *rd;
{
int changed, passes;
basic_block bb;
FOR_EACH_BB (bb)
! sbitmap_copy (rd->out[bb->index] /*dst*/, rd->gen[bb->index] /*src*/);
passes = 0;
changed = 1;
*************** compute_rd ()
*** 3006,3014 ****
changed = 0;
FOR_EACH_BB (bb)
{
! sbitmap_union_of_preds (reaching_defs[bb->index], rd_out, bb->index);
! changed |= sbitmap_union_of_diff_cg (rd_out[bb->index], rd_gen[bb->index],
! reaching_defs[bb->index], rd_kill[bb->index]);
}
passes++;
}
--- 3019,3027 ----
changed = 0;
FOR_EACH_BB (bb)
{
! sbitmap_union_of_preds (rd->reaching_defs[bb->index], rd->out, bb->index);
! changed |= sbitmap_union_of_diff_cg (rd->out[bb->index], rd->gen[bb->index],
! rd->reaching_defs[bb->index], rd->kill[bb->index]);
}
passes++;
}
*************** compute_rd ()
*** 3022,3056 ****
/* Allocate memory for available expression computation. */
static void
! alloc_avail_expr_mem (n_blocks, n_exprs)
int n_blocks, n_exprs;
{
! ae_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae_kill, n_blocks);
! ae_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae_gen, n_blocks);
! ae_in = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae_in, n_blocks);
! ae_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae_out, n_blocks);
}
static void
! free_avail_expr_mem ()
{
! sbitmap_vector_free (ae_kill);
! sbitmap_vector_free (ae_gen);
! sbitmap_vector_free (ae_in);
! sbitmap_vector_free (ae_out);
}
!
/* Compute the set of available expressions generated in each basic block. */
static void
! compute_ae_gen (expr_hash_table)
struct hash_table *expr_hash_table;
{
unsigned int i;
--- 3035,3072 ----
/* Allocate memory for available expression computation. */
static void
! alloc_avail_expr_mem (n_blocks, n_exprs, ae)
int n_blocks, n_exprs;
+ struct ae *ae;
{
! ae->kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae->kill, n_blocks);
! ae->gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae->gen, n_blocks);
! ae->in = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae->in, n_blocks);
! ae->out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
! sbitmap_vector_zero (ae->out, n_blocks);
}
static void
! free_avail_expr_mem (ae)
! struct ae *ae;
{
! sbitmap_vector_free (ae->kill);
! sbitmap_vector_free (ae->gen);
! sbitmap_vector_free (ae->in);
! sbitmap_vector_free (ae->out);
}
!
/* Compute the set of available expressions generated in each basic block. */
static void
! compute_ae_gen (ae, expr_hash_table)
! struct ae *ae;
struct hash_table *expr_hash_table;
{
unsigned int i;
*************** compute_ae_gen (expr_hash_table)
*** 3064,3070 ****
for (i = 0; i < expr_hash_table->size; i++)
for (expr = expr_hash_table->table[i]; expr != 0; expr = expr->next_same_hash)
for (occr = expr->avail_occr; occr != 0; occr = occr->next)
! SET_BIT (ae_gen[BLOCK_NUM (occr->insn)], expr->bitmap_index);
}
/* Return non-zero if expression X is killed in BB. */
--- 3080,3086 ----
for (i = 0; i < expr_hash_table->size; i++)
for (expr = expr_hash_table->table[i]; expr != 0; expr = expr->next_same_hash)
for (occr = expr->avail_occr; occr != 0; occr = occr->next)
! SET_BIT (ae->gen[BLOCK_NUM (occr->insn)], expr->bitmap_index);
}
/* Return non-zero if expression X is killed in BB. */
*************** expr_killed_p (x, bb)
*** 3133,3140 ****
/* Compute the set of available expressions killed in each basic block. */
static void
! compute_ae_kill (ae_gen, ae_kill, expr_hash_table)
! sbitmap *ae_gen, *ae_kill;
struct hash_table *expr_hash_table;
{
basic_block bb;
--- 3149,3156 ----
/* Compute the set of available expressions killed in each basic block. */
static void
! compute_ae_kill (ae, expr_hash_table)
! struct ae *ae;
struct hash_table *expr_hash_table;
{
basic_block bb;
*************** compute_ae_kill (ae_gen, ae_kill, expr_h
*** 3146,3156 ****
for (expr = expr_hash_table->table[i]; expr; expr = expr->next_same_hash)
{
/* Skip EXPR if generated in this block. */
! if (TEST_BIT (ae_gen[bb->index], expr->bitmap_index))
continue;
if (expr_killed_p (expr->expr, bb))
! SET_BIT (ae_kill[bb->index], expr->bitmap_index);
}
}
--- 3162,3172 ----
for (expr = expr_hash_table->table[i]; expr; expr = expr->next_same_hash)
{
/* Skip EXPR if generated in this block. */
! if (TEST_BIT (ae->gen[bb->index], expr->bitmap_index))
continue;
if (expr_killed_p (expr->expr, bb))
! SET_BIT (ae->kill[bb->index], expr->bitmap_index);
}
}
*************** compute_ae_kill (ae_gen, ae_kill, expr_h
*** 3173,3184 ****
the closest such expression. */
static int
! expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited)
struct occr *occr;
struct expr *expr;
basic_block bb;
int check_self_loop;
char *visited;
{
edge pred;
--- 3189,3201 ----
the closest such expression. */
static int
! expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited, ae)
struct occr *occr;
struct expr *expr;
basic_block bb;
int check_self_loop;
char *visited;
+ struct ae *ae;
{
edge pred;
*************** expr_reaches_here_p_work (occr, expr, bb
*** 3193,3199 ****
{
/* BB loops on itself. */
if (check_self_loop
! && TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index)
&& BLOCK_NUM (occr->insn) == pred_bb->index)
return 1;
--- 3210,3216 ----
{
/* BB loops on itself. */
if (check_self_loop
! && TEST_BIT (ae->gen[pred_bb->index], expr->bitmap_index)
&& BLOCK_NUM (occr->insn) == pred_bb->index)
return 1;
*************** expr_reaches_here_p_work (occr, expr, bb
*** 3201,3211 ****
}
/* Ignore this predecessor if it kills the expression. */
! else if (TEST_BIT (ae_kill[pred_bb->index], expr->bitmap_index))
visited[pred_bb->index] = 1;
/* Does this predecessor generate this expression? */
! else if (TEST_BIT (ae_gen[pred_bb->index], expr->bitmap_index))
{
/* Is this the occurrence we're looking for?
Note that there's only one generating occurrence per block
--- 3218,3228 ----
}
/* Ignore this predecessor if it kills the expression. */
! else if (TEST_BIT (ae->kill[pred_bb->index], expr->bitmap_index))
visited[pred_bb->index] = 1;
/* Does this predecessor generate this expression? */
! else if (TEST_BIT (ae->gen[pred_bb->index], expr->bitmap_index))
{
/* Is this the occurrence we're looking for?
Note that there's only one generating occurrence per block
*************** expr_reaches_here_p_work (occr, expr, bb
*** 3221,3227 ****
{
visited[pred_bb->index] = 1;
if (expr_reaches_here_p_work (occr, expr, pred_bb, check_self_loop,
! visited))
return 1;
}
--- 3238,3244 ----
{
visited[pred_bb->index] = 1;
if (expr_reaches_here_p_work (occr, expr, pred_bb, check_self_loop,
! visited, ae))
return 1;
}
*************** expr_reaches_here_p_work (occr, expr, bb
*** 3235,3250 ****
memory allocated for that function is returned. */
static int
! expr_reaches_here_p (occr, expr, bb, check_self_loop)
struct occr *occr;
struct expr *expr;
basic_block bb;
int check_self_loop;
{
int rval;
char *visited = (char *) xcalloc (last_basic_block, 1);
! rval = expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited);
free (visited);
return rval;
--- 3252,3268 ----
memory allocated for that function is returned. */
static int
! expr_reaches_here_p (occr, expr, bb, check_self_loop, ae)
struct occr *occr;
struct expr *expr;
basic_block bb;
int check_self_loop;
+ struct ae *ae;
{
int rval;
char *visited = (char *) xcalloc (last_basic_block, 1);
! rval = expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited, ae);
free (visited);
return rval;
*************** expr_reaches_here_p (occr, expr, bb, che
*** 3256,3264 ****
Called only by handle_avail_expr. */
static rtx
! computing_insn (expr, insn)
struct expr *expr;
rtx insn;
{
basic_block bb = BLOCK_FOR_INSN (insn);
--- 3274,3283 ----
Called only by handle_avail_expr. */
static rtx
! computing_insn (expr, insn, ae)
struct expr *expr;
rtx insn;
+ struct ae *ae;
{
basic_block bb = BLOCK_FOR_INSN (insn);
*************** computing_insn (expr, insn)
*** 3291,3297 ****
is generated later in the block [and thus there's a loop].
We let the normal cse pass handle the other cases. */
if (INSN_CUID (insn) < INSN_CUID (occr->insn)
! && expr_reaches_here_p (occr, expr, bb, 1))
{
can_reach++;
if (can_reach > 1)
--- 3310,3316 ----
is generated later in the block [and thus there's a loop].
We let the normal cse pass handle the other cases. */
if (INSN_CUID (insn) < INSN_CUID (occr->insn)
! && expr_reaches_here_p (occr, expr, bb, 1, ae))
{
can_reach++;
if (can_reach > 1)
*************** computing_insn (expr, insn)
*** 3300,3306 ****
insn_computes_expr = occr->insn;
}
}
! else if (expr_reaches_here_p (occr, expr, bb, 0))
{
can_reach++;
if (can_reach > 1)
--- 3319,3325 ----
insn_computes_expr = occr->insn;
}
}
! else if (expr_reaches_here_p (occr, expr, bb, 0, ae))
{
can_reach++;
if (can_reach > 1)
*************** computing_insn (expr, insn)
*** 3321,3332 ****
Only called by can_disregard_other_sets. */
static int
! def_reaches_here_p (insn, def_insn)
rtx insn, def_insn;
{
rtx reg;
! if (TEST_BIT (reaching_defs[BLOCK_NUM (insn)], INSN_CUID (def_insn)))
return 1;
if (BLOCK_NUM (insn) == BLOCK_NUM (def_insn))
--- 3340,3352 ----
Only called by can_disregard_other_sets. */
static int
! def_reaches_here_p (insn, def_insn, rd)
rtx insn, def_insn;
+ struct rd *rd;
{
rtx reg;
! if (TEST_BIT (rd->reaching_defs[BLOCK_NUM (insn)], INSN_CUID (def_insn)))
return 1;
if (BLOCK_NUM (insn) == BLOCK_NUM (def_insn))
*************** def_reaches_here_p (insn, def_insn)
*** 3358,3373 ****
always safe to return zero. */
static int
! can_disregard_other_sets (addr_this_reg, insn, for_combine)
struct reg_set **addr_this_reg;
rtx insn;
int for_combine;
{
int number_of_reaching_defs = 0;
struct reg_set *this_reg;
for (this_reg = *addr_this_reg; this_reg != 0; this_reg = this_reg->next)
! if (def_reaches_here_p (insn, this_reg->insn))
{
number_of_reaching_defs++;
/* Ignore parallels for now. */
--- 3378,3394 ----
always safe to return zero. */
static int
! can_disregard_other_sets (addr_this_reg, insn, for_combine, rd)
struct reg_set **addr_this_reg;
rtx insn;
int for_combine;
+ struct rd *rd;
{
int number_of_reaching_defs = 0;
struct reg_set *this_reg;
for (this_reg = *addr_this_reg; this_reg != 0; this_reg = this_reg->next)
! if (def_reaches_here_p (insn, this_reg->insn, rd))
{
number_of_reaching_defs++;
/* Ignore parallels for now. */
*************** can_disregard_other_sets (addr_this_reg,
*** 3406,3414 ****
The result is non-zero if any changes were made. */
static int
! handle_avail_expr (insn, expr)
rtx insn;
struct expr *expr;
{
rtx pat, insn_computes_expr, expr_set;
rtx to;
--- 3427,3437 ----
The result is non-zero if any changes were made. */
static int
! handle_avail_expr (insn, expr, ae, rd)
rtx insn;
struct expr *expr;
+ struct ae *ae;
+ struct rd *rd;
{
rtx pat, insn_computes_expr, expr_set;
rtx to;
*************** handle_avail_expr (insn, expr)
*** 3418,3424 ****
/* We only handle the case where one computation of the expression
reaches this instruction. */
! insn_computes_expr = computing_insn (expr, insn);
if (insn_computes_expr == NULL)
return 0;
expr_set = single_set (insn_computes_expr);
--- 3441,3447 ----
/* We only handle the case where one computation of the expression
reaches this instruction. */
! insn_computes_expr = computing_insn (expr, insn, ae);
if (insn_computes_expr == NULL)
return 0;
expr_set = single_set (insn_computes_expr);
*************** handle_avail_expr (insn, expr)
*** 3443,3451 ****
if (regnum_for_replacing >= max_gcse_regno
/* If the register the expression is computed into is set only once,
or only one set reaches this insn, we can use it. */
! || (((this_reg = reg_set_table[regnum_for_replacing]),
this_reg->next == NULL)
! || can_disregard_other_sets (&this_reg, insn, 0)))
{
use_src = 1;
found_setting = 1;
--- 3466,3474 ----
if (regnum_for_replacing >= max_gcse_regno
/* If the register the expression is computed into is set only once,
or only one set reaches this insn, we can use it. */
! || (((this_reg = reg_set_table.table[regnum_for_replacing]),
this_reg->next == NULL)
! || can_disregard_other_sets (&this_reg, insn, 0, rd)))
{
use_src = 1;
found_setting = 1;
*************** handle_avail_expr (insn, expr)
*** 3461,3472 ****
if (regnum_for_replacing >= max_gcse_regno)
abort ();
! this_reg = reg_set_table[regnum_for_replacing];
/* If the register the expression is computed into is set only once,
or only one set reaches this insn, use it. */
if (this_reg->next == NULL
! || can_disregard_other_sets (&this_reg, insn, 0))
found_setting = 1;
}
--- 3484,3495 ----
if (regnum_for_replacing >= max_gcse_regno)
abort ();
! this_reg = reg_set_table.table[regnum_for_replacing];
/* If the register the expression is computed into is set only once,
or only one set reaches this insn, use it. */
if (this_reg->next == NULL
! || can_disregard_other_sets (&this_reg, insn, 0, rd))
found_setting = 1;
}
*************** classic_gcse ()
*** 3601,3611 ****
&& ((expr = lookup_expr (src, &expr_hash_table)) != NULL)
/* Is the expression available [at the start of the
block]? */
! && TEST_BIT (ae_in[bb->index], expr->bitmap_index)
/* Are the operands unchanged since the start of the
block? */
&& oprs_not_set_p (src, insn))
! changed |= handle_avail_expr (insn, expr);
}
/* Keep track of everything modified by this insn. */
--- 3624,3634 ----
&& ((expr = lookup_expr (src, &expr_hash_table)) != NULL)
/* Is the expression available [at the start of the
block]? */
! && TEST_BIT (ae_global.in[bb->index], expr->bitmap_index)
/* Are the operands unchanged since the start of the
block? */
&& oprs_not_set_p (src, insn))
! changed |= handle_avail_expr (insn, expr, &ae_global, &rd_global);
}
/* Keep track of everything modified by this insn. */
*************** one_classic_gcse_pass (pass)
*** 3632,3655 ****
gcse_create_count = 0;
alloc_hash_table (max_cuid, &expr_hash_table, 0);
! alloc_rd_mem (last_basic_block, max_cuid);
compute_hash_table (&expr_hash_table);
if (gcse_file)
dump_hash_table (gcse_file, "Expression", &expr_hash_table);
if (expr_hash_table.n_elems > 0)
{
! compute_kill_rd ();
! compute_rd ();
! alloc_avail_expr_mem (last_basic_block, expr_hash_table.n_elems);
! compute_ae_gen (&expr_hash_table);
! compute_ae_kill (ae_gen, ae_kill, &expr_hash_table);
! compute_available (ae_gen, ae_kill, ae_out, ae_in);
changed = classic_gcse ();
! free_avail_expr_mem ();
}
! free_rd_mem ();
free_hash_table (&expr_hash_table);
if (gcse_file)
--- 3655,3678 ----
gcse_create_count = 0;
alloc_hash_table (max_cuid, &expr_hash_table, 0);
! alloc_rd_mem (last_basic_block, max_cuid, &rd_global);
compute_hash_table (&expr_hash_table);
if (gcse_file)
dump_hash_table (gcse_file, "Expression", &expr_hash_table);
if (expr_hash_table.n_elems > 0)
{
! compute_kill_rd (&rd_global);
! compute_rd (&rd_global);
! alloc_avail_expr_mem (last_basic_block, expr_hash_table.n_elems, &ae_global);
! compute_ae_gen (&ae_global, &expr_hash_table);
! compute_ae_kill (&ae_global, &expr_hash_table);
! compute_available (ae_global.gen, ae_global.kill, ae_global.out, ae_global.in);
changed = classic_gcse ();
! free_avail_expr_mem (&ae_global);
}
! free_rd_mem (&rd_global);
free_hash_table (&expr_hash_table);
if (gcse_file)
*************** compute_transp (x, indx, bmap, set_p)
*** 3738,3744 ****
}
else
{
! for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next)
SET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
}
}
--- 3761,3767 ----
}
else
{
! for (r = reg_set_table.table[REGNO (x)]; r != NULL; r = r->next)
SET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
}
}
*************** compute_transp (x, indx, bmap, set_p)
*** 3752,3758 ****
}
else
{
! for (r = reg_set_table[REGNO (x)]; r != NULL; r = r->next)
RESET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
}
}
--- 3775,3781 ----
}
else
{
! for (r = reg_set_table.table[REGNO (x)]; r != NULL; r = r->next)
RESET_BIT (bmap[BLOCK_NUM (r->insn)], indx);
}
}
*************** alloc_pre_mem (n_blocks, n_exprs)
*** 4677,4685 ****
pre_redundant = NULL;
pre_insert_map = NULL;
pre_delete_map = NULL;
! ae_in = NULL;
! ae_out = NULL;
! ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
/* pre_insert and pre_delete are allocated later. */
}
--- 4700,4708 ----
pre_redundant = NULL;
pre_insert_map = NULL;
pre_delete_map = NULL;
! ae_global.in = NULL;
! ae_global.out = NULL;
! ae_global.kill = sbitmap_vector_alloc (n_blocks, n_exprs);
/* pre_insert and pre_delete are allocated later. */
}
*************** free_pre_mem ()
*** 4702,4715 ****
sbitmap_vector_free (pre_insert_map);
if (pre_delete_map)
sbitmap_vector_free (pre_delete_map);
! if (ae_in)
! sbitmap_vector_free (ae_in);
! if (ae_out)
! sbitmap_vector_free (ae_out);
transp = comp = NULL;
pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL;
! ae_in = ae_out = NULL;
}
/* Top level routine to do the dataflow analysis needed by PRE. */
--- 4725,4738 ----
sbitmap_vector_free (pre_insert_map);
if (pre_delete_map)
sbitmap_vector_free (pre_delete_map);
! if (ae_global.in)
! sbitmap_vector_free (ae_global.in);
! if (ae_global.out)
! sbitmap_vector_free (ae_global.out);
transp = comp = NULL;
pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL;
! ae_global.in = ae_global.out = NULL;
}
/* Top level routine to do the dataflow analysis needed by PRE. */
*************** compute_pre_data ()
*** 4722,4728 ****
unsigned int ui;
compute_local_properties (transp, comp, antloc, &expr_hash_table);
! sbitmap_vector_zero (ae_kill, last_basic_block);
/* Collect expressions which might trap. */
trapping_expr = sbitmap_alloc (expr_hash_table.n_elems);
--- 4745,4751 ----
unsigned int ui;
compute_local_properties (transp, comp, antloc, &expr_hash_table);
! sbitmap_vector_zero (ae_global.kill, last_basic_block);
/* Collect expressions which might trap. */
trapping_expr = sbitmap_alloc (expr_hash_table.n_elems);
*************** compute_pre_data ()
*** 4757,4772 ****
break;
}
! sbitmap_a_or_b (ae_kill[bb->index], transp[bb->index], comp[bb->index]);
! sbitmap_not (ae_kill[bb->index], ae_kill[bb->index]);
}
edge_list = pre_edge_lcm (gcse_file, expr_hash_table.n_elems, transp, comp, antloc,
! ae_kill, &pre_insert_map, &pre_delete_map);
sbitmap_vector_free (antloc);
antloc = NULL;
! sbitmap_vector_free (ae_kill);
! ae_kill = NULL;
sbitmap_free (trapping_expr);
}
--- 4780,4795 ----
break;
}
! sbitmap_a_or_b (ae_global.kill[bb->index], transp[bb->index], comp[bb->index]);
! sbitmap_not (ae_global.kill[bb->index], ae_global.kill[bb->index]);
}
edge_list = pre_edge_lcm (gcse_file, expr_hash_table.n_elems, transp, comp, antloc,
! ae_global.kill, &pre_insert_map, &pre_delete_map);
sbitmap_vector_free (antloc);
antloc = NULL;
! sbitmap_vector_free (ae_global.kill);
! ae_global.kill = NULL;
sbitmap_free (trapping_expr);
}
*************** build_store_vectors ()
*** 6923,6930 ****
/* Build the gen_vector. This is any store in the table which is not killed
by aliasing later in its block. */
! ae_gen = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
! sbitmap_vector_zero (ae_gen, last_basic_block);
st_antloc = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (st_antloc, last_basic_block);
--- 6946,6953 ----
/* Build the gen_vector. This is any store in the table which is not killed
by aliasing later in its block. */
! ae_global.gen = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
! sbitmap_vector_zero (ae_global.gen, last_basic_block);
st_antloc = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (st_antloc, last_basic_block);
*************** build_store_vectors ()
*** 6948,6954 ****
the block), and replace it with this one). We'll copy the
old SRC expression to an unused register in case there
are any side effects. */
! if (TEST_BIT (ae_gen[bb->index], ptr->index))
{
/* Find previous store. */
rtx st;
--- 6971,6977 ----
the block), and replace it with this one). We'll copy the
old SRC expression to an unused register in case there
are any side effects. */
! if (TEST_BIT (ae_global.gen[bb->index], ptr->index))
{
/* Find previous store. */
rtx st;
*************** build_store_vectors ()
*** 6965,6971 ****
continue;
}
}
! SET_BIT (ae_gen[bb->index], ptr->index);
AVAIL_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
AVAIL_STORE_LIST (ptr));
}
--- 6988,6994 ----
continue;
}
}
! SET_BIT (ae_global.gen[bb->index], ptr->index);
AVAIL_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
AVAIL_STORE_LIST (ptr));
}
*************** build_store_vectors ()
*** 6982,6989 ****
free_INSN_LIST_list (&store_list);
}
! ae_kill = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
! sbitmap_vector_zero (ae_kill, last_basic_block);
transp = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (transp, last_basic_block);
--- 7005,7012 ----
free_INSN_LIST_list (&store_list);
}
! ae_global.kill = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
! sbitmap_vector_zero (ae_global.kill, last_basic_block);
transp = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (transp, last_basic_block);
*************** build_store_vectors ()
*** 7009,7015 ****
If we always kill it in this case, we'll sometimes do
uneccessary work, but it shouldn't actually hurt anything.
if (!TEST_BIT (ae_gen[b], ptr->index)). */
! SET_BIT (ae_kill[b->index], ptr->index);
}
else
SET_BIT (transp[b->index], ptr->index);
--- 7032,7038 ----
If we always kill it in this case, we'll sometimes do
uneccessary work, but it shouldn't actually hurt anything.
if (!TEST_BIT (ae_gen[b], ptr->index)). */
! SET_BIT (ae_global.kill[b->index], ptr->index);
}
else
SET_BIT (transp[b->index], ptr->index);
*************** build_store_vectors ()
*** 7024,7032 ****
fprintf (gcse_file, "ST_avail and ST_antic (shown under loads..)\n");
print_ldst_list (gcse_file);
dump_sbitmap_vector (gcse_file, "st_antloc", "", st_antloc, last_basic_block);
! dump_sbitmap_vector (gcse_file, "st_kill", "", ae_kill, last_basic_block);
dump_sbitmap_vector (gcse_file, "Transpt", "", transp, last_basic_block);
! dump_sbitmap_vector (gcse_file, "st_avloc", "", ae_gen, last_basic_block);
}
}
--- 7047,7055 ----
fprintf (gcse_file, "ST_avail and ST_antic (shown under loads..)\n");
print_ldst_list (gcse_file);
dump_sbitmap_vector (gcse_file, "st_antloc", "", st_antloc, last_basic_block);
! dump_sbitmap_vector (gcse_file, "st_kill", "", ae_global.kill, last_basic_block);
dump_sbitmap_vector (gcse_file, "Transpt", "", transp, last_basic_block);
! dump_sbitmap_vector (gcse_file, "st_avloc", "", ae_global.gen, last_basic_block);
}
}
*************** free_store_memory ()
*** 7196,7205 ****
{
free_ldst_mems ();
! if (ae_gen)
! sbitmap_vector_free (ae_gen);
! if (ae_kill)
! sbitmap_vector_free (ae_kill);
if (transp)
sbitmap_vector_free (transp);
if (st_antloc)
--- 7219,7228 ----
{
free_ldst_mems ();
! if (ae_global.gen)
! sbitmap_vector_free (ae_global.gen);
! if (ae_global.kill)
! sbitmap_vector_free (ae_global.kill);
if (transp)
sbitmap_vector_free (transp);
if (st_antloc)
*************** free_store_memory ()
*** 7211,7217 ****
if (reg_set_in_block)
sbitmap_vector_free (reg_set_in_block);
! ae_gen = ae_kill = transp = st_antloc = NULL;
pre_insert_map = pre_delete_map = reg_set_in_block = NULL;
}
--- 7234,7240 ----
if (reg_set_in_block)
sbitmap_vector_free (reg_set_in_block);
! ae_global.gen = ae_global.kill = transp = st_antloc = NULL;
pre_insert_map = pre_delete_map = reg_set_in_block = NULL;
}
*************** store_motion ()
*** 7248,7255 ****
add_noreturn_fake_exit_edges ();
build_store_vectors ();
! edge_list = pre_edge_rev_lcm (gcse_file, num_stores, transp, ae_gen,
! st_antloc, ae_kill, &pre_insert_map,
&pre_delete_map);
/* Now we want to insert the new stores which are going to be needed. */
--- 7271,7278 ----
add_noreturn_fake_exit_edges ();
build_store_vectors ();
! edge_list = pre_edge_rev_lcm (gcse_file, num_stores, transp, ae_global.gen,
! st_antloc, ae_global.kill, &pre_insert_map,
&pre_delete_map);
/* Now we want to insert the new stores which are going to be needed. */