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]

[PATCH] More IPA-PTA cleanups & fixes


This cleans up how we create varinfos (again), fixing a bug with
field merging, the build with C++ and some miscompiles with -fipa-pta.

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

Richard.

2010-04-28  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/43879
	PR tree-optimization/43909
	* tree-ssa-structalias.c (struct variable_info): Add
	only_restrict_pointers flag.
	(new_var_info): Initialize it.  Increment stats.total_vars here.
	(create_function_info_for): Do not increment stats.total_vars
	here.
	(get_function_part_constraint): Fix build with C++.
	(insert_into_field_list): Remove.
	(push_fields_onto_fieldstack): Properly merge fields.
	(create_variable_info_for): Split and simplify.
	(create_variable_info_for_1): New piece.
	(intra_create_variable_infos): Properly make restrict constraints
	from parameters.

	* gcc.dg/ipa/ipa-pta-14.c: Adjust.

Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2010-04-27 17:59:45.000000000 +0200
--- gcc/tree-ssa-structalias.c	2010-04-28 12:09:45.000000000 +0200
*************** struct variable_info
*** 275,280 ****
--- 275,283 ----
    /* True if this field may contain pointers.  */
    unsigned int may_have_pointers : 1;
  
+   /* True if this field has only restrict qualified pointers.  */
+   unsigned int only_restrict_pointers : 1;
+ 
    /* True if this represents a global variable.  */
    unsigned int is_global_var : 1;
  
*************** new_var_info (tree t, const char *name)
*** 412,417 ****
--- 415,421 ----
    ret->is_heap_var = false;
    ret->is_restrict_var = false;
    ret->may_have_pointers = true;
+   ret->only_restrict_pointers = false;
    ret->is_global_var = (t == NULL_TREE);
    ret->is_fn_info = false;
    if (t && DECL_P (t))
*************** new_var_info (tree t, const char *name)
*** 420,425 ****
--- 424,431 ----
    ret->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
    ret->next = NULL;
  
+   stats.total_vars++;
+ 
    VEC_safe_push (varinfo_t, heap, varmap, ret);
  
    return ret;
*************** get_function_part_constraint (varinfo_t
*** 3641,3647 ****
    else if (TREE_CODE (fi->decl) == FUNCTION_DECL)
      {
        varinfo_t ai = first_vi_for_offset (fi, part);
!       c.var = ai ? ai->id : anything_id;
        c.offset = 0;
        c.type = SCALAR;
      }
--- 3647,3656 ----
    else if (TREE_CODE (fi->decl) == FUNCTION_DECL)
      {
        varinfo_t ai = first_vi_for_offset (fi, part);
!       if (ai)
! 	c.var = ai->id;
!       else
! 	c.var = anything_id;
        c.offset = 0;
        c.type = SCALAR;
      }
*************** first_or_preceding_vi_for_offset (varinf
*** 4723,4741 ****
  }
  
  
- /* Insert the varinfo FIELD into the field list for BASE, at the front
-    of the list.  */
- 
- static void
- insert_into_field_list (varinfo_t base, varinfo_t field)
- {
-   varinfo_t prev = base;
-   varinfo_t curr = base->next;
- 
-   field->next = curr;
-   prev->next = field;
- }
- 
  /* This structure is used during pushing fields onto the fieldstack
     to track the offset of the field, since bitpos_of_field gives it
     relative to its immediate containing type, and we want it relative
--- 4732,4737 ----
*************** var_can_have_subvars (const_tree v)
*** 4821,4857 ****
  
     OFFSET is used to keep track of the offset in this entire
     structure, rather than just the immediately containing structure.
!    Returns the number of fields pushed.  */
  
! static int
  push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
  			     HOST_WIDE_INT offset)
  {
    tree field;
!   int count = 0;
  
    if (TREE_CODE (type) != RECORD_TYPE)
!     return 0;
  
    /* If the vector of fields is growing too big, bail out early.
       Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
       sure this fails.  */
    if (VEC_length (fieldoff_s, *fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE)
!     return 0;
  
    for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
      if (TREE_CODE (field) == FIELD_DECL)
        {
  	bool push = false;
- 	int pushed = 0;
  	HOST_WIDE_INT foff = bitpos_of_field (field);
  
  	if (!var_can_have_subvars (field)
  	    || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
  	    || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
  	  push = true;
! 	else if (!(pushed = push_fields_onto_fieldstack
! 		   (TREE_TYPE (field), fieldstack, offset + foff))
  		 && (DECL_SIZE (field)
  		     && !integer_zerop (DECL_SIZE (field))))
  	  /* Empty structures may have actual size, like in C++.  So
--- 4817,4853 ----
  
     OFFSET is used to keep track of the offset in this entire
     structure, rather than just the immediately containing structure.
!    Returns false if the caller is supposed to handle the field we
!    recursed for.  */
  
! static bool
  push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
  			     HOST_WIDE_INT offset)
  {
    tree field;
!   bool empty_p = true;
  
    if (TREE_CODE (type) != RECORD_TYPE)
!     return false;
  
    /* If the vector of fields is growing too big, bail out early.
       Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make
       sure this fails.  */
    if (VEC_length (fieldoff_s, *fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE)
!     return false;
  
    for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
      if (TREE_CODE (field) == FIELD_DECL)
        {
  	bool push = false;
  	HOST_WIDE_INT foff = bitpos_of_field (field);
  
  	if (!var_can_have_subvars (field)
  	    || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
  	    || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
  	  push = true;
! 	else if (!push_fields_onto_fieldstack
! 		    (TREE_TYPE (field), fieldstack, offset + foff)
  		 && (DECL_SIZE (field)
  		     && !integer_zerop (DECL_SIZE (field))))
  	  /* Empty structures may have actual size, like in C++.  So
*************** push_fields_onto_fieldstack (tree type,
*** 4874,4885 ****
  	    /* If adjacent fields do not contain pointers merge them.  */
  	    if (pair
  		&& !pair->may_have_pointers
- 		&& !could_have_pointers (field)
  		&& !pair->has_unknown_size
  		&& !has_unknown_size
! 		&& pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
  	      {
- 		pair = VEC_last (fieldoff_s, *fieldstack);
  		pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
  	      }
  	    else
--- 4870,4880 ----
  	    /* If adjacent fields do not contain pointers merge them.  */
  	    if (pair
  		&& !pair->may_have_pointers
  		&& !pair->has_unknown_size
  		&& !has_unknown_size
! 		&& pair->offset + (HOST_WIDE_INT)pair->size == offset + foff
! 		&& !could_have_pointers (field))
  	      {
  		pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
  	      }
  	    else
*************** push_fields_onto_fieldstack (tree type,
*** 4896,4909 ****
  		  = (!has_unknown_size
  		     && POINTER_TYPE_P (TREE_TYPE (field))
  		     && TYPE_RESTRICT (TREE_TYPE (field)));
- 		count++;
  	      }
  	  }
! 	else
! 	  count += pushed;
        }
  
!   return count;
  }
  
  /* Count the number of arguments DECL has, and set IS_VARARGS to true
--- 4891,4903 ----
  		  = (!has_unknown_size
  		     && POINTER_TYPE_P (TREE_TYPE (field))
  		     && TYPE_RESTRICT (TREE_TYPE (field)));
  	      }
  	  }
! 
! 	empty_p = false;
        }
  
!   return !empty_p;
  }
  
  /* Count the number of arguments DECL has, and set IS_VARARGS to true
*************** create_function_info_for (tree decl, con
*** 4955,4962 ****
      vi->fullsize = ~0;
    insert_vi_for_tree (vi->decl, vi);
  
-   stats.total_vars++;
- 
    prev_vi = vi;
  
    /* Create a variable for things the function clobbers and one for
--- 4949,4954 ----
*************** create_function_info_for (tree decl, con
*** 4979,4985 ****
        gcc_assert (prev_vi->offset < clobbervi->offset);
        prev_vi->next = clobbervi;
        prev_vi = clobbervi;
-       stats.total_vars++;
  
        asprintf (&tempname, "%s.use", name);
        newname = ggc_strdup (tempname);
--- 4971,4976 ----
*************** create_function_info_for (tree decl, con
*** 4994,5000 ****
        gcc_assert (prev_vi->offset < usevi->offset);
        prev_vi->next = usevi;
        prev_vi = usevi;
-       stats.total_vars++;
      }
  
    /* And one for the static chain.  */
--- 4985,4990 ----
*************** create_function_info_for (tree decl, con
*** 5017,5023 ****
        gcc_assert (prev_vi->offset < chainvi->offset);
        prev_vi->next = chainvi;
        prev_vi = chainvi;
-       stats.total_vars++;
        insert_vi_for_tree (fn->static_chain_decl, chainvi);
      }
  
--- 5007,5012 ----
*************** create_function_info_for (tree decl, con
*** 5047,5053 ****
        gcc_assert (prev_vi->offset < resultvi->offset);
        prev_vi->next = resultvi;
        prev_vi = resultvi;
-       stats.total_vars++;
        if (DECL_RESULT (decl))
  	insert_vi_for_tree (DECL_RESULT (decl), resultvi);
      }
--- 5036,5041 ----
*************** create_function_info_for (tree decl, con
*** 5078,5084 ****
        gcc_assert (prev_vi->offset < argvi->offset);
        prev_vi->next = argvi;
        prev_vi = argvi;
-       stats.total_vars++;
        if (arg)
  	{
  	  insert_vi_for_tree (arg, argvi);
--- 5066,5071 ----
*************** create_function_info_for (tree decl, con
*** 5111,5117 ****
        gcc_assert (prev_vi->offset < argvi->offset);
        prev_vi->next = argvi;
        prev_vi = argvi;
-       stats.total_vars++;
      }
  
    return vi->id;
--- 5098,5103 ----
*************** check_for_overlaps (VEC (fieldoff_s,heap
*** 5141,5188 ****
     This will also create any varinfo structures necessary for fields
     of DECL.  */
  
! static unsigned int
! create_variable_info_for (tree decl, const char *name)
  {
!   varinfo_t vi;
    tree decl_type = TREE_TYPE (decl);
    tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
    VEC (fieldoff_s,heap) *fieldstack = NULL;
  
-   if (var_can_have_subvars (decl) && use_field_sensitive)
-     push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
- 
-   /* If the variable doesn't have subvars, we may end up needing to
-      sort the field list and create fake variables for all the
-      fields.  */
-   vi = new_var_info (decl, name);
-   vi->offset = 0;
-   vi->may_have_pointers = could_have_pointers (decl);
    if (!declsize
        || !host_integerp (declsize, 1))
      {
!       vi->is_unknown_size_var = true;
!       vi->fullsize = ~0;
        vi->size = ~0;
      }
!   else
      {
        vi->fullsize = TREE_INT_CST_LOW (declsize);
        vi->size = vi->fullsize;
      }
  
!   insert_vi_for_tree (vi->decl, vi);
  
!   /* ???  The setting of vi->may_have_pointers is too conservative here
!      and may get refined below.  Thus we have superfluous constraints
!      here sometimes which triggers the commented assert in
!      dump_sa_points_to_info.  */
!   if (vi->is_global_var
!       && vi->may_have_pointers)
      {
        /* Mark global restrict qualified pointers.  */
!       if (POINTER_TYPE_P (TREE_TYPE (decl))
! 	  && TYPE_RESTRICT (TREE_TYPE (decl)))
  	make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
  
        /* For escaped variables initialize them from nonlocal.  */
--- 5127,5261 ----
     This will also create any varinfo structures necessary for fields
     of DECL.  */
  
! static varinfo_t
! create_variable_info_for_1 (tree decl, const char *name)
  {
!   varinfo_t vi, newvi;
    tree decl_type = TREE_TYPE (decl);
    tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
    VEC (fieldoff_s,heap) *fieldstack = NULL;
+   fieldoff_s *fo;
+   unsigned int i;
  
    if (!declsize
        || !host_integerp (declsize, 1))
      {
!       vi = new_var_info (decl, name);
!       vi->offset = 0;
        vi->size = ~0;
+       vi->fullsize = ~0;
+       vi->is_unknown_size_var = true;
+       vi->is_full_var = true;
+       vi->may_have_pointers = could_have_pointers (decl);
+       return vi;
      }
! 
!   /* Collect field information.  */
!   if (use_field_sensitive
!       && var_can_have_subvars (decl)
!       /* ???  Force us to not use subfields for global initializers
! 	 in IPA mode.  Else we'd have to parse arbitrary initializers.  */
!       && !(in_ipa_mode
! 	   && is_global_var (decl)
! 	   && DECL_INITIAL (decl)))
      {
+       fieldoff_s *fo = NULL;
+       bool notokay = false;
+       unsigned int i;
+ 
+       push_fields_onto_fieldstack (decl_type, &fieldstack, 0);
+ 
+       for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
+ 	if (fo->has_unknown_size
+ 	    || fo->offset < 0)
+ 	  {
+ 	    notokay = true;
+ 	    break;
+ 	  }
+ 
+       /* We can't sort them if we have a field with a variable sized type,
+ 	 which will make notokay = true.  In that case, we are going to return
+ 	 without creating varinfos for the fields anyway, so sorting them is a
+ 	 waste to boot.  */
+       if (!notokay)
+ 	{
+ 	  sort_fieldstack (fieldstack);
+ 	  /* Due to some C++ FE issues, like PR 22488, we might end up
+ 	     what appear to be overlapping fields even though they,
+ 	     in reality, do not overlap.  Until the C++ FE is fixed,
+ 	     we will simply disable field-sensitivity for these cases.  */
+ 	  notokay = check_for_overlaps (fieldstack);
+ 	}
+ 
+       if (notokay)
+ 	VEC_free (fieldoff_s, heap, fieldstack);
+     }
+ 
+   /* If we didn't end up collecting sub-variables create a full
+      variable for the decl.  */
+   if (VEC_length (fieldoff_s, fieldstack) <= 1
+       || VEC_length (fieldoff_s, fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE)
+     {
+       vi = new_var_info (decl, name);
+       vi->offset = 0;
+       vi->may_have_pointers = could_have_pointers (decl);
        vi->fullsize = TREE_INT_CST_LOW (declsize);
        vi->size = vi->fullsize;
+       vi->is_full_var = true;
+       VEC_free (fieldoff_s, heap, fieldstack);
+       return vi;
      }
  
!   vi = new_var_info (decl, name);
!   vi->fullsize = TREE_INT_CST_LOW (declsize);
!   for (i = 0, newvi = vi;
!        VEC_iterate (fieldoff_s, fieldstack, i, fo);
!        ++i, newvi = newvi->next)
!     {
!       const char *newname = "NULL";
!       char *tempname;
! 
!       if (dump_file)
! 	{
! 	  asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
! 		    "+" HOST_WIDE_INT_PRINT_DEC, name, fo->offset, fo->size);
! 	  newname = ggc_strdup (tempname);
! 	  free (tempname);
! 	}
!       newvi->name = newname;
!       newvi->offset = fo->offset;
!       newvi->size = fo->size;
!       newvi->fullsize = vi->fullsize;
!       newvi->may_have_pointers = fo->may_have_pointers;
!       newvi->only_restrict_pointers = fo->only_restrict_pointers;
!       if (i + 1 < VEC_length (fieldoff_s, fieldstack))
! 	newvi->next = new_var_info (decl, name);
!     }
! 
!   VEC_free (fieldoff_s, heap, fieldstack);
! 
!   return vi;
! }
! 
! static unsigned int
! create_variable_info_for (tree decl, const char *name)
! {
!   varinfo_t vi = create_variable_info_for_1 (decl, name);
!   unsigned int id = vi->id;
! 
!   insert_vi_for_tree (decl, vi);
  
!   /* Create initial constraints for globals.  */
!   for (; vi; vi = vi->next)
      {
+       if (!vi->may_have_pointers
+ 	  || !vi->is_global_var)
+ 	continue;
+ 
        /* Mark global restrict qualified pointers.  */
!       if ((POINTER_TYPE_P (TREE_TYPE (decl))
! 	   && TYPE_RESTRICT (TREE_TYPE (decl)))
! 	  || vi->only_restrict_pointers)
  	make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
  
        /* For escaped variables initialize them from nonlocal.  */
*************** create_variable_info_for (tree decl, con
*** 5194,5205 ****
  	 IPA mode generate constraints for it.  In non-IPA mode
  	 the initializer from nonlocal is all we need.  */
        if (in_ipa_mode
! 	  && DECL_INITIAL (vi->decl))
  	{
  	  VEC (ce_s, heap) *rhsc = NULL;
  	  struct constraint_expr lhs, *rhsp;
  	  unsigned i;
! 	  get_constraint_for (DECL_INITIAL (vi->decl), &rhsc);
  	  lhs.var = vi->id;
  	  lhs.offset = 0;
  	  lhs.type = SCALAR;
--- 5267,5278 ----
  	 IPA mode generate constraints for it.  In non-IPA mode
  	 the initializer from nonlocal is all we need.  */
        if (in_ipa_mode
! 	  && DECL_INITIAL (decl))
  	{
  	  VEC (ce_s, heap) *rhsc = NULL;
  	  struct constraint_expr lhs, *rhsp;
  	  unsigned i;
! 	  get_constraint_for (DECL_INITIAL (decl), &rhsc);
  	  lhs.var = vi->id;
  	  lhs.offset = 0;
  	  lhs.type = SCALAR;
*************** create_variable_info_for (tree decl, con
*** 5216,5325 ****
  		process_constraint (new_constraint (lhs, *rhsp));
  	    }
  	  VEC_free (ce_s, heap, rhsc);
- 	  /* ???  Force us to not use subfields.  Else we'd have to parse
- 	     arbitrary initializers.  */
- 	  VEC_free (fieldoff_s, heap, fieldstack);
  	}
      }
  
!   stats.total_vars++;
!   if (use_field_sensitive
!       && !vi->is_unknown_size_var
!       && var_can_have_subvars (decl)
!       && VEC_length (fieldoff_s, fieldstack) > 1
!       && VEC_length (fieldoff_s, fieldstack) <= MAX_FIELDS_FOR_FIELD_SENSITIVE)
!     {
!       fieldoff_s *fo = NULL;
!       bool notokay = false;
!       unsigned int i;
! 
!       for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
! 	{
! 	  if (fo->has_unknown_size
! 	      || fo->offset < 0)
! 	    {
! 	      notokay = true;
! 	      break;
! 	    }
! 	}
! 
!       /* We can't sort them if we have a field with a variable sized type,
! 	 which will make notokay = true.  In that case, we are going to return
! 	 without creating varinfos for the fields anyway, so sorting them is a
! 	 waste to boot.  */
!       if (!notokay)
! 	{
! 	  sort_fieldstack (fieldstack);
! 	  /* Due to some C++ FE issues, like PR 22488, we might end up
! 	     what appear to be overlapping fields even though they,
! 	     in reality, do not overlap.  Until the C++ FE is fixed,
! 	     we will simply disable field-sensitivity for these cases.  */
! 	  notokay = check_for_overlaps (fieldstack);
! 	}
! 
! 
!       if (VEC_length (fieldoff_s, fieldstack) != 0)
! 	fo = VEC_index (fieldoff_s, fieldstack, 0);
! 
!       if (fo == NULL || notokay)
! 	{
! 	  vi->is_unknown_size_var = 1;
! 	  vi->fullsize = ~0;
! 	  vi->size = ~0;
! 	  vi->is_full_var = true;
! 	  VEC_free (fieldoff_s, heap, fieldstack);
! 	  return vi->id;
! 	}
! 
!       vi->size = fo->size;
!       vi->offset = fo->offset;
!       vi->may_have_pointers = fo->may_have_pointers;
!       if (vi->is_global_var
! 	  && vi->may_have_pointers)
! 	{
! 	  if (fo->only_restrict_pointers)
! 	    make_constraint_from_restrict (vi, "GLOBAL_RESTRICT");
! 	}
!       for (i = VEC_length (fieldoff_s, fieldstack) - 1;
! 	   i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
! 	   i--)
! 	{
! 	  varinfo_t newvi;
! 	  const char *newname = "NULL";
! 	  char *tempname;
! 
! 	  if (dump_file)
! 	    {
! 	      asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
! 			"+" HOST_WIDE_INT_PRINT_DEC,
! 			vi->name, fo->offset, fo->size);
! 	      newname = ggc_strdup (tempname);
! 	      free (tempname);
! 	    }
! 	  newvi = new_var_info (decl, newname);
! 	  newvi->offset = fo->offset;
! 	  newvi->size = fo->size;
! 	  newvi->fullsize = vi->fullsize;
! 	  newvi->may_have_pointers = fo->may_have_pointers;
! 	  insert_into_field_list (vi, newvi);
! 	  if ((newvi->is_global_var || TREE_CODE (decl) == PARM_DECL)
! 	      && newvi->may_have_pointers)
! 	    {
! 	       if (fo->only_restrict_pointers)
! 		 make_constraint_from_restrict (newvi, "GLOBAL_RESTRICT");
! 	       if (newvi->is_global_var && !in_ipa_mode)
! 		 make_copy_constraint (newvi, nonlocal_id);
! 	    }
! 
! 	  stats.total_vars++;
! 	}
!     }
!   else
!     vi->is_full_var = true;
! 
!   VEC_free (fieldoff_s, heap, fieldstack);
! 
!   return vi->id;
  }
  
  /* Print out the points-to solution for VAR to FILE.  */
--- 5289,5298 ----
  		process_constraint (new_constraint (lhs, *rhsp));
  	    }
  	  VEC_free (ce_s, heap, rhsc);
  	}
      }
  
!   return id;
  }
  
  /* Print out the points-to solution for VAR to FILE.  */
*************** intra_create_variable_infos (void)
*** 5405,5412 ****
  	}
  
        for (p = get_vi_for_tree (t); p; p = p->next)
! 	if (p->may_have_pointers)
! 	  make_constraint_from (p, nonlocal_id);
        if (POINTER_TYPE_P (TREE_TYPE (t))
  	  && TYPE_RESTRICT (TREE_TYPE (t)))
  	make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT");
--- 5378,5389 ----
  	}
  
        for (p = get_vi_for_tree (t); p; p = p->next)
! 	{
! 	  if (p->may_have_pointers)
! 	    make_constraint_from (p, nonlocal_id);
! 	  if (p->only_restrict_pointers)
! 	    make_constraint_from_restrict (p, "PARM_RESTRICT");
! 	}
        if (POINTER_TYPE_P (TREE_TYPE (t))
  	  && TYPE_RESTRICT (TREE_TYPE (t)))
  	make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT");
Index: gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
===================================================================
*** gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c.orig	2010-04-27 17:59:45.000000000 +0200
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c	2010-04-28 11:39:03.000000000 +0200
*************** int main()
*** 21,28 ****
    void *p;
    a.p = (void *)&c;
    p = foo(&a, &a);
!   /* { dg-final { scan-ipa-dump "foo.result = { NULL a c }" "pta" { xfail *-*-* } } } */
!   /* { dg-final { scan-ipa-dump "foo.result = { NULL a a\[^ \]* c }" "pta" } } */
    ((struct X *)p)->p = (void *)0;
    if (a.p != (void *)0)
      abort ();
--- 21,28 ----
    void *p;
    a.p = (void *)&c;
    p = foo(&a, &a);
!   /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* c\[^ \]* }" "pta" { xfail *-*-* } } } */
!   /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" } } */
    ((struct X *)p)->p = (void *)0;
    if (a.p != (void *)0)
      abort ();


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