On 06/24/2013 06:23 PM, Iyer, Balaji V wrote:
Actually, to reduce the amount of changes to non-AN code, let's put the AN case
third, after the offset and {} cases, so you get something like

else if (flag_enable_cilkplus)
   {
     tree an = cp_parser_array_notation (loc, parser, &index,
                                        postfix_expression);
     if (an)
       return an;
     /* Otherwise, cp_parser_array_notation set 'index'. */
   }
else
   index = cp_parser_expression (parser, /*cast_p=*/false, NULL);

this way the change is just a few added lines, and everything else is in
cp_parser_array_notation.

If I do it this way, then I don't think I will be able to handle a normal array 
reference when cilk plus is enabled.

What I had in mind is that in the case of a normal array reference, cp_parser_array_notation will update index (which is passed by address) and return NULL_TREE, so that it gets back on the normal path.

One thing I could do is to assume that people won't use array notations in 
braced list. I had it like this a while back but I made the change to make sure 
I have covered more cases. Please let me know if that is OK and I will fix it.

Yes, that's OK.

I looked into this. But, magic_varargs_p is static to call.c. Should I make it 
non-static?

Yes.

After making it non-static I was planning to do something like this:

if (magic_varargs_p (fndecl)
  Nargs = (*params)->length ();
else
   nargs = convert_arguments (...)

Is that OK with you?

I was thinking to check magic_varargs_p in convert_arguments, where it currently has

          if (fndecl && DECL_BUILT_IN (fndecl)
              && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
            /* Don't do ellipsis conversion for __built_in_constant_p
               as this will result in spurious errors for non-trivial
               types.  */

change to "if (fndecl && magic_varargs_p (fndecl))"

By the way, why are you breaking out the elements of the
ARRAY_NOTATION_REF into a cilkplus_an_parts rather than using the _REF
directly?

I use the different parts of array notations for error checking and to create 
the outer for-loop. Also, to create the ARRAY_REF I need the induction variable.

I understand the need for cilkplus_an_loop_parts, but cilkplus_an_parts seems to contain exactly the same information as the ARRAY_NOTATION_REF.

Fixed! By the way, what is SFINAE?

SFINAE stands for "substitution failure is not an error". During template argument deduction, once we have a full set of template arguments we try to substitute them into the template declaration. In that context, things that would normally cause an error just fail and return error_mark_node silently.

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 55ed6a5..9d570b2 100644
Binary files a/gcc/cp/ChangeLog and b/gcc/cp/ChangeLog differ

This patch still has ChangeLog entries.

+  new_var = get_temp_regvar (TREE_TYPE (retval_expr),
+                            build_zero_cst (TREE_TYPE (retval_expr)));
   new_mod = expand_an_in_modify_expr (loc, new_var, NOP_EXPR,
+                                     TREE_OPERAND (retval_expr, 1),
+                                     tf_warning_or_error);

Why not pass TREE_OPERAND (retval_expr, 1) as the init to get_temp_regvar?

-         parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
          if (!length_index || length_index == error_mark_node)
            cp_parser_skip_to_end_of_statement (parser);
        
@@ -6180,7 +6158,6 @@ cp_parser_array_notation (location_t loc, cp_parser 
*parser, tree init_index,
              saved_colon_corrects_to_scope_p =
                parser->colon_corrects_to_scope_p;
              /* Disable correcting single colon correcting to scope.  */
-             parser->colon_corrects_to_scope_p = false;

This change looks like now you will only restore parser->colon_corrects_to_scope_p if you have a stride. I would suggest putting back the first restore, and removing all the corrects_to_scope_p code from the stride block, since there can't be an array-notation colon after the stride.

+           /* If stride and start are of same type and the induction var
+              is not, convert induction variable to stride's type.  */
+           if (TREE_TYPE (start) == TREE_TYPE (stride)
+               && TREE_TYPE (stride) != TREE_TYPE (var))

This seems impossible, since 'var' is created to have the same type as 'start'.

As you suggested further in the email, I have made var of type ptrdiff_type, so 
I think I should keep this.

I think it would be better to convert start/stride to ptrdiff_t.

Incidentally, types should be compared with same_type_p rather than ==.

+  if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
+      && TREE_CODE (lhs_len) == INTEGER_CST && rhs_len
+      && TREE_CODE (rhs_len) == INTEGER_CST)
+    {
+      HOST_WIDE_INT l_length = int_cst_value (lhs_len);
+      HOST_WIDE_INT r_length = int_cst_value (rhs_len);
+      if (absu_hwi (l_length) != absu_hwi (r_length))
+       {
+         error_at (location, "length mismatch between LHS and RHS");
+         pop_stmt_list (an_init);
+         return error_mark_node;
+       }
+    }

Another place that should use tree_int_cst_equal.

+      /* No need to compare ii < rhs_rank && ii >= lhs_rank because valid Array
+        notation expression cannot RHS's rank cannot be greater than LHS.  */

Too many "cannot"s.

+  if (processing_template_decl)
+    {
+      array_type = TREE_TYPE (array_value);
+      type = TREE_TYPE (array_type);
+    }

We should be able to parse array notation in a template even when the array expression has unknown type. In a template, just parse and remember the raw expressions without worrying about diagnostics and conversions.

+  if (flag_enable_cilkplus && contains_array_notation_expr (expr))
+    {
+      size_t rank = 0;
+
+      if (!find_rank (input_location, expr, expr, false, &rank))
+       return error_mark_node;
+
+      /* If the return expression contains array notations, then flag it as
+        error.  */
+      if (rank >= 1)
+       {
+         error_at (input_location, "array notation expression cannot be "
+                   "used as a return value");
+         return error_mark_node;
+       }
+    }
...
+  /* If an array's index is an array notation, then its rank cannot be
+     greater than one.  */
+  if (flag_enable_cilkplus && contains_array_notation_expr (idx))
+    {
+      size_t rank = 0;
+
+      /* If find_rank returns false, then it should have reported an error,
+        thus it is unnecessary for repetition.  */
+      if (!find_rank (loc, idx, idx, true, &rank))
+       return error_mark_node;
+      if (rank > 1)
+       {
+         error_at (loc, "rank of the array%'s index is greater than 1");
+         return error_mark_node;
+       }
+    }

More diagnostics that should move to expansion time.

+  if (flag_enable_cilkplus && contains_array_notation_expr (op0))
+    type0 = find_correct_array_notation_type (op0);
+  else
+    type0 = TREE_TYPE (op0);
...
+  if (flag_enable_cilkplus && TREE_CODE (arg) == ARRAY_NOTATION_REF)
+    {
+      val = build_address (arg);
+      if (TREE_CODE (arg) == OFFSET_REF)
+       PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
+      return val;
+    }
...
+  /* If we are dealing with built-in array notation function then we don't need
+     to convert them.  They will be broken up into modify exprs in future,
+     during which all these checks will be done.  */
+  if (flag_enable_cilkplus
+      && is_cilkplus_reduce_builtin (fndecl) != BUILT_IN_NONE)
+    return rhs;

More changes that should be unnecessary since ARRAY_NOTATION_REF has a normal type.

What remaining obstacles are there to sharing most of the expansion code between C and C++? That can be a separate patch, of course.

Jason

Reply via email to