From patchwork Fri Mar 25 09:52:08 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kai Tietz X-Patchwork-Id: 88356 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 5001AB6F8E for ; Fri, 25 Mar 2011 20:52:20 +1100 (EST) Received: (qmail 27726 invoked by alias); 25 Mar 2011 09:52:18 -0000 Received: (qmail 27713 invoked by uid 22791); 25 Mar 2011 09:52:16 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 25 Mar 2011 09:52:09 +0000 Received: by qwh5 with SMTP id 5so572426qwh.20 for ; Fri, 25 Mar 2011 02:52:08 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.18.77 with SMTP id v13mr426069qca.56.1301046728647; Fri, 25 Mar 2011 02:52:08 -0700 (PDT) Received: by 10.229.97.206 with HTTP; Fri, 25 Mar 2011 02:52:08 -0700 (PDT) In-Reply-To: <4D8C617F.102@redhat.com> References: <4D8B1270.50707@redhat.com> <4D8B3243.8060707@redhat.com> <4D8B7B34.7030006@redhat.com> <4D8C617F.102@redhat.com> Date: Fri, 25 Mar 2011 10:52:08 +0100 Message-ID: Subject: Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes From: Kai Tietz To: Jason Merrill Cc: GCC Patches X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 2011/3/25 Jason Merrill : > 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 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 {