Hi!

On Fri, Sep 20, 2013 at 12:00:41PM -0400, Jason Merrill wrote:

Thanks for the review, I'll try to get to most of that next week.

> On 09/12/2013 04:55 AM, Jakub Jelinek wrote:
> >-      if (t1 != t2)
> >+      if (t1 != t2 && !DECL_OMP_DECLARE_REDUCTION_P (newdecl))
> >     return 0;
> 
> What's the theory here?  Why should decls_match return true for
> reductions with mismatching templates?

In templates the UDRs are always FUNCTION_DECLs in classes or
at function block scope, the above one liner was I believe for the latter,
where without it duplicate_decls was returning incorrectly 0; the UDRs
from mismatching templates would actually never be seen by duplicate_decls,
but t1 was different from t2.  That was before the changes to
add the mangled names to the UDR DECL_NAMEs though, I can try to remove it
and see if the whole testsuite still passes.

> >+      && ! (DECL_OMP_DECLARE_REDUCTION_P (newdecl)
> >+            && DECL_CONTEXT (newdecl) == NULL_TREE
> >+            && DECL_CONTEXT (olddecl) == current_function_decl))
> 
> And this looks like you need to set DECL_CONTEXT sooner on reductions.

I know it is ugly, but setting FUNCTION_DECL DECL_CONTEXT too early resulted
in all kinds of problems, when the C++ frontend doesn't support nested
functions.  So the patch doesn't set DECL_CONTEXT until it is pushdecled
into the block scope.  The combiner/initializer expressions can't use vars
other than omp_{out,in,priv,orig}, so the UDRs aren't really nested in the
C nested function sense, and after all, after parsing the FUNCTION_DECL
for UDRs is just a container holding the expressions and artificial
VAR_DECLs, and is a FUNCTION_DECL so that normal C++ lookups can be
performed on it.

But like with the above, perhaps it isn't needed anymore, as with the
mangled type names in DECL_NAMEs we shouldn't really use overloads for UDRs.

> >+        if (TREE_CODE (argtype) == REFERENCE_TYPE)
> >+          error_at (DECL_SOURCE_LOCATION (t),
> >+                    "function, array or reference type in "
> >+                    "%<#pragma omp declare reduction%>");
> 
> Let's just say "reference type", since we know that's what it is.

That is true, but I wanted to match the same error message elsewhere,
otherwise the error will be different (more specific) for instantiation
vs. in non-template code.  Though, I could of course in that second spot
just special case REFERENCE_TYPE with a separate error message
and just have one about function or array type.
> 
> >+                     && DECL_CONTEXT (pattern_decl)
> >+                     && TREE_CODE (DECL_CONTEXT (pattern_decl))
> >+                        == FUNCTION_DECL)
> 
> This is DECL_FUNCTION_SCOPE_P.
>
> >+  return TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
> >+     || is_invisiref_parm (decl);
> 
> Needs parens to protect indentation.
> 
> >+/* Instantiate the special body of the artificial DECL_OMP_DECLARE_REDUCTION
> >+   function.  */
> 
> We could use documentation of what this special body looks like,
> either here, in cp_check_omp_declare_reduction, or elsewhere.

3xOk.
> 
> >+      for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
> >+    {
> >+      id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo));
> >+      if (id != NULL_TREE)
> >+        return id;
> 
> This should check for ambiguity rather than returning the first match.

I believe I need to discuss that on omp-lang, what exactly is the intended
behavior (and get the standard clarified).  Returning the first base class
is an option (and, depth-first vs. breadth-first?), or erroring out if more
than one base class has an UDR is another.

> >+   Also append INIT_EXPR for DECL_INITIAL of omp_priv after its
> >+   DECL_EXPR.  */
> 
> Why not let the DECL_EXPR handle initialization?

I can try that.

> Let's break out the finish_omp_clauses reduction code into a
> separate function, as it's rather large.

Will try that.
> 
> >+                if (DECL_TEMPLATE_INFO (id))
> >+                  id = instantiate_decl (id, /*defer_ok*/0, true);
> 
> Let's use mark_used instead.

Will that always instantiate it?

        Jakub

Reply via email to