invoke.texi (fdump-translation-unit): Delete documentation.
[gcc.git] / gcc / c / c-array-notation.c
index 6a5631c3b6f530b134f1364734d74cd7111f79aa..e430f5c681bfdd8e6e3389767d3ca14058c5dc11 100644 (file)
@@ -1,7 +1,7 @@
 /* This file is part of the Intel(R) Cilk(TM) Plus support
    This file contains routines to handle Array Notation expression
    handling routines in the C Compiler.
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+   Copyright (C) 2013-2017 Free Software Foundation, Inc.
    Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
                   Intel Corporation.
 
@@ -26,7 +26,7 @@
    An array notation expression has 4 major components:
    1. The array name
    2. Start Index
-   3. Number of elements we need to acess (we call it length)
+   3. Number of elements we need to access (we call it length)
    4. Stride
 
    For example, A[0:5:2], implies that we are accessing A[0], A[2], A[4],
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tree.h"
 #include "c-tree.h"
+#include "gimple-expr.h"
 #include "tree-iterator.h"
-#include "opts.h"
-#include "c-family/c-common.h"
 
 /* If *VALUE is not of type INTEGER_CST, PARM_DECL or VAR_DECL, then map it
    to a variable and then set *VALUE to the new variable.  */
@@ -83,7 +81,7 @@ make_triplet_val_inv (location_t loc, tree *value)
   tree var, new_exp;
   if (TREE_CODE (*value) != INTEGER_CST
       && TREE_CODE (*value) != PARM_DECL
-      && TREE_CODE (*value) != VAR_DECL)
+      && !VAR_P (*value))
     {
       var = build_decl (loc, VAR_DECL, NULL_TREE, integer_type_node);
       new_exp = build_modify_expr (loc, var, TREE_TYPE (var), NOP_EXPR, loc,
@@ -106,7 +104,7 @@ create_cmp_incr (location_t loc, vec<an_loop_parts> *node, size_t rank,
     {
       tree var = (*node)[ii].var;
       tree length = an_info[0][ii].length;
-      (*node)[ii].incr = build_unary_op (loc, POSTINCREMENT_EXPR, var, 0);
+      (*node)[ii].incr = build_unary_op (loc, POSTINCREMENT_EXPR, var, false);
       (*node)[ii].cmp = build2 (LT_EXPR, boolean_type_node, var, length);
     }
 }
@@ -207,12 +205,19 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
   location_t location = UNKNOWN_LOCATION;
   tree loop_with_init = alloc_stmt_list ();
   vec<vec<an_parts> > an_info = vNULL;
-  vec<an_loop_parts> an_loop_info = vNULL;
+  auto_vec<an_loop_parts> an_loop_info;
   enum built_in_function an_type =
     is_cilkplus_reduce_builtin (CALL_EXPR_FN (an_builtin_fn));
   if (an_type == BUILT_IN_NONE)
     return NULL_TREE;
 
+  /* Builtin call should contain at least one argument.  */
+  if (call_expr_nargs (an_builtin_fn) == 0)
+    {
+      error_at (EXPR_LOCATION (an_builtin_fn), "Invalid builtin arguments");
+      return error_mark_node;
+    }
+
   if (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE
       || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
     {
@@ -228,6 +233,8 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
   /* Fully fold any EXCESSIVE_PRECISION EXPR that can occur in the function
      parameter.  */
   func_parm = c_fully_fold (func_parm, false, NULL);
+  if (func_parm == error_mark_node)
+    return error_mark_node;
   
   location = EXPR_LOCATION (an_builtin_fn);
   
@@ -235,7 +242,10 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
     return error_mark_node;
  
   if (rank == 0)
-    return an_builtin_fn;
+    {
+      error_at (location, "Invalid builtin arguments");
+      return error_mark_node;
+    }
   else if (rank > 1 
           && (an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
               || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND))
@@ -282,8 +292,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
 
   for (ii = 0; ii < rank; ii++)
     {
-      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-                                 integer_type_node);
+      an_loop_info[ii].var = create_tmp_var (integer_type_node);
       an_loop_info[ii].ind_init =
        build_modify_expr (location, an_loop_info[ii].var,
                           TREE_TYPE (an_loop_info[ii].var), NOP_EXPR,
@@ -308,7 +317,9 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
       || an_type == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND)
     array_ind_value = build_decl (location, VAR_DECL, NULL_TREE, 
                                  TREE_TYPE (func_parm));
-  array_op0 = (*array_operand)[0];                           
+  array_op0 = (*array_operand)[0];
+  if (INDIRECT_REF_P (array_op0))
+    array_op0 = TREE_OPERAND (array_op0, 0);
   switch (an_type)
     {
     case BUILT_IN_CILKPLUS_SEC_REDUCE_ADD:
@@ -478,7 +489,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
          new_yes_expr = build_modify_expr
            (location, array_ind_value, TREE_TYPE (array_ind_value),
             NOP_EXPR,
-            location, func_parm, TREE_OPERAND (array_op0, 1));
+            location, func_parm, TREE_TYPE (TREE_OPERAND (array_op0, 1)));
        }
       new_yes_list = alloc_stmt_list ();
       append_to_statement_list (new_yes_ind, &new_yes_list);
@@ -528,7 +539,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
          new_yes_expr = build_modify_expr
            (location, array_ind_value, TREE_TYPE (array_ind_value),
             NOP_EXPR,
-            location, func_parm, TREE_OPERAND (array_op0, 1));
+            location, func_parm, TREE_TYPE (TREE_OPERAND (array_op0, 1)));
        }
       new_yes_list = alloc_stmt_list ();
       append_to_statement_list (new_yes_ind, &new_yes_list);
@@ -582,8 +593,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
     }
   append_to_statement_list_force (body, &loop_with_init);
 
-  an_info.release ();
-  an_loop_info.release ();
+  release_vec_vec (an_info);
   
   return loop_with_init;
 }
@@ -603,7 +613,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE;
   tree array_expr = NULL_TREE;
   tree an_init = NULL_TREE;
-  vec<tree> cond_expr = vNULL;
+  auto_vec<tree> cond_expr;
   tree body, loop_with_init = alloc_stmt_list();
   tree scalar_mods = NULL_TREE;
   vec<tree, va_gc> *rhs_array_operand = NULL, *lhs_array_operand = NULL;
@@ -613,7 +623,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   tree new_modify_expr, new_var = NULL_TREE, builtin_loop = NULL_TREE;
   size_t rhs_list_size = 0, lhs_list_size = 0; 
   vec<vec<an_parts> > lhs_an_info = vNULL, rhs_an_info = vNULL;
-  vec<an_loop_parts> lhs_an_loop_info = vNULL, rhs_an_loop_info = vNULL;
+  auto_vec<an_loop_parts> lhs_an_loop_info, rhs_an_loop_info;
   
   /* If either of this is true, an error message must have been send out
      already.  Not necessary to send out multiple error messages.  */
@@ -760,7 +770,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
          && length_mismatch_in_expr_p (EXPR_LOCATION (rhs), rhs_an_info)))
     {
       pop_stmt_list (an_init);
-      return error_mark_node;
+      goto error;
     }
   if (lhs_list_size > 0 && rhs_list_size > 0 && lhs_rank > 0 && rhs_rank > 0
       && TREE_CODE (lhs_an_info[0][0].length) == INTEGER_CST
@@ -775,14 +785,13 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
        {
          error_at (location, "length mismatch between LHS and RHS");
          pop_stmt_list (an_init);
-         return error_mark_node;
+         goto error;
        }
     }
   for (ii = 0; ii < lhs_rank; ii++)
     if (lhs_an_info[0][ii].is_vector)
       {
-       lhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-                                              integer_type_node);
+       lhs_an_loop_info[ii].var = create_tmp_var (integer_type_node);
        lhs_an_loop_info[ii].ind_init = build_modify_expr
          (location, lhs_an_loop_info[ii].var,
           TREE_TYPE (lhs_an_loop_info[ii].var), NOP_EXPR,
@@ -793,8 +802,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
     {
       /* When we have a polynomial, we assume that the indices are of type 
         integer.  */
-      rhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-                                            integer_type_node);
+      rhs_an_loop_info[ii].var = create_tmp_var (integer_type_node);
       rhs_an_loop_info[ii].ind_init = build_modify_expr
        (location, rhs_an_loop_info[ii].var,
         TREE_TYPE (rhs_an_loop_info[ii].var), NOP_EXPR,
@@ -820,7 +828,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
                                                 rhs_an_loop_info, rhs_rank,
                                                 rhs);
       if (!rhs_array_operand)
-       return error_mark_node;
+       goto error;
       replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
     }
   else if (rhs_list_size > 0)
@@ -829,7 +837,7 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
                                                 lhs_an_loop_info, lhs_rank,
                                                 lhs);
       if (!rhs_array_operand)
-       return error_mark_node;
+       goto error;
       replace_array_notations (&rhs, true, rhs_list, rhs_array_operand);
     }
   array_expr_lhs = lhs;
@@ -872,15 +880,15 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
     }
   append_to_statement_list_force (body, &loop_with_init);
 
-  lhs_an_info.release ();
-  lhs_an_loop_info.release ();
-  if (rhs_rank)
-    {
-      rhs_an_info.release ();
-      rhs_an_loop_info.release ();
-    }
-  cond_expr.release ();
+  release_vec_vec (lhs_an_info);
+  release_vec_vec (rhs_an_info);
   return loop_with_init;
+
+error:
+  release_vec_vec (lhs_an_info);
+  release_vec_vec (rhs_an_info);
+
+  return error_mark_node;
 }
 
 /* Helper function for fix_conditional_array_notations.  Encloses the 
@@ -900,7 +908,7 @@ fix_conditional_array_notations_1 (tree stmt)
   location_t location = EXPR_LOCATION (stmt);
   tree body = NULL_TREE, loop_with_init = alloc_stmt_list ();
   vec<vec<an_parts> > an_info = vNULL;
-  vec<an_loop_parts> an_loop_info = vNULL;
+  auto_vec<an_loop_parts> an_loop_info;
  
   if (TREE_CODE (stmt) == COND_EXPR)
     cond = COND_EXPR_COND (stmt);
@@ -970,8 +978,7 @@ fix_conditional_array_notations_1 (tree stmt)
   cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info);
   for (ii = 0; ii < rank; ii++)
     {
-      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-                                        integer_type_node);
+      an_loop_info[ii].var = create_tmp_var (integer_type_node);
       an_loop_info[ii].ind_init =
        build_modify_expr (location, an_loop_info[ii].var,
                           TREE_TYPE (an_loop_info[ii].var), NOP_EXPR,
@@ -997,9 +1004,7 @@ fix_conditional_array_notations_1 (tree stmt)
       body = pop_stmt_list (new_loop);
     }
   append_to_statement_list_force (body, &loop_with_init);
-
-  an_loop_info.release ();
-  an_info.release ();
+  release_vec_vec (an_info);
 
   return loop_with_init;
 }
@@ -1040,7 +1045,7 @@ fix_array_notation_expr (location_t location, enum tree_code code,
   tree loop_init;
   tree body, loop_with_init = alloc_stmt_list ();
   vec<vec<an_parts> > an_info = vNULL;
-  vec<an_loop_parts> an_loop_info = vNULL;
+  auto_vec<an_loop_parts> an_loop_info;
   
   if (!find_rank (location, arg.value, arg.value, false, &rank))
     {
@@ -1067,8 +1072,7 @@ fix_array_notation_expr (location_t location, enum tree_code code,
   loop_init = push_stmt_list ();
   for (ii = 0; ii < rank; ii++)
     {
-      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-                                        integer_type_node);
+      an_loop_info[ii].var = create_tmp_var (integer_type_node);
       an_loop_info[ii].ind_init =
        build_modify_expr (location, an_loop_info[ii].var,
                           TREE_TYPE (an_loop_info[ii].var), NOP_EXPR,
@@ -1084,7 +1088,7 @@ fix_array_notation_expr (location_t location, enum tree_code code,
 
   arg = default_function_array_read_conversion (location, arg);
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
-    arg.value = build_unary_op (location, code, arg.value, 0);
+    arg.value = build_unary_op (location, code, arg.value, false);
   else if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
     arg = parser_build_unary_op (location, code, arg);
 
@@ -1103,8 +1107,7 @@ fix_array_notation_expr (location_t location, enum tree_code code,
     }
   append_to_statement_list_force (body, &loop_with_init);
   arg.value = loop_with_init;
-  an_info.release ();
-  an_loop_info.release ();
+  release_vec_vec (an_info);
   return arg;
 }
 
@@ -1121,7 +1124,7 @@ fix_array_notation_call_expr (tree arg)
   tree body, loop_with_init = alloc_stmt_list ();
   location_t location = UNKNOWN_LOCATION;
   vec<vec<an_parts> > an_info = vNULL;
-  vec<an_loop_parts> an_loop_info = vNULL;
+  auto_vec<an_loop_parts> an_loop_info;
 
   if (TREE_CODE (arg) == CALL_EXPR
       && is_cilkplus_reduce_builtin (CALL_EXPR_FN (arg)))
@@ -1163,8 +1166,7 @@ fix_array_notation_call_expr (tree arg)
     }
   for (ii = 0; ii < rank; ii++)
     {
-      an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE,
-                                        integer_type_node);
+      an_loop_info[ii].var = create_tmp_var (integer_type_node);
       an_loop_info[ii].ind_init =
        build_modify_expr (location, an_loop_info[ii].var,
                           TREE_TYPE (an_loop_info[ii].var), NOP_EXPR, location,
@@ -1188,8 +1190,7 @@ fix_array_notation_call_expr (tree arg)
       body = pop_stmt_list (new_loop);
     }
   append_to_statement_list_force (body, &loop_with_init);
-  an_loop_info.release ();
-  an_info.release ();
+  release_vec_vec (an_info);
   return loop_with_init;
 }
 
@@ -1254,6 +1255,25 @@ expand_array_notations (tree *tp, int *walk_subtrees, void *)
                                         rhs_loc, rhs, TREE_TYPE (rhs));
       }
       break;
+    case DECL_EXPR:
+      {
+       tree x = DECL_EXPR_DECL (*tp);
+       if (DECL_INITIAL (x))
+         {
+           location_t loc = DECL_SOURCE_LOCATION (x);
+           tree lhs = x;
+           tree rhs = DECL_INITIAL (x);
+           DECL_INITIAL (x) = NULL;
+           tree new_modify_expr = build_modify_expr (loc, lhs,
+                                                     TREE_TYPE (lhs),
+                                                     NOP_EXPR,
+                                                     loc, rhs,
+                                                     TREE_TYPE(rhs));
+           expand_array_notations (&new_modify_expr, walk_subtrees, NULL);
+           *tp = new_modify_expr;
+         }
+      }
+      break;
     case CALL_EXPR:
       *tp = fix_array_notation_call_expr (*tp);
       break;
@@ -1282,7 +1302,7 @@ expand_array_notations (tree *tp, int *walk_subtrees, void *)
         A[x:y:z];
         A[x:y];
         Replace those with just void zero node.  */
-      *tp = void_zero_node;
+      *tp = void_node;
     default:
       break;
     }