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);

Reply via email to