From patchwork Fri May 22 12:33:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 475592 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id CCC74140B0E for ; Fri, 22 May 2015 22:34:04 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=vt99EZyC; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=byJ+tBvb9nNRtQGnwYMmJW8r5mDjJeNpy8uVprZzChgLxnFyH+qIU THJHJYVXrZkWbJuOi6P/3OgS/kfLs4cJweKushftT4sE8Ck6uLzun6FiYrUUNY99 BLNHhgfbsXchxtMB/+l5VhXrskvU+LKv69NB3ESNiL/IynMS7vgRb4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=U9kQ63/NjxnKB2Wg/dNi2F22Trw=; b=vt99EZyCeuSDddZo52BT fH6AMPxmLXESiHh/tbNrmZX9/nUfG2A5nrcKLtqAm4u7vJfR7/OQkvOddMYc7rBw w9kZ3/dT3sVv/RoSbh1ap8uM6uD61pnIourztXEzyTcW5/rbAIM9SLmvaQkfOvaT ao714tQJ6TrA5VYCn45cUDQ= Received: (qmail 42712 invoked by alias); 22 May 2015 12:33:54 -0000 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 Received: (qmail 42701 invoked by uid 89); 22 May 2015 12:33:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.4 required=5.0 tests=AWL, BAYES_50, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 22 May 2015 12:33:45 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 73772543970; Fri, 22 May 2015 14:33:41 +0200 (CEST) Date: Fri, 22 May 2015 14:33:41 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, mliska@suse.cz, rguenther@suse.de Subject: Add few cases to operand_equal_p Message-ID: <20150522123341.GD91616@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi, I am working on patch that makes operand_equal_p replace logic from ipa-icf-gimple's compare_op via a valueizer hook. Currently the patch however cuts number of merges on firefox to half (apparently becuase it gives up on some tree codes too early) The patch bellow merges code from ipa-icf-gimple.c that is missing in fold-const and is needed. Bootstrapped/regtested x86_64-linux, OK? Honza * fold-const.c (operand_equal_p): Handle OBJ_TYPE_REF, CONSTRUCTOR and be more tolerant about FIELD_DECL. * tree.c (add_expr): Handle FIELD_DECL. (prototype_p, virtual_method_call_p, obj_type_ref_class): Constify. * tree.h (prototype_p, virtual_method_call_p, obj_type_ref_class): Constify. Index: fold-const.c =================================================================== --- fold-const.c (revision 223500) @@ -3037,6 +3058,40 @@ operand_equal_p (const_tree arg0, const_ case DOT_PROD_EXPR: return OP_SAME (0) && OP_SAME (1) && OP_SAME (2); + /* OBJ_TYPE_REF really is just a transparent wrapper around expression, + but it holds additional type information for devirtualization that + needs to be matched. We may want to intoruce OEP flag if we want + to compare the actual value only, or if we also care about effects + of potentially merging the code. This flag can bypass this check + as well as the alias set matching in MEM_REF. */ + case OBJ_TYPE_REF: + { + if (!operand_equal_p (OBJ_TYPE_REF_EXPR (arg0), + OBJ_TYPE_REF_EXPR (arg1), flags)) + return false; + if (flag_devirtualize && virtual_method_call_p (arg0)) + { + if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg0)) + != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg1))) + return false; + if (!types_same_for_odr (obj_type_ref_class (arg0), + obj_type_ref_class (arg1))) + return false; + /* OBJ_TYPE_REF_OBJECT is used to track the instance of + object THIS pointer points to. Checking that both + addresses equal is safe approximation of the fact + that dynamic types are equal. + Do not care about the other flags, because this expression + does not attribute to actual value of OBJ_TYPE_REF */ + if (!operand_equal_p (OBJ_TYPE_REF_OBJECT (arg0), + OBJ_TYPE_REF_OBJECT (arg1), + OEP_ADDRESS_OF)) + return false; + } + + return true; + } + default: return 0; } @@ -3097,6 +3152,21 @@ operand_equal_p (const_tree arg0, const_ } case tcc_declaration: + /* At LTO time the FIELD_DECL may exist in multiple copies. + We only care about offsets and bit offsets for operands. */ + if (TREE_CODE (arg0) == FIELD_DECL) + { + tree offset1 = DECL_FIELD_OFFSET (arg0); + tree offset2 = DECL_FIELD_OFFSET (arg1); + + tree bit_offset1 = DECL_FIELD_BIT_OFFSET (arg0); + tree bit_offset2 = DECL_FIELD_BIT_OFFSET (arg1); + + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); + + return operand_equal_p (offset1, offset2, flags) + && operand_equal_p (bit_offset1, bit_offset2, flags); + } /* Consider __builtin_sqrt equal to sqrt. */ return (TREE_CODE (arg0) == FUNCTION_DECL && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1) @@ -3104,12 +3174,50 @@ operand_equal_p (const_tree arg0, const_ && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1)); default: + /* In GIMPLE empty constructors are allowed in initializers of + vector types. */ + if (TREE_CODE (arg0) == CONSTRUCTOR) + { + unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (arg0)); + unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (arg1)); + + if (length1 != length2) + return false; + + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF); + + for (unsigned i = 0; i < length1; i++) + if (!operand_equal_p (CONSTRUCTOR_ELT (arg0, i)->value, + CONSTRUCTOR_ELT (arg1, i)->value, flags)) + return false; + + return true; + } return 0; } #undef OP_SAME #undef OP_SAME_WITH_NULL } Index: tree.c =================================================================== --- tree.c (revision 223500) +++ tree.c (working copy) @@ -7647,6 +7647,12 @@ add_expr (const_tree t, inchash::hash &h } return; } + case FIELD_DECL: + /* At LTO time the FIELD_DECL may exist in multiple copies. + We only care about offsets and bit offsets for operands. */ + inchash::add_expr (DECL_FIELD_OFFSET (t), hstate); + inchash::add_expr (DECL_FIELD_BIT_OFFSET (t), hstate); + return; case FUNCTION_DECL: /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form. Otherwise nodes that compare equal according to operand_equal_p might @@ -11579,7 +11585,7 @@ stdarg_p (const_tree fntype) /* Return true if TYPE has a prototype. */ bool -prototype_p (tree fntype) +prototype_p (const_tree fntype) { tree t; @@ -12005,7 +12011,7 @@ lhd_gcc_personality (void) can't apply.) */ bool -virtual_method_call_p (tree target) +virtual_method_call_p (const_tree target) { if (TREE_CODE (target) != OBJ_TYPE_REF) return false; @@ -12026,7 +12032,7 @@ virtual_method_call_p (tree target) /* REF is OBJ_TYPE_REF, return the class the ref corresponds to. */ tree -obj_type_ref_class (tree ref) +obj_type_ref_class (const_tree ref) { gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF); ref = TREE_TYPE (ref); Index: tree.h =================================================================== --- tree.h (revision 223500) +++ tree.h (working copy) @@ -4375,7 +4375,7 @@ extern int operand_equal_for_phi_arg_p ( extern tree create_artificial_label (location_t); extern const char *get_name (tree); extern bool stdarg_p (const_tree); -extern bool prototype_p (tree); +extern bool prototype_p (const_tree); extern bool is_typedef_decl (tree x); extern bool typedef_variant_p (tree); extern bool auto_var_in_fn_p (const_tree, const_tree); @@ -4544,8 +4544,8 @@ extern location_t *block_nonartificial_l extern location_t tree_nonartificial_location (tree); extern tree block_ultimate_origin (const_tree); extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree); -extern bool virtual_method_call_p (tree); -extern tree obj_type_ref_class (tree ref); +extern bool virtual_method_call_p (const_tree); +extern tree obj_type_ref_class (const_tree ref); extern bool types_same_for_odr (const_tree type1, const_tree type2, bool strict=false); extern bool contains_bitfld_component_ref_p (const_tree);