From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com [IPv6:2a00:1450:4864:20::12b]) by sourceware.org (Postfix) with ESMTPS id C72553858420 for ; Wed, 3 Nov 2021 16:37:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C72553858420 Received: by mail-lf1-x12b.google.com with SMTP id x27so6362137lfu.5 for ; Wed, 03 Nov 2021 09:37:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=CYDuVWmB/caFq/qk+vhULNspJHban4gN+zwbIjJyM+k=; b=zOpxZGo8/iIQMR+XUr2/PEVY1J7tZRwYpW2EK0szfjEjhSd+i2IfwfV76IA3kUPBK0 E3p35NN8oqtBVmjl4gsBMTqcTtm57BhzVs/g3TOWoohu7fq/CABGKJAJ/Deah+rv10Bl neHccY8Ub3krxhGgK0biFcFxFHFROy5BmMRvPwGlIKGJcWjrTpJFT2jDgNcEb4ARu1xq eFY9n39MW66dVr6qeV8j68RtTapoTBj7US7sp8b5hqQ2aws1Y3FhEKuWfqmTdg6Kuzzg hk6CFqHmcO0Gz8+LVo8lzRiNOv2kKfmmcTrOA8l+Ku9reKPkHVnpNLwfX141DEQ7WGNE cRBA== X-Gm-Message-State: AOAM531bT5VlNDMnhOX0fxm2iwN/02p7Nm1Hv76ktajW40AHqPcu7Blp 7OC69h3btz2t6358EccNCMF2 X-Google-Smtp-Source: ABdhPJyrQvf1OIhBeci7bm/AaaEYTEe+lQ3Bm3bC2eLwGKtfda0scdzvL0LbR817qmAuBGQvHi5YBw== X-Received: by 2002:a05:6512:1082:: with SMTP id j2mr39191520lfg.568.1635957444879; Wed, 03 Nov 2021 09:37:24 -0700 (PDT) Received: from [192.168.0.231] ([185.30.228.145]) by smtp.gmail.com with ESMTPSA id d9sm135338ljc.55.2021.11.03.09.37.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Nov 2021 09:37:24 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.7\)) Subject: Re: [TCWG CI] Regression caused by gcc: handle retslot in modref From: Maxim Kuvyrkov In-Reply-To: <20211103151227.GA60321@kam.mff.cuni.cz> Date: Wed, 3 Nov 2021 19:37:23 +0300 Cc: gcc-regression@gcc.gnu.org Content-Transfer-Encoding: quoted-printable Message-Id: References: <2061970783.3427.1635561177235@jenkins.jenkins> <8B785EB0-B433-43FF-AE1C-442EEF25540A@linaro.org> <20211103151227.GA60321@kam.mff.cuni.cz> To: Jan Hubicka X-Mailer: Apple Mail (2.3608.120.23.2.7) X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-regression@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-regression mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Nov 2021 16:37:31 -0000 Hi Jan, Indeed, this seems to be fixed. Yesterday=E2=80=99s build scored = =E2=80=9C1=E2=80=9D (built binutils only), but build I triggered just = now scored =E2=80=9C2=E2=80=9D (built binutils and bootstrap_lto) [*] . Thanks! [*] = https://ci.linaro.org/job/tcwg_gcc_bootstrap-build-master-aarch64-bootstra= p_lto/ -- Maxim Kuvyrkov https://www.linaro.org > On 3 Nov 2021, at 18:12, Jan Hubicka wrote: >=20 >> Hi Jan, >>=20 >> Just wanted to make sure this is on your radar. >>=20 >> Your "handle retslot in modref=E2=80=9D patch broken LTO bootstrap on = aarch64 in all configurations that we test: >>=20 >> - tcwg_gcc_bootstrap/master-aarch64-bootstrap_lto >> - tcwg_gcc_bootstrap/master-aarch64-bootstrap_profiled_lto >> - tcwg_gcc_bootstrap/master-aarch64-bootstrap_profiled_lto_lean > Maxim, > I am trying lto build on other machine and lets see. I wonder - I = have > fixed a wrong code bug related to that patch today (causing > misopitmization of omnetpp). Is there any chance that this bug got > fixed? >=20 > Honza >>=20 >> Regards, >>=20 >> -- >> Maxim Kuvyrkov >> https://www.linaro.org >>=20 >>> On 30 Oct 2021, at 05:32, ci_notify@linaro.org wrote: >>>=20 >>> [TCWG CI] Regression caused by gcc: handle retslot in modref: >>> commit b8ef019ab938471f7f877a1eee3a6374fd8a6ae9 >>> Author: Jan Hubicka >>>=20 >>> handle retslot in modref >>>=20 >>> Results regressed to >>> # reset_artifacts: >>> -10 >>> # true: >>> 0 >>> # build_abe binutils: >>> 1 >>> # First few build errors in logs: >>> # 00:04:02 make[3]: [Makefile:1772: = aarch64-unknown-linux-gnu/bits/largefile-config.h] Error 1 (ignored) >>> # 00:04:02 make[3]: [Makefile:1773: = aarch64-unknown-linux-gnu/bits/largefile-config.h] Error 1 (ignored) >>> # 00:19:19 checking for suffix of object files... configure: error: = in = `/home/tcwg-buildslave/workspace/tcwg_gnu_13/abe/builds/aarch64-unknown-li= nux-gnu/aarch64-unknown-linux-gnu/gcc-gcc.git~master-stage2/aarch64-unknow= n-linux-gnu/libgcc': >>> # 00:19:19 configure: error: cannot compute suffix of object files: = cannot compile >>> # 00:19:19 make[2]: *** [Makefile:19796: = configure-stage2-target-libgcc] Error 1 >>> # 00:19:19 make[1]: *** [Makefile:25351: stage2-bubble] Error 2 >>> # 00:19:19 make: *** [Makefile:1019: all] Error 2 >>>=20 >>> from >>> # reset_artifacts: >>> -10 >>> # true: >>> 0 >>> # build_abe binutils: >>> 1 >>> # build_abe bootstrap_lto: >>> 2 >>>=20 >>> THIS IS THE END OF INTERESTING STUFF. BELOW ARE LINKS TO BUILDS, = REPRODUCTION INSTRUCTIONS, AND THE RAW COMMIT. >>>=20 >>> This commit has regressed these CI configurations: >>> - tcwg_gcc_bootstrap/master-aarch64-bootstrap_lto >>>=20 >>> First_bad build: = https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-aarch64-bootstr= ap_lto/3/artifact/artifacts/build-b8ef019ab938471f7f877a1eee3a6374fd8a6ae9= / >>> Last_good build: = https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-aarch64-bootstr= ap_lto/3/artifact/artifacts/build-4045d5fa42f2ee7b284977c8f2f0edc300a63e43= / >>> Baseline build: = https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-aarch64-bootstr= ap_lto/3/artifact/artifacts/build-baseline/ >>> Even more details: = https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-aarch64-bootstr= ap_lto/3/artifact/artifacts/ >>>=20 >>> Reproduce builds: >>> >>> mkdir investigate-gcc-b8ef019ab938471f7f877a1eee3a6374fd8a6ae9 >>> cd investigate-gcc-b8ef019ab938471f7f877a1eee3a6374fd8a6ae9 >>>=20 >>> # Fetch scripts >>> git clone https://git.linaro.org/toolchain/jenkins-scripts >>>=20 >>> # Fetch manifests and test.sh script >>> mkdir -p artifacts/manifests >>> curl -o artifacts/manifests/build-baseline.sh = https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-aarch64-bootstr= ap_lto/3/artifact/artifacts/manifests/build-baseline.sh --fail >>> curl -o artifacts/manifests/build-parameters.sh = https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-aarch64-bootstr= ap_lto/3/artifact/artifacts/manifests/build-parameters.sh --fail >>> curl -o artifacts/test.sh = https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-aarch64-bootstr= ap_lto/3/artifact/artifacts/test.sh --fail >>> chmod +x artifacts/test.sh >>>=20 >>> # Reproduce the baseline build (build all pre-requisites) >>> ./jenkins-scripts/tcwg_gnu-build.sh @@ = artifacts/manifests/build-baseline.sh >>>=20 >>> # Save baseline build state (which is then restored in = artifacts/test.sh) >>> mkdir -p ./bisect >>> rsync -a --del --delete-excluded --exclude /bisect/ --exclude = /artifacts/ --exclude /gcc/ ./ ./bisect/baseline/ >>>=20 >>> cd gcc >>>=20 >>> # Reproduce first_bad build >>> git checkout --detach b8ef019ab938471f7f877a1eee3a6374fd8a6ae9 >>> ../artifacts/test.sh >>>=20 >>> # Reproduce last_good build >>> git checkout --detach 4045d5fa42f2ee7b284977c8f2f0edc300a63e43 >>> ../artifacts/test.sh >>>=20 >>> cd .. >>> >>>=20 >>> Full commit (up to 1000 lines): >>> >>> commit b8ef019ab938471f7f877a1eee3a6374fd8a6ae9 >>> Author: Jan Hubicka >>> Date: Fri Oct 29 16:01:51 2021 +0200 >>>=20 >>> handle retslot in modref >>>=20 >>> Extend modref and tree-ssa-structalias to handle retslot flags. >>> Since retslot it essentially a hidden argument that is known to be = write-only >>> we can do pretty much the same stuff as we do for regular = parameters. >>> I plan to add static chain handling similar way. >>>=20 >>> We do not handle IPA propagation of retslot flags (where return = slot is >>> initialized via return slot of other function). For this ipa-prop = needs >>> to be extended to understand retslot as well. >>>=20 >>> Bootstrapped/regtested x86_64-linux, OK for the gimple bits? >>>=20 >>> Honza >>>=20 >>> gcc/ChangeLog: >>>=20 >>> * gimple.c (gimple_call_retslot_flags): New function. >>> * gimple.h (gimple_call_retslot_flags): Declare. >>> * ipa-modref.c: Include tree-cfg.h. >>> (struct escape_entry): Turn parm_index to signed. >>> (modref_summary_lto::modref_summary_lto): Add = retslot_flags. >>> (modref_summary::modref_summary): Initialize = retslot_flags. >>> (struct modref_summary_lto): Likewise. >>> (modref_summary::useful_p): Check retslot_flags. >>> (modref_summary_lto::useful_p): Likewise. >>> (modref_summary::dump): Dump retslot_flags. >>> (modref_summary_lto::dump): Likewise. >>> (struct escape_point): Add hidden_args enum. >>> (analyze_ssa_name_flags): Ignore return slot return; >>> use gimple_call_retslot_flags. >>> (record_escape_points): Break out from ... >>> (analyze_parms): ... here; handle retslot_flags. >>> (modref_summaries::duplicate): Duplicate retslot_flags. >>> (modref_summaries_lto::duplicate): Likewise. >>> (modref_write_escape_summary): Stream parm_index as = signed. >>> (modref_read_escape_summary): Likewise. >>> (modref_write): Stream retslot_flags. >>> (read_section): Likewise. >>> (struct escape_map): Fix typo in comment. >>> (update_escape_summary_1): Fix whitespace. >>> (ipa_merge_modref_summary_after_inlining): Drop = retslot_flags. >>> (modref_merge_call_site_flags): Merge retslot_flags. >>> * ipa-modref.h (struct modref_summary): Add retslot_flags. >>> * tree-ssa-structalias.c (handle_rhs_call): Handle = retslot_flags. >>> --- >>> gcc/gimple.c | 41 ++++++++++++- >>> gcc/gimple.h | 1 + >>> gcc/ipa-modref.c | 145 = +++++++++++++++++++++++++++++++++------------ >>> gcc/ipa-modref.h | 1 + >>> gcc/tree-ssa-structalias.c | 29 ++++++--- >>> 5 files changed, 170 insertions(+), 47 deletions(-) >>>=20 >>> diff --git a/gcc/gimple.c b/gcc/gimple.c >>> index cc7a88e822b..22dd6417d19 100644 >>> --- a/gcc/gimple.c >>> +++ b/gcc/gimple.c >>> @@ -1597,7 +1597,12 @@ gimple_call_arg_flags (const gcall *stmt, = unsigned arg) >>> if (!node->binds_to_current_def_p ()) >>> { >>> if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED)) >>> - modref_flags &=3D ~EAF_UNUSED; >>> + { >>> + modref_flags &=3D ~EAF_UNUSED; >>> + modref_flags |=3D EAF_NOESCAPE; >>> + } >>> + if ((modref_flags & EAF_NOREAD) && !(flags & EAF_NOREAD)) >>> + modref_flags &=3D ~EAF_NOREAD; >>> if ((modref_flags & EAF_DIRECT) && !(flags & EAF_DIRECT)) >>> modref_flags &=3D ~EAF_DIRECT; >>> } >>> @@ -1608,6 +1613,40 @@ gimple_call_arg_flags (const gcall *stmt, = unsigned arg) >>> return flags; >>> } >>>=20 >>> +/* Detects argument flags for return slot on call STMT. */ >>> + >>> +int >>> +gimple_call_retslot_flags (const gcall *stmt) >>> +{ >>> + int flags =3D EAF_DIRECT | EAF_NOREAD; >>> + >>> + tree callee =3D gimple_call_fndecl (stmt); >>> + if (callee) >>> + { >>> + cgraph_node *node =3D cgraph_node::get (callee); >>> + modref_summary *summary =3D node ? = get_modref_function_summary (node) >>> + : NULL; >>> + >>> + if (summary) >>> + { >>> + int modref_flags =3D summary->retslot_flags; >>> + >>> + /* We have possibly optimized out load. Be conservative here. = */ >>> + if (!node->binds_to_current_def_p ()) >>> + { >>> + if ((modref_flags & EAF_UNUSED) && !(flags & EAF_UNUSED)) >>> + { >>> + modref_flags &=3D ~EAF_UNUSED; >>> + modref_flags |=3D EAF_NOESCAPE; >>> + } >>> + } >>> + if (dbg_cnt (ipa_mod_ref_pta)) >>> + flags |=3D modref_flags; >>> + } >>> + } >>> + return flags; >>> +} >>> + >>> /* Detects return flags for the call STMT. */ >>>=20 >>> int >>> diff --git a/gcc/gimple.h b/gcc/gimple.h >>> index 303623b3ced..23a124ec769 100644 >>> --- a/gcc/gimple.h >>> +++ b/gcc/gimple.h >>> @@ -1589,6 +1589,7 @@ gimple_seq gimple_seq_copy (gimple_seq); >>> bool gimple_call_same_target_p (const gimple *, const gimple *); >>> int gimple_call_flags (const gimple *); >>> int gimple_call_arg_flags (const gcall *, unsigned); >>> +int gimple_call_retslot_flags (const gcall *); >>> int gimple_call_return_flags (const gcall *); >>> bool gimple_call_nonnull_result_p (gcall *); >>> tree gimple_call_nonnull_arg (gcall *); >>> diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c >>> index 0bbec8df0a2..3539cb43d11 100644 >>> --- a/gcc/ipa-modref.c >>> +++ b/gcc/ipa-modref.c >>> @@ -86,6 +86,7 @@ along with GCC; see the file COPYING3. If not see >>> #include "stringpool.h" >>> #include "tree-ssanames.h" >>> #include "attribs.h" >>> +#include "tree-cfg.h" >>>=20 >>>=20 >>> namespace { >>> @@ -133,7 +134,7 @@ static fnspec_summaries_t *fnspec_summaries =3D = NULL; >>> struct escape_entry >>> { >>> /* Parameter that escapes at a given call. */ >>> - unsigned int parm_index; >>> + int parm_index; >>> /* Argument it escapes to. */ >>> unsigned int arg; >>> /* Minimal flags known about the argument. */ >>> @@ -269,7 +270,7 @@ static GTY(()) fast_function_summary = >>> /* Summary for a single function which this pass produces. */ >>>=20 >>> modref_summary::modref_summary () >>> - : loads (NULL), stores (NULL), writes_errno (NULL) >>> + : loads (NULL), stores (NULL), retslot_flags (0), writes_errno = (false) >>> { >>> } >>>=20 >>> @@ -322,6 +323,8 @@ modref_summary::useful_p (int ecf_flags, bool = check_flags) >>> if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags)) >>> return true; >>> arg_flags.release (); >>> + if (check_flags && remove_useless_eaf_flags (retslot_flags, = ecf_flags, false)) >>> + return true; >>> if (ecf_flags & ECF_CONST) >>> return false; >>> if (loads && !loads->every_base) >>> @@ -363,6 +366,7 @@ struct GTY(()) modref_summary_lto >>> modref_records_lto *loads; >>> modref_records_lto *stores; >>> auto_vec GTY((skip)) arg_flags; >>> + eaf_flags_t retslot_flags; >>> bool writes_errno; >>>=20 >>> modref_summary_lto (); >>> @@ -374,7 +378,7 @@ struct GTY(()) modref_summary_lto >>> /* Summary for a single function which this pass produces. */ >>>=20 >>> modref_summary_lto::modref_summary_lto () >>> - : loads (NULL), stores (NULL), writes_errno (NULL) >>> + : loads (NULL), stores (NULL), retslot_flags (0), writes_errno = (false) >>> { >>> } >>>=20 >>> @@ -400,6 +404,8 @@ modref_summary_lto::useful_p (int ecf_flags, = bool check_flags) >>> if (check_flags && eaf_flags_useful_p (arg_flags, ecf_flags)) >>> return true; >>> arg_flags.release (); >>> + if (check_flags && remove_useless_eaf_flags (retslot_flags, = ecf_flags, false)) >>> + return true; >>> if (ecf_flags & ECF_CONST) >>> return false; >>> if (loads && !loads->every_base) >>> @@ -608,6 +614,11 @@ modref_summary::dump (FILE *out) >>> dump_eaf_flags (out, arg_flags[i]); >>> } >>> } >>> + if (retslot_flags) >>> + { >>> + fprintf (out, " Retslot flags:"); >>> + dump_eaf_flags (out, retslot_flags); >>> + } >>> } >>>=20 >>> /* Dump summary. */ >>> @@ -630,6 +641,11 @@ modref_summary_lto::dump (FILE *out) >>> dump_eaf_flags (out, arg_flags[i]); >>> } >>> } >>> + if (retslot_flags) >>> + { >>> + fprintf (out, " Retslot flags:"); >>> + dump_eaf_flags (out, retslot_flags); >>> + } >>> } >>>=20 >>> /* Get function summary for FUNC if it exists, return NULL = otherwise. */ >>> @@ -1396,6 +1412,11 @@ namespace { >>>=20 >>> struct escape_point >>> { >>> + /* Extra hidden args we keep track of. */ >>> + enum hidden_args >>> + { >>> + retslot_arg =3D -1 >>> + }; >>> /* Value escapes to this call. */ >>> gcall *call; >>> /* Argument it escapes to. */ >>> @@ -1705,7 +1726,11 @@ analyze_ssa_name_flags (tree name, = vec &lattice, int depth, >>> Returning name counts as an use by tree-ssa-structalias.c */ >>> if (greturn *ret =3D dyn_cast (use_stmt)) >>> { >>> - if (gimple_return_retval (ret) =3D=3D name) >>> + /* Returning through return slot is seen as memory write = earlier. */ >>> + if (DECL_RESULT (current_function_decl) >>> + && DECL_BY_REFERENCE (DECL_RESULT = (current_function_decl))) >>> + ; >>> + else if (gimple_return_retval (ret) =3D=3D name) >>> lattice[index].merge (~(EAF_UNUSED | EAF_NOT_RETURNED)); >>> else if (memory_access_to (gimple_return_retval (ret), name)) >>> { >>> @@ -1748,7 +1773,7 @@ analyze_ssa_name_flags (tree name, = vec &lattice, int depth, >>> may make LHS to escape. See PR 98499. */ >>> if (gimple_call_return_slot_opt_p (call) >>> && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs = (call)))) >>> - lattice[index].merge (EAF_NOREAD | EAF_DIRECT); >>> + lattice[index].merge (gimple_call_retslot_flags = (call)); >>> } >>>=20 >>> /* We do not track accesses to the static chain (we could) >>> @@ -1777,7 +1802,7 @@ analyze_ssa_name_flags (tree name, = vec &lattice, int depth, >>> lattice[index].merge (call_flags); >>> else >>> lattice[index].add_escape_point (call, i, >>> - call_flags, = true); >>> + call_flags, = true); >>> } >>> if (!ignore_retval) >>> merge_call_lhs_flags (call, i, index, false, >>> @@ -1912,6 +1937,29 @@ analyze_ssa_name_flags (tree name, = vec &lattice, int depth, >>> lattice[index].known =3D true; >>> } >>>=20 >>> +/* Record escape points of PARM_INDEX according to LATTICE. */ >>> + >>> +static void >>> +record_escape_points (modref_lattice &lattice, int parm_index, int = flags) >>> +{ >>> + if (lattice.escape_points.length ()) >>> + { >>> + escape_point *ep; >>> + unsigned int ip; >>> + cgraph_node *node =3D cgraph_node::get = (current_function_decl); >>> + >>> + FOR_EACH_VEC_ELT (lattice.escape_points, ip, ep) >>> + if ((ep->min_flags & flags) !=3D flags) >>> + { >>> + cgraph_edge *e =3D node->get_edge (ep->call); >>> + struct escape_entry ee =3D {parm_index, ep->arg, >>> + ep->min_flags, ep->direct}; >>> + >>> + escape_summaries->get_create (e)->esc.safe_push (ee); >>> + } >>> + } >>> +} >>> + >>> /* Determine EAF flags for function parameters. */ >>>=20 >>> static void >>> @@ -1921,16 +1969,22 @@ analyze_parms (modref_summary *summary, = modref_summary_lto *summary_lto, >>> unsigned int parm_index =3D 0; >>> unsigned int count =3D 0; >>> int ecf_flags =3D flags_from_decl_or_type (current_function_decl); >>> + tree retslot =3D NULL; >>>=20 >>> /* For novops functions we have nothing to gain by EAF flags. */ >>> if (ecf_flags & ECF_NOVOPS) >>> return; >>>=20 >>> + /* If there is return slot, look up its SSA name. */ >>> + if (DECL_RESULT (current_function_decl) >>> + && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) >>> + retslot =3D ssa_default_def (cfun, DECL_RESULT = (current_function_decl)); >>> + >>> for (tree parm =3D DECL_ARGUMENTS (current_function_decl); parm; >>> parm =3D TREE_CHAIN (parm)) >>> count++; >>>=20 >>> - if (!count) >>> + if (!count && !retslot) >>> return; >>>=20 >>> auto_vec lattice; >>> @@ -1984,24 +2038,24 @@ analyze_parms (modref_summary *summary, = modref_summary_lto *summary_lto, >>> summary_lto->arg_flags.safe_grow_cleared (count, true); >>> summary_lto->arg_flags[parm_index] =3D flags; >>> } >>> - if (lattice[SSA_NAME_VERSION (name)].escape_points.length ()) >>> - { >>> - escape_point *ep; >>> - unsigned int ip; >>> - cgraph_node *node =3D cgraph_node::get = (current_function_decl); >>> - >>> - gcc_checking_assert (ipa); >>> - FOR_EACH_VEC_ELT >>> - (lattice[SSA_NAME_VERSION (name)].escape_points, ip, = ep) >>> - if ((ep->min_flags & flags) !=3D flags) >>> - { >>> - cgraph_edge *e =3D node->get_edge (ep->call); >>> - struct escape_entry ee =3D {parm_index, ep->arg, >>> - ep->min_flags, = ep->direct}; >>> + record_escape_points (lattice[SSA_NAME_VERSION (name)], >>> + parm_index, flags); >>> + } >>> + } >>> + if (retslot) >>> + { >>> + analyze_ssa_name_flags (retslot, lattice, 0, ipa); >>> + int flags =3D lattice[SSA_NAME_VERSION (retslot)].flags; >>>=20 >>> - escape_summaries->get_create (e)->esc.safe_push = (ee); >>> - } >>> - } >>> + flags =3D remove_useless_eaf_flags (flags, ecf_flags, false); >>> + if (flags) >>> + { >>> + if (summary) >>> + summary->retslot_flags =3D flags; >>> + if (summary_lto) >>> + summary_lto->retslot_flags =3D flags; >>> + record_escape_points (lattice[SSA_NAME_VERSION (retslot)], >>> + escape_point::retslot_arg, flags); >>> } >>> } >>> if (ipa) >>> @@ -2287,6 +2341,7 @@ modref_summaries::duplicate (cgraph_node *, = cgraph_node *dst, >>> dst_data->writes_errno =3D src_data->writes_errno; >>> if (src_data->arg_flags.length ()) >>> dst_data->arg_flags =3D src_data->arg_flags.copy (); >>> + dst_data->retslot_flags =3D src_data->retslot_flags; >>> } >>>=20 >>> /* Called when new clone is inserted to callgraph late. */ >>> @@ -2312,6 +2367,7 @@ modref_summaries_lto::duplicate (cgraph_node = *, cgraph_node *, >>> dst_data->writes_errno =3D src_data->writes_errno; >>> if (src_data->arg_flags.length ()) >>> dst_data->arg_flags =3D src_data->arg_flags.copy (); >>> + dst_data->retslot_flags =3D src_data->retslot_flags; >>> } >>>=20 >>> namespace >>> @@ -2551,7 +2607,7 @@ modref_write_escape_summary (struct bitpack_d = *bp, escape_summary *esum) >>> escape_entry *ee; >>> FOR_EACH_VEC_ELT (esum->esc, i, ee) >>> { >>> - bp_pack_var_len_unsigned (bp, ee->parm_index); >>> + bp_pack_var_len_int (bp, ee->parm_index); >>> bp_pack_var_len_unsigned (bp, ee->arg); >>> bp_pack_var_len_unsigned (bp, ee->min_flags); >>> bp_pack_value (bp, ee->direct, 1); >>> @@ -2571,7 +2627,7 @@ modref_read_escape_summary (struct bitpack_d = *bp, cgraph_edge *e) >>> for (unsigned int i =3D 0; i < n; i++) >>> { >>> escape_entry ee; >>> - ee.parm_index =3D bp_unpack_var_len_unsigned (bp); >>> + ee.parm_index =3D bp_unpack_var_len_int (bp); >>> ee.arg =3D bp_unpack_var_len_unsigned (bp); >>> ee.min_flags =3D bp_unpack_var_len_unsigned (bp); >>> ee.direct =3D bp_unpack_value (bp, 1); >>> @@ -2628,6 +2684,7 @@ modref_write () >>> streamer_write_uhwi (ob, r->arg_flags.length ()); >>> for (unsigned int i =3D 0; i < r->arg_flags.length (); i++) >>> streamer_write_uhwi (ob, r->arg_flags[i]); >>> + streamer_write_uhwi (ob, r->retslot_flags); >>>=20 >>> write_modref_records (r->loads, ob); >>> write_modref_records (r->stores, ob); >>> @@ -2724,6 +2781,11 @@ read_section (struct lto_file_decl_data = *file_data, const char *data, >>> if (modref_sum_lto) >>> modref_sum_lto->arg_flags.quick_push (flags); >>> } >>> + eaf_flags_t flags =3D streamer_read_uhwi (&ib); >>> + if (modref_sum) >>> + modref_sum->retslot_flags =3D flags; >>> + if (modref_sum_lto) >>> + modref_sum_lto->retslot_flags =3D flags; >>> read_modref_records (&ib, data_in, >>> modref_sum ? &modref_sum->loads : NULL, >>> modref_sum_lto ? &modref_sum_lto->loads : = NULL); >>> @@ -3098,7 +3160,7 @@ struct escape_map >>> bool direct; >>> }; >>>=20 >>> -/* Update escape map fo E. */ >>> +/* Update escape map for E. */ >>>=20 >>> static void >>> update_escape_summary_1 (cgraph_edge *e, >>> @@ -3117,7 +3179,10 @@ update_escape_summary_1 (cgraph_edge *e, >>> { >>> unsigned int j; >>> struct escape_map *em; >>> - if (ee->parm_index >=3D map.length ()) >>> + /* TODO: We do not have jump functions for return slots, so = we >>> + never propagate them to outer function. */ >>> + if (ee->parm_index >=3D (int)map.length () >>> + || ee->parm_index < 0) >>> continue; >>> FOR_EACH_VEC_ELT (map[ee->parm_index], j, em) >>> { >>> @@ -3125,7 +3190,7 @@ update_escape_summary_1 (cgraph_edge *e, >>> if (ee->direct && !em->direct) >>> min_flags =3D deref_flags (min_flags, ignore_stores); >>> struct escape_entry entry =3D {em->parm_index, ee->arg, >>> - ee->min_flags, >>> + ee->min_flags, >>> ee->direct & em->direct}; >>> sum->esc.safe_push (entry); >>> } >>> @@ -3245,7 +3310,11 @@ ipa_merge_modref_summary_after_inlining = (cgraph_edge *edge) >>> FOR_EACH_VEC_ELT (sum->esc, i, ee) >>> { >>> bool needed =3D false; >>> - if (to_info && to_info->arg_flags.length () > ee->parm_index) >>> + /* TODO: We do not have jump functions for return slots, so we >>> + never propagate them to outer function. */ >>> + if (ee->parm_index < 0) >>> + continue; >>> + if (to_info && (int)to_info->arg_flags.length () > = ee->parm_index) >>> { >>> int flags =3D callee_info >>> && callee_info->arg_flags.length () > ee->arg >>> @@ -3259,7 +3328,7 @@ ipa_merge_modref_summary_after_inlining = (cgraph_edge *edge) >>> if (to_info->arg_flags[ee->parm_index]) >>> needed =3D true; >>> } >>> - if (to_info_lto && to_info_lto->arg_flags.length () > = ee->parm_index) >>> + if (to_info_lto && (int)to_info_lto->arg_flags.length () > = ee->parm_index) >>> { >>> int flags =3D callee_info_lto >>> && callee_info_lto->arg_flags.length () > = ee->arg >>> @@ -3798,29 +3867,31 @@ modref_merge_call_site_flags (escape_summary = *sum, >>> if (flags_lto & EAF_NOESCAPE) >>> flags_lto |=3D EAF_NODIRECTESCAPE; >>> if (!(flags & EAF_UNUSED) >>> - && cur_summary && ee->parm_index < = cur_summary->arg_flags.length ()) >>> + && cur_summary && ee->parm_index < = (int)cur_summary->arg_flags.length ()) >>> { >>> - int f =3D cur_summary->arg_flags[ee->parm_index]; >>> + eaf_flags_t &f =3D ee->parm_index =3D=3D = escape_point::retslot_arg >>> + ? cur_summary->retslot_flags >>> + : cur_summary->arg_flags[ee->parm_index]; >>> if ((f & flags) !=3D f) >>> { >>> f =3D remove_useless_eaf_flags >>> (f & flags, ecf_flags, >>> VOID_TYPE_P (TREE_TYPE (TREE_TYPE (caller)))); >>> - cur_summary->arg_flags[ee->parm_index] =3D f; >>> changed =3D true; >>> } >>> } >>> if (!(flags_lto & EAF_UNUSED) >>> && cur_summary_lto >>> - && ee->parm_index < cur_summary_lto->arg_flags.length ()) >>> + && ee->parm_index < (int)cur_summary_lto->arg_flags.length ()) >>> { >>> - int f =3D cur_summary_lto->arg_flags[ee->parm_index]; >>> + eaf_flags_t &f =3D ee->parm_index =3D=3D = escape_point::retslot_arg >>> + ? cur_summary_lto->retslot_flags >>> + : cur_summary_lto->arg_flags[ee->parm_index]; >>> if ((f & flags_lto) !=3D f) >>> { >>> f =3D remove_useless_eaf_flags >>> (f & flags_lto, ecf_flags, >>> VOID_TYPE_P (TREE_TYPE (TREE_TYPE (caller)))); >>> - cur_summary_lto->arg_flags[ee->parm_index] =3D f; >>> changed =3D true; >>> } >>> } >>> diff --git a/gcc/ipa-modref.h b/gcc/ipa-modref.h >>> index 5afa3aa439f..a4db27471eb 100644 >>> --- a/gcc/ipa-modref.h >>> +++ b/gcc/ipa-modref.h >>> @@ -31,6 +31,7 @@ struct GTY(()) modref_summary >>> modref_records *loads; >>> modref_records *stores; >>> auto_vec GTY((skip)) arg_flags; >>> + eaf_flags_t retslot_flags; >>> bool writes_errno; >>>=20 >>> modref_summary (); >>> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c >>> index 35971a54e02..99072df0768 100644 >>> --- a/gcc/tree-ssa-structalias.c >>> +++ b/gcc/tree-ssa-structalias.c >>> @@ -4254,17 +4254,28 @@ handle_rhs_call (gcall *stmt, vec = *results, >>> && gimple_call_lhs (stmt) !=3D NULL_TREE >>> && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt)))) >>> { >>> - auto_vec tmpc; >>> - struct constraint_expr *c; >>> - unsigned i; >>> + int flags =3D gimple_call_retslot_flags (stmt); >>> + if ((flags & (EAF_NOESCAPE | EAF_NOT_RETURNED)) >>> + !=3D (EAF_NOESCAPE | EAF_NOT_RETURNED)) >>> + { >>> + auto_vec tmpc; >>>=20 >>> - get_constraint_for_address_of (gimple_call_lhs (stmt), = &tmpc); >>> + get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc); >>>=20 >>> - make_constraints_to (callescape->id, tmpc); >>> - if (writes_global_memory) >>> - make_constraints_to (escaped_id, tmpc); >>> - FOR_EACH_VEC_ELT (tmpc, i, c) >>> - results->safe_push (*c); >>> + if (!(flags & (EAF_NOESCAPE | EAF_NODIRECTESCAPE))) >>> + { >>> + make_constraints_to (callescape->id, tmpc); >>> + if (writes_global_memory) >>> + make_constraints_to (escaped_id, tmpc); >>> + } >>> + if (!(flags & EAF_NOT_RETURNED)) >>> + { >>> + struct constraint_expr *c; >>> + unsigned i; >>> + FOR_EACH_VEC_ELT (tmpc, i, c) >>> + results->safe_push (*c); >>> + } >>> + } >>> } >>> } >>>=20 >>> >>=20