]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Makefile.in (cfgexpand.o): Depend on $(INSN_ATTR_H).
authorJakub Jelinek <jakub@redhat.com>
Mon, 21 Jun 2010 16:27:25 +0000 (18:27 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 21 Jun 2010 16:27:25 +0000 (18:27 +0200)
* Makefile.in (cfgexpand.o): Depend on $(INSN_ATTR_H).
* genattrtab.c (check_tune_attr, find_tune_attr): New functions.
(make_automaton_attrs): If find_tune_attr returns non-NULL,
write separate internal_dfa_insn_code_* and insn_default_latency_*
functions for each attribute's value and emit init_sched_attrs
function and function pointers.
* genattr.c (const_attrs, reservations): New variables.
(gen_attr): Add const attributes to const_attrs vector.
(check_tune_attr, find_tune_attr): New functions.
(main): Add reservations to reservations vector.  If find_tune_attr
returns true, add prototype for init_sched_attrs and make
internal_dfa_insn_code and insn_default_latency function pointers,
otherwise define init_sched_attrs as dummy macro.
* cfgexpand.c: Include insn-attr.h.
(gimple_expand_cfg): Call init_sched_attrs.

From-SVN: r161093

gcc/ChangeLog
gcc/Makefile.in
gcc/cfgexpand.c
gcc/genattr.c
gcc/genattrtab.c

index aa4d2a877e496b6300d12f1c905e292d6e709674..a5534853863b67f36fec33f9f09aa1169e2859a2 100644 (file)
@@ -1,5 +1,21 @@
 2010-06-21  Jakub Jelinek  <jakub@redhat.com>
 
+       * Makefile.in (cfgexpand.o): Depend on $(INSN_ATTR_H).
+       * genattrtab.c (check_tune_attr, find_tune_attr): New functions.
+       (make_automaton_attrs): If find_tune_attr returns non-NULL,
+       write separate internal_dfa_insn_code_* and insn_default_latency_*
+       functions for each attribute's value and emit init_sched_attrs
+       function and function pointers.
+       * genattr.c (const_attrs, reservations): New variables.
+       (gen_attr): Add const attributes to const_attrs vector.
+       (check_tune_attr, find_tune_attr): New functions.
+       (main): Add reservations to reservations vector.  If find_tune_attr
+       returns true, add prototype for init_sched_attrs and make
+       internal_dfa_insn_code and insn_default_latency function pointers,
+       otherwise define init_sched_attrs as dummy macro.
+       * cfgexpand.c: Include insn-attr.h.
+       (gimple_expand_cfg): Call init_sched_attrs.
+
        * stmt.c (resolve_asm_operand_names): Fix handling
        of %%.
 
index b88c032a0cf9c63334a67a5efa3e7c357d980bb4..30ef1efb523b59c34c8cc5b153a6ec69e874129d 100644 (file)
@@ -3193,7 +3193,7 @@ cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TREE_DUMP_H) $(EXCEPT_H) langhooks.h $(TREE_PASS_H) $(RTL_H) \
    $(DIAGNOSTIC_H) $(TOPLEV_H) $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \
    value-prof.h $(TREE_INLINE_H) $(TARGET_H) $(SSAEXPAND_H) \
-   tree-pretty-print.h gimple-pretty-print.h $(BITMAP_H) sbitmap.h
+   tree-pretty-print.h gimple-pretty-print.h $(BITMAP_H) sbitmap.h $(INSN_ATTR_H)
 cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \
    output.h $(TOPLEV_H) $(FUNCTION_H) $(EXCEPT_H) $(TM_P_H) $(INSN_ATTR_H) \
index cc8ff336a42e5364022c1a3e49ef2d0386df0ca4..f78badf30006756b8489aa1dd4317c39a0aa239e 100644 (file)
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssaexpand.h"
 #include "bitmap.h"
 #include "sbitmap.h"
+#include "insn-attr.h" /* For INSN_SCHEDULING.  */
 
 /* This variable holds information helping the rewriting of SSA trees
    into RTL.  */
@@ -3761,6 +3762,10 @@ gimple_expand_cfg (void)
   set_curr_insn_block (DECL_INITIAL (current_function_decl));
   prologue_locator = curr_insn_locator ();
 
+#ifdef INSN_SCHEDULING
+  init_sched_attrs ();
+#endif
+
   /* Make sure first insn is a note even if we don't want linenums.
      This makes sure the first insn will never be deleted.
      Also, final expects a note to appear there.  */
index e4609ca41743a47935f9697773acaa3e62897ec0..4fd22e219e328eb7aa48afd6cf1ce2ff6c124cbd 100644 (file)
@@ -1,6 +1,6 @@
 /* Generate attribute information (insn-attr.h) from machine description.
-   Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003, 2004, 2007, 2008
-   Free Software Foundation, Inc.
+   Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003, 2004, 2007, 2008,
+   2010  Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GCC.
@@ -40,12 +40,18 @@ write_upcase (const char *str)
     putchar (TOUPPER(*str));
 }
 
+static VEC (rtx, heap) *const_attrs, *reservations;
+
+
 static void
 gen_attr (rtx attr)
 {
   const char *p, *tag;
   int is_const = GET_CODE (XEXP (attr, 2)) == CONST;
 
+  if (is_const)
+    VEC_safe_push (rtx, heap, const_attrs, attr);
+
   printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0));
 
   /* If numeric attribute, don't need to write an enum.  */
@@ -92,6 +98,68 @@ extern int insn_current_length (rtx);\n\n\
     }
 }
 
+/* Check that attribute NAME is used in define_insn_reservation condition
+   EXP.  Return true if it is.  */
+static bool
+check_tune_attr (const char *name, rtx exp)
+{
+  switch (GET_CODE (exp))
+    {
+    case AND:
+      if (check_tune_attr (name, XEXP (exp, 0)))
+       return true;
+      return check_tune_attr (name, XEXP (exp, 1));
+
+    case IOR:
+      return (check_tune_attr (name, XEXP (exp, 0))
+             && check_tune_attr (name, XEXP (exp, 1)));
+
+    case EQ_ATTR:
+      return strcmp (XSTR (exp, 0), name) == 0;
+
+    default:
+      return false;
+    }
+}
+
+/* Try to find a const attribute (usually cpu or tune) that is used
+   in all define_insn_reservation conditions.  */
+static bool
+find_tune_attr (rtx exp)
+{
+  unsigned int i;
+  rtx attr;
+
+  switch (GET_CODE (exp))
+    {
+    case AND:
+    case IOR:
+      if (find_tune_attr (XEXP (exp, 0)))
+       return true;
+      return find_tune_attr (XEXP (exp, 1));
+
+    case EQ_ATTR:
+      if (strcmp (XSTR (exp, 0), "alternative") == 0)
+       return false;
+
+      for (i = 0; VEC_iterate (rtx, const_attrs, i, attr); i++)
+       if (strcmp (XSTR (attr, 0), XSTR (exp, 0)) == 0)
+         {
+           unsigned int j;
+           rtx resv;
+
+           for (j = 0; VEC_iterate (rtx, reservations, j, resv); j++)
+             if (! check_tune_attr (XSTR (attr, 0), XEXP (resv, 2)))
+               return false;
+           return true;
+         }
+      return false;
+
+    default:
+      return false;
+    }
+}
+
 int
 main (int argc, char **argv)
 {
@@ -162,11 +230,16 @@ main (int argc, char **argv)
         }
 
       else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
-       num_insn_reservations++;
+       {
+         num_insn_reservations++;
+         VEC_safe_push (rtx, heap, reservations, desc);
+       }
     }
 
   if (num_insn_reservations > 0)
     {
+      bool has_tune_attr
+       = find_tune_attr (XEXP (VEC_index (rtx, reservations, 0), 2));
       /* Output interface for pipeline hazards recognition based on
         DFA (deterministic finite state automata.  */
       printf ("\n#define INSN_SCHEDULING\n");
@@ -181,10 +254,24 @@ main (int argc, char **argv)
       printf ("#define CPU_UNITS_QUERY 0\n");
       printf ("#endif\n\n");
       /* Interface itself: */
-      printf ("/* Internal insn code number used by automata.  */\n");
-      printf ("extern int internal_dfa_insn_code (rtx);\n\n");
-      printf ("/* Insn latency time defined in define_insn_reservation. */\n");
-      printf ("extern int insn_default_latency (rtx);\n\n");
+      if (has_tune_attr)
+       {
+         printf ("/* Initialize fn pointers for internal_dfa_insn_code\n");
+         printf ("   and insn_default_latency.  */\n");
+         printf ("extern void init_sched_attrs (void);\n\n");
+         printf ("/* Internal insn code number used by automata.  */\n");
+         printf ("extern int (*internal_dfa_insn_code) (rtx);\n\n");
+         printf ("/* Insn latency time defined in define_insn_reservation. */\n");
+         printf ("extern int (*insn_default_latency) (rtx);\n\n");
+       }
+      else
+       {
+         printf ("#define init_sched_attrs() do { } while (0)\n\n");
+         printf ("/* Internal insn code number used by automata.  */\n");
+         printf ("extern int internal_dfa_insn_code (rtx);\n\n");
+         printf ("/* Insn latency time defined in define_insn_reservation. */\n");
+         printf ("extern int insn_default_latency (rtx);\n\n");
+       }
       printf ("/* Return nonzero if there is a bypass for given insn\n");
       printf ("   which is a data producer.  */\n");
       printf ("extern int bypass_p (rtx);\n\n");
index 9fe1c5caa7c59c4b738f45bafd41f34013e425fa..33b66f34009429f91f946724147429f5e12fa171 100644 (file)
@@ -1,6 +1,6 @@
 /* Generate code from machine description to compute values of attributes.
    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
@@ -4372,6 +4372,69 @@ process_bypasses (void)
        r->bypassed = true;
 }
 
+/* Check that attribute NAME is used in define_insn_reservation condition
+   EXP.  Return true if it is.  */
+static bool
+check_tune_attr (const char *name, rtx exp)
+{
+  switch (GET_CODE (exp))
+    {
+    case AND:
+      if (check_tune_attr (name, XEXP (exp, 0)))
+       return true;
+      return check_tune_attr (name, XEXP (exp, 1));
+
+    case IOR:
+      return (check_tune_attr (name, XEXP (exp, 0))
+             && check_tune_attr (name, XEXP (exp, 1)));
+
+    case EQ_ATTR:
+      return XSTR (exp, 0) == name;
+
+    default:
+      return false;
+    }
+}
+
+/* Try to find a const attribute (usually cpu or tune) that is used
+   in all define_insn_reservation conditions.  */
+static struct attr_desc *
+find_tune_attr (rtx exp)
+{
+  struct attr_desc *attr;
+
+  switch (GET_CODE (exp))
+    {
+    case AND:
+    case IOR:
+      attr = find_tune_attr (XEXP (exp, 0));
+      if (attr)
+       return attr;
+      return find_tune_attr (XEXP (exp, 1));
+
+    case EQ_ATTR:
+      if (XSTR (exp, 0) == alternative_name)
+       return NULL;
+
+      attr = find_attr (&XSTR (exp, 0), 0);
+      gcc_assert (attr);
+
+      if (attr->is_const && !attr->is_special)
+       {
+         struct insn_reserv *decl;
+
+         for (decl = all_insn_reservs; decl; decl = decl->next)
+           if (! check_tune_attr (attr->name, decl->condexp))
+             return NULL;
+         return attr;
+       }
+      return NULL;
+
+    default:
+      return NULL;
+    }
+}
+
 /* Create all of the attributes that describe automaton properties.  */
 static void
 make_automaton_attrs (void)
@@ -4379,28 +4442,154 @@ make_automaton_attrs (void)
   int i;
   struct insn_reserv *decl;
   rtx code_exp, lats_exp, byps_exp;
+  struct attr_desc *tune_attr;
 
   if (n_insn_reservs == 0)
     return;
 
-  code_exp = rtx_alloc (COND);
-  lats_exp = rtx_alloc (COND);
+  tune_attr = find_tune_attr (all_insn_reservs->condexp);
+  if (tune_attr != NULL)
+    {
+      rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
+      struct attr_value *val;
+      bool first = true;
+
+      gcc_assert (tune_attr->is_const
+                 && !tune_attr->is_special
+                 && !tune_attr->is_numeric);
+      for (val = tune_attr->first_value; val; val = val->next)
+       {
+         if (val == tune_attr->default_val)
+           continue;
+         gcc_assert (GET_CODE (val->value) == CONST_STRING);
+         printf ("static int internal_dfa_insn_code_%s (rtx);\n"
+                 "static int insn_default_latency_%s (rtx);\n",
+                 XSTR (val->value, 0), XSTR (val->value, 0));
+       }
+
+      printf ("\n");
+      printf ("int (*internal_dfa_insn_code) (rtx);\n");
+      printf ("int (*insn_default_latency) (rtx);\n");
+      printf ("\n");
+      printf ("void\n");
+      printf ("init_sched_attrs (void)\n");
+      printf ("{\n");
+
+      for (val = tune_attr->first_value; val; val = val->next)
+       {
+         int j;
+         char *name;
+         rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
+
+         if (val == tune_attr->default_val)
+           continue;
+         for (decl = all_insn_reservs, i = 0;
+              decl;
+              decl = decl->next)
+           {
+             rtx ctest = test;
+             rtx condexp
+               = simplify_and_tree (decl->condexp, &ctest, -2, 0);
+             if (condexp == false_rtx)
+               continue;
+             if (condexp == true_rtx)
+               break;
+             condexps[i] = condexp;
+             condexps[i + 1] = make_numeric_value (decl->insn_num);
+             condexps[i + 2] = make_numeric_value (decl->default_latency);
+             i += 3;
+           }
+
+         code_exp = rtx_alloc (COND);
+         lats_exp = rtx_alloc (COND);
+
+         j = i / 3 * 2;
+         XVEC (code_exp, 0) = rtvec_alloc (j);
+         XVEC (lats_exp, 0) = rtvec_alloc (j);
+
+         if (decl)
+           {
+             XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
+             XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
+           }
+         else
+           {
+             XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
+             XEXP (lats_exp, 1) = make_numeric_value (0);
+           }
+
+         while (i > 0)
+           {
+             i -= 3;
+             j -= 2;
+             XVECEXP (code_exp, 0, j) = condexps[i];
+             XVECEXP (lats_exp, 0, j) = condexps[i];
+
+             XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
+             XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
+           }
 
-  XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
-  XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
+         name = XNEWVEC (char,
+                         sizeof ("*internal_dfa_insn_code_")
+                         + strlen (XSTR (val->value, 0)));
+         strcpy (name, "*internal_dfa_insn_code_");
+         strcat (name, XSTR (val->value, 0));
+         make_internal_attr (name, code_exp, ATTR_NONE);
+         strcpy (name, "*insn_default_latency_");
+         strcat (name, XSTR (val->value, 0));
+         make_internal_attr (name, lats_exp, ATTR_NONE);
+         XDELETEVEC (name);
+
+         if (first)
+           {
+             printf ("  if (");
+             first = false;
+           }
+         else
+           printf ("  else if (");
+         write_test_expr (test, 0);
+         printf (")\n");
+         printf ("    {\n");
+         printf ("      internal_dfa_insn_code\n");
+         printf ("        = internal_dfa_insn_code_%s;\n",
+                 XSTR (val->value, 0));
+         printf ("      insn_default_latency\n");
+         printf ("        = insn_default_latency_%s;\n",
+                 XSTR (val->value, 0));
+         printf ("    }\n");
+       }
 
-  XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
-  XEXP (lats_exp, 1) = make_numeric_value (0);
+      printf ("  else\n");
+      printf ("    gcc_unreachable ();\n");
+      printf ("}\n");
+      printf ("\n");
 
-  for (decl = all_insn_reservs, i = 0;
-       decl;
-       decl = decl->next, i += 2)
+      XDELETEVEC (condexps);
+    }
+  else
     {
-      XVECEXP (code_exp, 0, i)   = decl->condexp;
-      XVECEXP (lats_exp, 0, i)   = decl->condexp;
+      code_exp = rtx_alloc (COND);
+      lats_exp = rtx_alloc (COND);
+
+      XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
+      XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
 
-      XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
-      XVECEXP (lats_exp, 0, i+1) = make_numeric_value (decl->default_latency);
+      XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
+      XEXP (lats_exp, 1) = make_numeric_value (0);
+
+      for (decl = all_insn_reservs, i = 0;
+          decl;
+          decl = decl->next, i += 2)
+       {
+         XVECEXP (code_exp, 0, i)   = decl->condexp;
+         XVECEXP (lats_exp, 0, i)   = decl->condexp;
+
+         XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
+         XVECEXP (lats_exp, 0, i+1)
+           = make_numeric_value (decl->default_latency);
+       }
+      make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
+      make_internal_attr ("*insn_default_latency",   lats_exp, ATTR_NONE);
     }
 
   if (n_bypasses == 0)
@@ -4423,8 +4612,6 @@ make_automaton_attrs (void)
          }
     }
 
-  make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
-  make_internal_attr ("*insn_default_latency",   lats_exp, ATTR_NONE);
   make_internal_attr ("*bypass_p",               byps_exp, ATTR_NONE);
 }