> +static tree
> +c_check_cilk_loop_incr (location_t loc, tree decl, tree incr)
> +{
> +  if (EXPR_HAS_LOCATION (incr))
> +    loc = EXPR_LOCATION (incr);
> +
> +  if (!incr)
> +    {
> +      error_at (loc, "missing increment");
> +      return error_mark_node;
> +    }

Either these tests are swapped, or the second one isn't really needed.


> +  switch (TREE_CODE (incr))
> +    {
> +    case POSTINCREMENT_EXPR:
> +    case PREINCREMENT_EXPR:
> +    case POSTDECREMENT_EXPR:
> +    case PREDECREMENT_EXPR:
> +      if (TREE_OPERAND (incr, 0) != decl)
> +     break;
> +
> +      // Bah... canonicalize into whatever OMP_FOR_INCR needs.
> +      if (POINTER_TYPE_P (TREE_TYPE (decl))
> +       && TREE_OPERAND (incr, 1))
> +     {
> +       tree t = fold_convert_loc (loc,
> +                                  sizetype, TREE_OPERAND (incr, 1));
> +
> +       if (TREE_CODE (incr) == POSTDECREMENT_EXPR
> +           || TREE_CODE (incr) == PREDECREMENT_EXPR)
> +         t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
> +       t = fold_build_pointer_plus (decl, t);
> +       incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
> +     }
> +      return incr;

Handling pointer types and pointer_plus_expr here (p++) ...

> +    case MODIFY_EXPR:
> +      {
> +     tree rhs;
> +
> +     if (TREE_OPERAND (incr, 0) != decl)
> +       break;
> +
> +     rhs = TREE_OPERAND (incr, 1);
> +     if (TREE_CODE (rhs) == PLUS_EXPR
> +         && (TREE_OPERAND (rhs, 0) == decl
> +             || TREE_OPERAND (rhs, 1) == decl)
> +         && INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
> +       return incr;
> +     else if (TREE_CODE (rhs) == MINUS_EXPR
> +              && TREE_OPERAND (rhs, 0) == decl
> +              && INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
> +       return incr;
> +     // Otherwise fail because only PLUS_EXPR and MINUS_EXPR are
> +     // allowed.
> +     break;

... but not here (p += 1)?


> +c_validate_cilk_plus_loop (tree *tp, int *walk_subtrees, void *data)
> +{
> +  if (!tp || !*tp)
> +    return NULL_TREE;
> +
> +  bool *valid = (bool *) data;
> +
> +  switch (TREE_CODE (*tp))
> +    {
> +    case CALL_EXPR:
> +      {
> +     tree fndecl = CALL_EXPR_FN (*tp);
> +
> +     if (TREE_CODE (fndecl) == ADDR_EXPR)
> +       fndecl = TREE_OPERAND (fndecl, 0);
> +     if (TREE_CODE (fndecl) == FUNCTION_DECL)
> +       {
> +         if (setjmp_call_p (fndecl))
> +           {
> +             error_at (EXPR_LOCATION (*tp),
> +                       "calls to setjmp are not allowed within loops "
> +                       "annotated with #pragma simd");
> +             *valid = false;
> +             *walk_subtrees = 0;
> +           }
> +       }
> +     break;

Why bother checking for setjmp?  While I agree it makes little sense, there are
plenty of other standard functions which also make no sense to use from within
#pragma simd.  What's likely to go wrong with a call to setjmp, as opposed to
getcontext, pthread_create, or even printf?

> +  if (DECL_REGISTER (decl))
> +    {
> +      error_at (loc, "induction variable cannot be declared register");
> +      return false;
> +    }

Why?

All of the actual gimple changes look good.  You could commit those now if you
like to reduce the size of the next patch.


r~

Reply via email to