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]

Enable setting MEM alias checking


This enables the test that the new and old alias sets conflict and fixes
a number of bugs uncovered with that test, mostly in Ada code (GNAT itself).

Tested on alphaev56.

Mon Oct  1 19:20:57 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* alias.c (get_alias_set): Try to replace PLACEHOLDER_EXPR.
	Loop through NOPs, placeholders, and components.
	Don't go through NOPs if change mode.
	(record_alias_subset): Do nothing if SUBSET and SET are the same.
	* emit-rtl.c (set_mem_alias_set): Enable check.
	* expr.c (find_placeholder): New function.
	(expand_expr, case PLACEHOLDER_EXPR): Use it.
	(expand_expr, case COMPONENT_EXPR): Always copy OP0 when we need
	to modify it and avoid unneeded copies.
	* expr.h (expand_expr): Always define.
	(find_placeholder): New declaration.

*** alias.c	2001/10/01 11:00:45	1.143
--- alias.c	2001/10/01 19:22:59
*************** get_alias_set (t)
*** 471,484 ****
  
    /* We can be passed either an expression or a type.  This and the
!      language-specific routine may make mutually-recursive calls to
!      each other to figure out what to do.  At each juncture, we see if
!      this is a tree that the language may need to handle specially.
!      First handle things that aren't types and start by removing nops
!      since we care only about the actual object.  */
    if (! TYPE_P (t))
      {
!       while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR
! 	     || TREE_CODE (t) == NON_LVALUE_EXPR)
! 	t = TREE_OPERAND (t, 0);
  
        /* Now give the language a chance to do something but record what we
--- 471,500 ----
  
    /* We can be passed either an expression or a type.  This and the
!      language-specific routine may make mutually-recursive calls to each other
!      to figure out what to do.  At each juncture, we see if this is a tree
!      that the language may need to handle specially.  First handle things that
!      aren't types and start by removing nops since we care only about the
!      actual object.  Also replace PLACEHOLDER_EXPRs and pick up the outermost
!      object that we could have a pointer to.  */
    if (! TYPE_P (t))
      {
!       /* Remove any NOPs and see what any PLACEHOLD_EXPRs will expand to.  */
!       while (((TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR)
! 	      && (TYPE_MODE (TREE_TYPE (t))
! 		  == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0)))))
! 	     || TREE_CODE (t) == NON_LVALUE_EXPR
! 	     || TREE_CODE (t) == PLACEHOLDER_EXPR
! 	     || (handled_component_p (t) && ! can_address_p (t)))
! 	{
! 	  /* Give the language a chance to do something with this tree
! 	     before we go inside it.  */
! 	  if ((set = lang_get_alias_set (t)) != -1)
! 	    return set;
! 
! 	  if (TREE_CODE (t) == PLACEHOLDER_EXPR)
! 	    t = find_placeholder (t, 0);
! 	  else
! 	    t = TREE_OPERAND (t, 0);
! 	}
  
        /* Now give the language a chance to do something but record what we
*************** get_alias_set (t)
*** 488,500 ****
  	return set;
  
!       /* Now loop the same way as get_inner_reference and get the alias
! 	 set to use.  Pick up the outermost object that we could have
! 	 a pointer to.  */
!       while (handled_component_p (t) && ! can_address_p (t))
! 	t = TREE_OPERAND (t, 0);
! 
        if (TREE_CODE (t) == INDIRECT_REF)
  	{
- 	  /* Check for accesses through restrict-qualified pointers.  */
  	  tree decl = find_base_decl (TREE_OPERAND (t, 0));
  
--- 504,510 ----
  	return set;
  
!       /* Check for accesses through restrict-qualified pointers.  */
        if (TREE_CODE (t) == INDIRECT_REF)
  	{
  	  tree decl = find_base_decl (TREE_OPERAND (t, 0));
  
*************** record_alias_subset (superset, subset)
*** 587,590 ****
--- 597,605 ----
    alias_set_entry superset_entry;
    alias_set_entry subset_entry;
+ 
+   /* It is possible in complex type situations for both sets to be the same,
+      in which case we can ignore this operation.  */
+   if (superset == subset)
+     return;
  
    if (superset == 0)
*** emit-rtl.c	2001/10/01 11:00:45	1.207
--- emit-rtl.c	2001/10/01 19:23:23
*************** set_mem_alias_set (mem, set)
*** 1717,1726 ****
  {
    /* It would be nice to enable this check, but we can't quite yet.  */
- #if 0
  #ifdef ENABLE_CHECKING	
    /* If the new and old alias sets don't conflict, something is wrong.  */
    if (!alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)))
      abort ();
- #endif
  #endif
  
--- 1717,1724 ----
*** expr.c	2001/09/21 16:58:18	1.353
--- expr.c	2001/10/01 19:24:29
*************** check_max_integer_computation_mode (exp)
*** 5956,5959 ****
--- 5956,6022 ----
  #endif
  
+ /* Return an object on the placeholder list that matches EXP, a
+    PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
+    PLACEHOLDER_EXPR or a pointer type to it.  For further information,
+    see tree.def.  If no such object is found, abort.  If PLIST is nonzero,
+    it is a location into which a pointer into the placeholder list at
+    which the object is found is placed.  */
+ 
+ tree
+ find_placeholder (exp, plist)
+      tree exp;
+      tree *plist;
+ {
+   tree type = TREE_TYPE (exp);
+   tree placeholder_expr;
+ 
+   for (placeholder_expr = placeholder_list; placeholder_expr != 0;
+        placeholder_expr = TREE_CHAIN (placeholder_expr))
+     {
+       tree need_type = TYPE_MAIN_VARIANT (type);
+       tree elt;
+ 
+       /* Find the outermost reference that is of the type we want.  If none,
+ 	 see if any object has a type that is a pointer to the type we
+ 	 want.  */
+       for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
+ 	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
+ 		   || TREE_CODE (elt) == COND_EXPR)
+ 		  ? TREE_OPERAND (elt, 1)
+ 		  : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
+ 		  ? TREE_OPERAND (elt, 0) : 0))
+ 	if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
+ 	  {
+ 	    if (plist)
+ 	      *plist = placeholder_expr;
+ 	    return elt;
+ 	  }
+ 
+       for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
+ 	   elt
+ 	   = ((TREE_CODE (elt) == COMPOUND_EXPR
+ 	       || TREE_CODE (elt) == COND_EXPR)
+ 	      ? TREE_OPERAND (elt, 1)
+ 	      : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
+ 		 || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
+ 		 || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
+ 		 || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
+ 	      ? TREE_OPERAND (elt, 0) : 0))
+ 	if (POINTER_TYPE_P (TREE_TYPE (elt))
+ 	    && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
+ 		== need_type))
+ 	  {
+ 	    if (plist)
+ 	      *plist = placeholder_expr;
+ 	    return build1 (INDIRECT_REF, need_type, elt);
+ 	  }
+     }
+ 
+   abort ();
+ }
+ 
  /* expand_expr: generate code for computing expression EXP.
     An rtx for the computed value is returned.  The value is never null.
*************** expand_expr (exp, target, tmode, modifie
*** 6483,6546 ****
      case PLACEHOLDER_EXPR:
        {
  	tree placeholder_expr;
  
! 	/* If there is an object on the head of the placeholder list,
! 	   see if some object in it of type TYPE or a pointer to it.  For
! 	   further information, see tree.def.  */
! 	for (placeholder_expr = placeholder_list;
! 	     placeholder_expr != 0;
! 	     placeholder_expr = TREE_CHAIN (placeholder_expr))
! 	  {
! 	    tree need_type = TYPE_MAIN_VARIANT (type);
! 	    tree object = 0;
! 	    tree old_list = placeholder_list;
! 	    tree elt;
! 
! 	    /* Find the outermost reference that is of the type we want.
! 	       If none, see if any object has a type that is a pointer to
! 	       the type we want.  */
! 	    for (elt = TREE_PURPOSE (placeholder_expr);
! 		 elt != 0 && object == 0;
! 		 elt
! 		 = ((TREE_CODE (elt) == COMPOUND_EXPR
! 		     || TREE_CODE (elt) == COND_EXPR)
! 		    ? TREE_OPERAND (elt, 1)
! 		    : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
! 		       || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
! 		       || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
! 		       || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
! 		    ? TREE_OPERAND (elt, 0) : 0))
! 	      if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
! 		object = elt;
! 
! 	    for (elt = TREE_PURPOSE (placeholder_expr);
! 		 elt != 0 && object == 0;
! 		 elt
! 		 = ((TREE_CODE (elt) == COMPOUND_EXPR
! 		     || TREE_CODE (elt) == COND_EXPR)
! 		    ? TREE_OPERAND (elt, 1)
! 		    : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
! 		       || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
! 		       || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
! 		       || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
! 		    ? TREE_OPERAND (elt, 0) : 0))
! 	      if (POINTER_TYPE_P (TREE_TYPE (elt))
! 		  && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
! 		      == need_type))
! 		object = build1 (INDIRECT_REF, need_type, elt);
! 
! 	    if (object != 0)
! 	      {
! 		/* Expand this object skipping the list entries before
! 		   it was found in case it is also a PLACEHOLDER_EXPR.
! 		   In that case, we want to translate it using subsequent
! 		   entries.  */
! 		placeholder_list = TREE_CHAIN (placeholder_expr);
! 		temp = expand_expr (object, original_target, tmode,
! 				    ro_modifier);
! 		placeholder_list = old_list;
! 		return temp;
! 	      }
! 	  }
        }
  
--- 6546,6557 ----
      case PLACEHOLDER_EXPR:
        {
+ 	tree old_list = placeholder_list;
  	tree placeholder_expr;
  
! 	exp = find_placeholder (exp, &placeholder_expr);
! 	placeholder_list = TREE_CHAIN (placeholder_expr);
! 	temp = expand_expr (exp, original_target, tmode, ro_modifier);
! 	placeholder_list = old_list;
! 	return temp;
        }
  
*************** expand_expr (exp, target, tmode, modifie
*** 6924,6927 ****
--- 6935,6939 ----
  					&mode1, &unsignedp, &volatilep,
  					&alignment);
+ 	rtx orig_op0;
  
  	/* If we got back the original object, something is wrong.  Perhaps
*************** expand_expr (exp, target, tmode, modifie
*** 6935,6947 ****
  	   to have to do.  This occurs in unchecked conversion in Ada.  */
  
! 	op0 = expand_expr (tem,
! 			   (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
! 			    && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
! 				!= INTEGER_CST)
! 			    ? target : NULL_RTX),
! 			   VOIDmode,
! 			   (modifier == EXPAND_INITIALIZER
! 			    || modifier == EXPAND_CONST_ADDRESS)
! 			   ? modifier : EXPAND_NORMAL);
  
  	/* If this is a constant, put it into a register if it is a
--- 6947,6960 ----
  	   to have to do.  This occurs in unchecked conversion in Ada.  */
  
! 	orig_op0 = op0
! 	  = expand_expr (tem,
! 			 (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
! 			  && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
! 			      != INTEGER_CST)
! 			  ? target : NULL_RTX),
! 			 VOIDmode,
! 			 (modifier == EXPAND_INITIALIZER
! 			  || modifier == EXPAND_CONST_ADDRESS)
! 			 ? modifier : EXPAND_NORMAL);
  
  	/* If this is a constant, put it into a register if it is a
*************** expand_expr (exp, target, tmode, modifie
*** 7032,7036 ****
  	if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0))
  	  {
! 	    op0 = copy_rtx (op0);
  	    MEM_VOLATILE_P (op0) = 1;
  	  }
--- 7045,7051 ----
  	if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0))
  	  {
! 	    if (op0 == orig_op0)
! 	      op0 = copy_rtx (op0);
! 
  	    MEM_VOLATILE_P (op0) = 1;
  	  }
*************** expand_expr (exp, target, tmode, modifie
*** 7173,7176 ****
--- 7188,7194 ----
  	else
  	  op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
+ 
+ 	if (op0 == orig_op0)
+ 	  op0 = copy_rtx (op0);
  
  	set_mem_attributes (op0, exp, 0);
*** expr.h	2001/10/01 11:00:44	1.93
--- expr.h	2001/10/01 19:24:37
*************** extern rtx store_expr PARAMS ((tree, rtx
*** 499,503 ****
  extern rtx force_operand PARAMS ((rtx, rtx));
  
! #ifdef TREE_CODE
  /* Generate code for computing expression EXP.
     An rtx for the computed value is returned.  The value is never null.
--- 499,510 ----
  extern rtx force_operand PARAMS ((rtx, rtx));
  
! /* Return an object on the placeholder list that matches EXP, a
!    PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
!    PLACEHOLDER_EXPR or a pointer type to it.  For further information,
!    see tree.def.  If no such object is found, abort.  If PLIST is nonzero,
!    it is a location into which a pointer into the placeholder list at
!    which the object is found is placed.  */
! extern tree find_placeholder PARAMS ((tree, tree *));
! 
  /* Generate code for computing expression EXP.
     An rtx for the computed value is returned.  The value is never null.
*************** extern rtx force_operand PARAMS ((rtx, r
*** 505,509 ****
  extern rtx expand_expr PARAMS ((tree, rtx, enum machine_mode,
  				enum expand_modifier));
- #endif
  
  /* At the start of a function, record that we have no previously-pushed
--- 512,515 ----


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