OSDN Git Service

* emit-rtl.c (set_mem_attributes_minus_bitpos): Explicitly derive
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Dec 2010 13:28:05 +0000 (13:28 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Dec 2010 13:28:05 +0000 (13:28 +0000)
default values from MEM mode if no memory attributes are present.
Do not use mode alignment, even on STRICT_ALIGNMENT targets, when
called with an expression (not a type).

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168344 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/emit-rtl.c

index 1246faf..b0e6c30 100644 (file)
@@ -1,3 +1,10 @@
+2010-12-30  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+       * emit-rtl.c (set_mem_attributes_minus_bitpos): Explicitly derive
+       default values from MEM mode if no memory attributes are present.
+       Do not use mode alignment, even on STRICT_ALIGNMENT targets, when
+       called with an expression (not a type).
+
 2010-12-30  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/i386.c (upper_128bits_state): Remove comments.
index 4a5b290..42b2da0 100644 (file)
@@ -1540,11 +1540,11 @@ void
 set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
                                 HOST_WIDE_INT bitpos)
 {
-  alias_set_type alias = MEM_ALIAS_SET (ref);
-  tree expr = MEM_EXPR (ref);
-  rtx offset = MEM_OFFSET (ref);
-  rtx size = MEM_SIZE (ref);
-  unsigned int align = MEM_ALIGN (ref);
+  alias_set_type alias;
+  tree expr = NULL;
+  rtx offset = NULL_RTX;
+  rtx size = NULL_RTX;
+  unsigned int align = BITS_PER_UNIT;
   HOST_WIDE_INT apply_bitpos = 0;
   tree type;
 
@@ -1580,6 +1580,34 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
       && TREE_CODE (type) != COMPLEX_TYPE)
     MEM_SCALAR_P (ref) = 1;
 
+  /* Default values from pre-existing memory attributes if present.  */
+  if (MEM_ATTRS (ref))
+    {
+      /* ??? Can this ever happen?  Calling this routine on a MEM that
+        already carries memory attributes should probably be invalid.  */
+      expr = MEM_EXPR (ref);
+      offset = MEM_OFFSET (ref);
+      size = MEM_SIZE (ref);
+      align = MEM_ALIGN (ref);
+    }
+
+  /* Otherwise, default values from the mode of the MEM reference.  */
+  else if (GET_MODE (ref) != BLKmode)
+    {
+      /* Respect mode size.  */
+      size = GEN_INT (GET_MODE_SIZE (GET_MODE (ref)));
+      /* ??? Is this really necessary?  We probably should always get
+        the size from the type below.  */
+
+      /* Respect mode alignment for STRICT_ALIGNMENT targets if T is a type;
+         if T is an object, always compute the object alignment below.  */
+      if (STRICT_ALIGNMENT && TYPE_P (t))
+       align = GET_MODE_ALIGNMENT (GET_MODE (ref));
+      /* ??? If T is a type, respecting mode alignment may *also* be wrong
+        e.g. if the type carries an alignment attribute.  Should we be
+        able to simply always use TYPE_ALIGN?  */
+    }
+
   /* We can set the alignment from the type if we are making an object,
      this is an INDIRECT_REF, or if TYPE_ALIGN_OK.  */
   if (objectp || TREE_CODE (t) == INDIRECT_REF || TYPE_ALIGN_OK (type))