diff options
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/alias.c | 22 | ||||
-rw-r--r-- | gcc/cse.c | 7 | ||||
-rw-r--r-- | gcc/cselib.c | 72 | ||||
-rw-r--r-- | gcc/cselib.h | 1 | ||||
-rw-r--r-- | gcc/varray.c | 2 |
7 files changed, 51 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d7a7971..efb09a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,17 @@ 2004-01-12 Jan Hubicka <jh@suse.cz> - Partial fox for PR opt/10776 II + * alias.c: Invlude varray.h + (alias_sets): Turn into varray. + (get_alias_set_entry): Use VARRAY; mark inline. + (mems_in_disjoint_alias_sets_p): Mark inline. + (record_alias_subset): Use varray. + (init_alias_once): Initialize varray. + (new_alias_set): Grow array. + * varray.c: Make VARRAY_GENERIC_PTR non GTYized. + +2004-01-12 Jan Hubicka <jh@suse.cz> + + Partial fix for PR opt/10776 II * cselib.c: Include params.h (cselib_invalidate_mem): Limit amount of nonconflicting memory locations. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 0a5c3c8..62b28b1 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1653,7 +1653,7 @@ web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ hard-reg-set.h flags.h real.h insn-config.h $(GGC_H) $(RECOG_H) $(EXPR_H) \ $(BASIC_BLOCK_H) function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) \ - except.h gt-gcse.h $(TREE_H) + except.h gt-gcse.h $(TREE_H) cselib.h sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ function.h hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) coretypes.h \ diff --git a/gcc/alias.c b/gcc/alias.c index 584f565..6c5f73b 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -42,6 +42,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "timevar.h" #include "target.h" #include "cgraph.h" +#include "varray.h" /* The alias sets assigned to MEMs assist the back-end in determining which MEMs can alias which other MEMs. In general, two MEMs in @@ -205,24 +206,21 @@ char *reg_known_equiv_p; static bool copying_arguments; /* The splay-tree used to store the various alias set entries. */ -static splay_tree alias_sets; +varray_type alias_sets; /* Returns a pointer to the alias set entry for ALIAS_SET, if there is such an entry, or NULL otherwise. */ -static alias_set_entry +static inline alias_set_entry get_alias_set_entry (HOST_WIDE_INT alias_set) { - splay_tree_node sn - = splay_tree_lookup (alias_sets, (splay_tree_key) alias_set); - - return sn != 0 ? ((alias_set_entry) sn->value) : 0; + return (alias_set_entry)VARRAY_GENERIC_PTR (alias_sets, alias_set); } /* Returns nonzero if the alias sets for MEM1 and MEM2 are such that the two MEMs cannot alias each other. */ -static int +static inline int mems_in_disjoint_alias_sets_p (rtx mem1, rtx mem2) { #ifdef ENABLE_CHECKING @@ -599,7 +597,10 @@ new_alias_set (void) static HOST_WIDE_INT last_alias_set; if (flag_strict_aliasing) - return ++last_alias_set; + { + VARRAY_GROW (alias_sets, last_alias_set + 2); + return ++last_alias_set; + } else return 0; } @@ -641,8 +642,7 @@ record_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset) superset_entry->children = splay_tree_new (splay_tree_compare_ints, 0, 0); superset_entry->has_zero_child = 0; - splay_tree_insert (alias_sets, (splay_tree_key) superset, - (splay_tree_value) superset_entry); + VARRAY_GENERIC_PTR (alias_sets, superset) = superset_entry; } if (subset == 0) @@ -2673,7 +2673,7 @@ init_alias_once (void) = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx); #endif - alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0); + VARRAY_GENERIC_PTR_INIT (alias_sets, 10, "alias sets"); } /* Set MEMORY_MODIFIED when X modifies DATA (that is assumed @@ -1768,6 +1768,7 @@ struct check_dependence_data { enum machine_mode mode; rtx exp; + rtx addr; }; static int @@ -1775,7 +1776,8 @@ check_dependence (rtx *x, void *data) { struct check_dependence_data *d = (struct check_dependence_data *) data; if (*x && GET_CODE (*x) == MEM) - return true_dependence (d->exp, d->mode, *x, cse_rtx_varies_p); + return canon_true_dependence (d->exp, d->mode, d->addr, *x, + cse_rtx_varies_p); else return 0; } @@ -1797,6 +1799,7 @@ invalidate (rtx x, enum machine_mode full_mode) { int i; struct table_elt *p; + rtx addr; switch (GET_CODE (x)) { @@ -1887,6 +1890,7 @@ invalidate (rtx x, enum machine_mode full_mode) return; case MEM: + addr = canon_rtx (get_addr (XEXP (x, 0))); /* Calculate the canonical version of X here so that true_dependence doesn't generate new RTL for X on each call. */ x = canon_rtx (x); @@ -1914,6 +1918,7 @@ invalidate (rtx x, enum machine_mode full_mode) if (!p->canon_exp) p->canon_exp = canon_rtx (p->exp); d.exp = x; + d.addr = addr; d.mode = full_mode; if (for_each_rtx (&p->canon_exp, check_dependence, &d)) remove_from_table (p, i); diff --git a/gcc/cselib.c b/gcc/cselib.c index 99c4bec..c3a6872 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -58,7 +58,6 @@ static cselib_val *new_cselib_val (unsigned int, enum machine_mode); static void add_mem_for_addr (cselib_val *, cselib_val *, rtx); static cselib_val *cselib_lookup_mem (rtx, int); static void cselib_invalidate_regno (unsigned int, enum machine_mode); -static int cselib_mem_conflict_p (rtx, rtx); static void cselib_invalidate_mem (rtx); static void cselib_invalidate_rtx (rtx, rtx, void *); static void cselib_record_set (rtx, cselib_val *, cselib_val *); @@ -168,6 +167,7 @@ new_elt_loc_list (struct elt_loc_list *next, rtx loc) el = ggc_alloc (sizeof (struct elt_loc_list)); el->next = next; el->loc = loc; + el->canon_loc = NULL; el->setting_insn = cselib_current_insn; el->in_libcall = cselib_current_insn_in_libcall; return el; @@ -1050,60 +1050,18 @@ cselib_invalidate_regno (unsigned int regno, enum machine_mode mode) } } } - -/* The memory at address MEM_BASE is being changed. - Return whether this change will invalidate VAL. */ + +/* Return 1 if X has a value that can vary even between two + executions of the program. 0 means X can be compared reliably + against certain constants or near-constants. */ static int -cselib_mem_conflict_p (rtx mem_base, rtx val) +cselib_rtx_varies_p (rtx x ATTRIBUTE_UNUSED, int from_alias ATTRIBUTE_UNUSED) { - enum rtx_code code; - const char *fmt; - int i, j; - - code = GET_CODE (val); - switch (code) - { - /* Get rid of a few simple cases quickly. */ - case REG: - case PC: - case CC0: - case SCRATCH: - case CONST: - case CONST_INT: - case CONST_DOUBLE: - case CONST_VECTOR: - case SYMBOL_REF: - case LABEL_REF: - return 0; - - case MEM: - if (GET_MODE (mem_base) == BLKmode - || GET_MODE (val) == BLKmode - || anti_dependence (val, mem_base)) - return 1; - - /* The address may contain nested MEMs. */ - break; - - default: - break; - } - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - { - if (cselib_mem_conflict_p (mem_base, XEXP (val, i))) - return 1; - } - else if (fmt[i] == 'E') - for (j = 0; j < XVECLEN (val, i); j++) - if (cselib_mem_conflict_p (mem_base, XVECEXP (val, i, j))) - return 1; - } - + /* We actually don't need to verify very hard. This is because + if X has actually changed, we invalidate the memory anyway, + so assume that all common memory addresses are + invariant. */ return 0; } @@ -1116,6 +1074,10 @@ cselib_invalidate_mem (rtx mem_rtx) { cselib_val **vp, *v, *next; int num_mems = 0; + rtx mem_addr; + + mem_addr = canon_rtx (get_addr (XEXP (mem_rtx, 0))); + mem_rtx = canon_rtx (mem_rtx); vp = &first_containing_mem; for (v = *vp; v != &dummy_val; v = next) @@ -1127,6 +1089,7 @@ cselib_invalidate_mem (rtx mem_rtx) while (*p) { rtx x = (*p)->loc; + rtx canon_x = (*p)->canon_loc; cselib_val *addr; struct elt_list **mem_chain; @@ -1137,8 +1100,11 @@ cselib_invalidate_mem (rtx mem_rtx) p = &(*p)->next; continue; } + if (!canon_x) + canon_x = (*p)->canon_loc = canon_rtx (x); if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS) - && ! cselib_mem_conflict_p (mem_rtx, x)) + && ! canon_true_dependence (mem_rtx, GET_MODE (mem_rtx), mem_addr, + x, cselib_rtx_varies_p)) { has_mem = true; num_mems++; diff --git a/gcc/cselib.h b/gcc/cselib.h index 7af7794..c751c42 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -49,6 +49,7 @@ struct elt_loc_list GTY(()) struct elt_loc_list *next; /* An rtl expression that holds the value. */ rtx loc; + rtx canon_loc; /* The insn that made the equivalence. */ rtx setting_insn; /* True when setting insn is inside libcall. */ diff --git a/gcc/varray.c b/gcc/varray.c index 7901471..aca4b6b 100644 --- a/gcc/varray.c +++ b/gcc/varray.c @@ -47,7 +47,7 @@ static const struct { { sizeof (unsigned long), 1 }, { sizeof (HOST_WIDE_INT), 1 }, { sizeof (unsigned HOST_WIDE_INT), 1 }, - { sizeof (void *), 1 }, + { sizeof (void *), 0 }, { sizeof (char *), 1 }, { sizeof (struct rtx_def *), 1 }, { sizeof (struct rtvec_def *), 1 }, |