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
Here it is as an attatchment. I set deliveryformat to "Plain Text Only"
in thunderbird.
Please let me know if anything else needs to be changed.
gcc/ChangeLog:
2016-01-19 Jesper Broge Jørgensen <jesperbr...@gmail.com>
* genattrtab.c (check_attr_set_switch): New function
(write_attr_set): Write a switch instead of if condition if possible
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 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.