From patchwork Mon Oct 3 19:07:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prathamesh Kulkarni X-Patchwork-Id: 77228 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp1829236qgf; Mon, 3 Oct 2016 12:08:10 -0700 (PDT) X-Received: by 10.98.217.7 with SMTP id s7mr8178466pfg.72.1475521690581; Mon, 03 Oct 2016 12:08:10 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id h75si12770273pfk.123.2016.10.03.12.08.10 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 03 Oct 2016 12:08:10 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-437587-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-437587-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-437587-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; q=dns; s=default; b=pJaKVd4HPISE/XP EqrbxOSMtxv7dwS5QJ2dcWXkbblOKHfmRdXMeHaMkCl2GkfYCZOL0r6jLrQ+hOf3 c/KsPnRFcbzUoRYXsEyJQPAVivy5wpmbRLcn9odGgg95Am5I2zgwG9VoZ61tUvhz kPVhTnQOxVFo3rqjdQ2oGmtccrUY= 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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; s=default; bh=t/ohHB9msGF7QNWh1Kk9K J+obps=; b=oQvkJrHSC4uIi5PCu+hBcVefUihzRA9DMNOpD6FiWmz/vZoS585Ge W7YYP84v1iNO9pn7Vw4vedgIEX/QsEpEHRrnlKOjfOK/Fuu4zYOLx6kRSW75OzDY 7o3O+QbqpvyrhUAJJsnw/Y7TwoxK5kujQ91Qg0WhkIwSSdkZFBeQM0= Received: (qmail 128004 invoked by alias); 3 Oct 2016 19:07:53 -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 127962 invoked by uid 89); 3 Oct 2016 19:07:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=richards, Richards, obtaining, sk:get_poi X-HELO: mail-it0-f43.google.com Received: from mail-it0-f43.google.com (HELO mail-it0-f43.google.com) (209.85.214.43) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 03 Oct 2016 19:07:41 +0000 Received: by mail-it0-f43.google.com with SMTP id 188so43303368iti.1 for ; Mon, 03 Oct 2016 12:07:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=G5+rAWUQNca/E6BSmIJGUP+dZExVC7Dok7LbOwrpXN4=; b=R+y0LymSOJ61Td4B7PPx+EULopVYQXcD0EF3fz3Owdt039nAErLMP8bB9hWHwpNW+A P5cxUu+s2jcJwJkFdKZWuyqEEd/lP9POimGy/vyfMHUV3kAY+GlVLiiusvLIdXM/IIeW hXw/leDa+21n32mymdUEYGFAu7yMkJKrE6d+DsbmwAKYNZ2//Vu9LKlCyF/5OGe6IfUb 0I7L78E9nJ0ajCiPnmv6GwNPnFz2cV2eTEKNdE9dBqALISsfP9MmxLPm+R7dl6JW8iuu i8KSM/yxsvsmCpkp5wKAe7HF+Av1PldIOBAVLY8LS6wAJ086yLzV/HJ+Ub/2IrizOXT/ YMLQ== X-Gm-Message-State: AA6/9RnNmFT8vTEIqIlEjlAkCle2v0bmrYY68Mh0h7jf2xsKSKQWGp/DQE/w+FxkjekJIK6924ksnleFDaQU+nNw X-Received: by 10.36.204.139 with SMTP id x133mr19768347itf.86.1475521659578; Mon, 03 Oct 2016 12:07:39 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.81.85 with HTTP; Mon, 3 Oct 2016 12:07:38 -0700 (PDT) In-Reply-To: <20160922115635.GB86459@kam.mff.cuni.cz> References: <20160922115635.GB86459@kam.mff.cuni.cz> From: Prathamesh Kulkarni Date: Tue, 4 Oct 2016 00:37:38 +0530 Message-ID: Subject: Re: [RFC] Extend ipa-bitwise-cp with pointer alignment propagation To: Jan Hubicka Cc: gcc Patches , Martin Jambor , Richard Biener X-IsSubscribed: yes On 22 September 2016 at 17:26, Jan Hubicka wrote: >> Hi, >> The attached patch tries to extend ipa bits propagation to handle >> pointer alignment propagation. >> The patch just disables ipa-cp-alignment pass, I suppose we want to >> eventually remove it ? > > Yes, can you please verify that alignments it computes are monotonously > worse than those your new code computes and include the removal in the > next iteration of the patch? >> >> Bootstrap+tested on x86_64-unknown-linux-gnu. >> Cross-tested on arm*-*-*, aarch64*-*-*. >> Does the patch look OK ? >> >> Thanks, >> Prathamesh >> @@ -2258,8 +2271,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs) >> &dest_plats->itself); >> ret |= propagate_context_accross_jump_function (cs, jump_func, i, >> &dest_plats->ctxlat); >> - ret |= propagate_alignment_accross_jump_function (cs, jump_func, >> - &dest_plats->alignment); >> +// ret |= propagate_alignment_accross_jump_function (cs, jump_func, >> +// &dest_plats->alignment); > > obviously we do not want commented out ocde.. > >> ret |= propagate_bits_accross_jump_function (cs, i, jump_func, >> &dest_plats->bits_lattice); >> ret |= propagate_aggs_accross_jump_function (cs, jump_func, >> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c >> index 1629781..5cee27b 100644 >> --- a/gcc/ipa-prop.c >> +++ b/gcc/ipa-prop.c >> @@ -1701,6 +1701,16 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, >> jfunc->bits.mask = 0; >> } >> } >> + else if (POINTER_TYPE_P (TREE_TYPE (arg))) >> + { >> + unsigned HOST_WIDE_INT bitpos; >> + unsigned align; >> + >> + jfunc->bits.known = true; >> + get_pointer_alignment_1 (arg, &align, &bitpos); >> + jfunc->bits.mask = wi::mask(TYPE_PRECISION (TREE_TYPE (arg)), false).and_not (align / BITS_PER_UNIT - 1); > > ... and long lines :) > >> + jfunc->bits.value = bitpos / BITS_PER_UNIT; >> + } >> else >> gcc_assert (!jfunc->bits.known); >> >> @@ -5534,7 +5544,7 @@ ipcp_update_bits (struct cgraph_node *node) >> next_parm = DECL_CHAIN (parm); >> >> if (!bits[i].known >> - || !INTEGRAL_TYPE_P (TREE_TYPE (parm)) >> + || !(INTEGRAL_TYPE_P (TREE_TYPE (parm)) || POINTER_TYPE_P (TREE_TYPE (parm))) > > I suppose eventually we may want to enable other types, too. > It does even make sense to propagate this on aggregates, but definitly on > vectors and complex numbers. > > Otherwise the patch seems fine to me (modulo Richard's comments) Hi, Sorry for late response, I was travelling. I tried to verify the alignments are monotonously worse with the attached patch (verify.diff), which asserts that alignment lattice is not better than bits lattice during each propagation step in propagate_constants_accross_call(). Does that look OK ? ipa-cp-alignment has better alignments than ipa-bit-cp in following cases: a) ipa_get_type() returns NULL: ipa-bits-cp sets lattice to bottom if ipa_get_type (param) returns NULL, for instance in case of K&R function, while ipa-cp-alignment doesn't look at param types, and can propagate alignments. The following assert: if (bits_lattice.bottom_p ()) gcc_assert (align_lattice.bottom_p()) triggered for 400.perlbench, 403.gcc, 456.hmmer and 481.wrf due to ipa_get_type() returning NULL. I am not really sure how to handle this case, since we need to know parameter's type during bits propagation for obtaining precision. b) This happens for attached test-case (test.i), which is a reduced (and slightly modified) test-case from 458.sjeng. Bits propagation sets lattice to bottom, while alignment propagation propagates . In bits_lattice::meet_with_1 m_mask = other_mask = 0x0fffffffffffffff0 m_value = 0x7 other_value = 0x8 In this case meet operation sets m_mask to: (m_mask | mask) | (m_value ^ other_value) = 0x0fffffffffffffff0 | (0xf) == 0x0ffffffffffffffff and hence the bits lattice is set to bottom. I suppose it doesn't matter for this case if bits propagation sets lattice to bottom, since propagating isn't really useful ? The attached patch (alignprop-4.diff) removes ipa-cp-alignment, and checks for misalign against old_misalgin and prints message in the dump file if they mismatch. Testing in progress. Thanks, Prathamesh > Honza diff --git a/gcc/common.opt b/gcc/common.opt index 0e01577..601a347 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1565,10 +1565,6 @@ fipa-cp-clone Common Report Var(flag_ipa_cp_clone) Optimization Perform cloning to make Interprocedural constant propagation stronger. -fipa-cp-alignment -Common Report Var(flag_ipa_cp_alignment) Optimization -Perform alignment discovery and propagation to make Interprocedural constant propagation stronger. - fipa-bit-cp Common Report Var(flag_ipa_bit_cp) Optimization Perform interprocedural bitwise constant propagation. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6767462..1dfa2e0 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -360,7 +360,7 @@ Objective-C and Objective-C++ Dialects}. -fgcse-sm -fhoist-adjacent-loads -fif-conversion @gol -fif-conversion2 -findirect-inlining @gol -finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol --finline-small-functions -fipa-cp -fipa-cp-clone -fipa-cp-alignment -fipa-bit-cp @gol +-finline-small-functions -fipa-cp -fipa-cp-clone -fipa-bit-cp @gol -fipa-pta -fipa-profile -fipa-pure-const -fipa-reference -fipa-icf @gol -fira-algorithm=@var{algorithm} @gol -fira-region=@var{region} -fira-hoist-pressure @gol @@ -6637,7 +6637,6 @@ also turns on the following optimization flags: -finline-small-functions @gol -findirect-inlining @gol -fipa-cp @gol --fipa-cp-alignment @gol -fipa-bit-cp @gol -fipa-sra @gol -fipa-icf @gol @@ -7639,14 +7638,6 @@ it may significantly increase code size (see @option{--param ipcp-unit-growth=@var{value}}). This flag is enabled by default at @option{-O3}. -@item -fipa-cp-alignment -@opindex -fipa-cp-alignment -When enabled, this optimization propagates alignment of function -parameters to support better vectorization and string operations. - -This flag is enabled by default at @option{-O2} and @option{-Os}. It -requires that @option{-fipa-cp} is enabled. - @item -fipa-bit-cp @opindex -fipa-bit-cp When enabled, perform ipa bitwise constant propagation. This flag is diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 95a2a1e..88baf69 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -238,36 +238,6 @@ public: struct ipcp_agg_lattice *next; }; -/* Lattice of pointer alignment. Unlike the previous types of lattices, this - one is only capable of holding one value. */ - -class ipcp_alignment_lattice -{ -public: - /* If bottom and top are both false, these two fields hold values as given by - ptr_info_def and get_pointer_alignment_1. */ - unsigned align; - unsigned misalign; - - inline bool bottom_p () const; - inline bool top_p () const; - inline bool set_to_bottom (); - bool meet_with (unsigned new_align, unsigned new_misalign); - bool meet_with (const ipcp_alignment_lattice &other, HOST_WIDE_INT offset); - void print (FILE * f); -private: - /* If set, this lattice is bottom and all other fields should be - disregarded. */ - bool bottom; - /* If bottom and not_top are false, the lattice is TOP. If not_top is true, - the known alignment is stored in the fields align and misalign. The field - is negated so that memset to zero initializes the lattice to TOP - state. */ - bool not_top; - - bool meet_with_1 (unsigned new_align, unsigned new_misalign); -}; - /* Lattice of known bits, only capable of holding one value. Bitwise constant propagation propagates which bits of a value are constant. @@ -354,8 +324,6 @@ public: ipcp_lattice ctxlat; /* Lattices describing aggregate parts. */ ipcp_agg_lattice *aggs; - /* Lattice describing known alignment. */ - ipcp_alignment_lattice alignment; /* Lattice describing known bits. */ ipcp_bits_lattice bits_lattice; /* Lattice describing value range. */ @@ -534,19 +502,6 @@ ipcp_lattice::print (FILE * f, bool dump_sources, bool dump_benefits) fprintf (f, "\n"); } -/* Print alignment lattice to F. */ - -void -ipcp_alignment_lattice::print (FILE * f) -{ - if (top_p ()) - fprintf (f, " Alignment unknown (TOP)\n"); - else if (bottom_p ()) - fprintf (f, " Alignment unusable (BOTTOM)\n"); - else - fprintf (f, " Alignment %u, misalignment %u\n", align, misalign); -} - void ipcp_bits_lattice::print (FILE *f) { @@ -595,7 +550,6 @@ print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits) plats->itself.print (f, dump_sources, dump_benefits); fprintf (f, " ctxs: "); plats->ctxlat.print (f, dump_sources, dump_benefits); - plats->alignment.print (f); plats->bits_lattice.print (f); fprintf (f, " "); plats->m_value_range.print (f); @@ -922,38 +876,6 @@ set_agg_lats_contain_variable (struct ipcp_param_lattices *plats) return ret; } -/* Return true if alignment information in the lattice is yet unknown. */ - -bool -ipcp_alignment_lattice::top_p () const -{ - return !bottom && !not_top; -} - -/* Return true if alignment information in the lattice is known to be - unusable. */ - -bool -ipcp_alignment_lattice::bottom_p () const -{ - return bottom; -} - -/* Set alignment information in the lattice to bottom. Return true if it - previously was in a different state. */ - -bool -ipcp_alignment_lattice::set_to_bottom () -{ - if (bottom_p ()) - return false; - bottom = true; - return true; -} - -/* Meet the current value of the lattice with described by OTHER - lattice. */ - bool ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other) { @@ -1022,82 +944,6 @@ ipcp_vr_lattice::set_to_bottom () return true; } -/* Meet the current value of the lattice with alignment described by NEW_ALIGN - and NEW_MISALIGN, assuming that we know the current value is neither TOP nor - BOTTOM. Return true if the value of lattice has changed. */ - -bool -ipcp_alignment_lattice::meet_with_1 (unsigned new_align, unsigned new_misalign) -{ - gcc_checking_assert (new_align != 0); - if (align == new_align && misalign == new_misalign) - return false; - - bool changed = false; - if (align > new_align) - { - align = new_align; - misalign = misalign % new_align; - changed = true; - } - if (misalign != (new_misalign % align)) - { - int diff = abs ((int) misalign - (int) (new_misalign % align)); - align = least_bit_hwi (diff); - if (align) - misalign = misalign % align; - else - set_to_bottom (); - changed = true; - } - gcc_checking_assert (bottom_p () || align != 0); - return changed; -} - -/* Meet the current value of the lattice with alignment described by NEW_ALIGN - and NEW_MISALIGN. Return true if the value of lattice has changed. */ - -bool -ipcp_alignment_lattice::meet_with (unsigned new_align, unsigned new_misalign) -{ - gcc_assert (new_align != 0); - if (bottom_p ()) - return false; - if (top_p ()) - { - not_top = true; - align = new_align; - misalign = new_misalign; - return true; - } - return meet_with_1 (new_align, new_misalign); -} - -/* Meet the current value of the lattice with OTHER, taking into account that - OFFSET has been added to the pointer value. Return true if the value of - lattice has changed. */ - -bool -ipcp_alignment_lattice::meet_with (const ipcp_alignment_lattice &other, - HOST_WIDE_INT offset) -{ - if (other.bottom_p ()) - return set_to_bottom (); - if (bottom_p () || other.top_p ()) - return false; - - unsigned adjusted_misalign = (other.misalign + offset) % other.align; - if (top_p ()) - { - not_top = true; - align = other.align; - misalign = adjusted_misalign; - return true; - } - - return meet_with_1 (other.align, adjusted_misalign); -} - /* Set lattice value to bottom, if it already isn't the case. */ bool @@ -1253,7 +1099,6 @@ set_all_contains_variable (struct ipcp_param_lattices *plats) ret = plats->itself.set_contains_variable (); ret |= plats->ctxlat.set_contains_variable (); ret |= set_agg_lats_contain_variable (plats); - ret |= plats->alignment.set_to_bottom (); ret |= plats->bits_lattice.set_to_bottom (); ret |= plats->m_value_range.set_to_bottom (); return ret; @@ -1342,7 +1187,6 @@ initialize_node_lattices (struct cgraph_node *node) plats->itself.set_to_bottom (); plats->ctxlat.set_to_bottom (); set_agg_lats_to_bottom (plats); - plats->alignment.set_to_bottom (); plats->bits_lattice.set_to_bottom (); plats->m_value_range.set_to_bottom (); } @@ -1910,59 +1754,6 @@ propagate_context_accross_jump_function (cgraph_edge *cs, return ret; } -/* Propagate alignments across jump function JFUNC that is associated with - edge CS and update DEST_LAT accordingly. */ - -static bool -propagate_alignment_accross_jump_function (cgraph_edge *cs, - ipa_jump_func *jfunc, - ipcp_alignment_lattice *dest_lat) -{ - if (dest_lat->bottom_p ()) - return false; - - if (jfunc->type == IPA_JF_PASS_THROUGH - || jfunc->type == IPA_JF_ANCESTOR) - { - struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); - HOST_WIDE_INT offset = 0; - int src_idx; - - if (jfunc->type == IPA_JF_PASS_THROUGH) - { - enum tree_code op = ipa_get_jf_pass_through_operation (jfunc); - if (op != NOP_EXPR) - { - if (op != POINTER_PLUS_EXPR - && op != PLUS_EXPR) - return dest_lat->set_to_bottom (); - tree operand = ipa_get_jf_pass_through_operand (jfunc); - if (!tree_fits_shwi_p (operand)) - return dest_lat->set_to_bottom (); - offset = tree_to_shwi (operand); - } - src_idx = ipa_get_jf_pass_through_formal_id (jfunc); - } - else - { - src_idx = ipa_get_jf_ancestor_formal_id (jfunc); - offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT; - } - - struct ipcp_param_lattices *src_lats; - src_lats = ipa_get_parm_lattices (caller_info, src_idx); - return dest_lat->meet_with (src_lats->alignment, offset); - } - else - { - if (jfunc->alignment.known) - return dest_lat->meet_with (jfunc->alignment.align, - jfunc->alignment.misalign); - else - return dest_lat->set_to_bottom (); - } -} - /* Propagate bits across jfunc that is associated with edge cs and update dest_lattice accordingly. */ @@ -1993,16 +1784,29 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j unsigned precision = TYPE_PRECISION (parm_type); signop sgn = TYPE_SIGN (parm_type); - if (jfunc->type == IPA_JF_PASS_THROUGH) + if (jfunc->type == IPA_JF_PASS_THROUGH + || jfunc->type == IPA_JF_ANCESTOR) { struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); - enum tree_code code = ipa_get_jf_pass_through_operation (jfunc); tree operand = NULL_TREE; + enum tree_code code; + unsigned src_idx; - if (code != NOP_EXPR) - operand = ipa_get_jf_pass_through_operand (jfunc); + if (jfunc->type == IPA_JF_PASS_THROUGH) + { + code = ipa_get_jf_pass_through_operation (jfunc); + src_idx = ipa_get_jf_pass_through_formal_id (jfunc); + if (code != NOP_EXPR) + operand = ipa_get_jf_pass_through_operand (jfunc); + } + else + { + code = POINTER_PLUS_EXPR; + src_idx = ipa_get_jf_ancestor_formal_id (jfunc); + unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT; + operand = build_int_cstu (size_type_node, offset); + } - int src_idx = ipa_get_jf_pass_through_formal_id (jfunc); struct ipcp_param_lattices *src_lats = ipa_get_parm_lattices (caller_info, src_idx); @@ -2426,8 +2230,6 @@ propagate_constants_accross_call (struct cgraph_edge *cs) &dest_plats->itself); ret |= propagate_context_accross_jump_function (cs, jump_func, i, &dest_plats->ctxlat); - ret |= propagate_alignment_accross_jump_function (cs, jump_func, - &dest_plats->alignment); ret |= propagate_bits_accross_jump_function (cs, i, jump_func, &dest_plats->bits_lattice); ret |= propagate_aggs_accross_jump_function (cs, jump_func, @@ -4997,81 +4799,6 @@ ipcp_decision_stage (struct ipa_topo_info *topo) } } -/* Look up all alignment information that we have discovered and copy it over - to the transformation summary. */ - -static void -ipcp_store_alignment_results (void) -{ - cgraph_node *node; - - FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) - { - ipa_node_params *info = IPA_NODE_REF (node); - bool dumped_sth = false; - bool found_useful_result = false; - - if (!opt_for_fn (node->decl, flag_ipa_cp_alignment)) - { - if (dump_file) - fprintf (dump_file, "Not considering %s for alignment discovery " - "and propagate; -fipa-cp-alignment: disabled.\n", - node->name ()); - continue; - } - - if (info->ipcp_orig_node) - info = IPA_NODE_REF (info->ipcp_orig_node); - - unsigned count = ipa_get_param_count (info); - for (unsigned i = 0; i < count ; i++) - { - ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); - if (!plats->alignment.bottom_p () - && !plats->alignment.top_p ()) - { - gcc_checking_assert (plats->alignment.align > 0); - found_useful_result = true; - break; - } - } - if (!found_useful_result) - continue; - - ipcp_grow_transformations_if_necessary (); - ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); - vec_safe_reserve_exact (ts->alignments, count); - - for (unsigned i = 0; i < count ; i++) - { - ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i); - ipa_alignment al; - - if (!plats->alignment.bottom_p () - && !plats->alignment.top_p ()) - { - al.known = true; - al.align = plats->alignment.align; - al.misalign = plats->alignment.misalign; - } - else - al.known = false; - - ts->alignments->quick_push (al); - if (!dump_file || !al.known) - continue; - if (!dumped_sth) - { - fprintf (dump_file, "Propagated alignment info for function %s/%i:\n", - node->name (), node->order); - dumped_sth = true; - } - fprintf (dump_file, " param %i: align: %u, misalign: %u\n", - i, al.align, al.misalign); - } - } -} - /* Look up all the bits information that we have discovered and copy it over to the transformation summary. */ @@ -5246,8 +4973,6 @@ ipcp_driver (void) ipcp_propagate_stage (&topo); /* Decide what constant propagation and cloning should be performed. */ ipcp_decision_stage (&topo); - /* Store results of alignment propagation. */ - ipcp_store_alignment_results (); /* Store results of bits propagation. */ ipcp_store_bits_results (); /* Store results of value range propagation. */ diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index feecd23..5ed9bbf 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -294,15 +294,6 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs) ctx->dump (dump_file); } - if (jump_func->alignment.known) - { - fprintf (f, " Alignment: %u, misalignment: %u\n", - jump_func->alignment.align, - jump_func->alignment.misalign); - } - else - fprintf (f, " Unknown alignment\n"); - if (jump_func->bits.known) { fprintf (f, " value: "); print_hex (jump_func->bits.value, f); @@ -402,7 +393,6 @@ static void ipa_set_jf_unknown (struct ipa_jump_func *jfunc) { jfunc->type = IPA_JF_UNKNOWN; - jfunc->alignment.known = false; jfunc->bits.known = false; jfunc->vr_known = false; } @@ -1678,25 +1668,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, useful_context = true; } - if (POINTER_TYPE_P (TREE_TYPE(arg))) - { - unsigned HOST_WIDE_INT hwi_bitpos; - unsigned align; - - get_pointer_alignment_1 (arg, &align, &hwi_bitpos); - if (align > BITS_PER_UNIT - && align % BITS_PER_UNIT == 0 - && hwi_bitpos % BITS_PER_UNIT == 0) - { - jfunc->alignment.known = true; - jfunc->alignment.align = align / BITS_PER_UNIT; - jfunc->alignment.misalign = hwi_bitpos / BITS_PER_UNIT; - } - else - gcc_assert (!jfunc->alignment.known); - gcc_assert (!jfunc->vr_known); - } - else + if (!POINTER_TYPE_P (TREE_TYPE (arg))) { wide_int min, max; value_range_type type; @@ -1713,7 +1685,6 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, } else gcc_assert (!jfunc->vr_known); - gcc_assert (!jfunc->alignment.known); } if (INTEGRAL_TYPE_P (TREE_TYPE (arg)) @@ -1733,6 +1704,17 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, jfunc->bits.mask = 0; } } + else if (POINTER_TYPE_P (TREE_TYPE (arg))) + { + unsigned HOST_WIDE_INT bitpos; + unsigned align; + + jfunc->bits.known = true; + get_pointer_alignment_1 (arg, &align, &bitpos); + jfunc->bits.mask = wi::mask(TYPE_PRECISION (TREE_TYPE (arg)), false) + .and_not (align / BITS_PER_UNIT - 1); + jfunc->bits.value = bitpos / BITS_PER_UNIT; + } else gcc_assert (!jfunc->bits.known); @@ -3745,18 +3727,9 @@ ipa_node_params_t::duplicate(cgraph_node *src, cgraph_node *dst, { ipcp_grow_transformations_if_necessary (); src_trans = ipcp_get_transformation_summary (src); - const vec *src_alignments = src_trans->alignments; const vec *src_vr = src_trans->m_vr; - vec *&dst_alignments - = ipcp_get_transformation_summary (dst)->alignments; vec *&dst_vr = ipcp_get_transformation_summary (dst)->m_vr; - if (vec_safe_length (src_trans->alignments) > 0) - { - vec_safe_reserve_exact (dst_alignments, src_alignments->length ()); - for (unsigned i = 0; i < src_alignments->length (); ++i) - dst_alignments->quick_push ((*src_alignments)[i]); - } if (vec_safe_length (src_trans->m_vr) > 0) { vec_safe_reserve_exact (dst_vr, src_vr->length ()); @@ -4688,15 +4661,6 @@ ipa_write_jump_function (struct output_block *ob, } bp = bitpack_create (ob->main_stream); - bp_pack_value (&bp, jump_func->alignment.known, 1); - streamer_write_bitpack (&bp); - if (jump_func->alignment.known) - { - streamer_write_uhwi (ob, jump_func->alignment.align); - streamer_write_uhwi (ob, jump_func->alignment.misalign); - } - - bp = bitpack_create (ob->main_stream); bp_pack_value (&bp, jump_func->bits.known, 1); streamer_write_bitpack (&bp); if (jump_func->bits.known) @@ -4780,17 +4744,6 @@ ipa_read_jump_function (struct lto_input_block *ib, } struct bitpack_d bp = streamer_read_bitpack (ib); - bool alignment_known = bp_unpack_value (&bp, 1); - if (alignment_known) - { - jump_func->alignment.known = true; - jump_func->alignment.align = streamer_read_uhwi (ib); - jump_func->alignment.misalign = streamer_read_uhwi (ib); - } - else - jump_func->alignment.known = false; - - bp = streamer_read_bitpack (ib); bool bits_known = bp_unpack_value (&bp, 1); if (bits_known) { @@ -5156,30 +5109,6 @@ write_ipcp_transformation_info (output_block *ob, cgraph_node *node) } ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); - if (ts && vec_safe_length (ts->alignments) > 0) - { - count = ts->alignments->length (); - - streamer_write_uhwi (ob, count); - for (unsigned i = 0; i < count; ++i) - { - ipa_alignment *parm_al = &(*ts->alignments)[i]; - - struct bitpack_d bp; - bp = bitpack_create (ob->main_stream); - bp_pack_value (&bp, parm_al->known, 1); - streamer_write_bitpack (&bp); - if (parm_al->known) - { - streamer_write_uhwi (ob, parm_al->align); - streamer_write_hwi_in_range (ob->main_stream, 0, parm_al->align, - parm_al->misalign); - } - } - } - else - streamer_write_uhwi (ob, 0); - if (ts && vec_safe_length (ts->m_vr) > 0) { count = ts->m_vr->length (); @@ -5250,32 +5179,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node, aggvals = av; } ipa_set_node_agg_value_chain (node, aggvals); - - count = streamer_read_uhwi (ib); - if (count > 0) - { - ipcp_grow_transformations_if_necessary (); - - ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); - vec_safe_grow_cleared (ts->alignments, count); - - for (i = 0; i < count; i++) - { - ipa_alignment *parm_al; - parm_al = &(*ts->alignments)[i]; - struct bitpack_d bp; - bp = streamer_read_bitpack (ib); - parm_al->known = bp_unpack_value (&bp, 1); - if (parm_al->known) - { - parm_al->align = streamer_read_uhwi (ib); - parm_al->misalign - = streamer_read_hwi_in_range (ib, "ipa-prop misalign", - 0, parm_al->align); - } - } - } - + count = streamer_read_uhwi (ib); if (count > 0) { @@ -5569,58 +5473,6 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb) return NULL; } -/* Update alignment of formal parameters as described in - ipcp_transformation_summary. */ - -static void -ipcp_update_alignments (struct cgraph_node *node) -{ - tree fndecl = node->decl; - tree parm = DECL_ARGUMENTS (fndecl); - tree next_parm = parm; - ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node); - if (!ts || vec_safe_length (ts->alignments) == 0) - return; - const vec &alignments = *ts->alignments; - unsigned count = alignments.length (); - - for (unsigned i = 0; i < count; ++i, parm = next_parm) - { - if (node->clone.combined_args_to_skip - && bitmap_bit_p (node->clone.combined_args_to_skip, i)) - continue; - gcc_checking_assert (parm); - next_parm = DECL_CHAIN (parm); - - if (!alignments[i].known || !is_gimple_reg (parm)) - continue; - tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm); - if (!ddef) - continue; - - if (dump_file) - fprintf (dump_file, " Adjusting alignment of param %u to %u, " - "misalignment to %u\n", i, alignments[i].align, - alignments[i].misalign); - - struct ptr_info_def *pi = get_ptr_info (ddef); - gcc_checking_assert (pi); - unsigned old_align; - unsigned old_misalign; - bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign); - - if (old_known - && old_align >= alignments[i].align) - { - if (dump_file) - fprintf (dump_file, " But the alignment was already %u.\n", - old_align); - continue; - } - set_ptr_info_alignment (pi, alignments[i].align, alignments[i].misalign); - } -} - /* Update bits info of formal parameters as described in ipcp_transformation_summary. */ @@ -5647,7 +5499,7 @@ ipcp_update_bits (struct cgraph_node *node) next_parm = DECL_CHAIN (parm); if (!bits[i].known - || !INTEGRAL_TYPE_P (TREE_TYPE (parm)) + || !(INTEGRAL_TYPE_P (TREE_TYPE (parm)) || POINTER_TYPE_P (TREE_TYPE (parm))) || !is_gimple_reg (parm)) continue; @@ -5662,12 +5514,53 @@ ipcp_update_bits (struct cgraph_node *node) fprintf (dump_file, "\n"); } - unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef)); - signop sgn = TYPE_SIGN (TREE_TYPE (ddef)); + if (INTEGRAL_TYPE_P (TREE_TYPE (ddef))) + { + unsigned prec = TYPE_PRECISION (TREE_TYPE (ddef)); + signop sgn = TYPE_SIGN (TREE_TYPE (ddef)); + + wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED) + | wide_int::from (bits[i].value, prec, sgn); + set_nonzero_bits (ddef, nonzero_bits); + } + else + { + unsigned tem = bits[i].mask.to_uhwi (); + unsigned HOST_WIDE_INT bitpos = bits[i].value.to_uhwi (); + unsigned align = tem & -tem; + unsigned misalign = bitpos & (align - 1); - wide_int nonzero_bits = wide_int::from (bits[i].mask, prec, UNSIGNED) - | wide_int::from (bits[i].value, prec, sgn); - set_nonzero_bits (ddef, nonzero_bits); + if (align > 1) + { + if (dump_file) + fprintf (dump_file, "Adjusting align: %u, misalign: %u\n", align, misalign); + + unsigned old_align, old_misalign; + struct ptr_info_def *pi = get_ptr_info (ddef); + bool old_known = get_ptr_info_alignment (pi, &old_align, &old_misalign); + + if (old_known + && old_align > align) + { + if (dump_file) + { + fprintf (dump_file, "But alignment was already %u.\n", old_align); + if (old_misalign & (align - 1) != misalign) + fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n", + old_misalign, misalign); + } + continue; + } + + if (old_known + && (misalign & (old_align - 1) != old_misalign) + && dump_file) + fprintf (dump_file, "old_misalign (%u) and misalign (%u) mismatch\n", + old_misalign, misalign); + + set_ptr_info_alignment (pi, align, misalign); + } + } } } @@ -5742,7 +5635,6 @@ ipcp_transform_function (struct cgraph_node *node) fprintf (dump_file, "Modification phase of node %s/%i\n", node->name (), node->order); - ipcp_update_alignments (node); ipcp_update_bits (node); ipcp_update_vr (node); aggval = ipa_get_agg_replacements_for_node (node); @@ -5775,7 +5667,6 @@ ipcp_transform_function (struct cgraph_node *node) fbi.bb_infos.release (); free_dominance_info (CDI_DOMINATORS); (*ipcp_transformations)[node->uid].agg_values = NULL; - (*ipcp_transformations)[node->uid].alignments = NULL; descriptors.release (); if (!something_changed) diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index a123978..4eeae88 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -143,17 +143,6 @@ struct GTY(()) ipa_agg_jump_function typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p; -/* Info about pointer alignments. */ -struct GTY(()) ipa_alignment -{ - /* The data fields below are valid only if known is true. */ - bool known; - /* See ptr_info_def and get_pointer_alignment_1 for description of these - two. */ - unsigned align; - unsigned misalign; -}; - /* Information about zero/non-zero bits. */ struct GTY(()) ipa_bits { @@ -186,9 +175,6 @@ struct GTY (()) ipa_jump_func description. */ struct ipa_agg_jump_function agg; - /* Information about alignment of pointers. */ - struct ipa_alignment alignment; - /* Information about zero/non-zero bits. */ struct ipa_bits bits; @@ -531,8 +517,6 @@ struct GTY(()) ipcp_transformation_summary { /* Linked list of known aggregate values. */ ipa_agg_replacement_value *agg_values; - /* Alignment information for pointers. */ - vec *alignments; /* Known bits information. */ vec *bits; /* Value range information. */ diff --git a/gcc/opts.c b/gcc/opts.c index 45f1f89c..90e6186 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -504,7 +504,6 @@ static const struct default_options default_options_table[] = { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 }, - { OPT_LEVELS_2_PLUS, OPT_fipa_cp_alignment, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 }, @@ -1423,9 +1422,6 @@ enable_fdo_optimizations (struct gcc_options *opts, if (!opts_set->x_flag_ipa_cp_clone && value && opts->x_flag_ipa_cp) opts->x_flag_ipa_cp_clone = value; - if (!opts_set->x_flag_ipa_cp_alignment - && value && opts->x_flag_ipa_cp) - opts->x_flag_ipa_cp_alignment = value; if (!opts_set->x_flag_ipa_bit_cp && value && opts->x_flag_ipa_cp) opts->x_flag_ipa_bit_cp = value; diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-1.c b/gcc/testsuite/gcc.dg/ipa/propalign-1.c index f34552c..1491de8 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-1.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-1.c @@ -27,5 +27,5 @@ bar (void) } -/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */ +/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */ /* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-2.c b/gcc/testsuite/gcc.dg/ipa/propalign-2.c index 67b149a..51799c7 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-2.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-2.c @@ -53,5 +53,5 @@ bar2 (void) through (c.buf); } -/* { dg-final { scan-ipa-dump "Adjusting alignment of param" "cp" } } */ +/* { dg-final { scan-ipa-dump "Adjusting align" "cp" } } */ /* { dg-final { scan-tree-dump-not "fail_the_test" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-3.c b/gcc/testsuite/gcc.dg/ipa/propalign-3.c index d3bc2c4..4f5df4a 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-3.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-ipa-cp-alignment -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fno-ipa-bit-cp -fno-early-inlining -fdump-ipa-cp -fdump-tree-optimized" } */ /* { dg-skip-if "No alignment restrictions" { { ! natural_alignment_32 } && { ! natural_alignment_64 } } } */ #include @@ -53,5 +53,5 @@ bar2 (void) through (c.buf); } -/* { dg-final { scan-ipa-dump-not "Adjusting alignment of param" "cp" } } */ +/* { dg-final { scan-ipa-dump-not "align:" "cp" } } */ /* { dg-final { scan-tree-dump "fail_the_test" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-4.c b/gcc/testsuite/gcc.dg/ipa/propalign-4.c index b680813..bd32bf0 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-4.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-4.c @@ -20,4 +20,4 @@ main() test (&aa[3]); return 0; } -/* { dg-final { scan-ipa-dump "Alignment 8, misalignment 4" "cp" } } */ +/* { dg-final { scan-ipa-dump "align: 8, misalign: 4" "cp" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/propalign-5.c b/gcc/testsuite/gcc.dg/ipa/propalign-5.c index f2cf600..68e57da 100644 --- a/gcc/testsuite/gcc.dg/ipa/propalign-5.c +++ b/gcc/testsuite/gcc.dg/ipa/propalign-5.c @@ -20,4 +20,4 @@ main() test (&bb); return 0; } -/* { dg-final { scan-ipa-dump "Alignment 2" "cp" } } */ +/* { dg-final { scan-ipa-dump "align: 2" "cp" } } */ diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 77da489..fee530e 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1910,6 +1910,28 @@ propagate_context_accross_jump_function (cgraph_edge *cs, return ret; } +static void +verify_align_worse_p (ipcp_param_lattices *dest_plats) +{ + ipcp_alignment_lattice align_lattice = dest_plats->alignment; + ipcp_bits_lattice bits_lattice = dest_plats->bits_lattice; + + if (bits_lattice.top_p ()) + gcc_assert (align_lattice.top_p () || align_lattice.bottom_p ()); + + else if (bits_lattice.bottom_p ()) + gcc_assert (align_lattice.bottom_p ()); + + else if ((!align_lattice.bottom_p () && !align_lattice.top_p ()) + && bits_lattice.constant_p ()) + { + bool align = align_lattice.align; + unsigned tem = bits_lattice.get_mask ().to_uhwi (); + unsigned bits_align = tem & -tem; + gcc_assert (align <= bits_align); + } +} + /* Propagate alignments across jump function JFUNC that is associated with edge CS and update DEST_LAT accordingly. */ @@ -2451,6 +2473,9 @@ propagate_constants_accross_call (struct cgraph_edge *cs) jump_func, dest_plats); else ret |= dest_plats->m_value_range.set_to_bottom (); + + if (flag_ipa_cp_alignment && flag_ipa_bit_cp) + verify_align_worse_p (dest_plats); } } for (; i < parms_count; i++)