diff mbox

[PING] genattrab.c generate switch

Message ID 569E2248.9040605@gmail.com
State New
Headers show

Commit Message

Jesper Broge Jørgensen Jan. 19, 2016, 11:47 a.m. UTC
On 19/01/16 10:44, Richard Biener wrote:
> On Mon, Jan 18, 2016 at 7:48 PM, Jeff Law <law@redhat.com> wrote:
>> On 01/18/2016 07:09 AM, Jesper Broge Jørgensen wrote:
>>> Ping patch:
>>>
>>> https://gcc.gnu.org/ml/gcc-patches/2016-01/msg00784.html
>> I'd put it in my gcc-7 queue.  But if Richard, Bernd, Richi or someone else
>> wants to work though the changes as a bugfix for bootstrapping on platforms
>> with crippled compilers, I won't object.
> I'd take it as a bugfix but the patch still needs review.
>
> Richard.
>
>> jeff
Here is the reformatted patch:


gcc/ChangeLog:

2016-01-19  Jesper Broge Jørgensen  <jesperbroge@gmail.com>

     * genattrtab.c (check_attr_set_switch): New function
     (write_attr_set): Write a switch instead of if condition, if possible


tests and
     sets of an attribute value.  We are passed an indentation amount 
and prefix
     and suffix strings to write around each attribute value (e.g., "return"
@@ -4123,6 +4220,7 @@ write_attr_set (FILE *outf, struct attr_desc 
*attr, int indent, rtx value,
          const char *prefix, const char *suffix, rtx known_true,
          int insn_code, int insn_index, unsigned int attrs_cached)
  {
+  int n_switches = 0;
    if (GET_CODE (value) == COND)
      {
        /* Assume the default value will be the default of the COND 
unless we
@@ -4132,6 +4230,7 @@ write_attr_set (FILE *outf, struct attr_desc 
*attr, int indent, rtx value,
        rtx newexp;
        int first_if = 1;
        int i;
+      int is_switch = 0;

        if (cached_attr_count)
      {
@@ -4176,40 +4275,68 @@ write_attr_set (FILE *outf, struct attr_desc 
*attr, int indent, rtx value,
        if (inner_true == false_rtx)
          continue;

+      is_switch = check_attr_set_switch (outf, testexp, attrs_cached, 0,
+                         indent);
+
        attrs_cached_inside = attrs_cached;
        attrs_cached_after = attrs_cached;
        write_indent (outf, indent);
-      fprintf (outf, "%sif ", first_if ? "" : "else ");
-      first_if = 0;
-      write_test_expr (outf, testexp, attrs_cached,
-               (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
-      attrs_cached = attrs_cached_after;
-      fprintf (outf, "\n");
-      write_indent (outf, indent + 2);
-      fprintf (outf, "{\n");
+      if (is_switch)
+        {
+          fprintf (outf, "switch ");
+          n_switches++;
+          first_if = 1;
+          check_attr_set_switch (outf, testexp, attrs_cached, 1, indent);
+          indent += 4;
+        }
+      else
+        {
+          fprintf (outf, "%sif ", first_if ? "" : "else ");
+          first_if = 0;
+          write_test_expr (outf, testexp, attrs_cached,
+                   (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
+          attrs_cached = attrs_cached_after;
+          fprintf (outf, "\n");
+        }
+      if (!is_switch)
+        {
+          write_indent (outf, indent + 2);
+          fprintf (outf, "{\n");
+        }
+

        write_attr_set (outf, attr, indent + 4,
                XVECEXP (value, 0, i + 1), prefix, suffix,
                inner_true, insn_code, insn_index,
                attrs_cached_inside);
        write_indent (outf, indent + 2);
-      fprintf (outf, "}\n");
+      if (is_switch)
+        {
+          fprintf (outf, "break;\n");
+          write_indent (outf, indent);
+          fprintf (outf, "default:\n");
+          indent += 4;
+        }
+      else
+        fprintf (outf, "}\n");
        our_known_true = newexp;
      }

-      if (! first_if)
+      if (! first_if && ! is_switch)
      {
        write_indent (outf, indent);
        fprintf (outf, "else\n");
        write_indent (outf, indent + 2);
        fprintf (outf, "{\n");
      }
+      else if (is_switch)
+    write_indent (outf, indent);

-      write_attr_set (outf, attr, first_if ? indent : indent + 4, 
default_val,
+      write_attr_set (outf, attr, (first_if || is_switch) ? indent : 
indent + 4, default_val,
                prefix, suffix, our_known_true, insn_code, insn_index,
                attrs_cached);

-      if (! first_if)
+      if (! first_if && ! is_switch)
      {
        write_indent (outf, indent + 2);
        fprintf (outf, "}\n");
@@ -4222,6 +4349,12 @@ write_attr_set (FILE *outf, struct attr_desc 
*attr, int indent, rtx value,
        write_attr_value (outf, attr, value);
        fprintf (outf, "%s\n", suffix);
      }
+  while (n_switches--)
+    {
+      indent -= 2;
+      write_indent (outf, indent);
+      fprintf (outf, "}\n");
+    }
  }

  /* Write a series of case statements for every instruction in list IE.

Comments

Bernd Schmidt Feb. 18, 2016, 12:22 p.m. UTC | #1
On 01/19/2016 12:47 PM, Jesper Broge Jørgensen wrote:
> Here is the reformatted patch:

This will probably have to wait until stage1.

> +      const int code = GET_CODE (op2);
> +      if (code != IOR)
> +    {
> +      if (code == EQ_ATTR)

All the formatting still looks completely mangled. This was probably 
done by your mailer. Please try attaching the diff as text/plain.


Bernd
Jesper Broge Jørgensen March 3, 2016, 9:29 p.m. UTC | #2
On 18/02/16 13:22, Bernd Schmidt wrote:
> On 01/19/2016 12:47 PM, Jesper Broge Jørgensen wrote:
>> Here is the reformatted patch:
>
> This will probably have to wait until stage1.
>
>> +      const int code = GET_CODE (op2);
>> +      if (code != IOR)
>> +    {
>> +      if (code == EQ_ATTR)
>
> All the formatting still looks completely mangled. This was probably 
> done by your mailer. Please try attaching the diff as text/plain.
>
>
> Bernd
>
Hi i send the patch back as an attatchment as requested about two weeks 
ago (https://gcc.gnu.org/ml/gcc-patches/2016-02/msg01256.html) but i 
have not received any response.

If it has to wait for stage 1 are there anything else i can do for the 
patch untill then?
Patrick Palka March 3, 2016, 10:36 p.m. UTC | #3
On Thu, Mar 3, 2016 at 4:29 PM, Jesper Broge Jørgensen
<jesperbroge@gmail.com> wrote:
>
> On 18/02/16 13:22, Bernd Schmidt wrote:
>>
>> On 01/19/2016 12:47 PM, Jesper Broge Jørgensen wrote:
>>>
>>> Here is the reformatted patch:
>>
>>
>> This will probably have to wait until stage1.
>>
>>> +      const int code = GET_CODE (op2);
>>> +      if (code != IOR)
>>> +    {
>>> +      if (code == EQ_ATTR)
>>
>>
>> All the formatting still looks completely mangled. This was probably done
>> by your mailer. Please try attaching the diff as text/plain.
>>
>>
>> Bernd
>>
> Hi i send the patch back as an attatchment as requested about two weeks ago
> (https://gcc.gnu.org/ml/gcc-patches/2016-02/msg01256.html) but i have not
> received any response.
>
> If it has to wait for stage 1 are there anything else i can do for the patch
> untill then?

I still suggest to try making write_test_expr() avoid emitting
redundant parentheses for chains of || or &&, which would fix the
original issue all the same.  Previously you claimed that such a
change would not be simpler than your current patch, but I gave it a
quick try and ended up with a much smaller patch:

 gcc/genattrtab.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)
David Malcolm March 4, 2016, 1:40 p.m. UTC | #4
On Thu, 2016-03-03 at 17:36 -0500, Patrick Palka wrote:
> On Thu, Mar 3, 2016 at 4:29 PM, Jesper Broge Jørgensen
> <jesperbroge@gmail.com> wrote:
> > 
> > On 18/02/16 13:22, Bernd Schmidt wrote:
> > > 
> > > On 01/19/2016 12:47 PM, Jesper Broge Jørgensen wrote:
> > > > 
> > > > Here is the reformatted patch:
> > > 
> > > 
> > > This will probably have to wait until stage1.
> > > 
> > > > +      const int code = GET_CODE (op2);
> > > > +      if (code != IOR)
> > > > +    {
> > > > +      if (code == EQ_ATTR)
> > > 
> > > 
> > > All the formatting still looks completely mangled. This was
> > > probably done
> > > by your mailer. Please try attaching the diff as text/plain.
> > > 
> > > 
> > > Bernd
> > > 
> > Hi i send the patch back as an attatchment as requested about two
> > weeks ago
> > (https://gcc.gnu.org/ml/gcc-patches/2016-02/msg01256.html) but i
> > have not
> > received any response.
> > 
> > If it has to wait for stage 1 are there anything else i can do for
> > the patch
> > untill then?
> 
> I still suggest to try making write_test_expr() avoid emitting
> redundant parentheses for chains of || or &&, which would fix the
> original issue all the same.  Previously you claimed that such a
> change would not be simpler than your current patch, but I gave it a
> quick try and ended up with a much smaller patch:
> 
>  gcc/genattrtab.c | 26 +++++++++++++++++++-------
>  1 file changed, 19 insertions(+), 7 deletions(-)

Patrick, did you forget to attach the patch?  I see the diffstat, but
no patch.
diff mbox

Patch

diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 2caf8f6..8e7f9e6 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -4113,6 +4113,103 @@  eliminate_known_true (rtx known_true, rtx exp, 
int insn_code, int insn_index)
    return exp;
  }

+/* Check if exp contains a series of IOR conditions on the same attr_name.
+   If it does it can be turned into a switch statement and returns true.
+   If write_cases is true it will write the cases of the switch to 
outf.  */
+
+static int
+check_attr_set_switch (FILE *outf, rtx exp, unsigned int attrs_cached,
+               int write_cases, int indent)
+{
+  if (GET_CODE (exp) != IOR)
+    return 0;
+  if (GET_CODE (XEXP (exp, 0)) != EQ_ATTR)
+    return 0;
+
+  rtx next = exp;
+  int ior_depth = 0;
+  int is_first = 1;
+
+  const char *attr_name_cmp = XSTR (XEXP (exp, 0), 0);
+
+  while (1)
+    {
+      rtx op1 = XEXP (next, 0);
+      rtx op2 = XEXP (next, 1);
+
+      if (GET_CODE (op1) != EQ_ATTR)
+    return 0;
+
+      const char *attr_name = XSTR (op1, 0);
+      const char *cmp_val = XSTR (op1, 1);
+
+      /* pointer compare is enough.  */
+      if (attr_name_cmp != attr_name)
+    return 0;
+
+      if (write_cases)
+    {
+      struct attr_desc *attr = find_attr (&attr_name, 0);
+      gcc_assert (attr);
+      if (is_first)
+        {
+          fprintf (outf, "(");
+          is_first = 0;
+          int i;
+          for (i = 0; i < cached_attr_count; i++)
+        if (attr->name == cached_attrs[i])
+          break;
+
+          if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
+        fprintf (outf, "cached_%s", attr->name);
+          else if (i < cached_attr_count &&
+               (attrs_to_cache & (1U << i)) != 0)
+        fprintf (outf, "(cached_%s = get_attr_%s (insn))", attr->name,
+             attr->name);
+          else
+        fprintf (outf, "get_attr_%s (insn)", attr->name);
+          fprintf (outf, ")\n");
+          write_indent (outf, indent);
+          fprintf (outf, "{\n");
+        }
+      write_indent (outf, indent);
+      fprintf (outf, "case ");
+      write_attr_valueq (outf, attr, cmp_val);
+      fprintf (outf, ":\n");
+    }
+
+      const int code = GET_CODE (op2);
+      if (code != IOR)
+    {
+      if (code == EQ_ATTR)
+        {
+          const char *attr_name = XSTR (op2, 0);
+          const char *cmp_val = XSTR (op2, 1);
+
+          if (attr_name == alternative_name)
+        return 0;
+
+          struct attr_desc *attr = find_attr (&attr_name, 0);
+          gcc_assert (attr);
+
+          if (attr->is_const)
+        return 0;
+          else if (write_cases)
+        {
+          write_indent (outf, indent);
+          fprintf (outf, "case ");
+          write_attr_valueq (outf, attr, cmp_val);
+          fprintf (outf, ":\n");
+        }
+        }
+      break;
+    }
+      next = op2;
+      ior_depth++;
+    }
+  return ior_depth > 2;
+}
+
  /* Write out a series of tests and assignment statements to perform