diff mbox

[middle-end,c,c++] : Optimize cost of comp_type_attributes

Message ID AANLkTimVYcnMhSWmwgrcvuB8yw1Fu1mOeku=5aZEQ8Oh@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz March 25, 2011, 9:52 a.m. UTC
2011/3/25 Jason Merrill <jason@redhat.com>:
> On 03/24/2011 08:44 PM, Kai Tietz wrote:
>>
>> +static bool
>> +attribute_value_equal (const_tree attr1, const_tree attr2)
>> +{
>> +  if (attr1 == attr2)
>> +    return true;
>
> I still think this test should be comparing TREE_VALUEs.
>
> Jason
>

Ok, it makes sense to check here for value indentity instead of
identity of list-node. Thanks. Updated patch attached.

Kai

Comments

Jason Merrill March 25, 2011, 10:06 a.m. UTC | #1
OK.

Jason
Kai Tietz March 25, 2011, 10:28 a.m. UTC | #2
2011/3/25 Jason Merrill <jason@redhat.com>:
> OK.
>
> Jason
>

Committed at revision 171445.

Thanks,
Kai
diff mbox

Patch

Index: gcc/gcc/c-typeck.c
===================================================================
--- gcc.orig/gcc/c-typeck.c	2011-03-25 09:27:47.101196700 +0100
+++ gcc/gcc/c-typeck.c	2011-03-25 09:35:35.038738400 +0100
@@ -1079,7 +1079,7 @@  comptypes_internal (const_tree type1, co
     return 1;
 
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
-  if (!(attrval = targetm.comp_type_attributes (t1, t2)))
+  if (!(attrval = comp_type_attributes (t1, t2)))
      return 0;
 
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
Index: gcc/gcc/cp/decl.c
===================================================================
--- gcc.orig/gcc/cp/decl.c	2011-03-25 09:27:47.102196700 +0100
+++ gcc/gcc/cp/decl.c	2011-03-25 09:35:35.090745000 +0100
@@ -1012,8 +1012,8 @@  decls_match (tree newdecl, tree olddecl)
 	    types_match =
 	      compparms (p1, p2)
 	      && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE
-	          || targetm.comp_type_attributes (TREE_TYPE (newdecl),
-						   TREE_TYPE (olddecl)) != 0);
+	          || comp_type_attributes (TREE_TYPE (newdecl),
+					   TREE_TYPE (olddecl)) != 0);
 	}
       else
 	types_match = 0;
Index: gcc/gcc/cp/search.c
===================================================================
--- gcc.orig/gcc/cp/search.c	2011-03-25 09:27:47.103196700 +0100
+++ gcc/gcc/cp/search.c	2011-03-25 09:35:35.145752000 +0100
@@ -1897,7 +1897,7 @@  check_final_overrider (tree overrider, t
     }
 
   /* Check for conflicting type attributes.  */
-  if (!targetm.comp_type_attributes (over_type, base_type))
+  if (!comp_type_attributes (over_type, base_type))
     {
       error ("conflicting type attributes specified for %q+#D", overrider);
       error ("  overriding %q+#D", basefn);
Index: gcc/gcc/cp/typeck.c
===================================================================
--- gcc.orig/gcc/cp/typeck.c	2011-03-25 09:27:47.110196700 +0100
+++ gcc/gcc/cp/typeck.c	2011-03-25 09:35:35.164754400 +0100
@@ -1338,7 +1338,7 @@  structural_comptypes (tree t1, tree t2,
   /* If we get here, we know that from a target independent POV the
      types are the same.  Make sure the target attributes are also
      the same.  */
-  return targetm.comp_type_attributes (t1, t2);
+  return comp_type_attributes (t1, t2);
 }
 
 /* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
Index: gcc/gcc/gimple.c
===================================================================
--- gcc.orig/gcc/gimple.c	2011-03-25 09:27:47.112196700 +0100
+++ gcc/gcc/gimple.c	2011-03-25 09:35:35.206259700 +0100
@@ -3615,7 +3615,7 @@  gimple_types_compatible_p_1 (tree t1, tr
 			 state, sccstack, sccstate, sccstate_obstack))
 	goto different_types;
 
-      if (!targetm.comp_type_attributes (t1, t2))
+      if (!comp_type_attributes (t1, t2))
 	goto different_types;
 
       if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2))
Index: gcc/gcc/tree-ssa.c
===================================================================
--- gcc.orig/gcc/tree-ssa.c	2011-03-25 09:27:47.113196700 +0100
+++ gcc/gcc/tree-ssa.c	2011-03-25 09:35:35.231762900 +0100
@@ -1438,7 +1438,7 @@  useless_type_conversion_p (tree outer_ty
 
       /* Defer to the target if necessary.  */
       if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type))
-	return targetm.comp_type_attributes (outer_type, inner_type) != 0;
+	return comp_type_attributes (outer_type, inner_type) != 0;
 
       return true;
     }
Index: gcc/gcc/tree.c
===================================================================
--- gcc.orig/gcc/tree.c	2011-03-25 09:31:02.378615000 +0100
+++ gcc/gcc/tree.c	2011-03-25 10:48:15.141401100 +0100
@@ -4287,7 +4287,7 @@  build_type_attribute_qual_variant (tree
 	 its canonical type, we will need to use structural equality
 	 checks for this type. */
       if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
-          || !targetm.comp_type_attributes (ntype, ttype))
+          || !comp_type_attributes (ntype, ttype))
 	SET_TYPE_STRUCTURAL_EQUALITY (ntype);
       else if (TYPE_CANONICAL (ntype) == ntype)
 	TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
@@ -4300,6 +4300,75 @@  build_type_attribute_qual_variant (tree
   return ttype;
 }
 
+/* Compare two attributes for their value identity.  Return true if the
+   attribute values are known to be equal; otherwise return false.
+*/
+
+static bool
+attribute_value_equal (const_tree attr1, const_tree attr2)
+{
+  if (TREE_VALUE (attr1) == TREE_VALUE (attr2))
+    return true;
+
+  if (TREE_VALUE (attr1) != NULL_TREE
+      && TREE_CODE (TREE_VALUE (attr1)) == TREE_LIST
+      && TREE_VALUE (attr2) != NULL
+      && TREE_CODE (TREE_VALUE (attr2)) == TREE_LIST)
+    return (simple_cst_list_equal (TREE_VALUE (attr1),
+				   TREE_VALUE (attr2)) == 1);
+
+  return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1);
+}
+
+/* Return 0 if the attributes for two types are incompatible, 1 if they
+   are compatible, and 2 if they are nearly compatible (which causes a
+   warning to be generated).  */
+int
+comp_type_attributes (const_tree type1, const_tree type2)
+{
+  const_tree a1 = TYPE_ATTRIBUTES (type1);
+  const_tree a2 = TYPE_ATTRIBUTES (type2);
+  const_tree a;
+
+  if (a1 == a2)
+    return 1;
+  for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
+    {
+      const struct attribute_spec *as;
+      const_tree attr;
+
+      as = lookup_attribute_spec (TREE_PURPOSE (a));
+      if (!as || as->affects_type_identity == false)
+        continue;
+
+      attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
+      if (!attr || !attribute_value_equal (a, attr))
+        break;
+    }
+  if (!a)
+    {
+      for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
+	{
+	  const struct attribute_spec *as;
+
+	  as = lookup_attribute_spec (TREE_PURPOSE (a));
+	  if (!as || as->affects_type_identity == false)
+	    continue;
+
+	  if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
+	    break;
+	  /* We don't need to compare trees again, as we did this
+	     already in first loop.  */
+	}
+      /* All types - affecting identity - are equal, so
+         there is no need to call target hook for comparison.  */
+      if (!a)
+        return 1;
+    }
+  /* As some type combinations - like default calling-convention - might
+     be compatible, we have to call the target hook to get the final result.  */
+  return targetm.comp_type_attributes (type1, type2);
+}
 
 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
    is ATTRIBUTE.
@@ -5300,23 +5369,10 @@  merge_attributes (tree a1, tree a2)
 	      tree a;
 	      for (a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
 					 attributes);
-		   a != NULL_TREE;
+		   a != NULL_TREE && !attribute_value_equal (a, a2);
 		   a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
 					 TREE_CHAIN (a)))
-		{
-		  if (TREE_VALUE (a) != NULL
-		      && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
-		      && TREE_VALUE (a2) != NULL
-		      && TREE_CODE (TREE_VALUE (a2)) == TREE_LIST)
-		    {
-		      if (simple_cst_list_equal (TREE_VALUE (a),
-						 TREE_VALUE (a2)) == 1)
-			break;
-		    }
-		  else if (simple_cst_equal (TREE_VALUE (a),
-					     TREE_VALUE (a2)) == 1)
-		    break;
-		}
+		;
 	      if (a == NULL_TREE)
 		{
 		  a1 = copy_node (a2);
@@ -6254,24 +6310,12 @@  attribute_list_contained (const_tree l1,
 	 const_tree.  */
       for (attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
 				    CONST_CAST_TREE(l1));
-	   attr != NULL_TREE;
+	   attr != NULL_TREE && !attribute_value_equal (t2, attr);
 	   attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
 				    TREE_CHAIN (attr)))
-	{
-	  if (TREE_VALUE (t2) != NULL
-	      && TREE_CODE (TREE_VALUE (t2)) == TREE_LIST
-	      && TREE_VALUE (attr) != NULL
-	      && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST)
-	    {
-	      if (simple_cst_list_equal (TREE_VALUE (t2),
-					 TREE_VALUE (attr)) == 1)
-		break;
-	    }
-	  else if (simple_cst_equal (TREE_VALUE (t2), TREE_VALUE (attr)) == 1)
-	    break;
-	}
+	;
 
-      if (attr == 0)
+      if (attr == NULL_TREE)
 	return 0;
     }
 
Index: gcc/gcc/tree.h
===================================================================
--- gcc.orig/gcc/tree.h	2011-03-25 09:31:02.416119700 +0100
+++ gcc/gcc/tree.h	2011-03-25 09:35:35.295271000 +0100
@@ -4286,6 +4286,11 @@  extern tree build_type_attribute_variant
 extern tree build_decl_attribute_variant (tree, tree);
 extern tree build_type_attribute_qual_variant (tree, tree, int);
 
+/* Return 0 if the attributes for two types are incompatible, 1 if they
+   are compatible, and 2 if they are nearly compatible (which causes a
+   warning to be generated).  */
+extern int comp_type_attributes (const_tree, const_tree);
+
 /* Structure describing an attribute and a function to handle it.  */
 struct attribute_spec
 {