Am 17.07.24 um 20:49 schrieb Richard Sandiford:
Georg-Johann Lay <a...@gjlay.de> writes:
[...]
Am 13.07.24 um 13:44 schrieb Richard Sandiford:
It shouldn't be necessary to emit the enum tag these days. If removing
Hi Richard,
I am not familiar with the gensupport policies, which is the reason why
the feature is just a suggestion / proposal and not a patch.
IMO patches should not come from someone like me who has no experience
in that area; better someone more experienced would take it over.
it causes anything to break, I think we should fix whatever that breaking
thing is. Could you try doing that, as a pre-patch? Or I can give it a
go, if you'd rather not.
Yes please.
OK, I pushed b19906a029a to remove the enum tags. The type name is
now stored as a const char * in attr_desc::cxx_type.
Great. With that in place, the feature would be something like the
attached delta (I didn't repeat the texi part).
There is one place where SYMBOL_REF issues fprint_c_condition in
line genattrtab.cc:3717 (after applying the delta) where I couln't
find a way to reach it.
And the "enum" in genattr.cc could be removed, too?
Johann
* read-md.h (fprint_c_condition): Add cxx_type parameter.
(print_c_condition): Same.
* genattrtab.cc (write_test_expr) [MATCH_TEST]: Pass down "bool"
as cxx_type argument to fprint_c_condition.
(write_attr_value) [SYMBOL_REF]: Pass down attr->cxx_type
as cxx_type argument to fprint_c_condition.
* genconditions.cc (write_one_condition): Pass down "$bool"
(bool with no capture) as cxx_type down to print_c_condition.
* genrecog.cc (print_test): Pass down "bool"
as cxx_type argument to print_c_condition.
* read-md.cc (md_reader::fprint_c_condition): Add cxx_type
parameter. Use it in lambda expression when cond is a block
of code.
(md_reader::print_c_condition): Add cxx_type parameter.
Pass it down to md_reader::fprint_c_condition.
If we do that, then we can just a return a const char * for the type.
Yes, const char* would be easier. I just didn't know how to alloc one,
and where. A new const char* property in class attr_desc_would solve
it.
And then in turn we can pass a const char * to (f)print_c_condition.
The MD reader then wouldn't need to know about attributes.
Thanks,
Richard
When this feature makes it into GCC, then match_test should behave
similar, I guess? I.e. support function bodies that return bool.
I just wasn't sure which caller of fprint_c_condition runs with
match_test resp. symbol_ref from which context (insn attribute or
predicate, etc).
Yeah, might be useful for match_test too.
Thanks for looking into this and for considering it as an extension.
The shortcomings like non-support of pathological comments like
/* } */ is probably not such a big issue. And fixing it would have
to touch the md scanner / lexer and have side effects I don't know,
like on build performance and stability of course. That part could
be fixed when someone actually needs it.
It looks like we don't support \{ and \}, but that's probably an oversight.
Thanks,
Richard
diff --git a/gcc/genattrtab.cc b/gcc/genattrtab.cc
index 2a51549ddd4..63ddef84469 100644
--- a/gcc/genattrtab.cc
+++ b/gcc/genattrtab.cc
@@ -3707,7 +3707,7 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
break;
case MATCH_TEST:
- rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
+ rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0), "bool");
if (flags & FLG_BITWISE)
fprintf (outf, " != 0");
break;
@@ -4385,7 +4385,8 @@ write_attr_value (FILE *outf, class attr_desc *attr, rtx value)
break;
case SYMBOL_REF:
- rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0));
+ rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0),
+ attr->cxx_type);
break;
case ATTR:
diff --git a/gcc/genconditions.cc b/gcc/genconditions.cc
index 13963dc3ff4..8a55f0f1033 100644
--- a/gcc/genconditions.cc
+++ b/gcc/genconditions.cc
@@ -141,9 +141,9 @@ write_one_condition (void **slot, void * ARG_UNUSED (dummy))
}
fputs ("\",\n __builtin_constant_p ", stdout);
- rtx_reader_ptr->print_c_condition (test->expr);
+ rtx_reader_ptr->print_c_condition (test->expr, "$bool");
fputs ("\n ? (int) ", stdout);
- rtx_reader_ptr->print_c_condition (test->expr);
+ rtx_reader_ptr->print_c_condition (test->expr, "$bool");
fputs ("\n : -1 },\n", stdout);
return 1;
}
diff --git a/gcc/genrecog.cc b/gcc/genrecog.cc
index ba09ec3b600..c597958a487 100644
--- a/gcc/genrecog.cc
+++ b/gcc/genrecog.cc
@@ -4762,7 +4762,7 @@ print_test (output_state *os, const rtx_test &test, bool is_param,
gcc_assert (!is_param && value == 1);
if (invert_p)
printf ("!");
- rtx_reader_ptr->print_c_condition (test.u.string);
+ rtx_reader_ptr->print_c_condition (test.u.string, "bool");
break;
case rtx_test::ACCEPT:
diff --git a/gcc/read-md.cc b/gcc/read-md.cc
index 93d1ea43781..e211549b353 100644
--- a/gcc/read-md.cc
+++ b/gcc/read-md.cc
@@ -170,31 +170,54 @@ md_reader::join_c_conditions (const char *cond1, const char *cond2)
directive for COND if its original file position is known. */
void
-md_reader::fprint_c_condition (FILE *outf, const char *cond)
+md_reader::fprint_c_condition (FILE *outf, const char *cond,
+ const char *cxx_type)
{
const char **halves = (const char **) htab_find (m_joined_conditions, &cond);
if (halves != 0)
{
fprintf (outf, "(");
- fprint_c_condition (outf, halves[1]);
+ fprint_c_condition (outf, halves[1], cxx_type);
fprintf (outf, " && ");
- fprint_c_condition (outf, halves[2]);
+ fprint_c_condition (outf, halves[2], cxx_type);
fprintf (outf, ")");
}
else
{
fputc ('\n', outf);
fprint_md_ptr_loc (outf, cond);
- fprintf (outf, "(%s)", cond);
+ if (cond[0] == '{')
+ {
+ // Like "( [&]() -> <cxx_type> <cond> () )"
+ // Where COND is actually the body of a function, including the
+ // outer {}'s. Print this as a lambda that's evaluated in place.
+ // The capture-all is required to have access to variables
+ // like "insn". Objects like "operands[]" and "which_alternative"
+ // are accessible since they are global or captured.
+ // When the expression is not evaluated locally (not in a function),
+ // then CXX_TYPE starts with a '$' to indicate that no capture
+ // should be performed.
+ bool no_capture = cxx_type && cxx_type[0] == '$';
+ if (cxx_type && no_capture)
+ fprintf (outf, "( []() -> %s %s () )", 1 + cxx_type, cond);
+ else if (cxx_type)
+ fprintf (outf, "( [&]() -> %s %s () )", cxx_type, cond);
+ else
+ fprintf (outf, "( [&]() /* unknown return type */ %s () )", cond);
+ }
+ else
+ {
+ fprintf (outf, "(%s)", cond);
+ }
}
}
/* Special fprint_c_condition for writing to STDOUT. */
void
-md_reader::print_c_condition (const char *cond)
+md_reader::print_c_condition (const char *cond, const char *cxx_type)
{
- fprint_c_condition (stdout, cond);
+ fprint_c_condition (stdout, cond, cxx_type);
}
/* A vfprintf-like function for reporting an error against line LINENO
diff --git a/gcc/read-md.h b/gcc/read-md.h
index 9703551a8fd..b6ee68647ec 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -204,8 +204,9 @@ class md_reader
void handle_enum (file_location loc, bool md_p);
const char *join_c_conditions (const char *cond1, const char *cond2);
- void fprint_c_condition (FILE *outf, const char *cond);
- void print_c_condition (const char *cond);
+ void fprint_c_condition (FILE *outf, const char *cond,
+ const char *cxx_type = nullptr);
+ void print_c_condition (const char *cond, const char *cxx_type = nullptr);
/* Defined in read-rtl.cc. */
const char *apply_iterator_to_string (const char *string);