OSDN Git Service

* g++.dg/crash38.C: moved into proper directory...
[pf3gnuchains/gcc-fork.git] / gcc / emit-rtl.c
index 351c70b..53bff45 100644 (file)
@@ -426,7 +426,7 @@ const_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode)
   rtx real = rtx_alloc (CONST_DOUBLE);
   PUT_MODE (real, mode);
 
-  memcpy (&CONST_DOUBLE_LOW (real), &value, sizeof (REAL_VALUE_TYPE));
+  real->u.rv = value;
 
   return lookup_const_double (real);
 }
@@ -607,6 +607,31 @@ gen_const_mem (enum machine_mode mode, rtx addr)
   return mem;
 }
 
+/* Generate a MEM referring to fixed portions of the frame, e.g., register
+   save areas.  */
+
+rtx
+gen_frame_mem (enum machine_mode mode, rtx addr)
+{
+  rtx mem = gen_rtx_MEM (mode, addr);
+  MEM_NOTRAP_P (mem) = 1;
+  set_mem_alias_set (mem, get_frame_alias_set ());
+  return mem;
+}
+
+/* Generate a MEM referring to a temporary use of the stack, not part
+    of the fixed stack frame.  For example, something which is pushed
+    by a target splitter.  */
+rtx
+gen_tmp_stack_mem (enum machine_mode mode, rtx addr)
+{
+  rtx mem = gen_rtx_MEM (mode, addr);
+  MEM_NOTRAP_P (mem) = 1;
+  if (!current_function_calls_alloca)
+    set_mem_alias_set (mem, get_frame_alias_set ());
+  return mem;
+}
+
 /* We want to create (subreg:OMODE (obj:IMODE) OFFSET).  Return true if
    this construct would be valid, and false otherwise.  */
 
@@ -954,7 +979,7 @@ set_reg_attrs_for_parm (rtx parm_rtx, rtx mem)
 void
 set_decl_rtl (tree t, rtx x)
 {
-  DECL_CHECK (t)->decl.rtl = x;
+  DECL_WRTL_CHECK (t)->decl_with_rtl.rtl = x;
 
   if (!x)
     return;
@@ -1118,7 +1143,8 @@ gen_lowpart_common (enum machine_mode mode, rtx x)
   /* Unfortunately, this routine doesn't take a parameter for the mode of X,
      so we have to make one up.  Yuk.  */
   innermode = GET_MODE (x);
-  if (GET_CODE (x) == CONST_INT && msize <= HOST_BITS_PER_WIDE_INT)
+  if (GET_CODE (x) == CONST_INT
+      && msize * BITS_PER_UNIT <= HOST_BITS_PER_WIDE_INT)
     innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
   else if (innermode == VOIDmode)
     innermode = mode_for_size (HOST_BITS_PER_WIDE_INT * 2, MODE_INT, 0);
@@ -1468,7 +1494,6 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
   MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
   MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type);
   MEM_POINTER (ref) = POINTER_TYPE_P (type);
-  MEM_NOTRAP_P (ref) = TREE_THIS_NOTRAP (t);
 
   /* If we are making an object of this type, or if this is a DECL, we know
      that it is a scalar if the type is not an aggregate.  */
@@ -1499,16 +1524,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
      the expression.  */
   if (! TYPE_P (t))
     {
-      tree base = get_base_address (t);
-      if (base && DECL_P (base)
-         && TREE_READONLY (base)
-         && (TREE_STATIC (base) || DECL_EXTERNAL (base)))
-       {
-         tree base_type = TREE_TYPE (base);
-         gcc_assert (!(base_type && TYPE_NEEDS_CONSTRUCTING (base_type))
-                     || DECL_ARTIFICIAL (base));
-         MEM_READONLY_P (ref) = 1;
-       }
+      tree base;
 
       if (TREE_THIS_VOLATILE (t))
        MEM_VOLATILE_P (ref) = 1;
@@ -1521,6 +1537,36 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
             || TREE_CODE (t) == SAVE_EXPR)
        t = TREE_OPERAND (t, 0);
 
+      /* We may look through structure-like accesses for the purposes of
+        examining TREE_THIS_NOTRAP, but not array-like accesses.  */
+      base = t;
+      while (TREE_CODE (base) == COMPONENT_REF
+            || TREE_CODE (base) == REALPART_EXPR
+            || TREE_CODE (base) == IMAGPART_EXPR
+            || TREE_CODE (base) == BIT_FIELD_REF)
+       base = TREE_OPERAND (base, 0);
+
+      if (DECL_P (base))
+       {
+         if (CODE_CONTAINS_STRUCT (TREE_CODE (base), TS_DECL_WITH_VIS))
+           MEM_NOTRAP_P (ref) = !DECL_WEAK (base);
+         else
+           MEM_NOTRAP_P (ref) = 1;
+       }
+      else
+       MEM_NOTRAP_P (ref) = TREE_THIS_NOTRAP (base);
+
+      base = get_base_address (base);
+      if (base && DECL_P (base)
+         && TREE_READONLY (base)
+         && (TREE_STATIC (base) || DECL_EXTERNAL (base)))
+       {
+         tree base_type = TREE_TYPE (base);
+         gcc_assert (!(base_type && TYPE_NEEDS_CONSTRUCTING (base_type))
+                     || DECL_ARTIFICIAL (base));
+         MEM_READONLY_P (ref) = 1;
+       }
+
       /* If this expression uses it's parent's alias set, mark it such
         that we won't change it.  */
       if (component_uses_parent_alias_set (t))
@@ -2138,7 +2184,7 @@ unshare_all_rtl (void)
 
 struct tree_opt_pass pass_unshare_all_rtl =
 {
-  NULL,                                 /* name */
+  "unshare",                            /* name */
   NULL,                                 /* gate */
   unshare_all_rtl,                      /* execute */
   NULL,                                 /* sub */
@@ -2149,7 +2195,7 @@ struct tree_opt_pass pass_unshare_all_rtl =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
+  TODO_dump_func,                       /* todo_flags_finish */
   0                                     /* letter */
 };
 
@@ -3726,7 +3772,7 @@ remove_unnecessary_notes (void)
 
 struct tree_opt_pass pass_remove_unnecessary_notes =
 {
-  NULL,                                 /* name */ 
+  "eunotes",                            /* name */ 
   NULL,                                        /* gate */
   remove_unnecessary_notes,             /* execute */
   NULL,                                 /* sub */
@@ -3737,7 +3783,7 @@ struct tree_opt_pass pass_remove_unnecessary_notes =
   0,                                    /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  0,                                   /* todo_flags_finish */
+  TODO_dump_func,                      /* todo_flags_finish */
   0                                     /* letter */ 
 };