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][RFC] Remove quadratic loop with component_uses_parent_alias_set


Eric, the current way component_uses_parent_alias_set is called from
get_alias_set causes the reference tree chain to be walked O(n^2)
in case there is any DECL_NONADDRESSABLE_P or TYPE_NONALIASED_COMPONENT
reference in the tree chain.  Also the comment above
component_uses_parent_alias_set doesn't seem to match behavior
in get_alias_set.  get_alias_set ends up using exactly the type of 
the parent
of the DECL_NONADDRESSABLE_P / TYPE_NONALIASED_COMPONENT reference
instead of "the alias set provided by the object at the heart of T"

I also fail to see why component_uses_parent_alias_set invokes
get_alias_set (is that to make 'a.c' in struct { char c; } a;
use the alias set of 'a' instead of the alias set of 'char'?
Or is it for correctness reasons in case there is a ref-all
indirect ref at the base?  For the former I believe it doesn't
work because it only checks the non-outermost type).

So, the following patch removes the quadraticness by returning
the parent of the innermost non-addressable (or alias-set zero)
reference component instead of just a flag.  That changes behavior
for the alias-set zero case but still doesn't match the overall
function comment.

The only other use besides from get_alias_set is to set
MEM_KEEP_ALIAS_SET_P - whatever that is exactly for, I can
see a single non-obvious use in store_constructor_field
(didn't bother to lookup how callers specify the alias_set argument).
In

            if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
                && DECL_NONADDRESSABLE_P (field))
              {
                to_rtx = copy_rtx (to_rtx);
                MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
              }

we can just drop the MEM_KEEP_ALIAS_SET_P check (well, in case
MEM_KEEP_ALIAS_SET_P is dropped).  And for the following call

            store_constructor_field (to_rtx, bitsize, bitpos, mode,
                                     value, cleared,
                                     get_alias_set (TREE_TYPE (field)));

pass MEM_ALIAS_SET instead of get_alias_set (TREE_TYPE (field)) for
DECL_NONADDRESSABLE_P (field), similar for the array handling in
the other use.

Btw, checks like

     if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
        set_mem_alias_set (to_rtx, alias_set);

seem to miss MEM_ALIAS_SET (to_rtx) being ALIAS_SET_MEMORY_BARRIER?
Or alias_set being zero / ALIAS_SET_MEMORY_BARRIER?

Anyway, the patch nearly preserves behavior for the emit-rtl.c use.

Comments?

Thanks,
Richard.

Index: gcc/alias.c
===================================================================
--- gcc/alias.c	(revision 202865)
+++ gcc/alias.c	(working copy)
@@ -510,41 +510,49 @@ objects_must_conflict_p (tree t1, tree t
    alias set used by the component, but we don't have per-FIELD_DECL
    assignable alias sets.  */
 
-bool
+tree
 component_uses_parent_alias_set (const_tree t)
 {
-  while (1)
+  const_tree non_addressable = NULL_TREE;
+  while (handled_component_p (t))
     {
-      /* If we're at the end, it vacuously uses its own alias set.  */
-      if (!handled_component_p (t))
-	return false;
-
       switch (TREE_CODE (t))
 	{
 	case COMPONENT_REF:
 	  if (DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1)))
-	    return true;
+	    non_addressable = t;
 	  break;
 
 	case ARRAY_REF:
 	case ARRAY_RANGE_REF:
 	  if (TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0))))
-	    return true;
+	    non_addressable = t;
 	  break;
 
 	case REALPART_EXPR:
 	case IMAGPART_EXPR:
 	  break;
 
-	default:
+	case BIT_FIELD_REF:
+	case VIEW_CONVERT_EXPR:
 	  /* Bitfields and casts are never addressable.  */
-	  return true;
+	  non_addressable = t;
+	  break;
+
+	default:
+	  gcc_unreachable ();
 	}
 
-      t = TREE_OPERAND (t, 0);
       if (get_alias_set (TREE_TYPE (t)) == 0)
-	return true;
+	non_addressable = t;
+
+      t = TREE_OPERAND (t, 0);
     }
+ 
+  if (non_addressable)
+    return TREE_OPERAND (non_addressable, 0);
+
+  return NULL_TREE;
 }
 
 
@@ -645,14 +653,11 @@ reference_alias_ptr_type_1 (tree *t)
 	       (TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1))))))
     return TREE_TYPE (TREE_OPERAND (inner, 1));
 
-  /* Otherwise, pick up the outermost object that we could have a pointer
-     to, processing conversions as above.  */
-  /* ???  Ick, this is worse than quadratic!  */
-  while (component_uses_parent_alias_set (*t))
-    {
-      *t = TREE_OPERAND (*t, 0);
-      STRIP_NOPS (*t);
-    }
+  /* Otherwise, pick up the outermost object that we could have
+     a pointer to.  */
+  tree tem = component_uses_parent_alias_set (*t);
+  if (tem)
+    *t = tem;
 
   return NULL_TREE;
 }
Index: gcc/alias.h
===================================================================
--- gcc/alias.h	(revision 202865)
+++ gcc/alias.h	(working copy)
@@ -33,7 +33,7 @@ extern alias_set_type get_alias_set (tre
 extern alias_set_type get_deref_alias_set (tree);
 extern alias_set_type get_varargs_alias_set (void);
 extern alias_set_type get_frame_alias_set (void);
-extern bool component_uses_parent_alias_set (const_tree);
+extern tree component_uses_parent_alias_set (const_tree);
 extern bool alias_set_subset_of (alias_set_type, alias_set_type);
 extern void record_alias_subset (alias_set_type, alias_set_type);
 extern void record_component_aliases (tree);


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