OSDN Git Service

PR target/40575
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index 65a13de..62b5c45 100644 (file)
@@ -455,6 +455,28 @@ set_rtl (tree t, rtx x)
       SA.partition_to_pseudo[var_to_partition (SA.map, t)] = x;
       if (x && !MEM_P (x))
        set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (t), x);
+      /* For the benefit of debug information at -O0 (where vartracking
+         doesn't run) record the place also in the base DECL if it's
+        a normal variable (not a parameter).  */
+      if (x && x != pc_rtx && TREE_CODE (SSA_NAME_VAR (t)) == VAR_DECL)
+       {
+         tree var = SSA_NAME_VAR (t);
+         /* If we don't yet have something recorded, just record it now.  */
+         if (!DECL_RTL_SET_P (var))
+           SET_DECL_RTL (var, x);
+         /* If we have it set alrady to "multiple places" don't
+            change this.  */
+         else if (DECL_RTL (var) == pc_rtx)
+           ;
+         /* If we have something recorded and it's not the same place
+            as we want to record now, we have multiple partitions for the
+            same base variable, with different places.  We can't just
+            randomly chose one, hence we have to say that we don't know.
+            This only happens with optimization, and there var-tracking
+            will figure out the right thing.  */
+         else if (DECL_RTL (var) != x)
+           SET_DECL_RTL (var, pc_rtx);
+       }
     }
   else
     SET_DECL_RTL (t, x);
@@ -542,8 +564,8 @@ get_decl_align_unit (tree decl)
      So here we only make sure stack_alignment_needed >= align.  */
   if (crtl->stack_alignment_needed < align)
     crtl->stack_alignment_needed = align;
-  if (crtl->max_used_stack_slot_alignment < crtl->stack_alignment_needed)
-    crtl->max_used_stack_slot_alignment = crtl->stack_alignment_needed;
+  if (crtl->max_used_stack_slot_alignment < align)
+    crtl->max_used_stack_slot_alignment = align;
 
   return align / BITS_PER_UNIT;
 }
@@ -1161,7 +1183,6 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
                  || (!DECL_EXTERNAL (var)
                      && !DECL_HAS_VALUE_EXPR_P (var)
                      && !TREE_STATIC (var)
-                     && !DECL_RTL_SET_P (var)
                      && TREE_TYPE (var) != error_mark_node
                      && !DECL_HARD_REGISTER (var)
                      && really_expand));
@@ -1174,7 +1195,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
     ;
   else if (TREE_STATIC (var))
     ;
-  else if (DECL_RTL_SET_P (var))
+  else if (TREE_CODE (origvar) != SSA_NAME && DECL_RTL_SET_P (var))
     ;
   else if (TREE_TYPE (var) == error_mark_node)
     {
@@ -1389,7 +1410,8 @@ add_stack_protection_conflicts (void)
 static void
 create_stack_guard (void)
 {
-  tree guard = build_decl (VAR_DECL, NULL, ptr_type_node);
+  tree guard = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
+                          VAR_DECL, NULL, ptr_type_node);
   TREE_THIS_VOLATILE (guard) = 1;
   TREE_USED (guard) = 1;
   expand_one_stack_var (guard);
@@ -1561,7 +1583,11 @@ expand_used_vars (void)
 
       /* Expanded above already.  */
       if (is_gimple_reg (var))
-       ;
+       {
+         TREE_USED (var) = 0;
+         ggc_free (t);
+         continue;
+       }
       /* We didn't set a block for static or extern because it's hard
         to tell the difference between a global variable (re)declared
         in a local scope, and one that's really declared there to
@@ -2321,7 +2347,8 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
        {
          t = get_base_address (t);
-         if (t && DECL_P (t))
+         if (t && DECL_P (t)
+              && DECL_MODE (t) != BLKmode)
            TREE_ADDRESSABLE (t) = 1;
        }
 
@@ -2438,7 +2465,7 @@ gimple_expand_cfg (void)
   rtl_profile_for_bb (ENTRY_BLOCK_PTR);
 
   insn_locators_alloc ();
-  if (!DECL_BUILT_IN (current_function_decl))
+  if (!DECL_IS_BUILTIN (current_function_decl))
     {
       /* Eventually, all FEs should explicitly set function_start_locus.  */
       if (cfun->function_start_locus == UNKNOWN_LOCATION)
@@ -2494,6 +2521,12 @@ gimple_expand_cfg (void)
          && !SA.partition_to_pseudo[i])
        SA.partition_to_pseudo[i] = DECL_RTL_IF_SET (var);
       gcc_assert (SA.partition_to_pseudo[i]);
+
+      /* If this decl was marked as living in multiple places, reset
+         this now to NULL.  */
+      if (DECL_RTL_IF_SET (var) == pc_rtx)
+       SET_DECL_RTL (var, NULL);
+
       /* Some RTL parts really want to look at DECL_RTL(x) when x
          was a decl marked in REG_ATTR or MEM_ATTR.  We could use
         SET_DECL_RTL here making this available, but that would mean