OSDN Git Service

PR 31567
[pf3gnuchains/gcc-fork.git] / gcc / omp-low.c
index b96da5f..3b99f69 100644 (file)
@@ -2318,14 +2318,14 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                                          name);
                  gimple_add_tmp_var (x);
                  TREE_ADDRESSABLE (x) = 1;
-                 x = build_fold_addr_expr_with_type (x, TREE_TYPE (new_var));
+                 x = build_fold_addr_expr (x);
                }
              else
                {
                  x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
-                 x = fold_convert (TREE_TYPE (new_var), x);
                }
 
+             x = fold_convert (TREE_TYPE (new_var), x);
              gimplify_assign (new_var, x, ilist);
 
              new_var = build_fold_indirect_ref (new_var);
@@ -3412,6 +3412,14 @@ expand_omp_taskreg (struct omp_region *region)
       /* Declare local variables needed in CHILD_CFUN.  */
       block = DECL_INITIAL (child_fn);
       BLOCK_VARS (block) = list2chain (child_cfun->local_decls);
+      /* The gimplifier could record temporaries in parallel/task block
+        rather than in containing function's local_decls chain,
+        which would mean cgraph missed finalizing them.  Do it now.  */
+      for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
+       if (TREE_CODE (t) == VAR_DECL
+           && TREE_STATIC (t)
+           && !DECL_EXTERNAL (t))
+         varpool_finalize_decl (t);
       DECL_SAVED_TREE (child_fn) = NULL;
       gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
       TREE_USED (block) = 1;
@@ -3495,6 +3503,8 @@ expand_omp_taskreg (struct omp_region *region)
          if (changed)
            cleanup_tree_cfg ();
        }
+      if (gimple_in_ssa_p (cfun))
+       update_ssa (TODO_update_ssa);
       current_function_decl = save_current;
       pop_cfun ();
     }
@@ -3802,21 +3812,25 @@ expand_omp_for_generic (struct omp_region *region,
 
   /* Iteration setup for sequential loop goes in L0_BB.  */
   gsi = gsi_start_bb (l0_bb);
+  t = istart0;
   if (bias)
-    t = fold_convert (type, fold_build2 (MINUS_EXPR, fd->iter_type,
-                                        istart0, bias));
-  else
-    t = fold_convert (type, istart0);
+    t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
+  if (POINTER_TYPE_P (type))
+    t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
+                                                     0), t);
+  t = fold_convert (type, t);
   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
                                false, GSI_CONTINUE_LINKING);
   stmt = gimple_build_assign (fd->loop.v, t);
   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
 
+  t = iend0;
   if (bias)
-    t = fold_convert (type, fold_build2 (MINUS_EXPR, fd->iter_type,
-                                        iend0, bias));
-  else
-    t = fold_convert (type, iend0);
+    t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
+  if (POINTER_TYPE_P (type))
+    t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
+                                                     0), t);
+  t = fold_convert (type, t);
   iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                   false, GSI_CONTINUE_LINKING);
   if (fd->collapse > 1)
@@ -3833,7 +3847,8 @@ expand_omp_for_generic (struct omp_region *region,
            itype = lang_hooks.types.type_for_size (TYPE_PRECISION (vtype), 0);
          t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
          t = fold_convert (itype, t);
-         t = fold_build2 (MULT_EXPR, itype, t, fd->loops[i].step);
+         t = fold_build2 (MULT_EXPR, itype, t,
+                          fold_convert (itype, fd->loops[i].step));
          if (POINTER_TYPE_P (vtype))
            t = fold_build2 (POINTER_PLUS_EXPR, vtype,
                             fd->loops[i].n1, fold_convert (sizetype, t));
@@ -5064,7 +5079,8 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
   /* Build the compare&swap statement.  */
   new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
   new_storedi = force_gimple_operand_gsi (&si,
-                                         fold_convert (itype, new_storedi),
+                                         fold_convert (TREE_TYPE (loadedi),
+                                                       new_storedi),
                                          true, NULL_TREE,
                                          true, GSI_SAME_STMT);
 
@@ -5072,7 +5088,7 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
     old_vali = loadedi;
   else
     {
-      old_vali = create_tmp_var (itype, NULL);
+      old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
       if (gimple_in_ssa_p (cfun))
        add_referenced_var (old_vali);
       stmt = gimple_build_assign (old_vali, loadedi);
@@ -5452,9 +5468,9 @@ struct gimple_opt_pass pass_expand_omp =
   NULL,                                        /* sub */
   NULL,                                        /* next */
   0,                                   /* static_pass_number */
-  0,                                   /* tv_id */
+  TV_NONE,                             /* tv_id */
   PROP_gimple_any,                     /* properties_required */
-  PROP_gimple_lomp,                    /* properties_provided */
+  0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_dump_func                       /* todo_flags_finish */
@@ -6575,6 +6591,11 @@ execute_lower_omp (void)
 {
   gimple_seq body;
 
+  /* This pass always runs, to provide PROP_gimple_lomp.
+     But there is nothing to do unless -fopenmp is given.  */
+  if (flag_openmp == 0)
+    return 0;
+
   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
                                 delete_omp_context);
 
@@ -6602,23 +6623,17 @@ execute_lower_omp (void)
   return 0;
 }
 
-static bool
-gate_lower_omp (void)
-{
-  return flag_openmp != 0;
-}
-
 struct gimple_opt_pass pass_lower_omp = 
 {
  {
   GIMPLE_PASS,
   "omplower",                          /* name */
-  gate_lower_omp,                      /* gate */
+  NULL,                                        /* gate */
   execute_lower_omp,                   /* execute */
   NULL,                                        /* sub */
   NULL,                                        /* next */
   0,                                   /* static_pass_number */
-  0,                                   /* tv_id */
+  TV_NONE,                             /* tv_id */
   PROP_gimple_any,                     /* properties_required */
   PROP_gimple_lomp,                    /* properties_provided */
   0,                                   /* properties_destroyed */