OSDN Git Service

contrib/
[pf3gnuchains/gcc-fork.git] / gcc / omp-low.c
index db5f858..2f9aede 100644 (file)
@@ -1097,7 +1097,7 @@ debug_all_omp_regions (void)
 struct omp_region *
 new_omp_region (basic_block bb, enum tree_code type, struct omp_region *parent)
 {
-  struct omp_region *region = xcalloc (1, sizeof (*region));
+  struct omp_region *region = XCNEW (struct omp_region);
 
   region->outer = parent;
   region->entry = bb;
@@ -1493,7 +1493,7 @@ create_omp_child_function_name (bool task_copy)
   const char *suffix;
 
   suffix = task_copy ? "_omp_cpyfn" : "_omp_fn";
-  prefix = alloca (len + strlen (suffix) + 1);
+  prefix = XALLOCAVEC (char, len + strlen (suffix) + 1);
   memcpy (prefix, IDENTIFIER_POINTER (name), len);
   strcpy (prefix + len, suffix);
 #ifndef NO_DOT_IN_LABEL
@@ -1853,8 +1853,8 @@ check_omp_nesting_restrictions (tree t, omp_context *ctx)
 static tree
 scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
 {
-  struct walk_stmt_info *wi = data;
-  omp_context *ctx = wi->info;
+  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+  omp_context *ctx = (omp_context *) wi->info;
   tree t = *tp;
 
   if (EXPR_HAS_LOCATION (t))
@@ -3140,7 +3140,7 @@ expand_omp_taskreg (struct omp_region *region)
 {
   basic_block entry_bb, exit_bb, new_bb;
   struct function *child_cfun;
-  tree child_fn, block, t, ws_args;
+  tree child_fn, block, t, ws_args, *tp;
   block_stmt_iterator si;
   tree entry_stmt;
   edge e;
@@ -3251,6 +3251,7 @@ expand_omp_taskreg (struct omp_region *region)
       block = DECL_INITIAL (child_fn);
       BLOCK_VARS (block) = list2chain (child_cfun->local_decls);
       DECL_SAVED_TREE (child_fn) = bb_stmt_list (single_succ (entry_bb));
+      TREE_USED (block) = 1;
 
       /* Reset DECL_CONTEXT on function arguments.  */
       for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
@@ -3287,11 +3288,22 @@ expand_omp_taskreg (struct omp_region *region)
          init_ssa_operands ();
          cfun->gimple_df->in_ssa_p = true;
          pop_cfun ();
+         block = NULL_TREE;
        }
-      new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
+      else
+       block = TREE_BLOCK (entry_stmt);
+
+      new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
       if (exit_bb)
        single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
 
+      /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
+      for (tp = &child_cfun->local_decls; *tp; )
+       if (DECL_CONTEXT (TREE_VALUE (*tp)) != cfun->decl)
+         tp = &TREE_CHAIN (*tp);
+       else
+         *tp = TREE_CHAIN (*tp);
+
       /* Inform the callgraph about the new function.  */
       DECL_STRUCT_FUNCTION (child_fn)->curr_properties
        = cfun->curr_properties;
@@ -5030,6 +5042,8 @@ expand_omp (struct omp_region *region)
 {
   while (region)
     {
+      location_t saved_location;
+
       /* First, determine whether this is a combined parallel+workshare
                 region.  */
       if (region->type == OMP_PARALLEL)
@@ -5038,6 +5052,10 @@ expand_omp (struct omp_region *region)
       if (region->inner)
        expand_omp (region->inner);
 
+      saved_location = input_location;
+      if (EXPR_HAS_LOCATION (last_stmt (region->entry)))
+       input_location = EXPR_LOCATION (last_stmt (region->entry));
+
       switch (region->type)
        {
        case OMP_PARALLEL:
@@ -5075,11 +5093,11 @@ expand_omp (struct omp_region *region)
          expand_omp_atomic (region);
          break;
 
-
        default:
          gcc_unreachable ();
        }
 
+      input_location = saved_location;
       region = region->next;
     }
 }
@@ -5263,10 +5281,11 @@ lower_omp_sections (tree *stmt_p, omp_context *ctx)
   tree t, dlist;
   tree_stmt_iterator tsi;
   unsigned i, len;
+  struct gimplify_ctx gctx;
 
   stmt = *stmt_p;
 
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
 
   dlist = NULL;
   ilist = NULL;
@@ -5312,12 +5331,18 @@ lower_omp_sections (tree *stmt_p, omp_context *ctx)
   olist = NULL_TREE;
   lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
 
-  pop_gimplify_context (NULL_TREE);
-  record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
-
-  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+  block = make_node (BLOCK);
+  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
   TREE_SIDE_EFFECTS (new_stmt) = 1;
 
+  pop_gimplify_context (new_stmt);
+
+  BIND_EXPR_VARS (new_stmt)
+    = chainon (BIND_EXPR_VARS (new_stmt), ctx->block_vars);
+  BLOCK_VARS (block) = BIND_EXPR_VARS (new_stmt);
+  if (BLOCK_VARS (block))
+    TREE_USED (block) = 1;
+
   new_body = alloc_stmt_list ();
   append_to_statement_list (ilist, &new_body);
   append_to_statement_list (stmt, &new_body);
@@ -5458,8 +5483,9 @@ static void
 lower_omp_single (tree *stmt_p, omp_context *ctx)
 {
   tree t, bind, block, single_stmt = *stmt_p, dlist;
+  struct gimplify_ctx gctx;
 
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
 
   block = make_node (BLOCK);
   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
@@ -5491,6 +5517,8 @@ lower_omp_single (tree *stmt_p, omp_context *ctx)
 
   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
+  if (BLOCK_VARS (block))
+    TREE_USED (block) = 1;
 }
 
 
@@ -5500,8 +5528,9 @@ static void
 lower_omp_master (tree *stmt_p, omp_context *ctx)
 {
   tree bind, block, stmt = *stmt_p, lab = NULL, x;
+  struct gimplify_ctx gctx;
 
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
 
   block = make_node (BLOCK);
   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
@@ -5539,8 +5568,9 @@ static void
 lower_omp_ordered (tree *stmt_p, omp_context *ctx)
 {
   tree bind, block, stmt = *stmt_p, x;
+  struct gimplify_ctx gctx;
 
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
 
   block = make_node (BLOCK);
   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
@@ -5583,6 +5613,7 @@ lower_omp_critical (tree *stmt_p, omp_context *ctx)
 {
   tree bind, block, stmt = *stmt_p;
   tree t, lock, unlock, name;
+  struct gimplify_ctx gctx;
 
   name = OMP_CRITICAL_NAME (stmt);
   if (name)
@@ -5632,7 +5663,7 @@ lower_omp_critical (tree *stmt_p, omp_context *ctx)
       unlock = build_call_expr (unlock, 0);
     }
 
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
 
   block = make_node (BLOCK);
   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
@@ -5714,25 +5745,29 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
 static void
 lower_omp_for (tree *stmt_p, omp_context *ctx)
 {
-  tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
+  tree t, stmt, ilist, dlist, new_stmt, block, *body_p, *rhs_p;
   struct omp_for_data fd;
   int i;
+  struct gimplify_ctx gctx;
 
   stmt = *stmt_p;
 
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
 
   lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
   lower_omp (&OMP_FOR_BODY (stmt), ctx);
 
+  block = make_node (BLOCK);
+  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
+  TREE_SIDE_EFFECTS (new_stmt) = 1;
+  body_p = &BIND_EXPR_BODY (new_stmt);
+
   /* Move declaration of temporaries in the loop body before we make
      it go away.  */
   if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
-    record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
-
-  new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
-  TREE_SIDE_EFFECTS (new_stmt) = 1;
-  body_p = &BIND_EXPR_BODY (new_stmt);
+    BIND_EXPR_VARS (new_stmt)
+      = chainon (BIND_EXPR_VARS (new_stmt),
+                BIND_EXPR_VARS (OMP_FOR_BODY (stmt)));
 
   /* The pre-body and input clauses go before the lowered OMP_FOR.  */
   ilist = NULL;
@@ -5786,8 +5821,12 @@ lower_omp_for (tree *stmt_p, omp_context *ctx)
   OMP_RETURN_NOWAIT (t) = fd.have_nowait;
   append_to_statement_list (t, body_p);
 
-  pop_gimplify_context (NULL_TREE);
-  record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
+  pop_gimplify_context (new_stmt);
+  BIND_EXPR_VARS (new_stmt)
+    = chainon (BIND_EXPR_VARS (new_stmt), ctx->block_vars);
+  BLOCK_VARS (block) = BIND_EXPR_VARS (new_stmt);
+  if (BLOCK_VARS (block))
+    TREE_USED (block) = 1;
 
   OMP_FOR_BODY (stmt) = NULL_TREE;
   OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
@@ -5800,8 +5839,8 @@ lower_omp_for (tree *stmt_p, omp_context *ctx)
 static tree
 check_combined_parallel (tree *tp, int *walk_subtrees, void *data)
 {
-  struct walk_stmt_info *wi = data;
-  int *info = wi->info;
+  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+  int *info = (int *) wi->info;
 
   *walk_subtrees = 0;
   switch (TREE_CODE (*tp))
@@ -5876,6 +5915,7 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
   bool record_needs_remap = false, srecord_needs_remap = false;
   splay_tree_node n;
   struct omp_taskcopy_context tcctx;
+  struct gimplify_ctx gctx;
 
   child_fn = OMP_TASK_COPYFN (task_stmt);
   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
@@ -5888,7 +5928,7 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
     DECL_CONTEXT (t) = child_fn;
 
   /* Populate the function.  */
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
   current_function_decl = child_fn;
 
   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
@@ -6105,6 +6145,7 @@ lower_omp_taskreg (tree *stmt_p, omp_context *ctx)
   tree clauses, par_bind, par_body, new_body, bind;
   tree olist, ilist, par_olist, par_ilist;
   tree stmt, child_fn, t;
+  struct gimplify_ctx gctx;
 
   stmt = *stmt_p;
 
@@ -6128,7 +6169,7 @@ lower_omp_taskreg (tree *stmt_p, omp_context *ctx)
   if (ctx->srecord_type)
     create_task_copyfn (stmt, ctx);
 
-  push_gimplify_context ();
+  push_gimplify_context (&gctx);
 
   par_olist = NULL_TREE;
   par_ilist = NULL_TREE;
@@ -6157,8 +6198,9 @@ lower_omp_taskreg (tree *stmt_p, omp_context *ctx)
 
   /* Once all the expansions are done, sequence all the different
      fragments inside OMP_TASKREG_BODY.  */
-  bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
-  append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
+  bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
+                BIND_EXPR_BLOCK (par_bind));
+  TREE_SIDE_EFFECTS (bind) = 1;
 
   new_body = alloc_stmt_list ();
 
@@ -6180,7 +6222,14 @@ lower_omp_taskreg (tree *stmt_p, omp_context *ctx)
   OMP_TASKREG_BODY (stmt) = new_body;
 
   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
-  append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
+  if (ilist || olist)
+    {
+      append_to_statement_list (bind, &ilist);
+      append_to_statement_list (olist, &ilist);
+      bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+      TREE_SIDE_EFFECTS (bind) = 1;
+      append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
+    }
 
   *stmt_p = bind;
 
@@ -6194,13 +6243,15 @@ static tree
 lower_omp_2 (tree *tp, int *walk_subtrees, void *data)
 {
   tree t = *tp;
-  omp_context *ctx = data;
+  omp_context *ctx = (omp_context *) data;
 
   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
-  if (TREE_CODE (t) == VAR_DECL
-      && ((ctx && DECL_HAS_VALUE_EXPR_P (t))
-         || (task_shared_vars
-             && bitmap_bit_p (task_shared_vars, DECL_UID (t)))))
+  if (TREE_CODE (t) == VAR_DECL && ctx && DECL_HAS_VALUE_EXPR_P (t))
+    return t;
+
+  if (task_shared_vars
+      && DECL_P (t)
+      && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
     return t;
 
   /* If a global variable has been privatized, TREE_CONSTANT on
@@ -6363,7 +6414,9 @@ lower_omp_1 (tree *tp, omp_context *ctx, tree_stmt_iterator *tsi)
 static void
 lower_omp (tree *stmt_p, omp_context *ctx)
 {
+  location_t saved_location = input_location;
   lower_omp_1 (stmt_p, ctx, NULL);
+  input_location = saved_location;
 }
 \f
 /* Main entry point.  */
@@ -6379,8 +6432,10 @@ execute_lower_omp (void)
 
   if (all_contexts->root)
     {
+      struct gimplify_ctx gctx;
+
       if (task_shared_vars)
-       push_gimplify_context ();
+       push_gimplify_context (&gctx);
       lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
       if (task_shared_vars)
        pop_gimplify_context (NULL);
@@ -6470,7 +6525,7 @@ diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
 static tree
 diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
 {
-  struct walk_stmt_info *wi = data;
+  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   tree context = (tree) wi->info;
   tree inner_context;
   tree t = *tp;
@@ -6532,7 +6587,7 @@ diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
 static tree
 diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
 {
-  struct walk_stmt_info *wi = data;
+  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   tree context = (tree) wi->info;
   splay_tree_node n;
   tree t = *tp;