public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Work towards fixing PR66142
@ 2015-09-18  7:58 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2015-09-18  7:58 UTC (permalink / raw)
  To: gcc-patches


The following patch fixes PR66142 up to the point where we run into
a alias disambiguation issue.  One step at a time...

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-09-18  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/66142
	* fold-const.c (operand_equal_p): When OEP_ADDRESS_OF
	treat MEM[&x] and x the same.
	* tree-ssa-sccvn.h (vn_reference_fold_indirect): Remove.
	* tree-ssa-sccvn.c (vn_reference_fold_indirect): Return true
	when we simplified sth.
	(vn_reference_maybe_forwprop_address): Likewise.
	(valueize_refs_1): When we simplified through
	vn_reference_fold_indirect or vn_reference_maybe_forwprop_address
	set valueized_anything to true.
	(vn_reference_lookup_3): Use stmt_kills_ref_p to see whether
	one ref kills the other instead of just a offset-based test.
	* tree-ssa-alias.c (stmt_kills_ref_p): Use OEP_ADDRESS_OF
	for the operand_equal_p test to compare bases and also compare
	sizes.

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 227859)
--- gcc/fold-const.c	(working copy)
*************** operand_equal_p (const_tree arg0, const_
*** 2752,2761 ****
  				   TREE_OPERAND (arg1, 0), flags);
      }
  
!   if (TREE_CODE (arg0) != TREE_CODE (arg1)
        /* NOP_EXPR and CONVERT_EXPR are considered equal.  */
!       && !(CONVERT_EXPR_P (arg0) && CONVERT_EXPR_P (arg1)))
!     return 0;
  
    /* This is needed for conversions and for COMPONENT_REF.
       Might as well play it safe and always test this.  */
--- 2759,2791 ----
  				   TREE_OPERAND (arg1, 0), flags);
      }
  
!   if (TREE_CODE (arg0) != TREE_CODE (arg1))
!     {
        /* NOP_EXPR and CONVERT_EXPR are considered equal.  */
!       if (CONVERT_EXPR_P (arg0) && CONVERT_EXPR_P (arg1))
! 	;
!       else if (flags & OEP_ADDRESS_OF)
! 	{
! 	  /* If we are interested in comparing addresses ignore
! 	     MEM_REF wrappings of the base that can appear just for
! 	     TBAA reasons.  */
! 	  if (TREE_CODE (arg0) == MEM_REF
! 	      && DECL_P (arg1)
! 	      && TREE_CODE (TREE_OPERAND (arg0, 0)) == ADDR_EXPR
! 	      && TREE_OPERAND (TREE_OPERAND (arg0, 0), 0) == arg1
! 	      && integer_zerop (TREE_OPERAND (arg0, 1)))
! 	    return 1;
! 	  else if (TREE_CODE (arg1) == MEM_REF
! 		   && DECL_P (arg0)
! 		   && TREE_CODE (TREE_OPERAND (arg1, 0)) == ADDR_EXPR
! 		   && TREE_OPERAND (TREE_OPERAND (arg1, 0), 0) == arg0
! 		   && integer_zerop (TREE_OPERAND (arg1, 1)))
! 	    return 1;
! 	  return 0;
! 	}
!       else
! 	return 0;
!     }
  
    /* This is needed for conversions and for COMPONENT_REF.
       Might as well play it safe and always test this.  */
Index: gcc/tree-ssa-sccvn.h
===================================================================
*** gcc/tree-ssa-sccvn.h	(revision 227859)
--- gcc/tree-ssa-sccvn.h	(working copy)
*************** vn_nary_op_t vn_nary_op_insert (tree, tr
*** 204,211 ****
  vn_nary_op_t vn_nary_op_insert_stmt (gimple, tree);
  vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code,
  				       tree, tree *, tree, unsigned int);
- void vn_reference_fold_indirect (vec<vn_reference_op_s> *,
- 				 unsigned int *);
  bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree,
  				    vec<vn_reference_op_s> );
  tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
--- 204,209 ----
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 227859)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** copy_reference_ops_from_call (gcall *cal
*** 1184,1190 ****
  
  /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
     *I_P to point to the last element of the replacement.  */
! void
  vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
  			    unsigned int *i_p)
  {
--- 1200,1206 ----
  
  /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
     *I_P to point to the last element of the replacement.  */
! static bool
  vn_reference_fold_indirect (vec<vn_reference_op_s> *ops,
  			    unsigned int *i_p)
  {
*************** vn_reference_fold_indirect (vec<vn_refer
*** 1210,1221 ****
  	mem_op->off = tree_to_shwi (mem_op->op0);
        else
  	mem_op->off = -1;
      }
  }
  
  /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
     *I_P to point to the last element of the replacement.  */
! static void
  vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
  				     unsigned int *i_p)
  {
--- 1226,1239 ----
  	mem_op->off = tree_to_shwi (mem_op->op0);
        else
  	mem_op->off = -1;
+       return true;
      }
+   return false;
  }
  
  /* Fold *& at position *I_P in a vn_reference_op_s vector *OPS.  Updates
     *I_P to point to the last element of the replacement.  */
! static bool
  vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
  				     unsigned int *i_p)
  {
*************** vn_reference_maybe_forwprop_address (vec
*** 1228,1239 ****
  
    def_stmt = SSA_NAME_DEF_STMT (op->op0);
    if (!is_gimple_assign (def_stmt))
!     return;
  
    code = gimple_assign_rhs_code (def_stmt);
    if (code != ADDR_EXPR
        && code != POINTER_PLUS_EXPR)
!     return;
  
    off = offset_int::from (mem_op->op0, SIGNED);
  
--- 1246,1257 ----
  
    def_stmt = SSA_NAME_DEF_STMT (op->op0);
    if (!is_gimple_assign (def_stmt))
!     return false;
  
    code = gimple_assign_rhs_code (def_stmt);
    if (code != ADDR_EXPR
        && code != POINTER_PLUS_EXPR)
!     return false;
  
    off = offset_int::from (mem_op->op0, SIGNED);
  
*************** vn_reference_maybe_forwprop_address (vec
*** 1265,1275 ****
  	  ops->pop ();
  	  ops->safe_splice (tem);
  	  --*i_p;
! 	  return;
  	}
        if (!addr_base
  	  || TREE_CODE (addr_base) != MEM_REF)
! 	return;
  
        off += addr_offset;
        off += mem_ref_offset (addr_base);
--- 1283,1293 ----
  	  ops->pop ();
  	  ops->safe_splice (tem);
  	  --*i_p;
! 	  return true;
  	}
        if (!addr_base
  	  || TREE_CODE (addr_base) != MEM_REF)
! 	return false;
  
        off += addr_offset;
        off += mem_ref_offset (addr_base);
*************** vn_reference_maybe_forwprop_address (vec
*** 1282,1288 ****
        ptroff = gimple_assign_rhs2 (def_stmt);
        if (TREE_CODE (ptr) != SSA_NAME
  	  || TREE_CODE (ptroff) != INTEGER_CST)
! 	return;
  
        off += wi::to_offset (ptroff);
        op->op0 = ptr;
--- 1300,1306 ----
        ptroff = gimple_assign_rhs2 (def_stmt);
        if (TREE_CODE (ptr) != SSA_NAME
  	  || TREE_CODE (ptroff) != INTEGER_CST)
! 	return false;
  
        off += wi::to_offset (ptroff);
        op->op0 = ptr;
*************** vn_reference_maybe_forwprop_address (vec
*** 1303,1308 ****
--- 1321,1327 ----
      vn_reference_maybe_forwprop_address (ops, i_p);
    else if (TREE_CODE (op->op0) == ADDR_EXPR)
      vn_reference_fold_indirect (ops, i_p);
+   return true;
  }
  
  /* Optimize the reference REF to a constant if possible or return
*************** valueize_refs_1 (vec<vn_reference_op_s>
*** 1475,1485 ****
  	  && vro->op0
  	  && TREE_CODE (vro->op0) == ADDR_EXPR
  	  && orig[i - 1].opcode == MEM_REF)
! 	vn_reference_fold_indirect (&orig, &i);
        else if (i > 0
  	       && vro->opcode == SSA_NAME
  	       && orig[i - 1].opcode == MEM_REF)
! 	vn_reference_maybe_forwprop_address (&orig, &i);
        /* If it transforms a non-constant ARRAY_REF into a constant
  	 one, adjust the constant offset.  */
        else if (vro->opcode == ARRAY_REF
--- 1494,1510 ----
  	  && vro->op0
  	  && TREE_CODE (vro->op0) == ADDR_EXPR
  	  && orig[i - 1].opcode == MEM_REF)
! 	{
! 	  if (vn_reference_fold_indirect (&orig, &i))
! 	    *valueized_anything = true;
! 	}
        else if (i > 0
  	       && vro->opcode == SSA_NAME
  	       && orig[i - 1].opcode == MEM_REF)
! 	{
! 	  if (vn_reference_maybe_forwprop_address (&orig, &i))
! 	    *valueized_anything = true;
! 	}
        /* If it transforms a non-constant ARRAY_REF into a constant
  	 one, adjust the constant offset.  */
        else if (vro->opcode == ARRAY_REF
*************** vn_reference_lookup_3 (ao_ref *ref, tree
*** 1880,1886 ****
  	       || handled_component_p (gimple_assign_rhs1 (def_stmt))))
      {
        tree base2;
!       HOST_WIDE_INT offset2, size2, maxsize2;
        int i, j;
        auto_vec<vn_reference_op_s> rhs;
        vn_reference_op_t vro;
--- 1948,1954 ----
  	       || handled_component_p (gimple_assign_rhs1 (def_stmt))))
      {
        tree base2;
!       HOST_WIDE_INT maxsize2;
        int i, j;
        auto_vec<vn_reference_op_s> rhs;
        vn_reference_op_t vro;
*************** vn_reference_lookup_3 (ao_ref *ref, tree
*** 1891,1898 ****
  
        /* See if the assignment kills REF.  */
        base2 = ao_ref_base (&lhs_ref);
-       offset2 = lhs_ref.offset;
-       size2 = lhs_ref.size;
        maxsize2 = lhs_ref.max_size;
        if (maxsize2 == -1
  	  || (base != base2
--- 1959,1964 ----
*************** vn_reference_lookup_3 (ao_ref *ref, tree
*** 1901,1908 ****
  		  || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
  		  || !tree_int_cst_equal (TREE_OPERAND (base, 1),
  					  TREE_OPERAND (base2, 1))))
! 	  || offset2 > offset
! 	  || offset2 + size2 < offset + maxsize)
  	return (void *)-1;
  
        /* Find the common base of ref and the lhs.  lhs_ops already
--- 1967,1973 ----
  		  || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0)
  		  || !tree_int_cst_equal (TREE_OPERAND (base, 1),
  					  TREE_OPERAND (base2, 1))))
! 	  || !stmt_kills_ref_p (def_stmt, ref))
  	return (void *)-1;
  
        /* Find the common base of ref and the lhs.  lhs_ops already

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c	(revision 227859)
--- gcc/tree-ssa-alias.c	(working copy)
*************** stmt_kills_ref_p (gimple stmt, ao_ref *r
*** 2282,2290 ****
  	      if (saved_lhs0)
  		TREE_OPERAND (lhs, 0) = saved_lhs0;
  	    }
! 	  /* Finally check if lhs is equal or equal to the base candidate
! 	     of the access.  */
! 	  if (operand_equal_p (lhs, base, 0))
  	    return true;
  	}
  
--- 2306,2321 ----
  	      if (saved_lhs0)
  		TREE_OPERAND (lhs, 0) = saved_lhs0;
  	    }
! 	  /* Finally check if the lhs has the same address and size as the
! 	     base candidate of the access.  */
! 	  if (lhs == base
! 	      || (((TYPE_SIZE (TREE_TYPE (lhs))
! 		    == TYPE_SIZE (TREE_TYPE (base)))
! 		   || (TYPE_SIZE (TREE_TYPE (lhs))
! 		       && TYPE_SIZE (TREE_TYPE (base))
! 		       && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
! 					   TYPE_SIZE (TREE_TYPE (base)), 0)))
! 		  && operand_equal_p (lhs, base, OEP_ADDRESS_OF)))
  	    return true;
  	}
  

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-09-18  7:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-18  7:58 [PATCH] Work towards fixing PR66142 Richard Biener

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).