Re: [RFC] Should SRA stop producing COMPONENT_REF for non-bit-fields (again)?

2012-04-13 Thread Richard Guenther
On Thu, 12 Apr 2012, Martin Jambor wrote:

 Hi,
 
 On Wed, Apr 04, 2012 at 04:42:05PM +0200, Richard Guenther wrote:
  On Wed, 4 Apr 2012, Martin Jambor wrote:
  
   Hi everyone, especially Richi and Eric,
   
   I'd like to know what is your attitude to changing SRA's
   build_ref_for_model to what it once looked like, so that it produces
   COMPONENT_REFs only for bit-fields.  The non-bit field handling was
   added in order to work-around problems when expanding non-aligned
   MEM_REFs on strict-alignment targets but that should not be a problem
   now and my experiments confirm that.  Last week I successfully
   bootstrapped and tested this patch on sparc64-linux (with the
   temporary MEM_EXPR patch, not including Java), ia64-linux (without
   Ada), x86_64-linux, i686-linux and tested it on hppa-linux (only C and
   C++).
 
 ...
 
   
   2012-03-20 Martin Jambor mjam...@suse.cz
   
 * tree-sra.c (build_ref_for_model): Create COMPONENT_REFs only for
 bit-fields.
   
   Index: src/gcc/tree-sra.c
   ===
   *** src.orig/gcc/tree-sra.c
   --- src/gcc/tree-sra.c
   *** build_ref_for_offset (location_t loc, tr
   *** 1489,1558 
   return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
 }
 
   - DEF_VEC_ALLOC_P_STACK (tree);
   - #define VEC_tree_stack_alloc(alloc) VEC_stack_alloc (tree, alloc)
   - 
 /* Construct a memory reference to a part of an aggregate BASE at the 
   given
   !OFFSET and of the type of MODEL.  In case this is a chain of 
   references
   !to component, the function will replicate the chain of 
   COMPONENT_REFs of
   !the expression of MODEL to access it.  GSI and INSERT_AFTER have the 
   same
   !meaning as in build_ref_for_offset.  */
 
 static tree
 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
  struct access *model, gimple_stmt_iterator *gsi,
  bool insert_after)
 {
   !   tree type = model-type, t;
   !   VEC(tree,stack) *cr_stack = NULL;
   ! 
   !   if (TREE_CODE (model-expr) == COMPONENT_REF)
 {
   !   tree expr = model-expr;
   ! 
   !   /* Create a stack of the COMPONENT_REFs so later we can walk them 
   in
   !  order from inner to outer.  */
   !   cr_stack = VEC_alloc (tree, stack, 6);
   ! 
   !   do {
   ! tree field = TREE_OPERAND (expr, 1);
   ! tree cr_offset = component_ref_field_offset (expr);
   ! HOST_WIDE_INT bit_pos
   !   = tree_low_cst (cr_offset, 1) * BITS_PER_UNIT
   !   + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
 
   ! /* We can be called with a model different from the one 
   associated
   !with BASE so we need to avoid going up the chain too far.  */
   ! if (offset - bit_pos  0)
   !   break;
   ! 
   ! offset -= bit_pos;
   ! VEC_safe_push (tree, stack, cr_stack, expr);
   ! 
   ! expr = TREE_OPERAND (expr, 0);
   ! type = TREE_TYPE (expr);
   !   } while (TREE_CODE (expr) == COMPONENT_REF);
 }
   ! 
   !   t = build_ref_for_offset (loc, base, offset, type, gsi, insert_after);
   ! 
   !   if (TREE_CODE (model-expr) == COMPONENT_REF)
   ! {
   !   unsigned i;
   !   tree expr;
   ! 
   !   /* Now replicate the chain of COMPONENT_REFs from inner to outer. 
*/
   !   FOR_EACH_VEC_ELT_REVERSE (tree, cr_stack, i, expr)
   ! {
   !   tree field = TREE_OPERAND (expr, 1);
   !   t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), 
   t, field,
   !TREE_OPERAND (expr, 2));
   ! }
   ! 
   !   VEC_free (tree, stack, cr_stack);
   ! }
   ! 
   !   return t;
 }
 
 /* Construct a memory reference consisting of component_refs and 
   array_refs to
   --- 1489,1520 
   return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
 }
 
 /* Construct a memory reference to a part of an aggregate BASE at the 
   given
   !OFFSET and of the same type as MODEL.  In case this is a reference 
   to a
   !bit-field, the function will replicate the last component_ref of 
   model's
   !expr to access it.  GSI and INSERT_AFTER have the same meaning as in
   !build_ref_for_offset.  */
 
 static tree
 build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
  struct access *model, gimple_stmt_iterator *gsi,
  bool insert_after)
 {
   !   if (TREE_CODE (model-expr) == COMPONENT_REF
   !DECL_BIT_FIELD (TREE_OPERAND (model-expr, 1)))
  
  I think you need to test DECL_BIT_FIELD_TYPE here
 
 I have no problems changing that but in between revisions 164280 and
 166730 this test worked fine.  What exactly is the difference?
 
  
 {
   !   /* This access represents 

Re: [RFC] Should SRA stop producing COMPONENT_REF for non-bit-fields (again)?

2012-04-13 Thread Rainer Orth
Richard Guenther rguent...@suse.de writes:

 Anyway, the patch I posted previously would risk re-introducing PR
 50386 and PR 50326, even though they are very unlikely with just
 bit-fields.  So my current working version is the following, but it
 causes failure of libmudflap.c++/pass55-frag.cxx execution test so I'm
 not actually proposing it yet (sigh).

 I would not worry about mudflap tests.  The patch looks good to my
 eyes.

Are you sure the failure is new?  At least for 64-bit at -O,
libmudflap.c++/pass55-frag.cxx already fails right now (cf. PR
libmudflap/49843).

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: [RFC] Should SRA stop producing COMPONENT_REF for non-bit-fields (again)?

2012-04-13 Thread Martin Jambor
On Fri, Apr 13, 2012 at 01:57:33PM +0200, Rainer Orth wrote:
 Richard Guenther rguent...@suse.de writes:
 
  Anyway, the patch I posted previously would risk re-introducing PR
  50386 and PR 50326, even though they are very unlikely with just
  bit-fields.  So my current working version is the following, but it
  causes failure of libmudflap.c++/pass55-frag.cxx execution test so I'm
  not actually proposing it yet (sigh).
 
  I would not worry about mudflap tests.  The patch looks good to my
  eyes.
 
 Are you sure the failure is new?  At least for 64-bit at -O,
 libmudflap.c++/pass55-frag.cxx already fails right now (cf. PR
 libmudflap/49843).
 

Well, my patch makes it fail on all other optimization levels too (the
supposedly no-optimization variant is actually compiled with -O2).
But thanks for pointing me towards the bug, I'll use it as an excuse
to commit the patch nevertheless (mainly because I really cannot see
anything wrong going on there, at least with respect to SRA and this
change).

Thanks,

Martin



Re: [RFC] Should SRA stop producing COMPONENT_REF for non-bit-fields (again)?

2012-04-12 Thread Martin Jambor
Hi,

On Wed, Apr 04, 2012 at 04:42:05PM +0200, Richard Guenther wrote:
 On Wed, 4 Apr 2012, Martin Jambor wrote:
 
  Hi everyone, especially Richi and Eric,
  
  I'd like to know what is your attitude to changing SRA's
  build_ref_for_model to what it once looked like, so that it produces
  COMPONENT_REFs only for bit-fields.  The non-bit field handling was
  added in order to work-around problems when expanding non-aligned
  MEM_REFs on strict-alignment targets but that should not be a problem
  now and my experiments confirm that.  Last week I successfully
  bootstrapped and tested this patch on sparc64-linux (with the
  temporary MEM_EXPR patch, not including Java), ia64-linux (without
  Ada), x86_64-linux, i686-linux and tested it on hppa-linux (only C and
  C++).

...

  
  2012-03-20 Martin Jambor mjam...@suse.cz
  
  * tree-sra.c (build_ref_for_model): Create COMPONENT_REFs only for
  bit-fields.
  
  Index: src/gcc/tree-sra.c
  ===
  *** src.orig/gcc/tree-sra.c
  --- src/gcc/tree-sra.c
  *** build_ref_for_offset (location_t loc, tr
  *** 1489,1558 
  return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
}

  - DEF_VEC_ALLOC_P_STACK (tree);
  - #define VEC_tree_stack_alloc(alloc) VEC_stack_alloc (tree, alloc)
  - 
/* Construct a memory reference to a part of an aggregate BASE at the 
  given
  !OFFSET and of the type of MODEL.  In case this is a chain of references
  !to component, the function will replicate the chain of COMPONENT_REFs 
  of
  !the expression of MODEL to access it.  GSI and INSERT_AFTER have the 
  same
  !meaning as in build_ref_for_offset.  */

static tree
build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
   struct access *model, gimple_stmt_iterator *gsi,
   bool insert_after)
{
  !   tree type = model-type, t;
  !   VEC(tree,stack) *cr_stack = NULL;
  ! 
  !   if (TREE_CODE (model-expr) == COMPONENT_REF)
{
  !   tree expr = model-expr;
  ! 
  !   /* Create a stack of the COMPONENT_REFs so later we can walk them in
  !order from inner to outer.  */
  !   cr_stack = VEC_alloc (tree, stack, 6);
  ! 
  !   do {
  !   tree field = TREE_OPERAND (expr, 1);
  !   tree cr_offset = component_ref_field_offset (expr);
  !   HOST_WIDE_INT bit_pos
  ! = tree_low_cst (cr_offset, 1) * BITS_PER_UNIT
  ! + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));

  !   /* We can be called with a model different from the one associated
  !  with BASE so we need to avoid going up the chain too far.  */
  !   if (offset - bit_pos  0)
  ! break;
  ! 
  !   offset -= bit_pos;
  !   VEC_safe_push (tree, stack, cr_stack, expr);
  ! 
  !   expr = TREE_OPERAND (expr, 0);
  !   type = TREE_TYPE (expr);
  !   } while (TREE_CODE (expr) == COMPONENT_REF);
}
  ! 
  !   t = build_ref_for_offset (loc, base, offset, type, gsi, insert_after);
  ! 
  !   if (TREE_CODE (model-expr) == COMPONENT_REF)
  ! {
  !   unsigned i;
  !   tree expr;
  ! 
  !   /* Now replicate the chain of COMPONENT_REFs from inner to outer.  
  */
  !   FOR_EACH_VEC_ELT_REVERSE (tree, cr_stack, i, expr)
  !   {
  ! tree field = TREE_OPERAND (expr, 1);
  ! t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), t, field,
  !  TREE_OPERAND (expr, 2));
  !   }
  ! 
  !   VEC_free (tree, stack, cr_stack);
  ! }
  ! 
  !   return t;
}

/* Construct a memory reference consisting of component_refs and 
  array_refs to
  --- 1489,1520 
  return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
}

/* Construct a memory reference to a part of an aggregate BASE at the 
  given
  !OFFSET and of the same type as MODEL.  In case this is a reference to a
  !bit-field, the function will replicate the last component_ref of 
  model's
  !expr to access it.  GSI and INSERT_AFTER have the same meaning as in
  !build_ref_for_offset.  */

static tree
build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
   struct access *model, gimple_stmt_iterator *gsi,
   bool insert_after)
{
  !   if (TREE_CODE (model-expr) == COMPONENT_REF
  !DECL_BIT_FIELD (TREE_OPERAND (model-expr, 1)))
 
 I think you need to test DECL_BIT_FIELD_TYPE here

I have no problems changing that but in between revisions 164280 and
166730 this test worked fine.  What exactly is the difference?

 
{
  !   /* This access represents a bit-field.  */
  !   tree t, exp_type;

  !   offset -= int_bit_position (TREE_OPERAND (model-expr, 1));
 
 I'm not sure that offset is now byte-aligned for all the funny Ada
 bit-layouted records.  But maybe we don't even try to SRA those?

Aggregates containing aggregate fields which start at position
straddling 

Re: [RFC] Should SRA stop producing COMPONENT_REF for non-bit-fields (again)?

2012-04-04 Thread Richard Guenther
On Wed, 4 Apr 2012, Martin Jambor wrote:

 Hi everyone, especially Richi and Eric,
 
 I'd like to know what is your attitude to changing SRA's
 build_ref_for_model to what it once looked like, so that it produces
 COMPONENT_REFs only for bit-fields.  The non-bit field handling was
 added in order to work-around problems when expanding non-aligned
 MEM_REFs on strict-alignment targets but that should not be a problem
 now and my experiments confirm that.  Last week I successfully
 bootstrapped and tested this patch on sparc64-linux (with the
 temporary MEM_EXPR patch, not including Java), ia64-linux (without
 Ada), x86_64-linux, i686-linux and tested it on hppa-linux (only C and
 C++).
 
 The main downside of this change I see is that dumps would be a bit
 more difficult to read and understand when the fields disappear from
 them.
 
 The upsides are:
 
   - the expr field of SRA access was originally intended only for
 debugging (meaning both for compiler-produced debug info and
 debugging SRA).  It was never intended to influence the memory
 accesses produced by SRA and when we create them artificially, the
 effects of the particular form are hard to reason about.  If we
 ever lower bit-field accesses on gimple level, build_ref_for_model
 could go away completely (yeah, I know I'm getting carried way
 here).
 
   - If something like PR 51528 creeps up again and we need to create
 replacements of type returned by lang_hooks.types.type_for_mode,
 the produced MEM_REFs could simply have this type.  OTOH, the
 current COMPONENT_REFs would require to be encapsulated in V_C_Es
 and that is quite a nightmare.  I tried it in December, even made
 it work, but it was particularly ugly and needed some quite
 questionable uses of V_C_Es.
 
   - Well, it does the same thing and is much simpler, is it not?
 
 The patch fulfills the criteria to be committed and I can do it soon.
 OTOH, keeping it so on a number of platforms takes quite a lot of time
 (and has uncovered some non-related bugs) so I'd like to know whether
 it's worth it.
 
 Thanks,
 
 Martin
 
 
 
 2012-03-20 Martin Jambor mjam...@suse.cz
 
   * tree-sra.c (build_ref_for_model): Create COMPONENT_REFs only for
   bit-fields.
 
 Index: src/gcc/tree-sra.c
 ===
 *** src.orig/gcc/tree-sra.c
 --- src/gcc/tree-sra.c
 *** build_ref_for_offset (location_t loc, tr
 *** 1489,1558 
 return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
   }
   
 - DEF_VEC_ALLOC_P_STACK (tree);
 - #define VEC_tree_stack_alloc(alloc) VEC_stack_alloc (tree, alloc)
 - 
   /* Construct a memory reference to a part of an aggregate BASE at the given
 !OFFSET and of the type of MODEL.  In case this is a chain of references
 !to component, the function will replicate the chain of COMPONENT_REFs of
 !the expression of MODEL to access it.  GSI and INSERT_AFTER have the same
 !meaning as in build_ref_for_offset.  */
   
   static tree
   build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
struct access *model, gimple_stmt_iterator *gsi,
bool insert_after)
   {
 !   tree type = model-type, t;
 !   VEC(tree,stack) *cr_stack = NULL;
 ! 
 !   if (TREE_CODE (model-expr) == COMPONENT_REF)
   {
 !   tree expr = model-expr;
 ! 
 !   /* Create a stack of the COMPONENT_REFs so later we can walk them in
 !  order from inner to outer.  */
 !   cr_stack = VEC_alloc (tree, stack, 6);
 ! 
 !   do {
 ! tree field = TREE_OPERAND (expr, 1);
 ! tree cr_offset = component_ref_field_offset (expr);
 ! HOST_WIDE_INT bit_pos
 !   = tree_low_cst (cr_offset, 1) * BITS_PER_UNIT
 !   + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
   
 ! /* We can be called with a model different from the one associated
 !with BASE so we need to avoid going up the chain too far.  */
 ! if (offset - bit_pos  0)
 !   break;
 ! 
 ! offset -= bit_pos;
 ! VEC_safe_push (tree, stack, cr_stack, expr);
 ! 
 ! expr = TREE_OPERAND (expr, 0);
 ! type = TREE_TYPE (expr);
 !   } while (TREE_CODE (expr) == COMPONENT_REF);
   }
 ! 
 !   t = build_ref_for_offset (loc, base, offset, type, gsi, insert_after);
 ! 
 !   if (TREE_CODE (model-expr) == COMPONENT_REF)
 ! {
 !   unsigned i;
 !   tree expr;
 ! 
 !   /* Now replicate the chain of COMPONENT_REFs from inner to outer.  */
 !   FOR_EACH_VEC_ELT_REVERSE (tree, cr_stack, i, expr)
 ! {
 !   tree field = TREE_OPERAND (expr, 1);
 !   t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), t, field,
 !TREE_OPERAND (expr, 2));
 ! }
 ! 
 !   VEC_free (tree, stack, cr_stack);
 ! }
 ! 
 !   return t;
   }
   
   /* Construct a memory reference consisting of component_refs and array_refs 
 to
 --- 1489,1520 
 return