OSDN Git Service

* java-tree.h (push_labeled_block, pop_labeled_block): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / omp-low.c
index f176f9e..feced73 100644 (file)
@@ -9,7 +9,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -18,9 +18,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -385,9 +384,12 @@ determine_parallel_type (struct omp_region *region)
 
   if (single_succ (par_entry_bb) == ws_entry_bb
       && single_succ (ws_exit_bb) == par_exit_bb
-      && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb))
+      && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb)
+      && (OMP_PARALLEL_COMBINED (last_stmt (par_entry_bb))
+         || (last_and_only_stmt (ws_entry_bb)
+             && last_and_only_stmt (par_exit_bb))))
     {
-      tree ws_stmt = last_stmt (region->inner->entry);
+      tree ws_stmt = last_stmt (ws_entry_bb);
 
       if (region->inner->type == OMP_FOR)
        {
@@ -516,6 +518,7 @@ omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
 
   TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
   DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
+  DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (var);
   DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
   DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
   TREE_USED (copy) = 1;
@@ -1503,9 +1506,9 @@ lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
     t = maybe_lookup_decl (decl, up);
 
-  gcc_assert (t);
+  gcc_assert (t || is_global_var (decl));
 
-  return t;
+  return t ? t : decl;
 }
 
 
@@ -2203,7 +2206,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
        {
          basic_block cond_bb, then_bb, else_bb;
          edge e;
-         tree t, then_lab, else_lab, tmp;
+         tree t, tmp;
 
          tmp = create_tmp_var (TREE_TYPE (val), NULL);
          e = split_block (bb, NULL);
@@ -2213,26 +2216,18 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
 
          then_bb = create_empty_bb (cond_bb);
          else_bb = create_empty_bb (then_bb);
-         then_lab = create_artificial_label ();
-         else_lab = create_artificial_label ();
 
          t = build3 (COND_EXPR, void_type_node,
-                     cond,
-                     build_and_jump (&then_lab),
-                     build_and_jump (&else_lab));
+                     cond, NULL_TREE, NULL_TREE);
 
          si = bsi_start (cond_bb);
          bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
 
          si = bsi_start (then_bb);
-         t = build1 (LABEL_EXPR, void_type_node, then_lab);
-         bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
          t = build_gimple_modify_stmt (tmp, val);
          bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
 
          si = bsi_start (else_bb);
-         t = build1 (LABEL_EXPR, void_type_node, else_lab);
-         bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
          t = build_gimple_modify_stmt (tmp, 
                                        build_int_cst (unsigned_type_node, 1));
          bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
@@ -2409,6 +2404,7 @@ expand_omp_parallel (struct omp_region *region)
   block_stmt_iterator si;
   tree entry_stmt;
   edge e;
+  bool do_cleanup_cfg = false;
 
   entry_stmt = last_stmt (region->entry);
   child_fn = OMP_PARALLEL_FN (entry_stmt);
@@ -2444,6 +2440,7 @@ expand_omp_parallel (struct omp_region *region)
          exit_succ_e = single_succ_edge (exit_bb);
          make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
        }
+      do_cleanup_cfg = true;
     }
   else
     {
@@ -2493,7 +2490,7 @@ expand_omp_parallel (struct omp_region *region)
       /* Declare local variables needed in CHILD_CFUN.  */
       block = DECL_INITIAL (child_fn);
       BLOCK_VARS (block) = list2chain (child_cfun->unexpanded_var_list);
-      DECL_SAVED_TREE (child_fn) = single_succ (entry_bb)->stmt_list;
+      DECL_SAVED_TREE (child_fn) = bb_stmt_list (single_succ (entry_bb));
 
       /* Reset DECL_CONTEXT on locals and function arguments.  */
       for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
@@ -2537,6 +2534,14 @@ expand_omp_parallel (struct omp_region *region)
 
   /* Emit a library call to launch the children threads.  */
   expand_parallel_call (region, new_bb, entry_stmt, ws_args);
+
+  if (do_cleanup_cfg)
+    {
+      /* Clean up the unreachable sub-graph we created above.  */
+      free_dominance_info (CDI_DOMINATORS);
+      free_dominance_info (CDI_POST_DOMINATORS);
+      cleanup_tree_cfg ();
+    }
 }
 
 
@@ -2569,7 +2574,6 @@ expand_omp_for_generic (struct omp_region *region,
                        enum built_in_function start_fn,
                        enum built_in_function next_fn)
 {
-  tree l0, l1, l2 = NULL, l3 = NULL;
   tree type, istart0, iend0, iend;
   tree t, list;
   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
@@ -2591,18 +2595,12 @@ expand_omp_for_generic (struct omp_region *region,
   l0_bb = create_empty_bb (entry_bb);
   l1_bb = single_succ (entry_bb);
 
-  l0 = tree_block_label (l0_bb);
-  l1 = tree_block_label (l1_bb);
-
   cont_bb = region->cont;
   exit_bb = region->exit;
   if (cont_bb)
     {
       l2_bb = create_empty_bb (cont_bb);
       l3_bb = single_succ (cont_bb);
-
-      l2 = tree_block_label (l2_bb);
-      l3 = tree_block_label (l3_bb);
     }
 
   si = bsi_last (entry_bb);
@@ -2630,8 +2628,7 @@ expand_omp_for_generic (struct omp_region *region,
       t = get_formal_tmp_var (t, &list);
       if (cont_bb)
        {
-         t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
-                     build_and_jump (&l3));
+         t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
          append_to_statement_list (t, &list);
        }
       bsi_insert_after (&si, list, BSI_SAME_STMT);
@@ -2672,8 +2669,7 @@ expand_omp_for_generic (struct omp_region *region,
   
   t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
-             build_and_jump (&l2));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_last (cont_bb);
@@ -2688,8 +2684,7 @@ expand_omp_for_generic (struct omp_region *region,
                       build_fold_addr_expr (istart0),
                       build_fold_addr_expr (iend0));
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
-             build_and_jump (&l3));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
   
   si = bsi_start (l2_bb);
@@ -2758,7 +2753,7 @@ static void
 expand_omp_for_static_nochunk (struct omp_region *region,
                               struct omp_for_data *fd)
 {
-  tree l0, l1, l2, n, q, s0, e0, e, t, nthreads, threadid;
+  tree n, q, s0, e0, e, t, nthreads, threadid;
   tree type, list;
   basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
   basic_block fin_bb;
@@ -2773,10 +2768,6 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   fin_bb = single_succ (cont_bb);
   exit_bb = region->exit;
 
-  l0 = tree_block_label (seq_start_bb);
-  l1 = tree_block_label (body_bb);
-  l2 = tree_block_label (fin_bb);
-
   /* Iteration space partitioning goes in ENTRY_BB.  */
   list = alloc_stmt_list ();
 
@@ -2827,8 +2818,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   e0 = get_formal_tmp_var (t, &list);
 
   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l2),
-             build_and_jump (&l0));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_last (entry_bb);
@@ -2862,8 +2852,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
 
   t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
-             build_and_jump (&l2));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_last (cont_bb);
@@ -2927,7 +2916,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
 static void
 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 {
-  tree l0, l1, l2, l3, l4, n, s0, e0, e, t;
+  tree n, s0, e0, e, t;
   tree trip, nthreads, threadid;
   tree type;
   basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
@@ -2946,12 +2935,6 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
   fin_bb = single_succ (cont_bb);
   exit_bb = region->exit;
 
-  l0 = tree_block_label (iter_part_bb);
-  l1 = tree_block_label (seq_start_bb);
-  l2 = tree_block_label (body_bb);
-  l3 = tree_block_label (trip_update_bb);
-  l4 = tree_block_label (fin_bb);
-
   /* Trip and adjustment setup goes in ENTRY_BB.  */
   list = alloc_stmt_list ();
 
@@ -3011,8 +2994,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
   e0 = get_formal_tmp_var (t, &list);
 
   t = build2 (LT_EXPR, boolean_type_node, s0, n);
-  t = build3 (COND_EXPR, void_type_node, t,
-             build_and_jump (&l1), build_and_jump (&l4));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
 
   si = bsi_start (iter_part_bb);
@@ -3045,8 +3027,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 
   t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
   t = get_formal_tmp_var (t, &list);
-  t = build3 (COND_EXPR, void_type_node, t,
-             build_and_jump (&l2), build_and_jump (&l3));
+  t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
   append_to_statement_list (t, &list);
   
   si = bsi_last (cont_bb);
@@ -4081,6 +4062,28 @@ lower_omp_for (tree *stmt_p, omp_context *ctx)
   *stmt_p = new_stmt;
 }
 
+/* Callback for walk_stmts.  Check if *TP only contains OMP_FOR
+   or OMP_PARALLEL.  */
+
+static tree
+check_combined_parallel (tree *tp, int *walk_subtrees, void *data)
+{
+  struct walk_stmt_info *wi = data;
+  int *info = wi->info;
+
+  *walk_subtrees = 0;
+  switch (TREE_CODE (*tp))
+    {
+    case OMP_FOR:
+    case OMP_SECTIONS:
+      *info = *info == 0 ? 1 : -1;
+      break;
+    default:
+      *info = -1;
+      break;
+    }
+  return NULL;
+}
 
 /* Lower the OpenMP parallel directive in *STMT_P.  CTX holds context
    information for the directive.  */
@@ -4098,6 +4101,19 @@ lower_omp_parallel (tree *stmt_p, omp_context *ctx)
   par_bind = OMP_PARALLEL_BODY (stmt);
   par_body = BIND_EXPR_BODY (par_bind);
   child_fn = ctx->cb.dst_fn;
+  if (!OMP_PARALLEL_COMBINED (stmt))
+    {
+      struct walk_stmt_info wi;
+      int ws_num = 0;
+
+      memset (&wi, 0, sizeof (wi));
+      wi.callback = check_combined_parallel;
+      wi.info = &ws_num;
+      wi.val_only = true;
+      walk_stmts (&wi, &par_bind);
+      if (ws_num == 1)
+       OMP_PARALLEL_COMBINED (stmt) = 1;
+    }
 
   push_gimplify_context ();