OSDN Git Service

* gcc.dg/asm-b.c: Fix comment typos.
[pf3gnuchains/gcc-fork.git] / gcc / gimplify.c
index 55889ea..d461d77 100644 (file)
@@ -1,6 +1,6 @@
 /* Tree lowering pass.  This pass converts the GENERIC functions-as-trees
    tree representation into the GIMPLE form.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Major work done by Sebastian Pop <s.pop@laposte.net>,
    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
 
@@ -293,6 +293,7 @@ create_artificial_label (void)
   tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
 
   DECL_ARTIFICIAL (lab) = 1;
+  DECL_IGNORED_P (lab) = 1;
   DECL_CONTEXT (lab) = current_function_decl;
   return lab;
 }
@@ -996,7 +997,12 @@ gimplify_decl_expr (tree *stmt_p)
             of the emitted code: see mx_register_decls().  */
          tree t, args, addr, ptr_type;
 
-         gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+         /* ??? We really shouldn't need to gimplify the type of the variable
+            since it already should have been done.  But leave this here
+            for now to avoid disrupting too many things at once.  */
+         if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
+           gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+
          gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
          gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
 
@@ -1427,8 +1433,15 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
   VARRAY_GENERIC_PTR_NOGC_INIT (stack, 10, "stack");
 
   /* We can handle anything that get_inner_reference can deal with.  */
-  for (p = expr_p; handled_component_p (*p); p = &TREE_OPERAND (*p, 0))
-    VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p);
+  for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
+    {
+      /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
+      if (TREE_CODE (*p) == INDIRECT_REF)
+       *p = fold_indirect_ref (*p);
+      if (!handled_component_p (*p))
+       break;
+      VARRAY_PUSH_GENERIC_PTR_NOGC (stack, *p);
+    }
 
   gcc_assert (VARRAY_ACTIVE_SIZE (stack));
 
@@ -1742,7 +1755,8 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
          return GS_OK;
        }
 
-      if (DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START)
+      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+         && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START)
         {
          tree arglist = TREE_OPERAND (*expr_p, 1);
          
@@ -1904,7 +1918,7 @@ shortcut_cond_expr (tree expr)
   tree true_label, false_label, end_label, t;
   tree *true_label_p;
   tree *false_label_p;
-  bool emit_end, emit_false;
+  bool emit_end, emit_false, jump_over_else;
   bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
   bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
 
@@ -1916,6 +1930,7 @@ shortcut_cond_expr (tree expr)
        {
          TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
          then_ = shortcut_cond_expr (expr);
+         then_se = then_ && TREE_SIDE_EFFECTS (then_);
          pred = TREE_OPERAND (pred, 0);
          expr = build (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
        }
@@ -1930,6 +1945,7 @@ shortcut_cond_expr (tree expr)
        {
          TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
          else_ = shortcut_cond_expr (expr);
+         else_se = else_ && TREE_SIDE_EFFECTS (else_);
          pred = TREE_OPERAND (pred, 0);
          expr = build (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
        }
@@ -2006,6 +2022,16 @@ shortcut_cond_expr (tree expr)
   emit_end = (end_label == NULL_TREE);
   emit_false = (false_label == NULL_TREE);
 
+  /* We only emit the jump over the else clause if we have to--if the
+     then clause may fall through.  Otherwise we can wind up with a
+     useless jump and a useless label at the end of gimplified code,
+     which will cause us to think that this conditional as a whole
+     falls through even if it doesn't.  If we then inline a function
+     which ends with such a condition, that can cause us to issue an
+     inappropriate warning about control reaching the end of a
+     non-void function.  */
+  jump_over_else = block_may_fallthru (then_);
+
   pred = shortcut_cond_r (pred, true_label_p, false_label_p);
 
   expr = NULL;
@@ -2014,8 +2040,11 @@ shortcut_cond_expr (tree expr)
   append_to_statement_list (then_, &expr);
   if (else_se)
     {
-      t = build_and_jump (&end_label);
-      append_to_statement_list (t, &expr);
+      if (jump_over_else)
+       {
+         t = build_and_jump (&end_label);
+         append_to_statement_list (t, &expr);
+       }
       if (emit_false)
        {
          t = build1 (LABEL_EXPR, void_type_node, false_label);
@@ -2088,10 +2117,13 @@ gimple_boolify (tree expr)
     TARGET is the tree for T1 above.
 
     PRE_P points to the list where side effects that must happen before
-       *EXPR_P should be stored.  */
+       *EXPR_P should be stored.
+
+   POST_P points to the list where side effects that must happen after
+     *EXPR_P should be stored.  */
 
 static enum gimplify_status
-gimplify_cond_expr (tree *expr_p, tree *pre_p, tree target)
+gimplify_cond_expr (tree *expr_p, tree *pre_p, tree *post_p, tree target)
 {
   tree expr = *expr_p;
   tree tmp, tmp2, type;
@@ -2107,7 +2139,7 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, tree target)
     {
       if (target)
        {
-         ret = gimplify_expr (&target, pre_p, NULL,
+         ret = gimplify_expr (&target, pre_p, post_p,
                               is_gimple_min_lval, fb_lvalue);
          if (ret != GS_ERROR)
            ret = GS_OK;
@@ -2367,6 +2399,95 @@ gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
   *expr_p = get_formal_tmp_var (*expr_p, pre_p);
 }
 
+/* A subroutine of gimplify_init_ctor_eval.  Create a loop for
+   a RANGE_EXPR in a CONSTRUCTOR for an array.
+
+      var = lower;
+    loop_entry:
+      object[var] = value;
+      if (var == upper)
+       goto loop_exit;
+      var = var + 1;
+      goto loop_entry;
+    loop_exit:
+
+   We increment var _after_ the loop exit check because we might otherwise
+   fail if upper == TYPE_MAX_VALUE (type for upper).
+
+   Note that we never have to deal with SAVE_EXPRs here, because this has
+   already been taken care of for us, in gimplify_init_ctor_preeval().  */
+
+static void gimplify_init_ctor_eval (tree, tree, tree *, bool);
+
+static void
+gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
+                              tree value, tree array_elt_type,
+                              tree *pre_p, bool cleared)
+{
+  tree loop_entry_label, loop_exit_label;
+  tree var, var_type, cref;
+
+  loop_entry_label = create_artificial_label ();
+  loop_exit_label = create_artificial_label ();
+
+  /* Create and initialize the index variable.  */
+  var_type = TREE_TYPE (upper);
+  var = create_tmp_var (var_type, NULL);
+  append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, lower), pre_p);
+
+  /* Add the loop entry label.  */
+  append_to_statement_list (build1 (LABEL_EXPR,
+                                   void_type_node,
+                                   loop_entry_label),
+                           pre_p);
+
+  /* Build the reference.  */
+  cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
+                var, NULL_TREE, NULL_TREE);
+
+  /* If we are a constructor, just call gimplify_init_ctor_eval to do
+     the store.  Otherwise just assign value to the reference.  */
+
+  if (TREE_CODE (value) == CONSTRUCTOR)
+    /* NB we might have to call ourself recursively through
+       gimplify_init_ctor_eval if the value is a constructor.  */
+    gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
+                            pre_p, cleared);
+  else
+    append_to_statement_list (build2 (MODIFY_EXPR, TREE_TYPE (cref),
+                                     cref, value),
+                             pre_p);
+
+  /* We exit the loop when the index var is equal to the upper bound.  */
+  gimplify_and_add (build3 (COND_EXPR, void_type_node,
+                           build2 (EQ_EXPR, boolean_type_node,
+                                   var, upper),
+                           build1 (GOTO_EXPR,
+                                   void_type_node,
+                                   loop_exit_label),
+                           NULL_TREE),
+                   pre_p);
+
+  /* Otherwise, increment the index var...  */
+  append_to_statement_list (build2 (MODIFY_EXPR, var_type, var,
+                                   build2 (PLUS_EXPR, var_type, var,
+                                           fold_convert (var_type,
+                                                         integer_one_node))),
+                           pre_p);
+
+  /* ...and jump back to the loop entry.  */
+  append_to_statement_list (build1 (GOTO_EXPR,
+                                   void_type_node,
+                                   loop_entry_label),
+                           pre_p);
+
+  /* Add the loop exit label.  */
+  append_to_statement_list (build1 (LABEL_EXPR,
+                                   void_type_node,
+                                   loop_exit_label),
+                           pre_p);
+}
+
 /* A subroutine of gimplify_init_constructor.  Generate individual
    MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
    assignments should happen.  LIST is the CONSTRUCTOR_ELTS of the
@@ -2395,14 +2516,31 @@ gimplify_init_ctor_eval (tree object, tree list, tree *pre_p, bool cleared)
       if (cleared && initializer_zerop (value))
        continue;
 
-      if (array_elt_type)
+      /* ??? Here's to hoping the front end fills in all of the indices,
+        so we don't have to figure out what's missing ourselves.  */
+      gcc_assert (purpose);
+
+      /* If we have a RANGE_EXPR, we have to build a loop to assign the
+        whole range.  */
+      if (TREE_CODE (purpose) == RANGE_EXPR)
        {
-         /* ??? Here's to hoping the front end fills in all of the indicies,
-            so we don't have to figure out what's missing ourselves.  */
-         gcc_assert (purpose);
-         /* ??? Need to handle this.  */
-         gcc_assert (TREE_CODE (purpose) != RANGE_EXPR);
+         tree lower = TREE_OPERAND (purpose, 0);
+         tree upper = TREE_OPERAND (purpose, 1);
 
+         /* If the lower bound is equal to upper, just treat it as if
+            upper was the index.  */
+         if (simple_cst_equal (lower, upper))
+           purpose = upper;
+         else
+           {
+             gimplify_init_ctor_eval_range (object, lower, upper, value,
+                                            array_elt_type, pre_p, cleared);
+             continue;
+           }
+       }
+
+      if (array_elt_type)
+       {
          cref = build (ARRAY_REF, array_elt_type, unshare_expr (object),
                        purpose, NULL_TREE, NULL_TREE);
        }
@@ -2458,8 +2596,8 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
     case ARRAY_TYPE:
       {
        struct gimplify_init_ctor_preeval_data preeval_data;
-       HOST_WIDE_INT num_elements, num_nonzero_elements;
-       HOST_WIDE_INT num_nonconstant_elements;
+       HOST_WIDE_INT num_type_elements, num_ctor_elements;
+       HOST_WIDE_INT num_nonzero_elements, num_nonconstant_elements;
        bool cleared;
 
        /* Aggregate types must lower constructors to initialization of
@@ -2469,11 +2607,13 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
          break;
 
        categorize_ctor_elements (ctor, &num_nonzero_elements,
-                                 &num_nonconstant_elements);
+                                 &num_nonconstant_elements,
+                                 &num_ctor_elements, &cleared);
 
        /* If a const aggregate variable is being initialized, then it
           should never be a lose to promote the variable to be static.  */
        if (num_nonconstant_elements == 0
+           && num_nonzero_elements > 1
            && TREE_READONLY (object)
            && TREE_CODE (object) == VAR_DECL)
          {
@@ -2552,12 +2692,11 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
           parts in, then generate code for the non-constant parts.  */
        /* TODO.  There's code in cp/typeck.c to do this.  */
 
-       num_elements = count_type_elements (TREE_TYPE (ctor));
+       num_type_elements = count_type_elements (TREE_TYPE (ctor));
 
        /* If there are "lots" of zeros, then block clear the object first.  */
-       cleared = false;
-       if (num_elements - num_nonzero_elements > CLEAR_RATIO
-           && num_nonzero_elements < num_elements/4)
+       if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
+           && num_nonzero_elements < num_type_elements/4)
          cleared = true;
 
        /* ??? This bit ought not be needed.  For any element not present
@@ -2565,19 +2704,8 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
           we'd need to *find* the elements that are not present, and that
           requires trickery to avoid quadratic compile-time behavior in
           large cases or excessive memory use in small cases.  */
-       else
-         {
-           HOST_WIDE_INT len = list_length (elt_list);
-           if (TREE_CODE (type) == ARRAY_TYPE)
-             {
-               tree nelts = array_type_nelts (type);
-               if (!host_integerp (nelts, 1)
-                   || tree_low_cst (nelts, 1) + 1 != len)
-                 cleared = true;
-             }
-           else if (len != fields_length (type))
-             cleared = true;
-         }
+       else if (num_ctor_elements < num_type_elements)
+         cleared = true;
 
        if (cleared)
          {
@@ -2590,14 +2718,20 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
            append_to_statement_list (*expr_p, pre_p);
          }
 
-       preeval_data.lhs_base_decl = get_base_address (object);
-       if (!DECL_P (preeval_data.lhs_base_decl))
-         preeval_data.lhs_base_decl = NULL;
-       preeval_data.lhs_alias_set = get_alias_set (object);
-
-       gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
-                                   pre_p, post_p, &preeval_data);
-       gimplify_init_ctor_eval (object, elt_list, pre_p, cleared);
+       /* If we have not block cleared the object, or if there are nonzero
+          elements in the constructor, add assignments to the individual
+          scalar fields of the object.  */
+       if (!cleared || num_nonzero_elements > 0)
+         {
+           preeval_data.lhs_base_decl = get_base_address (object);
+           if (!DECL_P (preeval_data.lhs_base_decl))
+             preeval_data.lhs_base_decl = NULL;
+           preeval_data.lhs_alias_set = get_alias_set (object);
+
+           gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
+                                       pre_p, post_p, &preeval_data);
+           gimplify_init_ctor_eval (object, elt_list, pre_p, cleared);
+         }
 
        *expr_p = NULL_TREE;
       }
@@ -2649,20 +2783,33 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
     case VECTOR_TYPE:
       /* Go ahead and simplify constant constructors to VECTOR_CST.  */
       if (TREE_CONSTANT (ctor))
-       TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list);
-      else
        {
-         /* Vector types use CONSTRUCTOR all the way through gimple
-            compilation as a general initializer.  */
-         for (; elt_list; elt_list = TREE_CHAIN (elt_list))
+         tree tem;
+
+         /* Even when ctor is constant, it might contain non-*_CST
+            elements (e.g. { 1.0/0.0 - 1.0/0.0, 0.0 }) and those don't
+            belong into VECTOR_CST nodes.  */
+         for (tem = elt_list; tem; tem = TREE_CHAIN (tem))
+           if (! CONSTANT_CLASS_P (TREE_VALUE (tem)))
+             break;
+
+         if (! tem)
            {
-             enum gimplify_status tret;
-             tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p,
-                                   is_gimple_val, fb_rvalue);
-             if (tret == GS_ERROR)
-               ret = GS_ERROR;
+             TREE_OPERAND (*expr_p, 1) = build_vector (type, elt_list);
+             break;
            }
        }
+
+      /* Vector types use CONSTRUCTOR all the way through gimple
+        compilation as a general initializer.  */
+      for (; elt_list; elt_list = TREE_CHAIN (elt_list))
+       {
+         enum gimplify_status tret;
+         tret = gimplify_expr (&TREE_VALUE (elt_list), pre_p, post_p,
+                               is_gimple_val, fb_rvalue);
+         if (tret == GS_ERROR)
+           ret = GS_ERROR;
+       }
       break;
 
     default:
@@ -2694,6 +2841,28 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
   while (ret != GS_UNHANDLED)
     switch (TREE_CODE (*from_p))
       {
+      case INDIRECT_REF:
+       {
+         /* If we have code like 
+
+               *(const A*)(A*)&x
+
+            where the type of "x" is a (possibly cv-qualified variant
+            of "A"), treat the entire expression as identical to "x".
+            This kind of code arises in C++ when an object is bound
+            to a const reference, and if "x" is a TARGET_EXPR we want
+            to take advantage of the optimization below.  */
+         tree t = fold_indirect_ref (*from_p);
+         if (t != *from_p)
+           {
+             *from_p = t;
+             ret = GS_OK;
+           }
+         else
+           ret = GS_UNHANDLED;
+         break;
+       }
+
       case TARGET_EXPR:
        {
          /* If we are initializing something from a TARGET_EXPR, strip the
@@ -2738,7 +2907,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
        if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
          {
            *expr_p = *from_p;
-           return gimplify_cond_expr (expr_p, pre_p, *to_p);
+           return gimplify_cond_expr (expr_p, pre_p, post_p, *to_p);
          }
        else
          ret = GS_UNHANDLED;
@@ -3124,10 +3293,6 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
   bool allows_mem, allows_reg, is_inout;
   enum gimplify_status ret, tret;
 
-  ASM_STRING (expr)
-    = resolve_asm_operand_names (ASM_STRING (expr), ASM_OUTPUTS (expr),
-                                ASM_INPUTS (expr));
-
   ret = GS_ALL_DONE;
   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
     {
@@ -3380,7 +3545,7 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
          ret = GS_OK;
           if (TREE_CODE (init) == BIND_EXPR)
            gimplify_bind_expr (&init, temp, pre_p);
-          if (init != temp)
+         if (init != temp)
            {
              init = build (MODIFY_EXPR, void_type_node, temp, init);
              ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
@@ -3556,7 +3721,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          break;
 
        case COND_EXPR:
-         ret = gimplify_cond_expr (expr_p, pre_p, NULL_TREE);
+         ret = gimplify_cond_expr (expr_p, pre_p, post_p, NULL_TREE);
          break;
 
        case CALL_EXPR:
@@ -3631,9 +3796,13 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          recalculate_side_effects (*expr_p);
          break;
 
+       case INDIRECT_REF:
+         *expr_p = fold_indirect_ref (*expr_p);
+         if (*expr_p != save_expr)
+           break;
+         /* else fall through.  */
        case ALIGN_INDIRECT_REF:
        case MISALIGNED_INDIRECT_REF:
-       case INDIRECT_REF:
          ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
                               is_gimple_reg, fb_rvalue);
          recalculate_side_effects (*expr_p);
@@ -4078,7 +4247,17 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
 void
 gimplify_type_sizes (tree type, tree *list_p)
 {
-  tree field;
+  tree field, t;
+
+  /* Note that we do not check for TYPE_SIZES_GIMPLIFIED already set because
+     that's not supposed to happen on types where gimplification does anything.
+     We should assert that it isn't set, but we can indeed be called multiple
+     times on pointers.  Unfortunately, this includes fat pointers which we
+     can't easily test for.  We could pass TYPE down to gimplify_one_sizepos
+     and test there, but it doesn't seem worth it.  */
+
+  /* We first do the main variant, then copy into any other variants. */
+  type = TYPE_MAIN_VARIANT (type);
 
   switch (TREE_CODE (type))
     {
@@ -4092,11 +4271,22 @@ gimplify_type_sizes (tree type, tree *list_p)
     case REAL_TYPE:
       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
+
+      for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+       {
+         TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
+         TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
+         TYPE_SIZES_GIMPLIFIED (t) = 1;
+       }
       break;
 
     case ARRAY_TYPE:
-      /* These anonymous types don't have declarations, so handle them here.  */
-      gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
+      /* These types may not have declarations, so handle them here.  */
+      if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (type)))
+       gimplify_type_sizes (TREE_TYPE (type), list_p);
+
+      if (!TYPE_SIZES_GIMPLIFIED (TYPE_DOMAIN (type)))
+         gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
       break;
 
     case RECORD_TYPE:
@@ -4113,9 +4303,19 @@ gimplify_type_sizes (tree type, tree *list_p)
 
   gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
+
+  for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+    {
+      TYPE_SIZE (t) = TYPE_SIZE (type);
+      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
+      TYPE_SIZES_GIMPLIFIED (t) = 1;
+    }
+
+  TYPE_SIZES_GIMPLIFIED (type) = 1;
 }
 
-/* Subroutine of the above to gimplify one size or position, *EXPR_P.
+/* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
+   a size or position, has had all of its SAVE_EXPRs evaluated.
    We add any required statements to STMT_P.  */
 
 void
@@ -4131,6 +4331,7 @@ gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
       || CONTAINS_PLACEHOLDER_P (*expr_p))
     return;
 
+  *expr_p = unshare_expr (*expr_p);
   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
 }
 \f