OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / gimplify.c
index c9498ee..af3d924 100644 (file)
@@ -1008,7 +1008,18 @@ gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p)
   for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
     {
       if (TREE_CODE (t) == VAR_DECL)
-       DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
+       {
+         struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
+
+         /* Mark variable as local.  */
+         if (ctx && !is_global_var (t)
+             && (! DECL_SEEN_IN_BIND_EXPR_P (t)
+                 || splay_tree_lookup (ctx->variables,
+                                       (splay_tree_key) t) == NULL))
+           omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN);
+
+         DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
+       }
 
       /* Preliminarily mark non-addressed complex variables as eligible
         for promotion to gimple registers.  We'll transform their uses
@@ -1020,16 +1031,6 @@ gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p)
        DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
     }
 
-  /* Mark variables seen in this bind expr as locals.  */
-  if (gimplify_omp_ctxp)
-    {
-      struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
-
-      for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
-       if (TREE_CODE (t) == VAR_DECL && !is_global_var (t))
-         omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
-    }
-
   gimple_push_bind_expr (bind_expr);
   gimplify_ctxp->save_stack = false;
 
@@ -1327,20 +1328,34 @@ gimplify_switch_expr (tree *expr_p, tree *pre_p)
       labels = gimplify_ctxp->case_labels;
       gimplify_ctxp->case_labels = saved_labels;
 
-      len = VEC_length (tree, labels);
-
-      for (i = 0; i < len; ++i)
+      i = 0;
+      while (i < VEC_length (tree, labels))
        {
-         tree t = VEC_index (tree, labels, i);
-         if (!CASE_LOW (t))
+         tree elt = VEC_index (tree, labels, i);
+         tree low = CASE_LOW (elt);
+         bool remove_element = FALSE;
+
+         if (low)
+           {
+             /* Discard empty ranges.  */
+             tree high = CASE_HIGH (elt);
+             if (high && INT_CST_LT (high, low))
+               remove_element = TRUE;
+           }
+         else
            {
              /* The default case must be the last label in the list.  */
-             default_case = t;
-             VEC_replace (tree, labels, i, VEC_index (tree, labels, len - 1));
-             len--;
-             break;
+             gcc_assert (!default_case);
+             default_case = elt;
+             remove_element = TRUE;
            }
+
+         if (remove_element)
+           VEC_ordered_remove (tree, labels, i);
+         else
+           i++;
        }
+      len = i;
 
       label_vec = make_tree_vec (len + 1);
       SWITCH_LABELS (*expr_p) = label_vec;
@@ -2325,7 +2340,7 @@ gimple_boolify (tree expr)
     default:
       /* Other expressions that get here must have boolean values, but
         might need to be converted to the appropriate mode.  */
-      return convert (boolean_type_node, expr);
+      return fold_convert (boolean_type_node, expr);
     }
 }
 
@@ -3027,7 +3042,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
        i = VEC_index (constructor_elt, elts, 1)->value;
        if (r == NULL || i == NULL)
          {
-           tree zero = convert (TREE_TYPE (type), integer_zero_node);
+           tree zero = fold_convert (TREE_TYPE (type), integer_zero_node);
            if (r == NULL)
              r = zero;
            if (i == NULL)
@@ -3530,8 +3545,8 @@ gimplify_boolean_expr (tree *expr_p)
   tree type = TREE_TYPE (*expr_p);
 
   *expr_p = build3 (COND_EXPR, type, *expr_p,
-                   convert (type, boolean_true_node),
-                   convert (type, boolean_false_node));
+                   fold_convert (type, boolean_true_node),
+                   fold_convert (type, boolean_false_node));
 
   return GS_OK;
 }
@@ -4489,6 +4504,11 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel)
              remove = true;
              break;
            }
+         /* Handle NRV results passed by reference.  */
+         if (TREE_CODE (decl) == INDIRECT_REF
+             && TREE_CODE (TREE_OPERAND (decl, 0)) == RESULT_DECL
+             && DECL_BY_REFERENCE (TREE_OPERAND (decl, 0)))
+           OMP_CLAUSE_DECL (c) = decl = TREE_OPERAND (decl, 0);
          omp_add_variable (ctx, decl, flags);
          if (TREE_CODE (c) == OMP_CLAUSE_REDUCTION
              && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
@@ -4516,13 +4536,22 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel)
              remove = true;
              break;
            }
+         /* Handle NRV results passed by reference.  */
+         if (TREE_CODE (decl) == INDIRECT_REF
+             && TREE_CODE (TREE_OPERAND (decl, 0)) == RESULT_DECL
+             && DECL_BY_REFERENCE (TREE_OPERAND (decl, 0)))
+           OMP_CLAUSE_DECL (c) = decl = TREE_OPERAND (decl, 0);
        do_notice:
          if (outer_ctx)
            omp_notice_variable (outer_ctx, decl, true);
          break;
 
-       case OMP_CLAUSE_SCHEDULE:
        case OMP_CLAUSE_IF:
+         OMP_CLAUSE_OPERAND (c, 0)
+           = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
+         /* Fall through.  */
+
+       case OMP_CLAUSE_SCHEDULE:
        case OMP_CLAUSE_NUM_THREADS:
          gs = gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
                              is_gimple_val, fb_rvalue);
@@ -5539,6 +5568,13 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          ret = gimplify_var_or_parm_decl (expr_p);
          break;
 
+       case RESULT_DECL:
+         /* When within an OpenMP context, notice uses of variables.  */
+         if (gimplify_omp_ctxp)
+           omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
+         ret = GS_ALL_DONE;
+         break;
+
        case SSA_NAME:
          /* Allow callbacks into the gimplifier during optimization.  */
          ret = GS_ALL_DONE;
@@ -5568,7 +5604,8 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          ret = gimplify_omp_atomic (expr_p, pre_p);
          break;
 
-       case OMP_RETURN_EXPR:
+       case OMP_RETURN:
+       case OMP_CONTINUE:
          ret = GS_ALL_DONE;
          break;
 
@@ -5684,7 +5721,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          /* Historically, the compiler has treated a bare
             reference to a volatile lvalue as forcing a load.  */
          tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
-         /* Normally, we do want to create a temporary for a
+         /* Normally, we do not want to create a temporary for a
             TREE_ADDRESSABLE type because such a type should not be
             copied by bitwise-assignment.  However, we make an
             exception here, as all we are doing here is ensuring that