This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Proto-patch to make insn-attrtab.c much smaller (was Re:[PATCH] Remove define_function_unit)


I would say it's definitely worth finding out whether that time and
space buys us anything.

If anybody wants to experiment, here's a patch. It does not remove *all* optimizations, only those based in optimize_attrs (250 lines of code), but it's enough for...


wc insn-attrtab.c.*
  50293  245411 2026436 insn-attrtab.c.opt
                 795200 insn-attrtab.o.opt
  13140   71926  563531 insn-attrtab.c.noopt
                 228328 insn-attrtab.o.noopt

This is basically the same ratio as Michael Matz's message (with a different patch) which can be found at http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00458.html

Jeff Law wrote in the same thread:

> I believe the "canonical" test for genattrtab optimizations was always
> the MIPS port.  IIRC the MIPS port was consistently the most
> problematical.

But, MIPS had a lot of define_function_units, and I guess Jeff was referring to that. Anyhow, just for reference, Michael's results were

Bootstrap time (for C,C++) x86 HEAD (-j4)       user    39m22.830s
with no optimizations in genattrtab:            user    37m15.600s
kdecore.ii (HEAD)                               user     3m43.130s
kdecore.ii no genattrtab optimization           user     3m43.260s
kdecore.ii mips, HEAD                           user      4m0.640s
kdecore.ii mips, no genattrtab optimization     user      4m1.490s

If anyone wants to pick this patch up and do more timings, that'd be good.

Paolo
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genattrtab.c,v
retrieving revision 1.149
diff -u -r1.149 genattrtab.c
--- genattrtab.c	20 Jul 2004 07:26:46 -0000	1.149
+++ genattrtab.c	20 Jul 2004 08:12:31 -0000
@@ -88,7 +88,7 @@
    `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
       independent of the insn code.
    `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
-      for the insn code currently being processed (see optimize_attrs).
+      for the insn code currently being processed.
    `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
       (see attr_rtx).
    `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
@@ -312,9 +312,7 @@
 static rtx one_fn		(rtx);
 static rtx max_fn		(rtx);
 static void write_length_unit_log (void);
-static rtx simplify_cond	(rtx, int, int);
 static void clear_struct_flag (rtx);
-static void remove_insn_ent  (struct attr_value *, struct insn_ent *);
 static void insert_insn_ent  (struct attr_value *, struct insn_ent *);
 static rtx insert_right_side	(enum rtx_code, rtx, rtx, int, int);
 static rtx make_alternative_compare (int);
@@ -324,7 +322,6 @@
 static rtx simplify_or_tree	(rtx, rtx *, int, int);
 static rtx simplify_test_exp	(rtx, int, int);
 static rtx simplify_test_exp_in_temp (rtx, int, int);
-static void optimize_attrs	(void);
 static void gen_attr		(rtx, int);
 static int count_alternatives	(rtx);
 static int compares_alternatives_p (rtx);
@@ -1714,152 +1711,6 @@
   printf ("int length_unit_log = %u;\n", length_unit_log);
 }
 
-/* Take a COND expression and see if any of the conditions in it can be
-   simplified.  If any are known true or known false for the particular insn
-   code, the COND can be further simplified.
-
-   Also call ourselves on any COND operations that are values of this COND.
-
-   We do not modify EXP; rather, we make and return a new rtx.  */
-
-static rtx
-simplify_cond (rtx exp, int insn_code, int insn_index)
-{
-  int i, j;
-  /* We store the desired contents here,
-     then build a new expression if they don't match EXP.  */
-  rtx defval = XEXP (exp, 1);
-  rtx new_defval = XEXP (exp, 1);
-  int len = XVECLEN (exp, 0);
-  rtx *tests = xmalloc (len * sizeof (rtx));
-  int allsame = 1;
-  rtx ret;
-
-  /* This lets us free all storage allocated below, if appropriate.  */
-  obstack_finish (rtl_obstack);
-
-  memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
-
-  /* See if default value needs simplification.  */
-  if (GET_CODE (defval) == COND)
-    new_defval = simplify_cond (defval, insn_code, insn_index);
-
-  /* Simplify the subexpressions, and see what tests we can get rid of.  */
-
-  for (i = 0; i < len; i += 2)
-    {
-      rtx newtest, newval;
-
-      /* Simplify this test.  */
-      newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
-      tests[i] = newtest;
-
-      newval = tests[i + 1];
-      /* See if this value may need simplification.  */
-      if (GET_CODE (newval) == COND)
-	newval = simplify_cond (newval, insn_code, insn_index);
-
-      /* Look for ways to delete or combine this test.  */
-      if (newtest == true_rtx)
-	{
-	  /* If test is true, make this value the default
-	     and discard this + any following tests.  */
-	  len = i;
-	  defval = tests[i + 1];
-	  new_defval = newval;
-	}
-
-      else if (newtest == false_rtx)
-	{
-	  /* If test is false, discard it and its value.  */
-	  for (j = i; j < len - 2; j++)
-	    tests[j] = tests[j + 2];
-	  i -= 2;
-	  len -= 2;
-	}
-
-      else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
-	{
-	  /* If this value and the value for the prev test are the same,
-	     merge the tests.  */
-
-	  tests[i - 2]
-	    = insert_right_side (IOR, tests[i - 2], newtest,
-				 insn_code, insn_index);
-
-	  /* Delete this test/value.  */
-	  for (j = i; j < len - 2; j++)
-	    tests[j] = tests[j + 2];
-	  len -= 2;
-	  i -= 2;
-	}
-
-      else
-	tests[i + 1] = newval;
-    }
-
-  /* If the last test in a COND has the same value
-     as the default value, that test isn't needed.  */
-
-  while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
-    len -= 2;
-
-  /* See if we changed anything.  */
-  if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
-    allsame = 0;
-  else
-    for (i = 0; i < len; i++)
-      if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
-	{
-	  allsame = 0;
-	  break;
-	}
-
-  if (len == 0)
-    {
-      if (GET_CODE (defval) == COND)
-	ret = simplify_cond (defval, insn_code, insn_index);
-      else
-	ret = defval;
-    }
-  else if (allsame)
-    ret = exp;
-  else
-    {
-      rtx newexp = rtx_alloc (COND);
-
-      XVEC (newexp, 0) = rtvec_alloc (len);
-      memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
-      XEXP (newexp, 1) = new_defval;
-      ret = newexp;
-    }
-  free (tests);
-  return ret;
-}
-
-/* Remove an insn entry from an attribute value.  */
-
-static void
-remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
-{
-  struct insn_ent *previe;
-
-  if (av->first_insn == ie)
-    av->first_insn = ie->next;
-  else
-    {
-      for (previe = av->first_insn; previe->next != ie; previe = previe->next)
-	;
-      previe->next = ie->next;
-    }
-
-  av->num_insns--;
-  if (ie->insn_code == -1)
-    av->has_asm_insn = 0;
-
-  num_insn_ents--;
-}
-
 /* Insert an insn entry in an attribute value list.  */
 
 static void
@@ -2850,106 +2701,6 @@
   return newexp;
 }
 
-/* Optimize the attribute lists by seeing if we can determine conditional
-   values from the known values of other attributes.  This will save subroutine
-   calls during the compilation.  */
-
-static void
-optimize_attrs (void)
-{
-  struct attr_desc *attr;
-  struct attr_value *av;
-  struct insn_ent *ie;
-  rtx newexp;
-  int i;
-  struct attr_value_list
-  {
-    struct attr_value *av;
-    struct insn_ent *ie;
-    struct attr_desc *attr;
-    struct attr_value_list *next;
-  };
-  struct attr_value_list **insn_code_values;
-  struct attr_value_list *ivbuf;
-  struct attr_value_list *iv;
-
-  /* For each insn code, make a list of all the insn_ent's for it,
-     for all values for all attributes.  */
-
-  if (num_insn_ents == 0)
-    return;
-
-  /* Make 2 extra elements, for "code" values -2 and -1.  */
-  insn_code_values = xcalloc ((insn_code_number + 2),
-			      sizeof (struct attr_value_list *));
-
-  /* Offset the table address so we can index by -2 or -1.  */
-  insn_code_values += 2;
-
-  iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
-
-  for (i = 0; i < MAX_ATTRS_INDEX; i++)
-    for (attr = attrs[i]; attr; attr = attr->next)
-      for (av = attr->first_value; av; av = av->next)
-	for (ie = av->first_insn; ie; ie = ie->next)
-	  {
-	    iv->attr = attr;
-	    iv->av = av;
-	    iv->ie = ie;
-	    iv->next = insn_code_values[ie->insn_code];
-	    insn_code_values[ie->insn_code] = iv;
-	    iv++;
-	  }
-
-  /* Sanity check on num_insn_ents.  */
-  if (iv != ivbuf + num_insn_ents)
-    abort ();
-
-  /* Process one insn code at a time.  */
-  for (i = -2; i < insn_code_number; i++)
-    {
-      /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
-	 We use it to mean "already simplified for this insn".  */
-      for (iv = insn_code_values[i]; iv; iv = iv->next)
-	clear_struct_flag (iv->av->value);
-
-      for (iv = insn_code_values[i]; iv; iv = iv->next)
-	{
-	  struct obstack *old = rtl_obstack;
-
-	  attr = iv->attr;
-	  av = iv->av;
-	  ie = iv->ie;
-	  if (GET_CODE (av->value) != COND)
-	    continue;
-
-	  rtl_obstack = temp_obstack;
-	  newexp = av->value;
-	  while (GET_CODE (newexp) == COND)
-	    {
-	      rtx newexp2 = simplify_cond (newexp, ie->insn_code,
-					   ie->insn_index);
-	      if (newexp2 == newexp)
-		break;
-	      newexp = newexp2;
-	    }
-
-	  rtl_obstack = old;
-	  if (newexp != av->value)
-	    {
-	      newexp = attr_copy_rtx (newexp);
-	      remove_insn_ent (av, ie);
-	      av = get_attr_value (newexp, attr, ie->insn_code);
-	      iv->av = av;
-	      insert_insn_ent (av, ie);
-	    }
-	}
-    }
-
-  free (ivbuf);
-  free (insn_code_values - 2);
-}
-
 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions.  */
 
 static void
@@ -4587,9 +4338,6 @@
   /* Construct extra attributes for `length'.  */
   make_length_attrs ();
 
-  /* Perform any possible optimizations to speed up compilation.  */
-  optimize_attrs ();
-
   /* Now write out all the `gen_attr_...' routines.  Do these before the
      special routines so that they get defined before they are used.  */
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]