From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 74372 invoked by alias); 6 Aug 2019 15:43:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 74296 invoked by uid 89); 6 Aug 2019 15:43:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_SOFTFAIL autolearn=ham version=3.3.1 spammy=HX-detected-operating-system:timestamps X-HELO: eggs.gnu.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (209.51.188.92) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 06 Aug 2019 15:43:34 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hv1cZ-0007LM-Bc for gcc-patches@gcc.gnu.org; Tue, 06 Aug 2019 11:43:33 -0400 Received: from mx2.suse.de ([195.135.220.15]:45220 helo=mx1.suse.de) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hv1cZ-0007K3-0z for gcc-patches@gcc.gnu.org; Tue, 06 Aug 2019 11:43:31 -0400 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id A42D1B606 for ; Tue, 6 Aug 2019 15:43:26 +0000 (UTC) Resent-From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Resent-To: GCC Patches Resent-Date: Tue, 6 Aug 2019 17:43:26 +0200 Resent-Message-ID: <8f68e58f-24f5-14fe-e39a-802dbb8c0154@suse.cz> Message-Id: In-Reply-To: References: From: Martin Liska Date: Tue, 06 Aug 2019 15:43:00 -0000 Subject: [PATCH 6/9] Integrate that for IPA ICF. To: gcc-patches@gcc.gnu.org MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.22.0" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 X-IsSubscribed: yes X-SW-Source: 2019-08/txt/msg00378.txt.bz2 This is a multi-part message in MIME format. --------------2.22.0 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: quoted-printable Content-length: 750 gcc/ChangeLog: 2019-07-24 Martin Liska * ipa-icf-gimple.c (func_checker::hash_operand_valueize): New function created from compare_operand. (func_checker::compare_cst_or_decl): Remove handling of FIELD_DECLs as it's handled in operand_equal_p. (func_checker::compare_operand): Transform to func_checker::operand_equal_valueize. (func_checker::operand_equal_valueize): New. * ipa-icf-gimple.h (class func_checker): Inherit from operand_compare. * ipa-icf.c (sem_function::equals_private): Properly set push_cfun and pop_cfun. --- gcc/ipa-icf-gimple.c | 226 +++++++++++++------------------------------ gcc/ipa-icf-gimple.h | 8 +- gcc/ipa-icf.c | 7 +- 3 files changed, 81 insertions(+), 160 deletions(-) --------------2.22.0 Content-Type: text/x-patch; name="0006-Integrate-that-for-IPA-ICF.patch" Content-Disposition: attachment; filename="0006-Integrate-that-for-IPA-ICF.patch" Content-Transfer-Encoding: quoted-printable Content-length: 9320 diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c index 4060c0e8eb3..8448d387428 100644 --- a/gcc/ipa-icf-gimple.c +++ b/gcc/ipa-icf-gimple.c @@ -324,6 +324,28 @@ func_checker::compare_memory_operand (tree t1, tree t2) /* Function compare for equality given trees T1 and T2 which can be either a constant or a declaration type. */ =20 +bool +func_checker::hash_operand_valueize (const_tree arg, inchash::hash &hstate, + unsigned int flags) +{ + switch (TREE_CODE (arg)) + { + case FUNCTION_DECL: + case VAR_DECL: + case LABEL_DECL: + case PARM_DECL: + case RESULT_DECL: + case CONST_DECL: + case SSA_NAME: + return true; + + default: + break; + } + + return false; +} + bool func_checker::compare_cst_or_decl (tree t1, tree t2) { @@ -347,19 +369,6 @@ func_checker::compare_cst_or_decl (tree t1, tree t2) return true; case VAR_DECL: return return_with_debug (compare_variable_decl (t1, t2)); - case FIELD_DECL: - { - tree offset1 =3D DECL_FIELD_OFFSET (t1); - tree offset2 =3D DECL_FIELD_OFFSET (t2); - - tree bit_offset1 =3D DECL_FIELD_BIT_OFFSET (t1); - tree bit_offset2 =3D DECL_FIELD_BIT_OFFSET (t2); - - ret =3D compare_operand (offset1, offset2) - && compare_operand (bit_offset1, bit_offset2); - - return return_with_debug (ret); - } case LABEL_DECL: { if (t1 =3D=3D t2) @@ -383,165 +392,68 @@ func_checker::compare_cst_or_decl (tree t1, tree t2) } } =20 -/* Function responsible for comparison of various operands T1 and T2. - If these components, from functions FUNC1 and FUNC2, are equal, true - is returned. */ - -bool -func_checker::compare_operand (tree t1, tree t2) +int +func_checker::operand_equal_valueize (const_tree ct1, const_tree ct2, + unsigned int) { - tree x1, x2, y1, y2, z1, z2; - bool ret; - - if (!t1 && !t2) - return true; - else if (!t1 || !t2) - return false; - - tree tt1 =3D TREE_TYPE (t1); - tree tt2 =3D TREE_TYPE (t2); - - if (!func_checker::compatible_types_p (tt1, tt2)) - return false; - - if (TREE_CODE (t1) !=3D TREE_CODE (t2)) - return return_false (); + tree t1 =3D const_cast (ct1); + tree t2 =3D const_cast (ct2); =20 switch (TREE_CODE (t1)) { - case CONSTRUCTOR: + case FUNCTION_DECL: + /* All function decls are in the symbol table and known to match + before we start comparing bodies. */ + return true; + case VAR_DECL: + return return_with_debug (compare_variable_decl (t1, t2)); + case LABEL_DECL: { - unsigned length1 =3D CONSTRUCTOR_NELTS (t1); - unsigned length2 =3D CONSTRUCTOR_NELTS (t2); - - if (length1 !=3D length2) - return return_false (); - - for (unsigned i =3D 0; i < length1; i++) - if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value, - CONSTRUCTOR_ELT (t2, i)->value)) - return return_false(); - - return true; + int *bb1 =3D m_label_bb_map.get (t1); + int *bb2 =3D m_label_bb_map.get (t2); + /* Labels can point to another function (non-local GOTOs). */ + return return_with_debug (bb1 !=3D NULL && bb2 !=3D NULL && *bb1 =3D=3D *= bb2); } - case ARRAY_REF: - case ARRAY_RANGE_REF: - /* First argument is the array, second is the index. */ - x1 =3D TREE_OPERAND (t1, 0); - x2 =3D TREE_OPERAND (t2, 0); - y1 =3D TREE_OPERAND (t1, 1); - y2 =3D TREE_OPERAND (t2, 1); - - if (!compare_operand (array_ref_low_bound (t1), - array_ref_low_bound (t2))) - return return_false_with_msg (""); - if (!compare_operand (array_ref_element_size (t1), - array_ref_element_size (t2))) - return return_false_with_msg (""); - - if (!compare_operand (x1, x2)) - return return_false_with_msg (""); - return compare_operand (y1, y2); - case MEM_REF: - { - x1 =3D TREE_OPERAND (t1, 0); - x2 =3D TREE_OPERAND (t2, 0); - y1 =3D TREE_OPERAND (t1, 1); - y2 =3D TREE_OPERAND (t2, 1); - - /* See if operand is an memory access (the test originate from - gimple_load_p). - - In this case the alias set of the function being replaced must - be subset of the alias set of the other function. At the moment - we seek for equivalency classes, so simply require inclussion in - both directions. */ =20 - if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2))) - return return_false (); - - if (!compare_operand (x1, x2)) - return return_false_with_msg (""); - - /* Type of the offset on MEM_REF does not matter. */ - return known_eq (wi::to_poly_offset (y1), wi::to_poly_offset (y2)); - } - case COMPONENT_REF: + case PARM_DECL: + case RESULT_DECL: + case CONST_DECL: + return compare_decl (t1, t2); + case SSA_NAME: + return compare_ssa_name (t1, t2); + case FIELD_DECL: { - x1 =3D TREE_OPERAND (t1, 0); - x2 =3D TREE_OPERAND (t2, 0); - y1 =3D TREE_OPERAND (t1, 1); - y2 =3D TREE_OPERAND (t2, 1); + tree offset1 =3D DECL_FIELD_OFFSET (t1); + tree offset2 =3D DECL_FIELD_OFFSET (t2); =20 - ret =3D compare_operand (x1, x2) - && compare_cst_or_decl (y1, y2); + tree bit_offset1 =3D DECL_FIELD_BIT_OFFSET (t1); + tree bit_offset2 =3D DECL_FIELD_BIT_OFFSET (t2); =20 + bool ret =3D (compare_operand (offset1, offset2) + && compare_operand (bit_offset1, bit_offset2)); return return_with_debug (ret); } - /* Virtual table call. */ - case OBJ_TYPE_REF: - { - if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1), OBJ_TYPE_REF_EXPR (t2))) - return return_false (); - if (opt_for_fn (m_source_func_decl, flag_devirtualize) - && virtual_method_call_p (t1)) - { - if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1)) - !=3D tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2))) - return return_false_with_msg ("OBJ_TYPE_REF token mismatch"); - if (!types_same_for_odr (obj_type_ref_class (t1), - obj_type_ref_class (t2))) - return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch"); - if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1), - OBJ_TYPE_REF_OBJECT (t2))) - return return_false_with_msg ("OBJ_TYPE_REF object mismatch"); - } - - return return_with_debug (true); - } - case IMAGPART_EXPR: - case REALPART_EXPR: - case ADDR_EXPR: - { - x1 =3D TREE_OPERAND (t1, 0); - x2 =3D TREE_OPERAND (t2, 0); + default: + break; + } =20 - ret =3D compare_operand (x1, x2); - return return_with_debug (ret); - } - case BIT_FIELD_REF: - { - x1 =3D TREE_OPERAND (t1, 0); - x2 =3D TREE_OPERAND (t2, 0); - y1 =3D TREE_OPERAND (t1, 1); - y2 =3D TREE_OPERAND (t2, 1); - z1 =3D TREE_OPERAND (t1, 2); - z2 =3D TREE_OPERAND (t2, 2); + return -1; +} =20 - ret =3D compare_operand (x1, x2) - && compare_cst_or_decl (y1, y2) - && compare_cst_or_decl (z1, z2); +/* Function responsible for comparison of various operands T1 and T2. + If these components, from functions FUNC1 and FUNC2, are equal, true + is returned. */ =20 - return return_with_debug (ret); - } - case SSA_NAME: - return compare_ssa_name (t1, t2); - case INTEGER_CST: - case COMPLEX_CST: - case VECTOR_CST: - case STRING_CST: - case REAL_CST: - case FUNCTION_DECL: - case VAR_DECL: - case FIELD_DECL: - case LABEL_DECL: - case PARM_DECL: - case RESULT_DECL: - case CONST_DECL: - return compare_cst_or_decl (t1, t2); - default: - return return_false_with_msg ("Unknown TREE code reached"); - } +bool +func_checker::compare_operand (tree t1, tree t2) +{ + if (!t1 && !t2) + return true; + else if (!t1 || !t2) + return false; + if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS)) + return true; + return return_false_with_msg ("operand_equal_p failed"); } =20 bool diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h index 351bddfb2f6..cb7d788e9ee 100644 --- a/gcc/ipa-icf-gimple.h +++ b/gcc/ipa-icf-gimple.h @@ -118,7 +118,7 @@ public: =20 /* A class aggregating all connections and semantic equivalents for a given pair of semantic function candidates. */ -class func_checker +class func_checker : operand_compare { public: /* Initialize internal structures for a given SOURCE_FUNC_DECL and @@ -134,7 +134,7 @@ public: hash_set *ignored_target_nodes =3D NULL); =20 /* Memory release routine. */ - ~func_checker(); + virtual ~func_checker (); =20 /* Function visits all gimple labels and creates corresponding mapping between basic blocks and labels. */ @@ -267,6 +267,10 @@ private: =20 /* Flag if ignore labels in comparison. */ bool m_ignore_labels; + + virtual int operand_equal_valueize (const_tree, const_tree, unsigned int= ); + virtual bool hash_operand_valueize (const_tree, inchash::hash &, + unsigned int); }; =20 } // ipa_icf_gimple namespace diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 13e63b77af1..ce98eefe7f5 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -878,9 +878,14 @@ sem_function::equals_private (sem_item *item) } =20 /* Checking all basic blocks. */ + push_cfun (DECL_STRUCT_FUNCTION (decl)); for (unsigned i =3D 0; i < bb_sorted.length (); ++i) if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]= )) - return return_false(); + { + pop_cfun (); + return return_false (); + } + pop_cfun (); =20 auto_vec bb_dict; =20 --------------2.22.0--