This is the mail archive of the gcc@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]

[RFC] ignoring type alias conflicts between structures and scalars


Jeff noticed that TBAA was creating some alias relations that don't seem
to make much sense.  For instance, given

------------------------------------------------------------------------------------struct int_float_s {
    int i;
    float f;
};

int X;

foo()
{
  struct int_float_s *x = bar();
  X = 10;
  x->i = 3;
  return X;
}
------------------------------------------------------------------------------------

After TBAA, we had

Variable: x, UID 1, struct int_float_s *, type memory tag: TMT.0
Variable: X, UID 2, int, is addressable, is global, call clobbered, default def: X_1
Variable: TMT.0, UID 5, struct int_float_s, is addressable, is global, call clobbered, may aliases: { X }

Jeff's argument is that it's not really possible for a pointer to a
structure to point to a scalar variable.  If the structure is not type
compatible with the scalar, then they can't alias.  That makes some
sense to me.

However, the front end says that those two types are alias compatible,
meaning that we could store into X via x.  So, I'm confused.  I
discussed this a bit with Nathan and Joseph on IRC.  Nathan pointed me
to some section in the C standard that seems to support the fact that
indeed TMT.0 should alias X.

The attached patch implements the idea of ignoring alias relations
between structures and scalars that are not type compatible.  It
survived bootstrap and testing on x86, ia64, x86-64 and ppc.  However, I
have zero confidence in it.  If the types cannot really conflict,
alias_sets_conflict_p() should tell me so.  I shouldn't need to short
circuit it this way.

I'm also attaching a program that breaks this patch.  Basically, it
causes 'bar()' to return &X.  Since we are now considering that X cannot
alias with TMT.0, we would optimize the function to 'return 10'.  The
question is: Is the program well defined?

If the program isn't well defined, why is alias_sets_conflict_p() saying
that 'struct int_float_s' and 'int' have conflicting alias sets?


Thanks.  Diego.
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.56
diff -d -c -p -u -r2.56 tree-ssa-alias.c
--- tree-ssa-alias.c	24 Nov 2004 14:46:23 -0000	2.56
+++ tree-ssa-alias.c	25 Nov 2004 14:26:09 -0000
@@ -928,7 +928,21 @@ compute_flow_insensitive_aliasing (struc
 			 || is_call_clobbered (var);
 	  if (!tag_stored_p && !var_stored_p)
 	    continue;
-	     
+
+	  /* A scalar variable cannot be aliased with a structure if
+	     their types are not compatible.  ???  But then, why would
+	     alias_sets_conflict_p say that their alias sets are in
+	     conflict?  Given a memory tag of type 'struct X { int b;
+	     float a; }' and a variable of type 'int', their alias
+	     sets are considered to conflict, but it doesn't seem
+	     possible that a 'struct X *' may point to the 'int'
+	     variable.  */
+	  if (TREE_CODE (TREE_TYPE (tag)) == RECORD_TYPE
+	      && !AGGREGATE_TYPE_P (TREE_TYPE (var))
+	      && !lang_hooks.types_compatible_p (TREE_TYPE (tag),
+		                                 TREE_TYPE (var)))
+	    continue;
+
 	  if (may_alias_p (p_map->var, p_map->set, var, v_map->set))
 	    {
 	      size_t num_tag_refs, num_var_refs;
struct int_float_s {
    int i;
    float f;
};

int X;

int *ptr_to_X () { return &X; }

foo()
{
  struct int_float_s *x = (struct int_float_s *) ptr_to_X ();
  X = 10;
  x->i = 3;
  return X;
}

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