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

Kai Tietz ktietz70@googlemail.com
Mon Mar 21 17:37:00 GMT 2011


Hello,

this patch does some search-cost optimization for comp_type_attributes
target hook. By recent patch about diagnostic of attributes affecting
type indentity, it is possible to avoid some searching for such kind
of type checks.

In general it would be possible to remove this target-hook completely,
but by doing so we would need to introduce an new hook which returns
the current default calling-convention. To avoid this the check just
avoids call of comp_type_attributes target hook for cases where all
type identity affecting attributes are compatible. If the don't match
the target hook gets called to handle target's default calling
convention proper.

ChangeLog gcc/

2011-03-11  Kai Tietz

	* c-typeck.c (comptypes_internal): Replace target
	hook call of comp_type_attributes by version in tree.c file.
	* gimple.c (gimple_types_compatible_p_1): Likewise.
	* tree-ssa.c (useless_type_conversion_p): Likewise.
	* tree.c (build_type_attribute_qual_variant): Likewise.
	(comp_type_attributes): New function.
	* tree.h (comp_type_attributes): New prototype.

ChangeLog cp/

2011-03-11  Kai Tietz

	* decl.c (decls_match): Replace target hook
	call of comp_type_attributes by version in tree.c file.
	* search.c (check_final_overrider): Likewise.
	* typeck.c (structural_comptypes): Likewise.

Tested for x86_64-pc-linux-gnu, and for x86_64-w64-mingw32. Ok for apply?

Regards,
Kai
-------------- next part --------------
Index: gcc/gcc/c-typeck.c
===================================================================
--- gcc.orig/gcc/c-typeck.c	2011-01-27 08:57:07.000000000 +0100
+++ gcc/gcc/c-typeck.c	2011-03-21 11:05:45.345143000 +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-17 18:55:30.000000000 +0100
+++ gcc/gcc/cp/decl.c	2011-03-21 11:12:00.528285200 +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-06 12:15:05.000000000 +0100
+++ gcc/gcc/cp/search.c	2011-03-21 11:12:36.760386100 +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-17 18:55:30.000000000 +0100
+++ gcc/gcc/cp/typeck.c	2011-03-21 11:13:12.125876900 +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	2010-12-02 20:10:55.000000000 +0100
+++ gcc/gcc/gimple.c	2011-03-21 11:06:27.447989400 +0100
@@ -3616,7 +3616,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-17 18:55:31.000000000 +0100
+++ gcc/gcc/tree-ssa.c	2011-03-21 11:07:24.362216600 +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-17 18:54:25.000000000 +0100
+++ gcc/gcc/tree.c	2011-03-21 11:04:26.742161700 +0100
@@ -4283,7 +4283,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);
@@ -4296,6 +4296,78 @@ build_type_attribute_qual_variant (tree
   return ttype;
 }
 
+/* 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 (IDENTIFIER_POINTER (TREE_PURPOSE (a)),
+			       CONST_CAST_TREE (a2));
+      if (!attr)
+	break;
+
+      if (TREE_VALUE (a) != NULL_TREE
+	  && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
+	  && TREE_VALUE (attr) != NULL
+	  && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST)
+	{
+	  if (simple_cst_list_equal (TREE_VALUE (a),
+				     TREE_VALUE (attr)) == 1)
+	    break;
+	}
+      else if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (attr)) == 1)
+	break;
+    }
+  if (!a)
+    {
+      for (a = a2; 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 (IDENTIFIER_POINTER (TREE_PURPOSE (a)),
+				   CONST_CAST_TREE (a1));
+	  if (!attr)
+	    break;
+
+	  if (TREE_VALUE (a) != NULL_TREE
+	      && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
+	      && TREE_VALUE (attr) != NULL
+	      && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST)
+	    {
+	      if (simple_cst_list_equal (TREE_VALUE (a),
+					 TREE_VALUE (attr)) == 1)
+		break;
+	    }
+	  else if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (attr)) == 1)
+	    break;
+	}
+      /* All types affecting identity are equal, so
+         there is no need to call target host for comparision.  */
+      if (!a)
+        return 1;
+    }
+  /* As some types might be compatible for target, we have to call
+     for attributes affecting type identity the target hook
+     to get final result.  */
+  return targetm.comp_type_attributes (type1, type2);
+}
 
 /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
    is ATTRIBUTE.
Index: gcc/gcc/tree.h
===================================================================
--- gcc.orig/gcc/tree.h	2011-03-21 09:04:39.000000000 +0100
+++ gcc/gcc/tree.h	2011-03-21 09:50:06.218247100 +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
 {


More information about the Gcc-patches mailing list