Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / omp-low.c
index e5e128c..7440bef 100644 (file)
@@ -3,8 +3,7 @@
    marshalling to implement data sharing and copying clauses.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
-   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 2005-2013 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -34,7 +33,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "diagnostic-core.h"
 #include "tree-flow.h"
-#include "timevar.h"
 #include "flags.h"
 #include "function.h"
 #include "expr.h"
@@ -131,7 +129,7 @@ static int taskreg_nesting_level;
 struct omp_region *root_omp_region;
 static bitmap task_shared_vars;
 
-static void scan_omp (gimple_seq, omp_context *);
+static void scan_omp (gimple_seq *, omp_context *);
 static tree scan_omp_1_op (tree *, int *, void *);
 
 #define WALK_SUBSTMTS  \
@@ -158,7 +156,7 @@ scan_omp_op (tree *tp, omp_context *ctx)
   return walk_tree (tp, scan_omp_1_op, &wi, NULL);
 }
 
-static void lower_omp (gimple_seq, omp_context *);
+static void lower_omp (gimple_seq *, omp_context *);
 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
 
@@ -336,9 +334,11 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
       switch (TREE_CODE (t))
        {
        case PLUS_EXPR:
-       case POINTER_PLUS_EXPR:
          loop->step = TREE_OPERAND (t, 1);
          break;
+       case POINTER_PLUS_EXPR:
+         loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
+         break;
        case MINUS_EXPR:
          loop->step = TREE_OPERAND (t, 1);
          loop->step = fold_build1_loc (loc,
@@ -398,17 +398,21 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
 
       if (collapse_count && *collapse_count == NULL)
        {
-         if ((i == 0 || count != NULL_TREE)
-             && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
-             && TREE_CONSTANT (loop->n1)
-             && TREE_CONSTANT (loop->n2)
-             && TREE_CODE (loop->step) == INTEGER_CST)
+         t = fold_binary (loop->cond_code, boolean_type_node,
+                          fold_convert (TREE_TYPE (loop->v), loop->n1),
+                          fold_convert (TREE_TYPE (loop->v), loop->n2));
+         if (t && integer_zerop (t))
+           count = build_zero_cst (long_long_unsigned_type_node);
+         else if ((i == 0 || count != NULL_TREE)
+                  && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
+                  && TREE_CONSTANT (loop->n1)
+                  && TREE_CONSTANT (loop->n2)
+                  && TREE_CODE (loop->step) == INTEGER_CST)
            {
              tree itype = TREE_TYPE (loop->v);
 
              if (POINTER_TYPE_P (itype))
-               itype
-                 = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
+               itype = signed_type_for (itype);
              t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
              t = fold_build2_loc (loc,
                               PLUS_EXPR, itype,
@@ -436,7 +440,7 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
              if (TREE_CODE (count) != INTEGER_CST)
                count = NULL_TREE;
            }
-         else
+         else if (count && !integer_zerop (count))
            count = NULL_TREE;
        }
     }
@@ -551,12 +555,12 @@ workshare_safe_to_combine_p (basic_block ws_entry_bb)
    parallel+workshare call.  WS_STMT is the workshare directive being
    expanded.  */
 
-static VEC(tree,gc) *
+static vec<tree, va_gc> *
 get_ws_args_for (gimple ws_stmt)
 {
   tree t;
   location_t loc = gimple_location (ws_stmt);
-  VEC(tree,gc) *ws_args;
+  vec<tree, va_gc> *ws_args;
 
   if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
     {
@@ -564,21 +568,21 @@ get_ws_args_for (gimple ws_stmt)
 
       extract_omp_for_data (ws_stmt, &fd, NULL);
 
-      ws_args = VEC_alloc (tree, gc, 3 + (fd.chunk_size != 0));
+      vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
 
       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
-      VEC_quick_push (tree, ws_args, t);
+      ws_args->quick_push (t);
 
       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
-      VEC_quick_push (tree, ws_args, t);
+      ws_args->quick_push (t);
 
       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
-      VEC_quick_push (tree, ws_args, t);
+      ws_args->quick_push (t);
 
       if (fd.chunk_size)
        {
          t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
-         VEC_quick_push (tree, ws_args, t);
+         ws_args->quick_push (t);
        }
 
       return ws_args;
@@ -590,8 +594,8 @@ get_ws_args_for (gimple ws_stmt)
         the exit of the sections region.  */
       basic_block bb = single_succ (gimple_bb (ws_stmt));
       t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
-      ws_args = VEC_alloc (tree, gc, 1);
-      VEC_quick_push (tree, ws_args, t);
+      vec_alloc (ws_args, 1);
+      ws_args->quick_push (t);
       return ws_args;
     }
 
@@ -1250,8 +1254,8 @@ static void
 finalize_task_copyfn (gimple task_stmt)
 {
   struct function *child_cfun;
-  tree child_fn, old_fn;
-  gimple_seq seq, new_seq;
+  tree child_fn;
+  gimple_seq seq = NULL, new_seq;
   gimple bind;
 
   child_fn = gimple_omp_task_copy_fn (task_stmt);
@@ -1262,24 +1266,20 @@ finalize_task_copyfn (gimple task_stmt)
 
   /* Inform the callgraph about the new function.  */
   DECL_STRUCT_FUNCTION (child_fn)->curr_properties
-    = cfun->curr_properties;
+    = cfun->curr_properties & ~PROP_loops;
 
-  old_fn = current_function_decl;
   push_cfun (child_cfun);
-  current_function_decl = child_fn;
   bind = gimplify_body (child_fn, false);
-  seq = gimple_seq_alloc ();
   gimple_seq_add_stmt (&seq, bind);
   new_seq = maybe_catch_exception (seq);
   if (new_seq != seq)
     {
       bind = gimple_build_bind (NULL, new_seq, NULL);
-      seq = gimple_seq_alloc ();
+      seq = NULL;
       gimple_seq_add_stmt (&seq, bind);
     }
   gimple_set_body (child_fn, seq);
   pop_cfun ();
-  current_function_decl = old_fn;
 
   cgraph_add_new_function (child_fn, false);
 }
@@ -1540,12 +1540,12 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
          && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
        {
-         scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
-         scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
+         scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
+         scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
        }
       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
               && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
-       scan_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+       scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
 }
 
 /* Create a new name for omp child function.  Returns an identifier.  */
@@ -1670,7 +1670,7 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
   gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
 
   scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_omp_body_ptr (stmt), ctx);
 
   if (TYPE_FIELDS (ctx->record_type) == NULL)
     ctx->record_type = ctx->receiver_decl = NULL;
@@ -1727,7 +1727,7 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
       create_omp_child_function (ctx, true);
     }
 
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_omp_body_ptr (stmt), ctx);
 
   if (TYPE_FIELDS (ctx->record_type) == NULL)
     {
@@ -1780,7 +1780,7 @@ scan_omp_for (gimple stmt, omp_context *outer_ctx)
 
   scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
 
-  scan_omp (gimple_omp_for_pre_body (stmt), ctx);
+  scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
     {
       scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
@@ -1788,7 +1788,7 @@ scan_omp_for (gimple stmt, omp_context *outer_ctx)
       scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
       scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
     }
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_omp_body_ptr (stmt), ctx);
 }
 
 /* Scan an OpenMP sections directive.  */
@@ -1800,7 +1800,7 @@ scan_omp_sections (gimple stmt, omp_context *outer_ctx)
 
   ctx = new_omp_context (stmt, outer_ctx);
   scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_omp_body_ptr (stmt), ctx);
 }
 
 /* Scan an OpenMP single directive.  */
@@ -1820,7 +1820,7 @@ scan_omp_single (gimple stmt, omp_context *outer_ctx)
   TYPE_NAME (ctx->record_type) = name;
 
   scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
-  scan_omp (gimple_omp_body (stmt), ctx);
+  scan_omp (gimple_omp_body_ptr (stmt), ctx);
 
   if (TYPE_FIELDS (ctx->record_type) == NULL)
     ctx->record_type = NULL;
@@ -2047,7 +2047,7 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_CRITICAL:
       ctx = new_omp_context (stmt, ctx);
-      scan_omp (gimple_omp_body (stmt), ctx);
+      scan_omp (gimple_omp_body_ptr (stmt), ctx);
       break;
 
     case GIMPLE_BIND:
@@ -2074,7 +2074,7 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
    clauses found during the scan.  */
 
 static void
-scan_omp (gimple_seq body, omp_context *ctx)
+scan_omp (gimple_seq *body_p, omp_context *ctx)
 {
   location_t saved_location;
   struct walk_stmt_info wi;
@@ -2084,7 +2084,7 @@ scan_omp (gimple_seq body, omp_context *ctx)
   wi.want_locations = true;
 
   saved_location = input_location;
-  walk_gimple_seq (body, scan_omp_1_stmt, scan_omp_1_op, &wi);
+  walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
   input_location = saved_location;
 }
 \f
@@ -2265,14 +2265,11 @@ static void
 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                         omp_context *ctx)
 {
-  gimple_stmt_iterator diter;
   tree c, dtor, copyin_seq, x, ptr;
   bool copyin_by_ref = false;
   bool lastprivate_firstprivate = false;
   int pass;
 
-  *dlist = gimple_seq_alloc ();
-  diter = gsi_start (*dlist);
   copyin_seq = NULL;
 
   /* Do all the fixed sized types in the first pass, and the variable sized
@@ -2461,7 +2458,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 
                  dtor = x;
                  gimplify_stmt (&dtor, &tseq);
-                 gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
+                 gimple_seq_add_seq (dlist, tseq);
                }
              break;
 
@@ -2504,7 +2501,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
                    x = build_fold_addr_expr_loc (clause_loc, x);
                  SET_DECL_VALUE_EXPR (placeholder, x);
                  DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
-                 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
+                 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
                  gimple_seq_add_seq (ilist,
                                      OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
                  OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
@@ -2608,7 +2605,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
 
          if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
            {
-             lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+             lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
              gimple_seq_add_seq (stmt_list,
                                  OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
            }
@@ -2712,7 +2709,7 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
            ref = build_fold_addr_expr_loc (clause_loc, ref);
          SET_DECL_VALUE_EXPR (placeholder, ref);
          DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
-         lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
+         lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
          gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
          OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
          OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
@@ -2951,7 +2948,7 @@ gimple_build_cond_empty (tree cond)
 
 static void
 expand_parallel_call (struct omp_region *region, basic_block bb,
-                     gimple entry_stmt, VEC(tree,gc) *ws_args)
+                     gimple entry_stmt, vec<tree, va_gc> *ws_args)
 {
   tree t, t1, t2, val, cond, c, clauses;
   gimple_stmt_iterator gsi;
@@ -2959,7 +2956,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
   enum built_in_function start_ix;
   int start_ix2;
   location_t clause_loc;
-  VEC(tree,gc) *args;
+  vec<tree, va_gc> *args;
 
   clauses = gimple_omp_parallel_clauses (entry_stmt);
 
@@ -3070,7 +3067,6 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
          if (gimple_in_ssa_p (cfun))
            {
              gimple phi = create_phi_node (tmp_join, bb);
-             SSA_NAME_DEF_STMT (tmp_join) = phi;
              add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
              add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
            }
@@ -3091,11 +3087,12 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
     t1 = build_fold_addr_expr (t);
   t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
 
-  args = VEC_alloc (tree, gc, 3 + VEC_length (tree, ws_args));
-  VEC_quick_push (tree, args, t2);
-  VEC_quick_push (tree, args, t1);
-  VEC_quick_push (tree, args, val);
-  VEC_splice (tree, args, ws_args);
+  vec_alloc (args, 3 + vec_safe_length (ws_args));
+  args->quick_push (t2);
+  args->quick_push (t1);
+  args->quick_push (val);
+  if (ws_args)
+    args->splice (*ws_args);
 
   t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
                               builtin_decl_explicit (start_ix), args);
@@ -3205,12 +3202,12 @@ maybe_catch_exception (gimple_seq body)
 /* Chain all the DECLs in LIST by their TREE_CHAIN fields.  */
 
 static tree
-vec2chain (VEC(tree,gc) *v)
+vec2chain (vec<tree, va_gc> *v)
 {
   tree chain = NULL_TREE, t;
   unsigned ix;
 
-  FOR_EACH_VEC_ELT_REVERSE (tree, v, ix, t)
+  FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
     {
       DECL_CHAIN (t) = chain;
       chain = t;
@@ -3392,6 +3389,25 @@ optimize_omp_library_calls (gimple entry_stmt)
       }
 }
 
+/* Callback for expand_omp_build_assign.  Return non-NULL if *tp needs to be
+   regimplified.  */
+
+static tree
+expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
+{
+  tree t = *tp;
+
+  /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
+  if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
+    return t;
+
+  if (TREE_CODE (t) == ADDR_EXPR)
+    recompute_tree_invariant_for_addr_expr (t);
+
+  *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
+  return NULL_TREE;
+}
+
 /* Expand the OpenMP parallel or task directive starting at REGION.  */
 
 static void
@@ -3400,18 +3416,14 @@ expand_omp_taskreg (struct omp_region *region)
   basic_block entry_bb, exit_bb, new_bb;
   struct function *child_cfun;
   tree child_fn, block, t;
-  tree save_current;
   gimple_stmt_iterator gsi;
   gimple entry_stmt, stmt;
   edge e;
-  VEC(tree,gc) *ws_args;
+  vec<tree, va_gc> *ws_args;
 
   entry_stmt = last_stmt (region->entry);
   child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
-  /* If this function has been already instrumented, make sure
-     the child function isn't instrumented again.  */
-  child_cfun->after_tree_profile = cfun->after_tree_profile;
 
   entry_bb = region->entry;
   exit_bb = region->exit;
@@ -3513,9 +3525,9 @@ expand_omp_taskreg (struct omp_region *region)
              /* If we are in ssa form, we must load the value from the default
                 definition of the argument.  That should not be defined now,
                 since the argument is not used uninitialized.  */
-             gcc_assert (gimple_default_def (cfun, arg) == NULL);
+             gcc_assert (ssa_default_def (cfun, arg) == NULL);
              narg = make_ssa_name (arg, gimple_build_nop ());
-             set_default_def (arg, narg);
+             set_ssa_default_def (cfun, arg, narg);
              /* ?? Is setting the subcode really necessary ??  */
              gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
              gimple_assign_set_rhs1 (parcopy_stmt, narg);
@@ -3535,7 +3547,8 @@ expand_omp_taskreg (struct omp_region *region)
            && !DECL_EXTERNAL (t))
          varpool_finalize_decl (t);
       DECL_SAVED_TREE (child_fn) = NULL;
-      gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
+      /* We'll create a CFG for child_fn, so no gimple body is needed.  */
+      gimple_set_body (child_fn, NULL);
       TREE_USED (block) = 1;
 
       /* Reset DECL_CONTEXT on function arguments.  */
@@ -3568,11 +3581,9 @@ expand_omp_taskreg (struct omp_region *region)
 
       if (gimple_in_ssa_p (cfun))
        {
-         push_cfun (child_cfun);
          init_tree_ssa (child_cfun);
-         init_ssa_operands ();
-         cfun->gimple_df->in_ssa_p = true;
-         pop_cfun ();
+         init_ssa_operands (child_cfun);
+         child_cfun->gimple_df->in_ssa_p = true;
          block = NULL_TREE;
        }
       else
@@ -3583,29 +3594,27 @@ expand_omp_taskreg (struct omp_region *region)
        single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
 
       /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
-      num = VEC_length (tree, child_cfun->local_decls);
+      num = vec_safe_length (child_cfun->local_decls);
       for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
        {
-         t = VEC_index (tree, child_cfun->local_decls, srcidx);
+         t = (*child_cfun->local_decls)[srcidx];
          if (DECL_CONTEXT (t) == cfun->decl)
            continue;
          if (srcidx != dstidx)
-           VEC_replace (tree, child_cfun->local_decls, dstidx, t);
+           (*child_cfun->local_decls)[dstidx] = t;
          dstidx++;
        }
       if (dstidx != num)
-       VEC_truncate (tree, child_cfun->local_decls, dstidx);
+       vec_safe_truncate (child_cfun->local_decls, dstidx);
 
       /* Inform the callgraph about the new function.  */
       DECL_STRUCT_FUNCTION (child_fn)->curr_properties
-       = cfun->curr_properties;
+       = cfun->curr_properties & ~PROP_loops;
       cgraph_add_new_function (child_fn, true);
 
       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
         fixed in a following pass.  */
       push_cfun (child_cfun);
-      save_current = current_function_decl;
-      current_function_decl = child_fn;
       if (optimize)
        optimize_omp_library_calls (entry_stmt);
       rebuild_cgraph_edges ();
@@ -3626,7 +3635,6 @@ expand_omp_taskreg (struct omp_region *region)
        }
       if (gimple_in_ssa_p (cfun))
        update_ssa (TODO_update_ssa);
-      current_function_decl = save_current;
       pop_cfun ();
     }
 
@@ -3635,7 +3643,8 @@ expand_omp_taskreg (struct omp_region *region)
     expand_parallel_call (region, new_bb, entry_stmt, ws_args);
   else
     expand_task_call (new_bb, entry_stmt);
-  update_ssa (TODO_update_ssa_only_virtuals);
+  if (gimple_in_ssa_p (cfun))
+    update_ssa (TODO_update_ssa_only_virtuals);
 }
 
 
@@ -3671,22 +3680,29 @@ expand_omp_taskreg (struct omp_region *region)
 
     we generate pseudocode
 
+       if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
        if (cond3 is <)
          adj = STEP3 - 1;
        else
          adj = STEP3 + 1;
        count3 = (adj + N32 - N31) / STEP3;
+       if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
        if (cond2 is <)
          adj = STEP2 - 1;
        else
          adj = STEP2 + 1;
        count2 = (adj + N22 - N21) / STEP2;
+       if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
        if (cond1 is <)
          adj = STEP1 - 1;
        else
          adj = STEP1 + 1;
        count1 = (adj + N12 - N11) / STEP1;
        count = count1 * count2 * count3;
+       goto Z1;
+    Z0:
+       count = 0;
+    Z1:
        more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
        if (more) goto L0; else goto L3;
     L0:
@@ -3746,11 +3762,6 @@ expand_omp_for_generic (struct omp_region *region,
   iend0 = create_tmp_var (fd->iter_type, ".iend0");
   TREE_ADDRESSABLE (istart0) = 1;
   TREE_ADDRESSABLE (iend0) = 1;
-  if (gimple_in_ssa_p (cfun))
-    {
-      add_referenced_var (istart0);
-      add_referenced_var (iend0);
-    }
 
   /* See if we need to bias by LLONG_MIN.  */
   if (fd->iter_type == long_long_unsigned_type_node
@@ -3799,6 +3810,9 @@ expand_omp_for_generic (struct omp_region *region,
   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
   if (fd->collapse > 1)
     {
+      basic_block zero_iter_bb = NULL;
+      int first_zero_iter = -1;
+
       /* collapsed loops need work for expansion in SSA form.  */
       gcc_assert (!gimple_in_ssa_p (cfun));
       counts = (tree *) alloca (fd->collapse * sizeof (tree));
@@ -3806,8 +3820,53 @@ expand_omp_for_generic (struct omp_region *region,
        {
          tree itype = TREE_TYPE (fd->loops[i].v);
 
+         if (SSA_VAR_P (fd->loop.n2)
+             && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
+                                   fold_convert (itype, fd->loops[i].n1),
+                                   fold_convert (itype, fd->loops[i].n2)))
+                 == NULL_TREE || !integer_onep (t)))
+           {
+             tree n1, n2;
+             n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
+             n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
+                                            true, GSI_SAME_STMT);
+             n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
+             n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
+                                            true, GSI_SAME_STMT);
+             stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
+                                       NULL_TREE, NULL_TREE);
+             gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+             if (walk_tree (gimple_cond_lhs_ptr (stmt),
+                            expand_omp_regimplify_p, NULL, NULL)
+                 || walk_tree (gimple_cond_rhs_ptr (stmt),
+                               expand_omp_regimplify_p, NULL, NULL))
+               {
+                 gsi = gsi_for_stmt (stmt);
+                 gimple_regimplify_operands (stmt, &gsi);
+               }
+             e = split_block (entry_bb, stmt);
+             if (zero_iter_bb == NULL)
+               {
+                 first_zero_iter = i;
+                 zero_iter_bb = create_empty_bb (entry_bb);
+                 if (current_loops)
+                   add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
+                 gsi = gsi_after_labels (zero_iter_bb);
+                 stmt = gimple_build_assign (fd->loop.n2,
+                                             build_zero_cst (type));
+                 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+                 set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
+                                          entry_bb);
+               }
+             ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
+             ne->probability = REG_BR_PROB_BASE / 2000 - 1;
+             e->flags = EDGE_TRUE_VALUE;
+             e->probability = REG_BR_PROB_BASE - ne->probability;
+             entry_bb = e->dest;
+             gsi = gsi_last_bb (entry_bb);
+           }
          if (POINTER_TYPE_P (itype))
-           itype = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
+           itype = signed_type_for (itype);
          t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
                                     ? -1 : 1));
          t = fold_build2 (PLUS_EXPR, itype,
@@ -3830,7 +3889,7 @@ expand_omp_for_generic (struct omp_region *region,
            counts[i] = t;
          else
            {
-             counts[i] = create_tmp_var (type, ".count");
+             counts[i] = create_tmp_reg (type, ".count");
              t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
                                            true, GSI_SAME_STMT);
              stmt = gimple_build_assign (counts[i], t);
@@ -3850,6 +3909,23 @@ expand_omp_for_generic (struct omp_region *region,
              gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
            }
        }
+      if (zero_iter_bb)
+       {
+         /* Some counts[i] vars might be uninitialized if
+            some loop has zero iterations.  But the body shouldn't
+            be executed in that case, so just avoid uninit warnings.  */
+         for (i = first_zero_iter; i < fd->collapse; i++)
+           if (SSA_VAR_P (counts[i]))
+             TREE_NO_WARNING (counts[i]) = 1;
+         gsi_prev (&gsi);
+         e = split_block (entry_bb, gsi_stmt (gsi));
+         entry_bb = e->dest;
+         make_edge (zero_iter_bb, entry_bb, EDGE_FALLTHRU);
+         gsi = gsi_last_bb (entry_bb);
+         set_immediate_dominator (CDI_DOMINATORS, entry_bb,
+                                  get_immediate_dominator (CDI_DOMINATORS,
+                                                           zero_iter_bb));
+       }
     }
   if (in_combined_parallel)
     {
@@ -3871,8 +3947,7 @@ expand_omp_for_generic (struct omp_region *region,
          && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
        {
          /* Avoid casting pointers to integer of a different size.  */
-         tree itype
-           = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
+         tree itype = signed_type_for (type);
          t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
          t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
        }
@@ -3939,11 +4014,12 @@ expand_omp_for_generic (struct omp_region *region,
   if (bias)
     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 (signed_type_for (type), t);
   t = fold_convert (type, t);
-  t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                               false, GSI_CONTINUE_LINKING);
+  t = force_gimple_operand_gsi (&gsi, t,
+                               DECL_P (fd->loop.v)
+                               && TREE_ADDRESSABLE (fd->loop.v),
+                               NULL_TREE, false, GSI_CONTINUE_LINKING);
   stmt = gimple_build_assign (fd->loop.v, t);
   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
 
@@ -3951,15 +4027,13 @@ expand_omp_for_generic (struct omp_region *region,
   if (bias)
     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 (signed_type_for (type), t);
   t = fold_convert (type, t);
   iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                   false, GSI_CONTINUE_LINKING);
   if (fd->collapse > 1)
     {
-      tree tem = create_tmp_var (type, ".tem");
-
+      tree tem = create_tmp_reg (type, ".tem");
       stmt = gimple_build_assign (tem, fd->loop.v);
       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
       for (i = fd->collapse - 1; i >= 0; i--)
@@ -3967,7 +4041,7 @@ expand_omp_for_generic (struct omp_region *region,
          tree vtype = TREE_TYPE (fd->loops[i].v), itype;
          itype = vtype;
          if (POINTER_TYPE_P (vtype))
-           itype = lang_hooks.types.type_for_size (TYPE_PRECISION (vtype), 0);
+           itype = signed_type_for (vtype);
          t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
          t = fold_convert (itype, t);
          t = fold_build2 (MULT_EXPR, itype, t,
@@ -3976,8 +4050,11 @@ expand_omp_for_generic (struct omp_region *region,
            t = fold_build_pointer_plus (fd->loops[i].n1, t);
          else
            t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
-         t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                       false, GSI_CONTINUE_LINKING);
+         t = force_gimple_operand_gsi (&gsi, t,
+                                       DECL_P (fd->loops[i].v)
+                                       && TREE_ADDRESSABLE (fd->loops[i].v),
+                                       NULL_TREE, false,
+                                       GSI_CONTINUE_LINKING);
          stmt = gimple_build_assign (fd->loops[i].v, t);
          gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
          if (i != 0)
@@ -4005,12 +4082,15 @@ expand_omp_for_generic (struct omp_region *region,
        t = fold_build_pointer_plus (vmain, fd->loop.step);
       else
        t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
-      t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                   true, GSI_SAME_STMT);
+      t = force_gimple_operand_gsi (&gsi, t,
+                                   DECL_P (vback) && TREE_ADDRESSABLE (vback),
+                                   NULL_TREE, true, GSI_SAME_STMT);
       stmt = gimple_build_assign (vback, t);
       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
 
-      t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
+      t = build2 (fd->loop.cond_code, boolean_type_node,
+                 DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
+                 iend);
       stmt = gimple_build_cond_empty (t);
       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
 
@@ -4035,8 +4115,12 @@ expand_omp_for_generic (struct omp_region *region,
                  e->probability = REG_BR_PROB_BASE / 8;
 
                  t = fd->loops[i + 1].n1;
-                 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                               false, GSI_CONTINUE_LINKING);
+                 t = force_gimple_operand_gsi (&gsi, t,
+                                               DECL_P (fd->loops[i + 1].v)
+                                               && TREE_ADDRESSABLE
+                                                       (fd->loops[i + 1].v),
+                                               NULL_TREE, false,
+                                               GSI_CONTINUE_LINKING);
                  stmt = gimple_build_assign (fd->loops[i + 1].v, t);
                  gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
                }
@@ -4050,8 +4134,11 @@ expand_omp_for_generic (struct omp_region *region,
              else
                t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
                                 fd->loops[i].step);
-             t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                                           false, GSI_CONTINUE_LINKING);
+             t = force_gimple_operand_gsi (&gsi, t,
+                                           DECL_P (fd->loops[i].v)
+                                           && TREE_ADDRESSABLE (fd->loops[i].v),
+                                           NULL_TREE, false,
+                                           GSI_CONTINUE_LINKING);
              stmt = gimple_build_assign (fd->loops[i].v, t);
              gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
 
@@ -4060,8 +4147,12 @@ expand_omp_for_generic (struct omp_region *region,
                  t = fd->loops[i].n2;
                  t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                                false, GSI_CONTINUE_LINKING);
+                 tree v = fd->loops[i].v;
+                 if (DECL_P (v) && TREE_ADDRESSABLE (v))
+                   v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
+                                                 false, GSI_CONTINUE_LINKING);
                  t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
-                                  fd->loops[i].v, t);
+                                  v, t);
                  stmt = gimple_build_cond_empty (t);
                  gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
                  e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
@@ -4154,6 +4245,7 @@ expand_omp_for_generic (struct omp_region *region,
 
    where COND is "<" or ">", we generate pseudocode
 
+       if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
        if (cond is <)
          adj = STEP - 1;
        else
@@ -4197,7 +4289,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
 
   itype = type = TREE_TYPE (fd->loop.v);
   if (POINTER_TYPE_P (type))
-    itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
+    itype = signed_type_for (type);
 
   entry_bb = region->entry;
   cont_bb = region->cont;
@@ -4214,6 +4306,50 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   gsi = gsi_last_bb (entry_bb);
   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
 
+  t = fold_binary (fd->loop.cond_code, boolean_type_node,
+                  fold_convert (type, fd->loop.n1),
+                  fold_convert (type, fd->loop.n2));
+  if (TYPE_UNSIGNED (type)
+      && (t == NULL_TREE || !integer_onep (t)))
+    {
+      tree n1, n2;
+      n1 = fold_convert (type, unshare_expr (fd->loop.n1));
+      n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
+                                    true, GSI_SAME_STMT);
+      n2 = fold_convert (type, unshare_expr (fd->loop.n2));
+      n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
+                                    true, GSI_SAME_STMT);
+      stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
+                               NULL_TREE, NULL_TREE);
+      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+      if (walk_tree (gimple_cond_lhs_ptr (stmt),
+                    expand_omp_regimplify_p, NULL, NULL)
+         || walk_tree (gimple_cond_rhs_ptr (stmt),
+                       expand_omp_regimplify_p, NULL, NULL))
+       {
+         gsi = gsi_for_stmt (stmt);
+         gimple_regimplify_operands (stmt, &gsi);
+       }
+      ep = split_block (entry_bb, stmt);
+      ep->flags = EDGE_TRUE_VALUE;
+      entry_bb = ep->dest;
+      ep->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
+      ep = make_edge (ep->src, fin_bb, EDGE_FALSE_VALUE);
+      ep->probability = REG_BR_PROB_BASE / 2000 - 1;
+      if (gimple_in_ssa_p (cfun))
+       {
+         int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
+         for (gsi = gsi_start_phis (fin_bb);
+              !gsi_end_p (gsi); gsi_next (&gsi))
+           {
+             gimple phi = gsi_stmt (gsi);
+             add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
+                          ep, UNKNOWN_LOCATION);
+           }
+       }
+      gsi = gsi_last_bb (entry_bb);
+    }
+
   t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
   t = fold_convert (itype, t);
   nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
@@ -4247,12 +4383,12 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   t = fold_convert (itype, t);
   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
 
-  q = create_tmp_var (itype, "q");
+  q = create_tmp_reg (itype, "q");
   t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
   gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
 
-  tt = create_tmp_var (itype, "tt");
+  tt = create_tmp_reg (itype, "tt");
   t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
   gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
@@ -4297,8 +4433,10 @@ expand_omp_for_static_nochunk (struct omp_region *region,
     t = fold_build_pointer_plus (fd->loop.n1, t);
   else
     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
-  t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                               false, GSI_CONTINUE_LINKING);
+  t = force_gimple_operand_gsi (&gsi, t,
+                               DECL_P (fd->loop.v)
+                               && TREE_ADDRESSABLE (fd->loop.v),
+                               NULL_TREE, false, GSI_CONTINUE_LINKING);
   stmt = gimple_build_assign (fd->loop.v, t);
   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
 
@@ -4323,12 +4461,14 @@ expand_omp_for_static_nochunk (struct omp_region *region,
     t = fold_build_pointer_plus (vmain, fd->loop.step);
   else
     t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
-  t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
-                               true, GSI_SAME_STMT);
+  t = force_gimple_operand_gsi (&gsi, t,
+                               DECL_P (vback) && TREE_ADDRESSABLE (vback),
+                               NULL_TREE, true, GSI_SAME_STMT);
   stmt = gimple_build_assign (vback, t);
   gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
 
-  t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
+  t = build2 (fd->loop.cond_code, boolean_type_node,
+             DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback, e);
   gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
 
   /* Remove the GIMPLE_OMP_CONTINUE statement.  */
@@ -4371,6 +4511,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
 
    where COND is "<" or ">", we generate pseudocode
 
+       if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
        if (cond is <)
          adj = STEP - 1;
        else
@@ -4414,7 +4555,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 
   itype = type = TREE_TYPE (fd->loop.v);
   if (POINTER_TYPE_P (type))
-    itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
+    itype = signed_type_for (type);
 
   entry_bb = region->entry;
   se = split_block (entry_bb, last_stmt (entry_bb));
@@ -4436,6 +4577,50 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
   si = gsi_last_bb (entry_bb);
   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
 
+  t = fold_binary (fd->loop.cond_code, boolean_type_node,
+                  fold_convert (type, fd->loop.n1),
+                  fold_convert (type, fd->loop.n2));
+  if (TYPE_UNSIGNED (type)
+      && (t == NULL_TREE || !integer_onep (t)))
+    {
+      tree n1, n2;
+      n1 = fold_convert (type, unshare_expr (fd->loop.n1));
+      n1 = force_gimple_operand_gsi (&si, n1, true, NULL_TREE,
+                                    true, GSI_SAME_STMT);
+      n2 = fold_convert (type, unshare_expr (fd->loop.n2));
+      n2 = force_gimple_operand_gsi (&si, n2, true, NULL_TREE,
+                                    true, GSI_SAME_STMT);
+      stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
+                               NULL_TREE, NULL_TREE);
+      gsi_insert_before (&si, stmt, GSI_SAME_STMT);
+      if (walk_tree (gimple_cond_lhs_ptr (stmt),
+                    expand_omp_regimplify_p, NULL, NULL)
+         || walk_tree (gimple_cond_rhs_ptr (stmt),
+                       expand_omp_regimplify_p, NULL, NULL))
+       {
+         si = gsi_for_stmt (stmt);
+         gimple_regimplify_operands (stmt, &si);
+       }
+      se = split_block (entry_bb, stmt);
+      se->flags = EDGE_TRUE_VALUE;
+      entry_bb = se->dest;
+      se->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
+      se = make_edge (se->src, fin_bb, EDGE_FALSE_VALUE);
+      se->probability = REG_BR_PROB_BASE / 2000 - 1;
+      if (gimple_in_ssa_p (cfun))
+       {
+         int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
+         for (si = gsi_start_phis (fin_bb);
+              !gsi_end_p (si); gsi_next (&si))
+           {
+             gimple phi = gsi_stmt (si);
+             add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
+                          se, UNKNOWN_LOCATION);
+           }
+       }
+      si = gsi_last_bb (entry_bb);
+    }
+
   t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
   t = fold_convert (itype, t);
   nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
@@ -4473,10 +4658,9 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
   n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
                                true, GSI_SAME_STMT);
 
-  trip_var = create_tmp_var (itype, ".trip");
+  trip_var = create_tmp_reg (itype, ".trip");
   if (gimple_in_ssa_p (cfun))
     {
-      add_referenced_var (trip_var);
       trip_init = make_ssa_name (trip_var, NULL);
       trip_main = make_ssa_name (trip_var, NULL);
       trip_back = make_ssa_name (trip_var, NULL);
@@ -4529,8 +4713,10 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
     t = fold_build_pointer_plus (fd->loop.n1, t);
   else
     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
-  t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
-                               false, GSI_CONTINUE_LINKING);
+  t = force_gimple_operand_gsi (&si, t,
+                               DECL_P (fd->loop.v)
+                               && TREE_ADDRESSABLE (fd->loop.v),
+                               NULL_TREE, false, GSI_CONTINUE_LINKING);
   stmt = gimple_build_assign (fd->loop.v, t);
   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
 
@@ -4555,10 +4741,15 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
     t = fold_build_pointer_plus (v_main, fd->loop.step);
   else
     t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
+  if (DECL_P (v_back) && TREE_ADDRESSABLE (v_back))
+    t = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+                                 true, GSI_SAME_STMT);
   stmt = gimple_build_assign (v_back, t);
   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
 
-  t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
+  t = build2 (fd->loop.cond_code, boolean_type_node,
+             DECL_P (v_back) && TREE_ADDRESSABLE (v_back)
+             ? t : v_back, e);
   gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
 
   /* Remove GIMPLE_OMP_CONTINUE.  */
@@ -4593,7 +4784,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
       gimple_stmt_iterator psi;
       gimple phi;
       edge re, ene;
-      edge_var_map_vector head;
+      edge_var_map_vector *head;
       edge_var_map *vm;
       size_t i;
 
@@ -4606,7 +4797,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
       ene = single_succ_edge (entry_bb);
 
       psi = gsi_start_phis (fin_bb);
-      for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
+      for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
           gsi_next (&psi), ++i)
        {
          gimple nphi;
@@ -4616,7 +4807,6 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
          t = gimple_phi_result (phi);
          gcc_assert (t == redirect_edge_var_map_result (vm));
          nphi = create_phi_node (t, iter_part_bb);
-         SSA_NAME_DEF_STMT (t) = nphi;
 
          t = PHI_ARG_DEF_FROM_EDGE (phi, se);
          locus = gimple_phi_arg_location_from_edge (phi, se);
@@ -4629,7 +4819,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
          locus = redirect_edge_var_map_location (vm);
          add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
        }
-      gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
+      gcc_assert (!gsi_end_p (psi) && i == head->length ());
       redirect_edge_var_map_clear (re);
       while (1)
        {
@@ -4641,7 +4831,6 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 
       /* Make phi node for trip.  */
       phi = create_phi_node (trip_main, iter_part_bb);
-      SSA_NAME_DEF_STMT (trip_main) = phi;
       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
                   UNKNOWN_LOCATION);
       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
@@ -4719,7 +4908,8 @@ expand_omp_for (struct omp_region *region)
                              (enum built_in_function) next_ix);
     }
 
-  update_ssa (TODO_update_ssa_only_virtuals);
+  if (gimple_in_ssa_p (cfun))
+    update_ssa (TODO_update_ssa_only_virtuals);
 }
 
 
@@ -4754,7 +4944,7 @@ static void
 expand_omp_sections (struct omp_region *region)
 {
   tree t, u, vin = NULL, vmain, vnext, l2;
-  VEC (tree,heap) *label_vec;
+  vec<tree> label_vec;
   unsigned len;
   basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
   gimple_stmt_iterator si, switch_si;
@@ -4805,9 +4995,9 @@ expand_omp_sections (struct omp_region *region)
      and a default case to abort if something goes wrong.  */
   len = EDGE_COUNT (l0_bb->succs);
 
-  /* Use VEC_quick_push on label_vec throughout, since we know the size
+  /* Use vec::quick_push on label_vec throughout, since we know the size
      in advance.  */
-  label_vec = VEC_alloc (tree, heap, len);
+  label_vec.create (len);
 
   /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
      GIMPLE_OMP_SECTIONS statement.  */
@@ -4852,7 +5042,7 @@ expand_omp_sections (struct omp_region *region)
     }
 
   t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
-  VEC_quick_push (tree, label_vec, t);
+  label_vec.quick_push (t);
   i = 1;
 
   /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR.  */
@@ -4876,7 +5066,7 @@ expand_omp_sections (struct omp_region *region)
       t = gimple_block_label (s_entry_bb);
       u = build_int_cst (unsigned_type_node, casei);
       u = build_case_label (u, NULL, t);
-      VEC_quick_push (tree, label_vec, u);
+      label_vec.quick_push (u);
 
       si = gsi_last_bb (s_entry_bb);
       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
@@ -4899,10 +5089,10 @@ expand_omp_sections (struct omp_region *region)
   u = build_case_label (NULL, NULL, t);
   make_edge (l0_bb, default_bb, 0);
 
-  stmt = gimple_build_switch_vec (vmain, u, label_vec);
+  stmt = gimple_build_switch (vmain, u, label_vec);
   gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
   gsi_remove (&switch_si, true);
-  VEC_free (tree, heap, label_vec);
+  label_vec.release ();
 
   si = gsi_start_bb (default_bb);
   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
@@ -5312,7 +5502,7 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
     {
       tree iaddr_val;
 
-      iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
+      iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
                                                           true), NULL);
       iaddr_val
        = force_gimple_operand_gsi (&si,
@@ -5322,11 +5512,7 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
       loadedi = create_tmp_var (itype, NULL);
       if (gimple_in_ssa_p (cfun))
-       {
-         add_referenced_var (iaddr);
-         add_referenced_var (loadedi);
-         loadedi = make_ssa_name (loadedi, NULL);
-       }
+       loadedi = make_ssa_name (loadedi, NULL);
     }
   else
     {
@@ -5346,7 +5532,6 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
     {
       gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
       phi = create_phi_node (loadedi, loop_header);
-      SSA_NAME_DEF_STMT (loadedi) = phi;
       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
               initial);
     }
@@ -5403,8 +5588,6 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
   else
     {
       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);
       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
 
@@ -5793,6 +5976,7 @@ struct gimple_opt_pass pass_expand_omp =
  {
   GIMPLE_PASS,
   "ompexp",                            /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   gate_expand_omp,                     /* gate */
   execute_expand_omp,                  /* execute */
   NULL,                                        /* sub */
@@ -5817,9 +6001,8 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 {
   tree block, control;
   gimple_stmt_iterator tgsi;
-  unsigned i, len;
   gimple stmt, new_stmt, bind, t;
-  gimple_seq ilist, dlist, olist, new_body, body;
+  gimple_seq ilist, dlist, olist, new_body;
   struct gimplify_ctx gctx;
 
   stmt = gsi_stmt (*gsi_p);
@@ -5831,13 +6014,10 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
                           &ilist, &dlist, ctx);
 
-  tgsi = gsi_start (gimple_omp_body (stmt));
-  for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
-    continue;
-
-  tgsi = gsi_start (gimple_omp_body (stmt));
-  body = NULL;
-  for (i = 0; i < len; i++, gsi_next (&tgsi))
+  new_body = gimple_omp_body (stmt);
+  gimple_omp_set_body (stmt, NULL);
+  tgsi = gsi_start (new_body);
+  for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
     {
       omp_context *sctx;
       gimple sec_start;
@@ -5846,32 +6026,33 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
       sctx = maybe_lookup_ctx (sec_start);
       gcc_assert (sctx);
 
-      gimple_seq_add_stmt (&body, sec_start);
-
-      lower_omp (gimple_omp_body (sec_start), sctx);
-      gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
+      lower_omp (gimple_omp_body_ptr (sec_start), sctx);
+      gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
+                           GSI_CONTINUE_LINKING);
       gimple_omp_set_body (sec_start, NULL);
 
-      if (i == len - 1)
+      if (gsi_one_before_end_p (tgsi))
        {
          gimple_seq l = NULL;
          lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
                                     &l, ctx);
-         gimple_seq_add_seq (&body, l);
+         gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
          gimple_omp_section_set_last (sec_start);
        }
 
-      gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
+      gsi_insert_after (&tgsi, gimple_build_omp_return (false),
+                       GSI_CONTINUE_LINKING);
     }
 
   block = make_node (BLOCK);
-  bind = gimple_build_bind (NULL, body, block);
+  bind = gimple_build_bind (NULL, new_body, block);
 
   olist = NULL;
   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
 
   block = make_node (BLOCK);
   new_stmt = gimple_build_bind (NULL, NULL, block);
+  gsi_replace (gsi_p, new_stmt, true);
 
   pop_gimplify_context (new_stmt);
   gimple_bind_append_vars (new_stmt, ctx->block_vars);
@@ -5901,9 +6082,6 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   gimple_seq_add_stmt (&new_body, t);
 
   gimple_bind_set_body (new_stmt, new_body);
-  gimple_omp_set_body (stmt, NULL);
-
-  gsi_replace (gsi_p, new_stmt, true);
 }
 
 
@@ -6036,10 +6214,14 @@ lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   push_gimplify_context (&gctx);
 
+  block = make_node (BLOCK);
+  bind = gimple_build_bind (NULL, NULL, block);
+  gsi_replace (gsi_p, bind, true);
   bind_body = NULL;
+  dlist = NULL;
   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
                           &bind_body, &dlist, ctx);
-  lower_omp (gimple_omp_body (single_stmt), ctx);
+  lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
 
   gimple_seq_add_stmt (&bind_body, single_stmt);
 
@@ -6058,15 +6240,12 @@ lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
         (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
                            OMP_CLAUSE_NOWAIT));
   gimple_seq_add_stmt (&bind_body, t);
-
-  block = make_node (BLOCK);
-  bind = gimple_build_bind (NULL, bind_body, block);
+  gimple_bind_set_body (bind, bind_body);
 
   pop_gimplify_context (bind);
 
   gimple_bind_append_vars (bind, ctx->block_vars);
   BLOCK_VARS (block) = ctx->block_vars;
-  gsi_replace (gsi_p, bind, true);
   if (BLOCK_VARS (block))
     TREE_USED (block) = 1;
 }
@@ -6086,8 +6265,9 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   push_gimplify_context (&gctx);
 
   block = make_node (BLOCK);
-  bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
-                                block);
+  bind = gimple_build_bind (NULL, NULL, block);
+  gsi_replace (gsi_p, bind, true);
+  gimple_bind_add_stmt (bind, stmt);
 
   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
   x = build_call_expr_loc (loc, bfn_decl, 0);
@@ -6097,7 +6277,7 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   gimplify_and_add (x, &tseq);
   gimple_bind_add_seq (bind, tseq);
 
-  lower_omp (gimple_omp_body (stmt), ctx);
+  lower_omp (gimple_omp_body_ptr (stmt), ctx);
   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
   gimple_omp_set_body (stmt, NULL);
@@ -6110,7 +6290,6 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   gimple_bind_append_vars (bind, ctx->block_vars);
   BLOCK_VARS (block) = ctx->block_vars;
-  gsi_replace (gsi_p, bind, true);
 }
 
 
@@ -6126,14 +6305,15 @@ lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   push_gimplify_context (&gctx);
 
   block = make_node (BLOCK);
-  bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
-                                  block);
+  bind = gimple_build_bind (NULL, NULL, block);
+  gsi_replace (gsi_p, bind, true);
+  gimple_bind_add_stmt (bind, stmt);
 
   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
                         0);
   gimple_bind_add_stmt (bind, x);
 
-  lower_omp (gimple_omp_body (stmt), ctx);
+  lower_omp (gimple_omp_body_ptr (stmt), ctx);
   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
   gimple_omp_set_body (stmt, NULL);
@@ -6147,7 +6327,6 @@ lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   gimple_bind_append_vars (bind, ctx->block_vars);
   BLOCK_VARS (block) = gimple_bind_vars (bind);
-  gsi_replace (gsi_p, bind, true);
 }
 
 
@@ -6223,13 +6402,15 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   push_gimplify_context (&gctx);
 
   block = make_node (BLOCK);
-  bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
+  bind = gimple_build_bind (NULL, NULL, block);
+  gsi_replace (gsi_p, bind, true);
+  gimple_bind_add_stmt (bind, stmt);
 
   tbody = gimple_bind_body (bind);
   gimplify_and_add (lock, &tbody);
   gimple_bind_set_body (bind, tbody);
 
-  lower_omp (gimple_omp_body (stmt), ctx);
+  lower_omp (gimple_omp_body_ptr (stmt), ctx);
   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
   gimple_omp_set_body (stmt, NULL);
@@ -6243,7 +6424,6 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   pop_gimplify_context (bind);
   gimple_bind_append_vars (bind, ctx->block_vars);
   BLOCK_VARS (block) = gimple_bind_vars (bind);
-  gsi_replace (gsi_p, bind, true);
 }
 
 
@@ -6311,11 +6491,15 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   push_gimplify_context (&gctx);
 
-  lower_omp (gimple_omp_for_pre_body (stmt), ctx);
-  lower_omp (gimple_omp_body (stmt), ctx);
+  lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
+  lower_omp (gimple_omp_body_ptr (stmt), ctx);
 
   block = make_node (BLOCK);
   new_stmt = gimple_build_bind (NULL, NULL, block);
+  /* Replace at gsi right away, so that 'stmt' is no member
+     of a sequence anymore as we're going to add to to a different
+     one below.  */
+  gsi_replace (gsi_p, new_stmt, true);
 
   /* Move declaration of temporaries in the loop body before we make
      it go away.  */
@@ -6385,7 +6569,6 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   gimple_bind_set_body (new_stmt, body);
   gimple_omp_set_body (stmt, NULL);
   gimple_omp_for_set_pre_body (stmt, NULL);
-  gsi_replace (gsi_p, new_stmt, true);
 }
 
 /* Callback for walk_stmts.  Check if the current statement only contains
@@ -6490,7 +6673,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
 
   /* Populate the function.  */
   push_gimplify_context (&gctx);
-  current_function_decl = child_fn;
+  push_cfun (child_cfun);
 
   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
   TREE_SIDE_EFFECTS (bind) = 1;
@@ -6537,8 +6720,6 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
   else
     tcctx.cb.decl_map = NULL;
 
-  push_cfun (child_cfun);
-
   arg = DECL_ARGUMENTS (child_fn);
   TREE_TYPE (arg) = build_pointer_type (record_type);
   sarg = DECL_CHAIN (arg);
@@ -6696,7 +6877,6 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
   pop_gimplify_context (NULL);
   BIND_EXPR_BODY (bind) = list;
   pop_cfun ();
-  current_function_decl = ctx->cb.src_fn;
 }
 
 /* Lower the OpenMP parallel or task directive in the current statement
@@ -6738,7 +6918,7 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   par_olist = NULL;
   par_ilist = NULL;
   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
-  lower_omp (par_body, ctx);
+  lower_omp (&par_body, ctx);
   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
     lower_reduction_clauses (clauses, &par_olist, ctx);
 
@@ -6784,15 +6964,10 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   gimple_omp_set_body (stmt, new_body);
 
   bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
-  gimple_bind_add_stmt (bind, stmt);
-  if (ilist || olist)
-    {
-      gimple_seq_add_stmt (&ilist, bind);
-      gimple_seq_add_seq (&ilist, olist);
-      bind = gimple_build_bind (NULL, ilist, NULL);
-    }
-
   gsi_replace (gsi_p, bind, true);
+  gimple_bind_add_seq (bind, ilist);
+  gimple_bind_add_stmt (bind, stmt);
+  gimple_bind_add_seq (bind, olist);
 
   pop_gimplify_context (NULL);
 }
@@ -6857,20 +7032,20 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
        gimple_regimplify_operands (stmt, gsi_p);
       break;
     case GIMPLE_CATCH:
-      lower_omp (gimple_catch_handler (stmt), ctx);
+      lower_omp (gimple_catch_handler_ptr (stmt), ctx);
       break;
     case GIMPLE_EH_FILTER:
-      lower_omp (gimple_eh_filter_failure (stmt), ctx);
+      lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
       break;
     case GIMPLE_TRY:
-      lower_omp (gimple_try_eval (stmt), ctx);
-      lower_omp (gimple_try_cleanup (stmt), ctx);
+      lower_omp (gimple_try_eval_ptr (stmt), ctx);
+      lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
       break;
     case GIMPLE_TRANSACTION:
-      lower_omp (gimple_transaction_body (stmt), ctx);
+      lower_omp (gimple_transaction_body_ptr (stmt), ctx);
       break;
     case GIMPLE_BIND:
-      lower_omp (gimple_bind_body (stmt), ctx);
+      lower_omp (gimple_bind_body_ptr (stmt), ctx);
       break;
     case GIMPLE_OMP_PARALLEL:
     case GIMPLE_OMP_TASK:
@@ -6923,11 +7098,11 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 }
 
 static void
-lower_omp (gimple_seq body, omp_context *ctx)
+lower_omp (gimple_seq *body, omp_context *ctx)
 {
   location_t saved_location = input_location;
-  gimple_stmt_iterator gsi = gsi_start (body);
-  for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
+  gimple_stmt_iterator gsi;
+  for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
     lower_omp_1 (&gsi, ctx);
   input_location = saved_location;
 }
@@ -6948,7 +7123,7 @@ execute_lower_omp (void)
                                 delete_omp_context);
 
   body = gimple_body (current_function_decl);
-  scan_omp (body, NULL);
+  scan_omp (&body, NULL);
   gcc_assert (taskreg_nesting_level == 0);
 
   if (all_contexts->root)
@@ -6957,7 +7132,7 @@ execute_lower_omp (void)
 
       if (task_shared_vars)
        push_gimplify_context (&gctx);
-      lower_omp (body, NULL);
+      lower_omp (&body, NULL);
       if (task_shared_vars)
        pop_gimplify_context (NULL);
     }
@@ -6976,6 +7151,7 @@ struct gimple_opt_pass pass_lower_omp =
  {
   GIMPLE_PASS,
   "omplower",                          /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   NULL,                                        /* gate */
   execute_lower_omp,                   /* execute */
   NULL,                                        /* sub */
@@ -7135,7 +7311,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_CRITICAL:
       wi->info = stmt;
-      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+      walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
       wi->info = context;
       break;
 
@@ -7143,9 +7319,9 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
       wi->info = stmt;
       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
         walk them.  */
-      walk_gimple_seq (gimple_omp_for_pre_body (stmt),
-                      diagnose_sb_2, NULL, wi);
-      walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+      walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
+                          diagnose_sb_2, NULL, wi);
+      walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
       wi->info = context;
       break;
 
@@ -7218,7 +7394,9 @@ diagnose_omp_structured_block_errors (void)
 
   memset (&wi, 0, sizeof (wi));
   wi.want_locations = true;
-  walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
+  walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
+
+  gimple_set_body (current_function_decl, body);
 
   splay_tree_delete (all_labels);
   all_labels = NULL;
@@ -7237,6 +7415,7 @@ struct gimple_opt_pass pass_diagnose_omp_blocks =
   {
     GIMPLE_PASS,
     "*diagnose_omp_blocks",            /* name */
+    OPTGROUP_NONE,                      /* optinfo_flags */
     gate_diagnose_omp_blocks,          /* gate */
     diagnose_omp_structured_block_errors,      /* execute */
     NULL,                              /* sub */