re PR middle-end/15855 (g++ crash with -O2 and -O3 on input file)

2005-09-26  Richard Guenther  <rguenther@suse.de>

	PR middle-end/15855
	* gcse.c: Include hashtab.h, define ldst entry hashtable.
	(pre_ldst_expr_hash, pre_ldst_expr_eq): New functions.
	(ldst_entry): Use the hashtable instead of list-walking.
	(find_rtx_in_ldst): Likewise.
	(free_ldst_entry): Free the hashtable.
	(compute_ld_motion_mems): Create the hashtable.
	(trim_ld_motion_mems): Remove entry from hashtable if
	removing it from list.
	(compute_store_table): Likewise^2.
	(store_motion): Free hashtable in case we did not see
	any stores.

From-SVN: r104641
This commit is contained in:
Richard Guenther 2005-09-26 08:38:29 +00:00 committed by Richard Biener
parent 3f1dfb4145
commit 9727e468b1
2 changed files with 59 additions and 10 deletions

View File

@ -1,3 +1,18 @@
2005-09-26 Richard Guenther <rguenther@suse.de>
PR middle-end/15855
* gcse.c: Include hashtab.h, define ldst entry hashtable.
(pre_ldst_expr_hash, pre_ldst_expr_eq): New functions.
(ldst_entry): Use the hashtable instead of list-walking.
(find_rtx_in_ldst): Likewise.
(free_ldst_entry): Free the hashtable.
(compute_ld_motion_mems): Create the hashtable.
(trim_ld_motion_mems): Remove entry from hashtable if
removing it from list.
(compute_store_table): Likewise^2.
(store_motion): Free hashtable in case we did not see
any stores.
2005-09-25 Kazu Hirata <kazu@codesourcery.com>
* fold-const.c (fold_binary): Use op0 and op1 instead of arg0

View File

@ -170,6 +170,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "obstack.h"
#include "timevar.h"
#include "tree-pass.h"
#include "hashtab.h"
/* Propagate flow information through back edges and thus enable PRE's
moving loop invariant calculations out of loops.
@ -471,6 +472,9 @@ static rtx *implicit_sets;
/* Head of the list of load/store memory refs. */
static struct ls_expr * pre_ldst_mems = NULL;
/* Hashtable for the load/store memory refs. */
static htab_t pre_ldst_table = NULL;
/* Bitmap containing one bit for each register in the program.
Used when performing GCSE to track which registers have been set since
the start of the basic block. */
@ -5015,6 +5019,21 @@ one_code_hoisting_pass (void)
load towards the exit, and we end up with no loads or stores of 'i'
in the loop. */
static hashval_t
pre_ldst_expr_hash (const void *p)
{
int do_not_record_p = 0;
const struct ls_expr *x = p;
return hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
}
static int
pre_ldst_expr_eq (const void *p1, const void *p2)
{
const struct ls_expr *ptr1 = p1, *ptr2 = p2;
return expr_equiv_p (ptr1->pattern, ptr2->pattern);
}
/* This will search the ldst list for a matching expression. If it
doesn't find one, we create one and initialize it. */
@ -5024,13 +5043,16 @@ ldst_entry (rtx x)
int do_not_record_p = 0;
struct ls_expr * ptr;
unsigned int hash;
void **slot;
struct ls_expr e;
hash = hash_rtx (x, GET_MODE (x), &do_not_record_p,
NULL, /*have_reg_qty=*/false);
for (ptr = pre_ldst_mems; ptr != NULL; ptr = ptr->next)
if (ptr->hash_index == hash && expr_equiv_p (ptr->pattern, x))
return ptr;
e.pattern = x;
slot = htab_find_slot_with_hash (pre_ldst_table, &e, hash, INSERT);
if (*slot)
return (struct ls_expr *)*slot;
ptr = xmalloc (sizeof (struct ls_expr));
@ -5045,6 +5067,7 @@ ldst_entry (rtx x)
ptr->index = 0;
ptr->hash_index = hash;
pre_ldst_mems = ptr;
*slot = ptr;
return ptr;
}
@ -5065,6 +5088,9 @@ free_ldst_entry (struct ls_expr * ptr)
static void
free_ldst_mems (void)
{
htab_delete (pre_ldst_table);
pre_ldst_table = NULL;
while (pre_ldst_mems)
{
struct ls_expr * tmp = pre_ldst_mems;
@ -5117,13 +5143,13 @@ print_ldst_list (FILE * file)
static struct ls_expr *
find_rtx_in_ldst (rtx x)
{
struct ls_expr * ptr;
for (ptr = pre_ldst_mems; ptr != NULL; ptr = ptr->next)
if (expr_equiv_p (ptr->pattern, x) && ! ptr->invalid)
return ptr;
return NULL;
struct ls_expr e;
void **slot;
e.pattern = x;
slot = htab_find_slot (pre_ldst_table, &e, NO_INSERT);
if (!slot || ((struct ls_expr *)*slot)->invalid)
return NULL;
return *slot;
}
/* Assign each element of the list of mems a monotonically increasing value. */
@ -5244,6 +5270,8 @@ compute_ld_motion_mems (void)
rtx insn;
pre_ldst_mems = NULL;
pre_ldst_table = htab_create (13, pre_ldst_expr_hash,
pre_ldst_expr_eq, NULL);
FOR_EACH_BB (bb)
{
@ -5334,6 +5362,7 @@ trim_ld_motion_mems (void)
else
{
*last = ptr->next;
htab_remove_elt_with_hash (pre_ldst_table, ptr, ptr->hash_index);
free_ldst_entry (ptr);
ptr = * last;
}
@ -5693,6 +5722,8 @@ compute_store_table (void)
max_gcse_regno);
sbitmap_vector_zero (reg_set_in_block, last_basic_block);
pre_ldst_mems = 0;
pre_ldst_table = htab_create (13, pre_ldst_expr_hash,
pre_ldst_expr_eq, NULL);
last_set_in = xcalloc (max_gcse_regno, sizeof (int));
already_set = xmalloc (sizeof (int) * max_gcse_regno);
@ -5780,6 +5811,7 @@ compute_store_table (void)
if (!AVAIL_STORE_LIST (ptr))
{
*prev_next_ptr_ptr = ptr->next;
htab_remove_elt_with_hash (pre_ldst_table, ptr, ptr->hash_index);
free_ldst_entry (ptr);
}
else
@ -6399,6 +6431,8 @@ store_motion (void)
num_stores = compute_store_table ();
if (num_stores == 0)
{
htab_delete (pre_ldst_table);
pre_ldst_table = NULL;
sbitmap_vector_free (reg_set_in_block);
end_alias_analysis ();
return;