OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index 579c3cd..10bacda 100644 (file)
@@ -357,8 +357,7 @@ aggregate_contains_union_type (tree type)
    and due to type based aliasing rules decides that for two overlapping
    union temporaries { short s; int i; } accesses to the same mem through
    different types may not alias and happily reorders stores across
-   life-time boundaries of the temporaries (See PR25654).
-   We also have to mind MEM_IN_STRUCT_P and MEM_SCALAR_P.  */
+   life-time boundaries of the temporaries (See PR25654).  */
 
 static void
 add_alias_set_conflicts (void)
@@ -698,6 +697,8 @@ update_alias_info_with_stack_vars (void)
                                           (void *)(size_t) uid)) = part;
          *((tree *) pointer_map_insert (cfun->gimple_df->decls_to_pointers,
                                         decl)) = name;
+         if (TREE_ADDRESSABLE (decl))
+           TREE_ADDRESSABLE (name) = 1;
        }
 
       /* Make the SSA name point to all partition members.  */
@@ -2587,6 +2588,8 @@ expand_debug_parm_decl (tree decl)
              reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
              incoming = replace_equiv_address_nv (incoming, reg);
            }
+         else
+           incoming = copy_rtx (incoming);
        }
 #endif
 
@@ -2602,7 +2605,7 @@ expand_debug_parm_decl (tree decl)
          || (GET_CODE (XEXP (incoming, 0)) == PLUS
              && XEXP (XEXP (incoming, 0), 0) == virtual_incoming_args_rtx
              && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
-    return incoming;
+    return copy_rtx (incoming);
 
   return NULL_RTX;
 }
@@ -3635,6 +3638,57 @@ expand_debug_source_expr (tree exp)
   return op0;
 }
 
+/* Ensure INSN_VAR_LOCATION_LOC (insn) doesn't have unbound complexity.
+   Allow 4 levels of rtl nesting for most rtl codes, and if we see anything
+   deeper than that, create DEBUG_EXPRs and emit DEBUG_INSNs before INSN.  */
+
+static void
+avoid_complex_debug_insns (rtx insn, rtx *exp_p, int depth)
+{
+  rtx exp = *exp_p;
+  const char *format_ptr;
+  int i, j;
+
+  if (exp == NULL_RTX)
+    return;
+
+  if ((OBJECT_P (exp) && !MEM_P (exp)) || GET_CODE (exp) == CLOBBER)
+    return;
+
+  if (depth == 4)
+    {
+      /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
+      rtx dval = make_debug_expr_from_rtl (exp);
+
+      /* Emit a debug bind insn before INSN.  */
+      rtx bind = gen_rtx_VAR_LOCATION (GET_MODE (exp),
+                                      DEBUG_EXPR_TREE_DECL (dval), exp,
+                                      VAR_INIT_STATUS_INITIALIZED);
+
+      emit_debug_insn_before (bind, insn);
+      *exp_p = dval;
+      return;
+    }
+
+  format_ptr = GET_RTX_FORMAT (GET_CODE (exp));
+  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
+    switch (*format_ptr++)
+      {
+      case 'e':
+       avoid_complex_debug_insns (insn, &XEXP (exp, i), depth + 1);
+       break;
+
+      case 'E':
+      case 'V':
+       for (j = 0; j < XVECLEN (exp, i); j++)
+         avoid_complex_debug_insns (insn, &XVECEXP (exp, i, j), depth + 1);
+       break;
+
+      default:
+       break;
+      }
+}
+
 /* Expand the _LOCs in debug insns.  We run this after expanding all
    regular insns, so that any variables referenced in the function
    will have their DECL_RTLs set.  */
@@ -3655,7 +3709,7 @@ expand_debug_locations (void)
     if (DEBUG_INSN_P (insn))
       {
        tree value = (tree)INSN_VAR_LOCATION_LOC (insn);
-       rtx val;
+       rtx val, prev_insn, insn2;
        enum machine_mode mode;
 
        if (value == NULL_TREE)
@@ -3685,6 +3739,9 @@ expand_debug_locations (void)
          }
 
        INSN_VAR_LOCATION_LOC (insn) = val;
+       prev_insn = PREV_INSN (insn);
+       for (insn2 = insn; insn2 != prev_insn; insn2 = PREV_INSN (insn2))
+         avoid_complex_debug_insns (insn2, &INSN_VAR_LOCATION_LOC (insn2), 0);
       }
 
   flag_strict_aliasing = save_strict_alias;