diff options
Diffstat (limited to 'gcc')
| -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 }, | 
