"Alexander Monakov" <[EMAIL PROTECTED]> writes:

> The implementation follows the outline presented in my initial message
> on the project, here: http://gcc.gnu.org/ml/gcc/2007-03/msg00900.html
> .  Data references and data dependency relations obtained via
> compute_dependencies_for_loop are copied into containing struct (which
> is a member of struct function).  This containing struct is marked
> GTY((skip)), because its lifetime and lifetime of its components is
> known (from the moment of export until destruction late in the RTL
> pipeline).  However, I need to preserve trees that are referenced in
> the exported datarefs (to be able to bind MEMs to datarefs later), so
> I need to put them into a GC-visible array.  For now that array is
> global.  Can it be done better?

It seems to me that this array could also be in the function struct.
I don't see why not.  Given the way it is used, it also seems to me
that this array should be a pointer_map.

> MEMs are bound to datarefs by means of saving original trees for MEMs
> during expand.  This is a large part of the attached patch with
> changes to emit-rtl.[ch], which adds new field to struct mem_attrs
> (mem_orig_expr), initializes it and propagates through various RTL
> transformations.  Notice that it has stricter hashing  (as compared to
> orig_expr part of the same struct), so it will reduce sharing of
> mem_attrs (and also increase size of the struct, obviously).  Can it
> be a problem?  Please also note that this patch is a part of aliasing
> information exporting patch by Dmitry Melnik, which available now in
> alias-export branch.

Adding a new field to mem_attrs could be a problem.  You'll have to
measure to see how much the memory usage changes.

> After original tree is found, a corresponding dataref is looked up in
> exported info.  I guess I will need here hashtabs for fast lookup
> (also for searching ddrs for pairs of datarefs), am I right?

Yes, hash tables or pointer maps.

> The verifier also frequently breaks on passes that create unreachable
> basic blocks (because dominator analysis called from flow_loops_find
> asserts there are none).  For now I just place
> delete_unreachable_blocks in such passes, is that ok?

Not for the final patch, but it's OK for debugging.


> +/* If EXPR contains conversions at the root of the tree, all of them 
> +   will be removed.  */
> +
> +static tree
> +skip_conversions (tree expr)
> +{
> +  tree inner = expr;
> +  /* Remove any conversions: they don't change what the underlying
> +     object is.  Likewise for SAVE_EXPR.  */
> +  while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR
> +        || TREE_CODE (inner) == NON_LVALUE_EXPR
> +        || TREE_CODE (inner) == VIEW_CONVERT_EXPR
> +        || TREE_CODE (inner) == SAVE_EXPR)
> +    inner = TREE_OPERAND (inner, 0);
> +  return inner;
> +}

I don't understand why it's OK to throw all these away.  Some of them
change the meaning of the expression.  I also don't understand why you
want to throw them away.


> @@ -1401,27 +1456,36 @@ component_ref_for_mem_expr (tree ref)
>  {
>    tree inner = TREE_OPERAND (ref, 0);
>  
> -  if (TREE_CODE (inner) == COMPONENT_REF)
> +  /* Remove any conversions: they don't change what the underlying
> +     object is.  Likewise for SAVE_EXPR.  */
> +  while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR
> +      || TREE_CODE (inner) == NON_LVALUE_EXPR
> +      || TREE_CODE (inner) == VIEW_CONVERT_EXPR
> +      || TREE_CODE (inner) == SAVE_EXPR)
> +    inner = TREE_OPERAND (inner, 0);
> +
> +  if (TREE_CODE (inner) == COMPONENT_REF || TREE_CODE (inner) == 
> INDIRECT_REF)
>      inner = component_ref_for_mem_expr (inner);
>    else
>      {
> -      /* Now remove any conversions: they don't change what the underlying
> -      object is.  Likewise for SAVE_EXPR.  */
> -      while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == 
> CONVERT_EXPR
> -          || TREE_CODE (inner) == NON_LVALUE_EXPR
> -          || TREE_CODE (inner) == VIEW_CONVERT_EXPR
> -          || TREE_CODE (inner) == SAVE_EXPR)
> -     inner = TREE_OPERAND (inner, 0);
> -
>        if (! DECL_P (inner))
>       inner = NULL_TREE;
>      }
>  
>    if (inner == TREE_OPERAND (ref, 0))
>      return ref;
> -  else
> -    return build3 (COMPONENT_REF, TREE_TYPE (ref), inner,
> -                TREE_OPERAND (ref, 1), NULL_TREE);
> +  else if (TREE_CODE (ref) == COMPONENT_REF)
> +    {
> +      return build3 (COMPONENT_REF, TREE_TYPE (ref), inner,
> +                  TREE_OPERAND (ref, 1), NULL_TREE);
> +    }
> +  else  /* INDIRECT_REF.  */
> +    {
> +      if (inner == NULL_TREE)
> +     return NULL_TREE;
> +      else
> +     return build1 (INDIRECT_REF, TREE_TYPE (ref), inner);
> +    }
>  }

The handling of INDIRECT_REF here seems clearly wrong.  You definitely
can't discard conversions for an INDIRECT_REF.


Hope this helps a bit.  I will have more luck understanding what is
going on when I see how you use the data.

Ian

Reply via email to