This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fix lto bootstrap


On Mon, 4 Oct 2010, Jan Hubicka wrote:

> Hi,
> LTO bootstrap fails because we incorrectly fold
> insn_data[CODE_FOR_insv].operand[1].predicate (GEN_INT..
> into call to NULL.
> 
> The problem is that we have
> MEM[ptr+24].predicate access, where ptr is isnsn_code[2000].
> The reference really access insn_code[2001].predicate, but since 
> get_base_constructor handle ARRAY_REF by calling fold_const_aggregate_ref that
> return constructor of insn_code[2000] only, we don't find matching field while
> looking for field at offset 24.
> 
> The following patch makes get_base_constructor to use
> get_ref_base_and_extend and simply adjust the offset of outer reference.
> This makes the code bit simpler too.
> 
> Bootstrapped/regetested x86_64-linux, OK? I also did C only profedbootstrap
> and verified that it works now.
> 
> Honza
> 
> 	PR middle-end/45871
> 	* tree-ssa-ccp.c (get_base_constructor): Take HOST_WIDE_INT offset;
> 	use get_ref_base_and_offset to handle references.
> 	(fold_const_aggregate_ref): Update.
> Index: tree-ssa-ccp.c
> ===================================================================
> *** tree-ssa-ccp.c	(revision 164917)
> --- tree-ssa-ccp.c	(working copy)
> *************** ccp_fold (gimple stmt)
> *** 1319,1336 ****
>   }
>   
>   /* See if we can find constructor defining value of BASE.
>   
>      As a special case, return error_mark_node when constructor
>      is not explicitly available, but it is known to be zero
>      such as 'static const int a;'.  */
>   static tree
> ! get_base_constructor (tree base, tree *offset)
>   {
> !   *offset = NULL;
>     if (TREE_CODE (base) == MEM_REF)
>       {
>         if (!integer_zerop (TREE_OPERAND (base, 1)))
> !         *offset = TREE_OPERAND (base, 1);
>   
>         base = get_constant_value (TREE_OPERAND (base, 0));
>         if (!base || TREE_CODE (base) != ADDR_EXPR)
> --- 1319,1344 ----
>   }
>   
>   /* See if we can find constructor defining value of BASE.
> +    When we know the consructor with constant offset (such as
> +    base is array[40] and we do know constructor of array), then
> +    BIT_OFFSET is adjusted accordingly.
>   
>      As a special case, return error_mark_node when constructor
>      is not explicitly available, but it is known to be zero
>      such as 'static const int a;'.  */
>   static tree
> ! get_base_constructor (tree base, HOST_WIDE_INT *bit_offset)
>   {
> !   HOST_WIDE_INT bit_offset2, size, max_size;
>     if (TREE_CODE (base) == MEM_REF)
>       {
>         if (!integer_zerop (TREE_OPERAND (base, 1)))
> ! 	{
> ! 	  if (!host_integerp (TREE_OPERAND (base, 1), 0))
> ! 	    return NULL_TREE;
> ! 	  *bit_offset += (TREE_INT_CST_LOW (TREE_OPERAND (base, 1))
> ! 			  * BITS_PER_UNIT);

Please use mem_ref_offset (base).low * BITS_PER_UNIT.  Note that
the overflow check is wrong as you are multiplying with BITS_PER_UNIT.

Using get_addr_base_and_unit_offset () throughout folding and
handling bit-field references explicitly would avoid this.
Consider following up with such cleanup (or I might take a stab
at the code if you like).

Ok with that change.

Thanks,
Richard.

> ! 	}
>   
>         base = get_constant_value (TREE_OPERAND (base, 0));
>         if (!base || TREE_CODE (base) != ADDR_EXPR)
> *************** get_base_constructor (tree base, tree *o
> *** 1359,1365 ****
>   
>       case ARRAY_REF:
>       case COMPONENT_REF:
> !       return fold_const_aggregate_ref (base);
>         break;
>   
>       case STRING_CST:
> --- 1367,1377 ----
>   
>       case ARRAY_REF:
>       case COMPONENT_REF:
> !       base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size);
> !       if (max_size == -1 || size != max_size)
> ! 	return NULL_TREE;
> !       *bit_offset +=  bit_offset2;
> !       return get_base_constructor (base, bit_offset);
>         break;
>   
>       case STRING_CST:
> *************** fold_const_aggregate_ref (tree t)
> *** 1597,1603 ****
>     tree ctor, idx, base;
>     HOST_WIDE_INT offset, size, max_size;
>     tree tem;
> -   tree ctr_offset;
>   
>     if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration)
>       return get_symbol_constant_value (t);
> --- 1609,1614 ----
> *************** fold_const_aggregate_ref (tree t)
> *** 1633,1645 ****
>   	      offset *= BITS_PER_UNIT;
>   
>   	      base = TREE_OPERAND (t, 0);
> ! 	      ctor = get_base_constructor (base, &ctr_offset);
> ! 	      if (ctr_offset)
> ! 		{
> ! 		  if (!host_integerp (ctr_offset, 1))
> ! 		    return NULL_TREE;
> ! 		  offset += TREE_INT_CST_LOW (ctr_offset) * BITS_PER_UNIT;
> ! 		}
>   	      /* Empty constructor.  Always fold to 0. */
>   	      if (ctor == error_mark_node)
>   		return build_zero_cst (TREE_TYPE (t));
> --- 1644,1650 ----
>   	      offset *= BITS_PER_UNIT;
>   
>   	      base = TREE_OPERAND (t, 0);
> ! 	      ctor = get_base_constructor (base, &offset);
>   	      /* Empty constructor.  Always fold to 0. */
>   	      if (ctor == error_mark_node)
>   		return build_zero_cst (TREE_TYPE (t));
> *************** fold_const_aggregate_ref (tree t)
> *** 1661,1667 ****
>       case TARGET_MEM_REF:
>       case MEM_REF:
>         base = get_ref_base_and_extent (t, &offset, &size, &max_size);
> !       ctor = get_base_constructor (base, &ctr_offset);
>   
>         /* Empty constructor.  Always fold to 0. */
>         if (ctor == error_mark_node)
> --- 1666,1672 ----
>       case TARGET_MEM_REF:
>       case MEM_REF:
>         base = get_ref_base_and_extent (t, &offset, &size, &max_size);
> !       ctor = get_base_constructor (base, &offset);
>   
>         /* Empty constructor.  Always fold to 0. */
>         if (ctor == error_mark_node)
> *************** fold_const_aggregate_ref (tree t)
> *** 1673,1684 ****
>         if (!ctor)
>   	return NULL_TREE;
>   
> -       if (ctr_offset)
> - 	{
> - 	  if (!host_integerp (ctr_offset, 1))
> - 	    return NULL_TREE;
> - 	  offset += TREE_INT_CST_LOW (ctr_offset) * BITS_PER_UNIT;
> - 	}
>         /* Out of bound array access.  Value is undefined, but don't fold. */
>         if (offset < 0)
>   	return NULL_TREE;
> --- 1678,1683 ----
> 
> 

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]