From patchwork Wed Dec 2 08:07:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 551225 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 00FBF1401DA for ; Wed, 2 Dec 2015 19:07:24 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=qxy16jmT; 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=Fzasc+kVTvjnkG1+P/OZilaZYQEbZYKGdbqgsWF+w9eKB5AkMDXOX DU7Cj6UQy5MZsvxQ1ryU7mWB275TNbI0x7MuYT5iX1aNpASaJKurR+Z+Lh66VR44 HBGwXZf3fM7b7gIY/vF/NeFklb7Knx3RQ3SJcKiFny1KGx7fjMaJoU= 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=28kKYpY6pEQtaYfGOE2DSzicKRM=; b=qxy16jmTILytSCI11vcX +UAcLhX32IZqq1Xh6WNk/1FEN7/Zv4da9kD8+MfTenuBvwqmE13fm/l87oSNEfTf UooMpZJK9IqQ3ZtsHLo8Nz7DlseYCr57xxuXny87ReqHVCMMpKq+3HxYKi9D+84Q RTvP9kD5NJt2ZYWDujPCmFM= Received: (qmail 59334 invoked by alias); 2 Dec 2015 08:07:14 -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 59320 invoked by uid 89); 2 Dec 2015 08:07:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.5 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; Wed, 02 Dec 2015 08:07:10 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 87418543D45; Wed, 2 Dec 2015 09:07:06 +0100 (CET) Date: Wed, 2 Dec 2015 09:07:06 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, rguenther@suse.de Subject: -fstrict-aliasing fixes 4/6: do not fiddle with flag_strict_aliasing when expanding debug locations Message-ID: <20151202080706.GA92803@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi, this patch removes flag_strict_aliasing kludge in expanding debug locations and instead it introduces explicit parameter DEBUG that makes set_mem_attributes_minus_bitpos to not affect alias sets. This is sanity checked by comparing number of alias sets before and after at a time we originally overwritten flag_strict_aliasing. I also added code to prevent memory attributes creation for !optimize and to avoid get_alias_set computation for !flag_strict_aliasing. This slightly optimizes -O0 builds but the results seems to be down in the noise (I would not object to leave it out). The patch should fix at least one (latent?) bug that call_stmt expansion invoke expand_debug_expr without clearing flag_strict_aliasing. Bootstrapped/regtested x86_64-linux, also tested with compare-debug, OK? Honza * cfgexpand.c: Include alias.h (expand_debug_expr): Pass debug=true to set_mem_attributes. (expand_debug_locations): Do not fiddle with flag_strict_aliasing; sanity check that no new alias set was introduced. * varasm.c: Include alias.h (make_decl_rtl): New parameter DEBUG; pass it to set_mem_attributes. (make_decl_rtl_for_debug): Do ont fiddle with flag_strict_aliasing; assert that no new alias set was introduced. * varasm.h (make_decl_rtl): New parameter debug. * alias.h (num_alias_sets): New function. * emit-rtl.c (set_mem_attributes_minus_bitpos): New parameter DEBUG; exit early when not optimizing; do not introduce new alias set when producing debug only attributes. (set_mem_attributes): New parameter DEBUG. * emit-rtl.h (set_mem_attributes, set_mem_attributes_minus_bitpos): New parameters DEBUG. (num_alias_sets): New function. Index: cfgexpand.c =================================================================== --- cfgexpand.c (revision 231122) +++ cfgexpand.c (working copy) @@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. #include "builtins.h" #include "tree-chkp.h" #include "rtl-chkp.h" +#include "alias.h" /* Some systems use __main in a way incompatible with its use in gcc, in these cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to @@ -4178,7 +4179,7 @@ expand_debug_expr (tree exp) return NULL_RTX; op0 = gen_rtx_CONST_STRING (Pmode, TREE_STRING_POINTER (exp)); op0 = gen_rtx_MEM (BLKmode, op0); - set_mem_attributes (op0, exp, 0); + set_mem_attributes (op0, exp, 0, true); return op0; } /* Fall through... */ @@ -4346,7 +4347,7 @@ expand_debug_expr (tree exp) return NULL; op0 = gen_rtx_MEM (mode, op0); - set_mem_attributes (op0, exp, 0); + set_mem_attributes (op0, exp, 0, true); if (TREE_CODE (exp) == MEM_REF && !is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0))) set_mem_expr (op0, NULL_TREE); @@ -4372,7 +4373,7 @@ expand_debug_expr (tree exp) op0 = gen_rtx_MEM (mode, op0); - set_mem_attributes (op0, exp, 0); + set_mem_attributes (op0, exp, 0, true); set_mem_addr_space (op0, as); return op0; @@ -4458,7 +4459,7 @@ expand_debug_expr (tree exp) op0 = copy_rtx (op0); if (op0 == orig_op0) op0 = shallow_copy_rtx (op0); - set_mem_attributes (op0, exp, 0); + set_mem_attributes (op0, exp, 0, true); } if (bitpos == 0 && mode == GET_MODE (op0)) @@ -5219,12 +5220,11 @@ expand_debug_locations (void) { rtx_insn *insn; rtx_insn *last = get_last_insn (); - int save_strict_alias = flag_strict_aliasing; /* New alias sets while setting up memory attributes cause -fcompare-debug failures, even though it doesn't bring about any codegen changes. */ - flag_strict_aliasing = 0; + int num = num_alias_sets (); for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if (DEBUG_INSN_P (insn)) @@ -5284,7 +5284,7 @@ expand_debug_locations (void) avoid_complex_debug_insns (insn2, &INSN_VAR_LOCATION_LOC (insn2), 0); } - flag_strict_aliasing = save_strict_alias; + gcc_checking_assert (num == num_alias_sets ()); } /* Performs swapping operands of commutative operations to expand Index: varasm.c =================================================================== --- varasm.c (revision 231122) +++ varasm.c (working copy) @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. #include "common/common-target.h" #include "asan.h" #include "rtl-iter.h" +#include "alias.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" /* Needed for external data declarations. */ @@ -1280,7 +1281,7 @@ ultimate_transparent_alias_target (tree This is never called for PARM_DECL nodes. */ void -make_decl_rtl (tree decl) +make_decl_rtl (tree decl, bool debug) { const char *name = 0; int reg_number; @@ -1470,7 +1471,7 @@ make_decl_rtl (tree decl) x = gen_rtx_MEM (DECL_MODE (decl), x); if (TREE_CODE (decl) != FUNCTION_DECL) - set_mem_attributes (x, decl, 1); + set_mem_attributes (x, decl, 1, debug); SET_DECL_RTL (decl, x); /* Optionally set flags or add text to the name to record information @@ -1487,27 +1488,25 @@ make_decl_rtl (tree decl) rtx make_decl_rtl_for_debug (tree decl) { - unsigned int save_aliasing_flag; rtx rtl; if (DECL_RTL_SET_P (decl)) return DECL_RTL (decl); - /* Kludge alert! Somewhere down the call chain, make_decl_rtl will - call new_alias_set. If running with -fcompare-debug, sometimes - we do not want to create alias sets that will throw the alias - numbers off in the comparison dumps. So... clearing - flag_strict_aliasing will keep new_alias_set() from creating a - new set. */ - save_aliasing_flag = flag_strict_aliasing; - flag_strict_aliasing = 0; + int num = num_alias_sets (); + make_decl_rtl (decl, true); rtl = DECL_RTL (decl); /* Reset DECL_RTL back, as various parts of the compiler expects DECL_RTL set meaning it is actually going to be output. */ SET_DECL_RTL (decl, NULL); + + /* Be sure that make_decl_rtl will not cal lnew_alias set. + If running with -fcompare-debug, sometimes + we do not want to create alias sets that will throw the alias + numbers off in the comparison dumps. */ + gcc_checking_assert (num == num_alias_sets ()); - flag_strict_aliasing = save_aliasing_flag; return rtl; } Index: varasm.h =================================================================== --- varasm.h (revision 231122) +++ varasm.h (working copy) @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. extern tree cold_function_name; extern tree tree_output_constant_def (tree); -extern void make_decl_rtl (tree); +extern void make_decl_rtl (tree, bool debug = false); extern rtx make_decl_rtl_for_debug (tree); extern void make_decl_one_only (tree, tree); extern int supports_one_only (void); Index: alias.h =================================================================== --- alias.h (revision 231122) +++ alias.h (working copy) @@ -25,6 +25,7 @@ extern alias_set_type get_alias_set (tre extern alias_set_type get_deref_alias_set (tree); extern alias_set_type get_varargs_alias_set (void); extern alias_set_type get_frame_alias_set (void); +extern int num_alias_sets (void); extern tree component_uses_parent_alias_set_from (const_tree); extern bool alias_set_subset_of (alias_set_type, alias_set_type); extern void record_alias_subset (alias_set_type, alias_set_type); Index: emit-rtl.c =================================================================== --- emit-rtl.c (revision 231122) +++ emit-rtl.c (working copy) @@ -1738,16 +1738,20 @@ get_mem_align_offset (rtx mem, unsigned /* Given REF (a MEM) and T, either the type of X or the expression corresponding to REF, set the memory attributes. OBJECTP is nonzero if we are making a new object of this type. BITPOS is nonzero if - there is an offset outstanding on T that will be applied later. */ + there is an offset outstanding on T that will be applied later. + if DEBUG is true, assume that the MEM will be used only for debug + insns. */ void set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, - HOST_WIDE_INT bitpos) + HOST_WIDE_INT bitpos, bool debug) { HOST_WIDE_INT apply_bitpos = 0; tree type; struct mem_attrs attrs, *defattrs, *refattrs; addr_space_t as; + bool global_var = false; + tree orig_t = t; /* It can happen that type_for_mode was given a mode for which there is no language-level type. In which case it returns NULL, which @@ -1759,18 +1763,8 @@ set_mem_attributes_minus_bitpos (rtx ref if (type == error_mark_node) return; - /* If we have already set DECL_RTL = ref, get_alias_set will get the - wrong answer, as it assumes that DECL_RTL already has the right alias - info. Callers should not set DECL_RTL until after the call to - set_mem_attributes. */ - gcc_assert (!DECL_P (t) || ref != DECL_RTL_IF_SET (t)); - memset (&attrs, 0, sizeof (attrs)); - /* Get the alias set from the expression or type (perhaps using a - front-end routine) and use it. */ - attrs.alias = get_alias_set (t); - MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type); MEM_POINTER (ref) = POINTER_TYPE_P (type); @@ -1829,6 +1823,12 @@ set_mem_attributes_minus_bitpos (rtx ref { tree base; + if (TREE_CODE (t) == CONST_DECL + || (TREE_CODE (t) == VAR_DECL + && auto_var_in_fn_p (t, current_function_decl)) + || (TREE_CODE (t) == LABEL_DECL && DECL_NONLOCAL (t))) + global_var = true; + if (TREE_THIS_VOLATILE (t)) MEM_VOLATILE_P (ref) = 1; @@ -1866,13 +1866,20 @@ set_mem_attributes_minus_bitpos (rtx ref as = TYPE_ADDR_SPACE (TREE_TYPE (base)); } + /* When not optimizing, there is no need to attach memory attributes + unless we produce DECL_RTL of declaration that may later be used in a + function that is optimized. */ + if (!optimize && !global_var) + return; + /* If this expression uses it's parent's alias set, mark it such that we won't change it. */ - if (component_uses_parent_alias_set_from (t) != NULL_TREE) + if (!debug && (flag_strict_aliasing || global_var) + && component_uses_parent_alias_set_from (t) != NULL_TREE) MEM_KEEP_ALIAS_SET_P (ref) = 1; /* If this is a decl, set the attributes of the MEM from it. */ - if (DECL_P (t)) + else if (DECL_P (t)) { attrs.expr = t; attrs.offset_known_p = true; @@ -1962,6 +1969,11 @@ set_mem_attributes_minus_bitpos (rtx ref obj_align = (obj_bitpos & -obj_bitpos); attrs.align = MAX (attrs.align, obj_align); } + /* When not optimizing, there is no need to attach memory attributes + unless we produce DECL_RTL of declaration that may later be used in a + function that is optimized. */ + else if (!global_var && !optimize) + return; if (tree_fits_uhwi_p (new_size)) { @@ -1980,15 +1992,29 @@ set_mem_attributes_minus_bitpos (rtx ref attrs.size += apply_bitpos / BITS_PER_UNIT; } + /* Get the alias set from the expression or type (perhaps using a + front-end routine) and use it. Never produce new alias sets when + the memory reference is used only for debug (so the alias numbers + are stable) and with !flag_strict_aliasing for all function local RTLs. */ + if (!debug && (flag_strict_aliasing || global_var)) + { + /* If we have already set DECL_RTL = ref, get_alias_set will get the + wrong answer, as it assumes that DECL_RTL already has the right alias + info. Callers should not set DECL_RTL until after the call to + set_mem_attributes. */ + gcc_assert (!DECL_P (orig_t) || ref != DECL_RTL_IF_SET (orig_t)); + attrs.alias = get_alias_set (orig_t); + } + /* Now set the attributes we computed above. */ attrs.addrspace = as; set_mem_attrs (ref, &attrs); } void -set_mem_attributes (rtx ref, tree t, int objectp) +set_mem_attributes (rtx ref, tree t, int objectp, bool debug) { - set_mem_attributes_minus_bitpos (ref, t, objectp, 0); + set_mem_attributes_minus_bitpos (ref, t, objectp, 0, debug); } /* Set the alias set of MEM to SET. */ Index: emit-rtl.h =================================================================== --- emit-rtl.h (revision 231122) +++ emit-rtl.h (working copy) @@ -484,13 +484,16 @@ extern rtx offset_address (rtx, rtx, uns /* Given REF, a MEM, and T, either the type of X or the expression corresponding to REF, set the memory attributes. OBJECTP is nonzero - if we are making a new object of this type. */ -extern void set_mem_attributes (rtx, tree, int); + if we are making a new object of this type. + If DEBUG is true, the memory expression will be used only for debug + statements and in that case avoid creation of new alias set. */ +extern void set_mem_attributes (rtx, tree, int, bool debug = false); /* Similar, except that BITPOS has not yet been applied to REF, so if we alter MEM_OFFSET according to T then we should subtract BITPOS expecting that it'll be added back in later. */ -extern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT); +extern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT, + bool debug = false); /* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN bits aligned for 0 <= OFFSET < ALIGN / BITS_PER_UNIT, or Index: alias.c =================================================================== --- alias.c (revision 231146) +++ alias.c (working copy) @@ -1096,6 +1096,17 @@ new_alias_set (void) return 0; } +/* Return number of alias sets; used for sanity checking that we did not + introduced new ones for debug statements. */ + +int +num_alias_sets (void) +{ + if (!alias_sets) + return 0; + return alias_sets->length (); +} + /* Indicate that things in SUBSET can alias things in SUPERSET, but that not everything that aliases SUPERSET also aliases SUBSET. For example, in C, a store to an `int' can alias a load of a structure containing an