public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Alexandre Oliva <aoliva@redhat.com>
To: Bernd Schmidt <bernds_cb1@t-online.de>
Cc: Daniel Berlin <dberlin@dberlin.org>,
	GCC Patches <gcc-patches@gcc.gnu.org>,
	        Diego Novillo <dnovillo@redhat.com>,
	Andrew Pinski <pinskia@gmail.com>
Subject: Re: Reload bug & SRA oddness
Date: Mon, 30 Apr 2007 19:08:00 -0000	[thread overview]
Message-ID: <ork5vtu5ev.fsf@free.oliva.athome.lsd.ic.unicamp.br> (raw)
In-Reply-To: <or4pmxvkv1.fsf@free.oliva.athome.lsd.ic.unicamp.br> (Alexandre Oliva's message of "Mon\, 30 Apr 2007 14\:21\:38 -0300")

[-- Attachment #1: Type: text/plain, Size: 523 bytes --]

On Apr 30, 2007, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Apr 30, 2007, Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>> As a consequence of all these problems, I'd like to see this patch
>> reverted for now until it we know how to do it properly.

> Sounds like a reasonable trade-off.  I'm sorry that I haven't had time
> to look into this throughout the past two weeks.  I was finally able
> to start looking into this yesterday, but I haven't got anywhere so
> far.

Here's the reversal patch I'm checking in.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gcc-sra-bit-field-ref-revert.patch --]
[-- Type: text/x-patch, Size: 27508 bytes --]

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR middle-end/22156
	Temporarily revert:
	2007-04-06  Andreas Tobler  <a.tobler@schweiz.org>
	* tree-sra.c (sra_build_elt_assignment): Initialize min/maxshift.
	2007-04-05  Alexandre Oliva  <aoliva@redhat.com>
	* tree-sra.c (try_instantiate_multiple_fields): Needlessly
	initialize align to silence bogus warning.
	2007-04-05  Alexandre Oliva  <aoliva@redhat.com>
	* tree-sra.c (struct sra_elt): Add in_bitfld_block.  Remove
	all_no_warning.
	(struct sra_walk_fns): Remove use_all parameter from use.
	(sra_hash_tree): Handle BIT_FIELD_REFs.
	(sra_elt_hash): Don't hash bitfld blocks.
	(sra_elt_eq): Skip them in parent compares as well.  Handle
	BIT_FIELD_REFs.
	(sra_walk_expr): Don't maintain or pass down use_all_p.
	(scan_use): Remove use_all parameter.
	(scalarize_use): Likewise.  Re-expand assignment to
	BIT_FIELD_REF of gimple_reg.  De-scalarize before input or
	output, and re-scalarize after output.  Don't mark anything
	for no warning.
	(scalarize_ldst): Adjust.
	(scalarize_walk_gimple_modify_statement): Likewise.
	(build_element_name_1): Handle BIT_FIELD_REFs.
	(instantiate_element): Don't warn for any element whose parent
	is used as a whole.
	(instantiate_missing_elements_1): Return the sra_elt.
	(canon_type_for_field): New.
	(try_instantiate_multiple_fields): New.
	(instantiate_missing_elemnts): Use them.
	(mark_no_warning): Removed.
	(generate_one_element_ref): Handle BIT_FIELD_REFs.
	(REPLDUP, sra_build_elt_assignment): New.
	(generate_copy_inout): Use them.
	(generate_element_copy): Likewise.  Handle bitfld differences.
	(generate_element_zero): Don't recurse for blocks.  Use
	sra_build_elt_assignment.
	(generate_one_element_int): Take elt instead of var.  Use
	sra_build_elt_assignment.
	(generate_element_init_1): Adjust.
	(scalarize_use, scalarize_copy): Use REPLDUP.
	(scalarize_ldst): Move assert before dereference.
	(dump_sra_elt_name): Handle BIT_FIELD_REFs.

Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c	(revision 124300)
+++ gcc/tree-sra.c	(working copy)
@@ -147,10 +147,6 @@
 
   /* True if there is BIT_FIELD_REF on the lhs with a vector. */
   bool is_vector_lhs;
-
-  /* 1 if the element is a field that is part of a block, 2 if the field
-     is the block itself, 0 if it's neither.  */
-  char in_bitfld_block;
 };
 
 #define IS_ELEMENT_FOR_GROUP(ELEMENT) (TREE_CODE (ELEMENT) == RANGE_EXPR)
@@ -465,12 +461,6 @@
       h = iterative_hash_expr (DECL_FIELD_BIT_OFFSET (t), h);
       break;
 
-    case BIT_FIELD_REF:
-      /* Don't take operand 0 into account, that's our parent.  */
-      h = iterative_hash_expr (TREE_OPERAND (t, 1), 0);
-      h = iterative_hash_expr (TREE_OPERAND (t, 2), h);
-      break;
-
     default:
       gcc_unreachable ();
     }
@@ -489,14 +479,12 @@
 
   h = sra_hash_tree (e->element);
 
-  /* Take into account everything except bitfield blocks back up the
-     chain.  Given that chain lengths are rarely very long, this
-     should be acceptable.  If we truly identify this as a performance
-     problem, it should work to hash the pointer value
-     "e->parent".  */
+  /* Take into account everything back up the chain.  Given that chain
+     lengths are rarely very long, this should be acceptable.  If we
+     truly identify this as a performance problem, it should work to
+     hash the pointer value "e->parent".  */
   for (p = e->parent; p ; p = p->parent)
-    if (!p->in_bitfld_block)
-      h = (h * 65521) ^ sra_hash_tree (p->element);
+    h = (h * 65521) ^ sra_hash_tree (p->element);
 
   return h;
 }
@@ -509,17 +497,8 @@
   const struct sra_elt *a = x;
   const struct sra_elt *b = y;
   tree ae, be;
-  const struct sra_elt *ap = a->parent;
-  const struct sra_elt *bp = b->parent;
 
-  if (ap)
-    while (ap->in_bitfld_block)
-      ap = ap->parent;
-  if (bp)
-    while (bp->in_bitfld_block)
-      bp = bp->parent;
-
-  if (ap != bp)
+  if (a->parent != b->parent)
     return false;
 
   ae = a->element;
@@ -554,11 +533,6 @@
 	return false;
       return fields_compatible_p (ae, be);
 
-    case BIT_FIELD_REF:
-      return
-	tree_int_cst_equal (TREE_OPERAND (ae, 1), TREE_OPERAND (be, 1))
-	&& tree_int_cst_equal (TREE_OPERAND (ae, 2), TREE_OPERAND (be, 2));
-
     default:
       gcc_unreachable ();
     }
@@ -697,9 +671,10 @@
   /* Invoked when ELT is required as a unit.  Note that ELT might refer to
      a leaf node, in which case this is a simple scalar reference.  *EXPR_P
      points to the location of the expression.  IS_OUTPUT is true if this
-     is a left-hand-side reference.  */
+     is a left-hand-side reference.  USE_ALL is true if we saw something we
+     couldn't quite identify and had to force the use of the entire object.  */
   void (*use) (struct sra_elt *elt, tree *expr_p,
-	       block_stmt_iterator *bsi, bool is_output);
+	       block_stmt_iterator *bsi, bool is_output, bool use_all);
 
   /* Invoked when we have a copy between two scalarizable references.  */
   void (*copy) (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
@@ -753,6 +728,7 @@
   tree expr = *expr_p;
   tree inner = expr;
   bool disable_scalarization = false;
+  bool use_all_p = false;
 
   /* We're looking to collect a reference expression between EXPR and INNER,
      such that INNER is a scalarizable decl and all other nodes through EXPR
@@ -773,7 +749,7 @@
 	    if (disable_scalarization)
 	      elt->cannot_scalarize = true;
 	    else
-	      fns->use (elt, expr_p, bsi, is_output);
+	      fns->use (elt, expr_p, bsi, is_output, use_all_p);
 	  }
 	return;
 
@@ -860,6 +836,7 @@
       use_all:
         expr_p = &TREE_OPERAND (inner, 0);
 	inner = expr = *expr_p;
+	use_all_p = true;
 	break;
 
       default:
@@ -907,14 +884,11 @@
   sra_walk_tree_list (ASM_OUTPUTS (expr), bsi, true, fns);
 }
 
-static void sra_replace (block_stmt_iterator *bsi, tree list);
-static tree sra_build_elt_assignment (struct sra_elt *elt, tree src);
-
 /* Walk a GIMPLE_MODIFY_STMT and categorize the assignment appropriately.  */
 
 static void
 sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
-			     const struct sra_walk_fns *fns)
+		      const struct sra_walk_fns *fns)
 {
   struct sra_elt *lhs_elt, *rhs_elt;
   tree lhs, rhs;
@@ -937,7 +911,7 @@
       if (!rhs_elt->is_scalar && !TREE_SIDE_EFFECTS (lhs))
 	fns->ldst (rhs_elt, lhs, bsi, false);
       else
-	fns->use (rhs_elt, &GIMPLE_STMT_OPERAND (expr, 1), bsi, false);
+	fns->use (rhs_elt, &GIMPLE_STMT_OPERAND (expr, 1), bsi, false, false);
     }
 
   /* If it isn't scalarizable, there may be scalarizable variables within, so
@@ -984,9 +958,7 @@
       /* Otherwise we're being used in some context that requires the
 	 aggregate to be seen as a whole.  Invoke USE.  */
       else
-	{
-	  fns->use (lhs_elt, &GIMPLE_STMT_OPERAND (expr, 0), bsi, true);
-	}
+	fns->use (lhs_elt, &GIMPLE_STMT_OPERAND (expr, 0), bsi, true, false);
     }
 
   /* Similarly to above, LHS_ELT being null only means that the LHS as a
@@ -1097,7 +1069,7 @@
 static void
 scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
 	  block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
-	  bool is_output ATTRIBUTE_UNUSED)
+	  bool is_output ATTRIBUTE_UNUSED, bool use_all ATTRIBUTE_UNUSED)
 {
   elt->n_uses += 1;
 }
@@ -1205,15 +1177,6 @@
       sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (t));
       obstack_grow (&sra_obstack, buffer, strlen (buffer));
     }
-  else if (TREE_CODE (t) == BIT_FIELD_REF)
-    {
-      sprintf (buffer, "B" HOST_WIDE_INT_PRINT_DEC,
-	       tree_low_cst (TREE_OPERAND (t, 2), 1));
-      obstack_grow (&sra_obstack, buffer, strlen (buffer));
-      sprintf (buffer, "F" HOST_WIDE_INT_PRINT_DEC,
-	       tree_low_cst (TREE_OPERAND (t, 1), 1));
-      obstack_grow (&sra_obstack, buffer, strlen (buffer));
-    }
   else
     {
       tree name = DECL_NAME (t);
@@ -1246,12 +1209,9 @@
 {
   struct sra_elt *base_elt;
   tree var, base;
-  bool nowarn = TREE_NO_WARNING (elt->element);
 
   for (base_elt = elt; base_elt->parent; base_elt = base_elt->parent)
-    if (!nowarn)
-      nowarn = base_elt->parent->n_uses
-	|| TREE_NO_WARNING (base_elt->parent->element);
+    continue;
   base = base_elt->element;
 
   elt->replacement = var = make_rename_temp (elt->type, "SR");
@@ -1280,7 +1240,9 @@
       DECL_DEBUG_EXPR_IS_FROM (var) = 1;
       
       DECL_IGNORED_P (var) = 0;
-      TREE_NO_WARNING (var) = nowarn;
+      TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
+      if (elt->element && TREE_NO_WARNING (elt->element))
+	TREE_NO_WARNING (var) = 1;
     }
   else
     {
@@ -1375,7 +1337,7 @@
 
 static void instantiate_missing_elements (struct sra_elt *elt);
 
-static struct sra_elt *
+static void
 instantiate_missing_elements_1 (struct sra_elt *elt, tree child, tree type)
 {
   struct sra_elt *sub = lookup_element (elt, child, type, INSERT);
@@ -1386,268 +1348,8 @@
     }
   else
     instantiate_missing_elements (sub);
-  return sub;
 }
 
-/* Obtain the canonical type for field F of ELEMENT.  */
-
-static tree
-canon_type_for_field (tree f, tree element)
-{
-  tree field_type = TREE_TYPE (f);
-
-  /* canonicalize_component_ref() unwidens some bit-field types (not
-     marked as DECL_BIT_FIELD in C++), so we must do the same, lest we
-     may introduce type mismatches.  */
-  if (INTEGRAL_TYPE_P (field_type)
-      && DECL_MODE (f) != TYPE_MODE (field_type))
-    field_type = TREE_TYPE (get_unwidened (build3 (COMPONENT_REF,
-						   field_type,
-						   element,
-						   f, NULL_TREE),
-					   NULL_TREE));
-
-  return field_type;
-}
-
-/* Look for adjacent fields of ELT starting at F that we'd like to
-   scalarize as a single variable.  Return the last field of the
-   group.  */
-
-static tree
-try_instantiate_multiple_fields (struct sra_elt *elt, tree f)
-{
-  unsigned HOST_WIDE_INT align, oalign, word, bit, size, alchk;
-  enum machine_mode mode;
-  tree first = f, prev;
-  tree type, var;
-  struct sra_elt *block;
-
-  if (!is_sra_scalar_type (TREE_TYPE (f))
-      || !host_integerp (DECL_FIELD_OFFSET (f), 1)
-      || !host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)
-      || !host_integerp (DECL_SIZE (f), 1)
-      || lookup_element (elt, f, NULL, NO_INSERT))
-    return f;
-
-  /* Taking the alignment of elt->element is not enough, since it
-     might be just an array index or some such.  We shouldn't need to
-     initialize align here, but our optimizers don't always realize
-     that, if we leave the loop without initializing align, we'll fail
-     the assertion right after the loop.  */
-  align = (unsigned HOST_WIDE_INT)-1;
-  for (block = elt; block; block = block->parent)
-    if (DECL_P (block->element))
-      {
-	align = DECL_ALIGN (block->element);
-	break;
-      }
-  gcc_assert (block);
-
-  oalign = DECL_OFFSET_ALIGN (f);
-  word = tree_low_cst (DECL_FIELD_OFFSET (f), 1);
-  bit = tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
-  size = tree_low_cst (DECL_SIZE (f), 1);
-
-  if (align > oalign)
-    align = oalign;
-
-  alchk = align - 1;
-  alchk = ~alchk;
-
-  if ((bit & alchk) != ((bit + size - 1) & alchk))
-    return f;
-
-  /* Find adjacent fields in the same alignment word.  */
-
-  for (prev = f, f = TREE_CHAIN (f);
-       f && TREE_CODE (f) == FIELD_DECL
-	 && is_sra_scalar_type (TREE_TYPE (f))
-	 && host_integerp (DECL_FIELD_OFFSET (f), 1)
-	 && host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)
-	 && host_integerp (DECL_SIZE (f), 1)
-	 && (HOST_WIDE_INT)word == tree_low_cst (DECL_FIELD_OFFSET (f), 1)
-	 && !lookup_element (elt, f, NULL, NO_INSERT);
-       prev = f, f = TREE_CHAIN (f))
-    {
-      unsigned HOST_WIDE_INT nbit, nsize;
-
-      nbit = tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
-      nsize = tree_low_cst (DECL_SIZE (f), 1);
-
-      if (bit + size == nbit)
-	{
-	  if ((bit & alchk) != ((nbit + nsize - 1) & alchk))
-	    break;
-	  size += nsize;
-	}
-      else if (nbit + nsize == bit)
-	{
-	  if ((nbit & alchk) != ((bit + size - 1) & alchk))
-	    break;
-	  bit = nbit;
-	  size += nsize;
-	}
-      else
-	break;
-    }
-
-  f = prev;
-
-  if (f == first)
-    return f;
-
-  gcc_assert ((bit & alchk) == ((bit + size - 1) & alchk));
-
-  /* Try to widen the bit range so as to cover padding bits as well.  */
-
-  if ((bit & ~alchk) || size != align)
-    {
-      unsigned HOST_WIDE_INT mbit = bit & alchk;
-      unsigned HOST_WIDE_INT msize = align;
-
-      for (f = TYPE_FIELDS (elt->type);
-	   f; f = TREE_CHAIN (f))
-	{
-	  unsigned HOST_WIDE_INT fword, fbit, fsize;
-
-	  /* Skip the fields from first to prev.  */
-	  if (f == first)
-	    {
-	      f = prev;
-	      continue;
-	    }
-
-	  if (!(TREE_CODE (f) == FIELD_DECL
-		&& host_integerp (DECL_FIELD_OFFSET (f), 1)
-		&& host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)))
-	    continue;
-
-	  fword = tree_low_cst (DECL_FIELD_OFFSET (f), 1);
-	  /* If we're past the selected word, we're fine.  */
-	  if (word < fword)
-	    continue;
-
-	  fbit = tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
-
-	  if (host_integerp (DECL_SIZE (f), 1))
-	    fsize = tree_low_cst (DECL_SIZE (f), 1);
-	  else
-	    /* Assume a variable-sized field takes up all space till
-	       the end of the word.  ??? Endianness issues?  */
-	    fsize = align - fbit;
-
-	  if (fword < word)
-	    {
-	      /* A large field might start at a previous word and
-		 extend into the selected word.  Exclude those
-		 bits.  ??? Endianness issues? */
-	      HOST_WIDE_INT diff = fbit + fsize
-		- (HOST_WIDE_INT)((word - fword) * BITS_PER_UNIT + mbit);
-
-	      if (diff <= 0)
-		continue;
-
-	      mbit += diff;
-	      msize -= diff;
-	    }
-	  else
-	    {
-	      gcc_assert (fword == word);
-
-	      /* Non-overlapping, great.  */
-	      if (fbit + fsize <= mbit
-		  || mbit + msize <= fbit)
-		continue;
-
-	      if (fbit <= mbit)
-		{
-		  unsigned HOST_WIDE_INT diff = fbit + fsize - mbit;
-		  mbit += diff;
-		  msize -= diff;
-		}
-	      else if (fbit > mbit)
-		msize -= (mbit + msize - fbit);
-	      else
-		gcc_unreachable ();
-	    }
-	}
-
-      bit = mbit;
-      size = msize;
-    }
-
-  /* Now we know the bit range we're interested in.  Find the smallest
-     machine mode we can use to access it.  */
-
-  for (mode = smallest_mode_for_size (size, MODE_INT);
-       ;
-       mode = GET_MODE_WIDER_MODE (mode))
-    {
-      gcc_assert (mode != VOIDmode);
-
-      alchk = GET_MODE_PRECISION (mode) - 1;
-      alchk = ~alchk;
-
-      if ((bit & alchk) == ((bit + size - 1) & alchk))
-	break;
-    }
-
-  gcc_assert (~alchk < align);
-
-  /* Create the field group as a single variable.  */
-
-  type = lang_hooks.types.type_for_mode (mode, 1);
-  gcc_assert (type);
-  var = build3 (BIT_FIELD_REF, type, NULL_TREE,
-		bitsize_int (size),
-		bitsize_int (word * BITS_PER_UNIT + bit));
-  BIT_FIELD_REF_UNSIGNED (var) = 1;
-
-  block = instantiate_missing_elements_1 (elt, var, type);
-  gcc_assert (block && block->is_scalar);
-
-  var = block->replacement;
-
-  if (((word * BITS_PER_UNIT + bit) & ~alchk)
-      || (HOST_WIDE_INT)size != tree_low_cst (DECL_SIZE (var), 1))
-    {
-      block->replacement = build3 (BIT_FIELD_REF,
-				   TREE_TYPE (block->element), var,
-				   bitsize_int (size),
-				   bitsize_int ((word * BITS_PER_UNIT
-						 + bit) & ~alchk));
-      BIT_FIELD_REF_UNSIGNED (block->replacement) = 1;
-      TREE_NO_WARNING (block->replacement) = 1;
-    }
-
-  block->in_bitfld_block = 2;
-
-  /* Add the member fields to the group, such that they access
-     portions of the group variable.  */
-
-  for (f = first; f != TREE_CHAIN (prev); f = TREE_CHAIN (f))
-    {
-      tree field_type = canon_type_for_field (f, elt->element);
-      struct sra_elt *fld = lookup_element (block, f, field_type, INSERT);
-
-      gcc_assert (fld && fld->is_scalar && !fld->replacement);
-
-      fld->replacement = build3 (BIT_FIELD_REF, field_type, var,
-				 DECL_SIZE (f),
-				 bitsize_int
-				 ((word * BITS_PER_UNIT
-				   + (TREE_INT_CST_LOW
-				      (DECL_FIELD_BIT_OFFSET (f))))
-				  & ~alchk));
-      BIT_FIELD_REF_UNSIGNED (fld->replacement) = TYPE_UNSIGNED (field_type);
-      TREE_NO_WARNING (block->replacement) = 1;
-      fld->in_bitfld_block = 1;
-    }
-
-  return prev;
-}
-
 static void
 instantiate_missing_elements (struct sra_elt *elt)
 {
@@ -1661,17 +1363,21 @@
 	for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
 	  if (TREE_CODE (f) == FIELD_DECL)
 	    {
-	      tree last = try_instantiate_multiple_fields (elt, f);
+	      tree field_type = TREE_TYPE (f);
 
-	      if (last != f)
-		{
-		  f = last;
-		  continue;
-		}
+	      /* canonicalize_component_ref() unwidens some bit-field
+		 types (not marked as DECL_BIT_FIELD in C++), so we
+		 must do the same, lest we may introduce type
+		 mismatches.  */
+	      if (INTEGRAL_TYPE_P (field_type)
+		  && DECL_MODE (f) != TYPE_MODE (field_type))
+		field_type = TREE_TYPE (get_unwidened (build3 (COMPONENT_REF,
+							       field_type,
+							       elt->element,
+							       f, NULL_TREE),
+						       NULL_TREE));
 
-	      instantiate_missing_elements_1 (elt, f,
-					      canon_type_for_field
-					      (f, elt->element));
+	      instantiate_missing_elements_1 (elt, f, field_type);
 	    }
 	break;
       }
@@ -1983,16 +1689,6 @@
       {
 	tree field = elt->element;
 
-	/* We can't test elt->in_bitfld_blk here because, when this is
-	   called from instantiate_element, we haven't set this field
-	   yet.  */
-	if (TREE_CODE (field) == BIT_FIELD_REF)
-	  {
-	    tree ret = copy_node (field);
-	    TREE_OPERAND (ret, 0) = base;
-	    return ret;
-	  }
-
 	/* Watch out for compatible records with differing field lists.  */
 	if (DECL_FIELD_CONTEXT (field) != TYPE_MAIN_VARIANT (TREE_TYPE (base)))
 	  field = find_compatible_field (TREE_TYPE (base), field);
@@ -2045,126 +1741,6 @@
   return build_gimple_modify_stmt (dst, src);
 }
 
-/* BIT_FIELD_REFs must not be shared.  sra_build_elt_assignment()
-   takes care of assignments, but we must create copies for uses.  */
-#define REPLDUP(t) (TREE_CODE (t) != BIT_FIELD_REF ? (t) : copy_node (t))
-
-static tree
-sra_build_elt_assignment (struct sra_elt *elt, tree src)
-{
-  tree dst = elt->replacement;
-  tree var, type, tmp, tmp2, tmp3;
-  tree list, stmt;
-  tree cst, cst2, mask;
-  tree minshift = NULL, maxshift = NULL;
-
-  if (TREE_CODE (dst) != BIT_FIELD_REF
-      || !elt->in_bitfld_block)
-    return sra_build_assignment (REPLDUP (dst), src);
-
-  var = TREE_OPERAND (dst, 0);
-
-  /* Try to widen the assignment to the entire variable.
-     We need the source to be a BIT_FIELD_REF as well, such that, for
-     BIT_FIELD_REF<d,sz,dp> = BIT_FIELD_REF<s,sz,sp>,
-     if sp >= dp, we can turn it into
-     d = BIT_FIELD_REF<s,sp+sz,sp-dp>.  */
-  if (elt->in_bitfld_block == 2
-      && TREE_CODE (src) == BIT_FIELD_REF
-      && !tree_int_cst_lt (TREE_OPERAND (src, 2), TREE_OPERAND (dst, 2)))
-    {
-      src = fold_build3 (BIT_FIELD_REF, TREE_TYPE (var),
-			 TREE_OPERAND (src, 0),
-			 size_binop (PLUS_EXPR, TREE_OPERAND (src, 1),
-				     TREE_OPERAND (dst, 2)),
-			 size_binop (MINUS_EXPR, TREE_OPERAND (src, 2),
-				     TREE_OPERAND (dst, 2)));
-      BIT_FIELD_REF_UNSIGNED (src) = 1;
-
-      return sra_build_assignment (var, src);
-    }
-
-  if (!is_gimple_reg (var))
-    return sra_build_assignment (REPLDUP (dst), src);
-
-  list = alloc_stmt_list ();
-
-  cst = TREE_OPERAND (dst, 2);
-  if (WORDS_BIG_ENDIAN)
-    {
-      cst = size_binop (MINUS_EXPR, DECL_SIZE (var), cst);
-      maxshift = cst;
-    }
-  else
-    minshift = cst;
-
-  cst2 = size_binop (PLUS_EXPR, TREE_OPERAND (dst, 1),
-		     TREE_OPERAND (dst, 2));
-  if (WORDS_BIG_ENDIAN)
-    {
-      cst2 = size_binop (MINUS_EXPR, DECL_SIZE (var), cst2);
-      minshift = cst2;
-    }
-  else
-    maxshift = cst2;
-
-  type = TREE_TYPE (var);
-
-  mask = build_int_cst_wide (type, 1, 0);
-  cst = int_const_binop (LSHIFT_EXPR, mask, maxshift, 1);
-  cst2 = int_const_binop (LSHIFT_EXPR, mask, minshift, 1);
-  mask = int_const_binop (MINUS_EXPR, cst, cst2, 1);
-  mask = fold_build1 (BIT_NOT_EXPR, type, mask);
-
-  if (!WORDS_BIG_ENDIAN)
-    cst2 = TREE_OPERAND (dst, 2);
-
-  tmp = make_rename_temp (type, "SR");
-  stmt = build_gimple_modify_stmt (tmp,
-				   fold_build2 (BIT_AND_EXPR, type,
-						var, mask));
-  append_to_statement_list (stmt, &list);
-
-  if (is_gimple_reg (src))
-    tmp2 = src;
-  else
-    {
-      tmp2 = make_rename_temp (TREE_TYPE (src), "SR");
-      stmt = sra_build_assignment (tmp2, src);
-      append_to_statement_list (stmt, &list);
-    }
-
-  if (!TYPE_UNSIGNED (TREE_TYPE (tmp2))
-      || TYPE_MAIN_VARIANT (TREE_TYPE (tmp2)) != TYPE_MAIN_VARIANT (type))
-    {
-      tmp3 = make_rename_temp (type, "SR");
-      tmp2 = fold_build3 (BIT_FIELD_REF, type, tmp2, TREE_OPERAND (dst, 1),
-			  bitsize_int (0));
-      if (TREE_CODE (tmp2) == BIT_FIELD_REF)
-	BIT_FIELD_REF_UNSIGNED (tmp2) = 1;
-      stmt = sra_build_assignment (tmp3, tmp2);
-      append_to_statement_list (stmt, &list);
-      tmp2 = tmp3;
-    }
-
-  if (!integer_zerop (minshift))
-    {
-      tmp3 = make_rename_temp (type, "SR");
-      stmt = build_gimple_modify_stmt (tmp3,
-				       fold_build2 (LSHIFT_EXPR, type,
-						    tmp2, minshift));
-      append_to_statement_list (stmt, &list);
-      tmp2 = tmp3;
-    }
-
-  stmt = build_gimple_modify_stmt (var,
-				   fold_build2 (BIT_IOR_EXPR, type,
-						tmp, tmp2));
-  append_to_statement_list (stmt, &list);
-
-  return list;
-}
-
 /* Generate a set of assignment statements in *LIST_P to copy all
    instantiated elements under ELT to or from the equivalent structure
    rooted at EXPR.  COPY_OUT controls the direction of the copy, with
@@ -2195,9 +1771,9 @@
   else if (elt->replacement)
     {
       if (copy_out)
-	t = sra_build_elt_assignment (elt, expr);
+	t = sra_build_assignment (elt->replacement, expr);
       else
-	t = sra_build_assignment (expr, REPLDUP (elt->replacement));
+	t = sra_build_assignment (expr, elt->replacement);
       append_to_statement_list (t, list_p);
     }
   else
@@ -2222,19 +1798,6 @@
   FOR_EACH_ACTUAL_CHILD (dc, dst)
     {
       sc = lookup_element (src, dc->element, NULL, NO_INSERT);
-      if (!sc && dc->in_bitfld_block == 2)
-	{
-	  struct sra_elt *dcs;
-
-	  FOR_EACH_ACTUAL_CHILD (dcs, dc)
-	    {
-	      sc = lookup_element (src, dcs->element, NULL, NO_INSERT);
-	      gcc_assert (sc);
-	      generate_element_copy (dcs, sc, list_p);
-	    }
-
-	  continue;
-	}
       gcc_assert (sc);
       generate_element_copy (dc, sc, list_p);
     }
@@ -2245,7 +1808,7 @@
 
       gcc_assert (src->replacement);
 
-      t = sra_build_elt_assignment (dst, REPLDUP (src->replacement));
+      t = sra_build_assignment (dst->replacement, src->replacement);
       append_to_statement_list (t, list_p);
     }
 }
@@ -2266,9 +1829,8 @@
       return;
     }
 
-  if (!elt->in_bitfld_block)
-    FOR_EACH_ACTUAL_CHILD (c, elt)
-      generate_element_zero (c, list_p);
+  FOR_EACH_ACTUAL_CHILD (c, elt)
+    generate_element_zero (c, list_p);
 
   if (elt->replacement)
     {
@@ -2277,7 +1839,7 @@
       gcc_assert (elt->is_scalar);
       t = fold_convert (elt->type, integer_zero_node);
 
-      t = sra_build_elt_assignment (elt, t);
+      t = sra_build_assignment (elt->replacement, t);
       append_to_statement_list (t, list_p);
     }
 }
@@ -2286,10 +1848,10 @@
    Add the result to *LIST_P.  */
 
 static void
-generate_one_element_init (struct sra_elt *elt, tree init, tree *list_p)
+generate_one_element_init (tree var, tree init, tree *list_p)
 {
   /* The replacement can be almost arbitrarily complex.  Gimplify.  */
-  tree stmt = sra_build_elt_assignment (elt, init);
+  tree stmt = sra_build_assignment (var, init);
   gimplify_and_add (stmt, list_p);
 }
 
@@ -2318,7 +1880,7 @@
     {
       if (elt->replacement)
 	{
-	  generate_one_element_init (elt, init, list_p);
+	  generate_one_element_init (elt->replacement, init, list_p);
 	  elt->visited = true;
 	}
       return result;
@@ -2477,7 +2039,7 @@
 
 static void
 scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
-	       bool is_output)
+	       bool is_output, bool use_all)
 {
   tree list = NULL, stmt = bsi_stmt (*bsi);
 
@@ -2486,27 +2048,8 @@
       /* If we have a replacement, then updating the reference is as
 	 simple as modifying the existing statement in place.  */
       if (is_output)
-	{
-	  if (TREE_CODE (elt->replacement) == BIT_FIELD_REF
-	      && is_gimple_reg (TREE_OPERAND (elt->replacement, 0))
-	      && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
-	      && &GIMPLE_STMT_OPERAND (stmt, 0) == expr_p)
-	    {
-	      tree newstmt = sra_build_elt_assignment
-		(elt, GIMPLE_STMT_OPERAND (stmt, 1));
-	      if (TREE_CODE (newstmt) != STATEMENT_LIST)
-		{
-		  tree list = alloc_stmt_list ();
-		  append_to_statement_list (newstmt, &list);
-		  newstmt = list;
-		}
-	      sra_replace (bsi, newstmt);
-	      return;
-	    }
-
-	  mark_all_v_defs (stmt);
-	}
-      *expr_p = REPLDUP (elt->replacement);
+	mark_all_v_defs (stmt);
+      *expr_p = elt->replacement;
       update_stmt (stmt);
     }
   else
@@ -2524,24 +2067,18 @@
 	 This optimization would be most effective if sra_walk_function
 	 processed the blocks in dominator order.  */
 
-      generate_copy_inout (elt, false, generate_element_ref (elt), &list);
-      if (list)
+      generate_copy_inout (elt, is_output, generate_element_ref (elt), &list);
+      if (list == NULL)
+	return;
+      mark_all_v_defs (list);
+      if (is_output)
+	sra_insert_after (bsi, list);
+      else
 	{
-	  mark_all_v_defs (list);
 	  sra_insert_before (bsi, list);
-	  mark_no_warning (elt);
+	  if (use_all)
+	    mark_no_warning (elt);
 	}
-
-      if (is_output)
-	{
-	  list = NULL;
-	  generate_copy_inout (elt, true, generate_element_ref (elt), &list);
-	  if (list)
-	    {
-	      mark_all_v_defs (list);
-	      sra_insert_after (bsi, list);
-	    }
-	}
     }
 }
 
@@ -2564,7 +2101,7 @@
       gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
 
       GIMPLE_STMT_OPERAND (stmt, 0) = lhs_elt->replacement;
-      GIMPLE_STMT_OPERAND (stmt, 1) = REPLDUP (rhs_elt->replacement);
+      GIMPLE_STMT_OPERAND (stmt, 1) = rhs_elt->replacement;
       update_stmt (stmt);
     }
   else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
@@ -2706,7 +2243,7 @@
     {
       /* Since ELT is not fully instantiated, we have to leave the
 	 block copy in place.  Treat this as a USE.  */
-      scalarize_use (elt, NULL, bsi, is_output);
+      scalarize_use (elt, NULL, bsi, is_output, false);
     }
   else
     {
@@ -2718,8 +2255,8 @@
 
       mark_all_v_defs (stmt);
       generate_copy_inout (elt, is_output, other, &list);
-      gcc_assert (list);
       mark_all_v_defs (list);
+      gcc_assert (list);
 
       /* Preserve EH semantics.  */
       if (stmt_ends_bb_p (stmt))
@@ -2815,10 +2352,6 @@
 	    fputc ('.', f);
 	  print_generic_expr (f, elt->element, dump_flags);
 	}
-      else if (TREE_CODE (elt->element) == BIT_FIELD_REF)
-	fprintf (f, "$B" HOST_WIDE_INT_PRINT_DEC "F" HOST_WIDE_INT_PRINT_DEC,
-		 tree_low_cst (TREE_OPERAND (elt->element, 2), 1),
-		 tree_low_cst (TREE_OPERAND (elt->element, 1), 1));
       else if (TREE_CODE (elt->element) == RANGE_EXPR)
 	fprintf (f, "["HOST_WIDE_INT_PRINT_DEC".."HOST_WIDE_INT_PRINT_DEC"]",
 		 TREE_INT_CST_LOW (TREE_OPERAND (elt->element, 0)),

[-- Attachment #3: Type: text/plain, Size: 249 bytes --]


-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member         http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

  reply	other threads:[~2007-04-30 17:40 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-20  0:29 Bernd Schmidt
2007-04-20  3:19 ` Andrew Pinski
2007-04-20  3:53 ` Daniel Berlin
2007-04-20  4:30   ` Bernd Schmidt
2007-04-20  4:48     ` Andrew Pinski
2007-04-20  7:32     ` Alexandre Oliva
2007-04-20 12:57       ` Bernd Schmidt
2007-04-20 18:28         ` Alexandre Oliva
2007-04-20 18:40         ` Alexandre Oliva
2007-04-30 10:09           ` Bernd Schmidt
2007-04-30 19:04             ` Alexandre Oliva
2007-04-30 19:08               ` Alexandre Oliva [this message]
2007-05-01 15:38             ` Alexandre Oliva
2007-05-01 15:45               ` Eric Botcazou
2007-05-04  0:19                 ` Alexandre Oliva
2007-05-01 15:53               ` Diego Novillo
2007-05-01 16:03                 ` Eric Botcazou
2007-05-01 16:51                   ` Arnaud Charlet
2007-05-01 16:54                     ` Arnaud Charlet
2007-05-01 17:31                   ` Andreas Schwab
2007-05-01 16:24               ` Roman Zippel
2007-05-04  4:07                 ` Alexandre Oliva
2007-05-04  5:24                   ` Alexandre Oliva
2007-05-05 18:19                     ` Roman Zippel
2007-05-06  5:13                       ` Alexandre Oliva
2007-05-06 12:13                         ` Bernd Schmidt
2007-05-06 14:27                           ` Alexandre Oliva
2007-05-06 15:01                             ` Alexandre Oliva
2007-05-06 23:44                               ` Alexandre Oliva
2007-05-06 23:51                                 ` Diego Novillo
2007-05-07  0:14                                   ` Alexandre Oliva
2007-05-07  2:21                                     ` Andrew Pinski
2007-05-09 12:25                                     ` Bernd Schmidt
2007-05-10  7:47                                       ` Alexandre Oliva
2007-05-10 11:00                                         ` Bernd Schmidt
2007-05-22  7:09                                           ` Alexandre Oliva
2007-05-22 17:34                                             ` Roman Zippel
2007-05-22 20:49                                               ` Alexandre Oliva
2007-05-23 13:07                                                 ` Roman Zippel
2007-05-22 21:23                                             ` Alexandre Oliva
2007-05-09 18:32                                     ` Roman Zippel
2007-05-10  7:49                                       ` Alexandre Oliva
2007-05-15 17:39                                         ` Alexandre Oliva
2007-05-17 21:17                                           ` Andrew Pinski
2007-05-28 10:49                                           ` Bernd Schmidt
2007-05-31 20:57                                             ` Alexandre Oliva
2007-06-02 17:41                                               ` Bernd Schmidt
2007-06-06  3:18                                                 ` Alexandre Oliva
2007-06-25 18:48                                                   ` Alexandre Oliva
2007-06-26 23:01                                                   ` Bernd Schmidt
2007-06-28  4:50                                                     ` Alexandre Oliva
2007-07-03  0:52                                                       ` Roman Zippel
2007-07-06  9:21                                                         ` Alexandre Oliva
2007-08-24  7:28                                                           ` SRA bit-field optimization (was: Re: Reload bug & SRA oddness) Alexandre Oliva
2007-09-28  9:17                                                             ` SRA bit-field optimization Alexandre Oliva
2007-10-02 17:15                                                               ` Richard Guenther
2007-10-03  8:38                                                                 ` Richard Sandiford
2007-10-03 16:50                                                                   ` Alexandre Oliva
2007-10-03 18:23                                                                     ` Richard Sandiford
2007-10-04 19:56                                                                     ` Richard Sandiford
2007-10-05 17:43                                                                       ` Alexandre Oliva
2007-10-06  8:02                                                                         ` Richard Sandiford
2007-10-06 21:06                                                                           ` John David Anglin
2007-10-06 22:12                                                                             ` Richard Sandiford
2007-10-07 23:44                                                                               ` Alexandre Oliva
2007-10-08 21:14                                                                                 ` John David Anglin
2007-10-08 23:51                                                                                   ` Alexandre Oliva
2007-10-09  0:31                                                                                     ` John David Anglin
2007-10-09  4:41                                                                                       ` Alexandre Oliva
2007-10-09  4:45                                                                                 ` Alexandre Oliva
2007-10-06 16:01                                                                         ` David Daney
2007-10-03 14:37                                                                 ` Daniel Berlin
2007-10-03 14:44                                                                   ` Diego Novillo
2007-10-05 15:03                                                                 ` Richard Guenther
2007-10-05 16:20                                                                   ` Alexandre Oliva
2007-10-05 16:24                                                                     ` Richard Guenther
2007-10-05 16:26                                                                     ` Diego Novillo
2007-10-05 20:08                                                                       ` Alexandre Oliva
2007-10-09  4:55                                                                     ` Alexandre Oliva
2007-10-03  7:45                                                               ` Eric Botcazou
2007-10-03 21:36                                                                 ` Eric Botcazou
2007-10-08 20:28                                                                 ` Alexandre Oliva
2007-10-05  6:24                                                                   ` Eric Botcazou
2007-10-05 16:03                                                                     ` Alexandre Oliva
2007-10-07  9:01                                                                       ` Eric Botcazou
2007-10-07 23:58                                                                         ` Alexandre Oliva
2007-10-08  5:13                                                                           ` Eric Botcazou
2007-10-08 20:29                                                                             ` Alexandre Oliva
2007-10-08 21:00                                                                               ` Eric Botcazou
2007-10-08 23:56                                                                                 ` Alexandre Oliva
2007-09-29 17:52                                                           ` Reload bug & SRA oddness Diego Novillo
2007-04-20 17:07     ` Daniel Berlin
2007-04-28 20:48   ` Bernd Schmidt
2007-04-28 21:26     ` Richard Guenther
2007-04-28 21:49       ` Daniel Berlin
2007-04-29 10:04         ` Richard Guenther
2007-04-29 10:27           ` Richard Guenther
2007-04-29 10:31             ` Richard Guenther
2007-04-29 11:16               ` Richard Guenther
2007-04-20 14:01 ` Bernd Schmidt
2007-04-20 22:00   ` Eric Botcazou
2007-04-28 16:25     ` Bernd Schmidt
2007-04-28 17:46       ` Eric Botcazou
2007-04-29  6:42   ` Bernd Schmidt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ork5vtu5ev.fsf@free.oliva.athome.lsd.ic.unicamp.br \
    --to=aoliva@redhat.com \
    --cc=bernds_cb1@t-online.de \
    --cc=dberlin@dberlin.org \
    --cc=dnovillo@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=pinskia@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).