lists.linaro.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
List overview
Download
linaro-toolchain
August 2021
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
linaro-toolchain@lists.linaro.org
12 participants
87 discussions
Start a n
N
ew thread
[CI-NOTIFY]: TCWG Bisect tcwg_bmk_tx1/gnu-release-aarch64-spec2k6-O2 - Build # 17 - Fixed!
by ci_notify@linaro.org
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_gnu_tx1/gnu-release-aarch64-spec2k6-O2. So far, this commit has regressed CI configurations: - tcwg_bmk_gnu_tx1/gnu-release-aarch64-spec2k6-O2 Culprit: <cut> commit 0b92cf305dcf34387a8e2564e55ca8948df3b47a Author: Jan Hubicka <hubicka(a)ucw.cz> Date: Tue Oct 1 18:58:35 2019 +0200 invoke.texi (early-inlining-insns-O2): Document. * doc/invoke.texi (early-inlining-insns-O2): Document. (early-inlining-insns): Update. * params.def (early-inlining-insns-O2): New bound. (early-inlining-insns): Update docs. * ipa-inline.c (want_early_inline_function_p): Use new bound. * g++.dg/tree-ssa/pr61034.C: Set early-inlining-insns-O2=14. * g++.dg/tree-ssa/pr8781.C: Likewise. * g++.dg/warn/Wstringop-truncation-1.C: Likewise. * gcc.dg/ipa/pr63416.c: likewise. * gcc.dg/vect/pr66142.c: Likewise. * gcc.dg/tree-ssa/ssa-thread-12.c: Mark compure_idf inline. From-SVN: r276416 </cut> Results regressed to (for first_bad == 0b92cf305dcf34387a8e2564e55ca8948df3b47a) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # true: 0 # benchmark -O2 -- artifacts/build-0b92cf305dcf34387a8e2564e55ca8948df3b47a/results_id: 1 # 483.xalancbmk,Xalan_base.default regressed by 103 # 447.dealII,[.] _ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_ba regressed by 1239 from (for last_good == 7552c36afa1f9058bb39f336ae84f019621885a0) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # true: 0 # benchmark -O2 -- artifacts/build-7552c36afa1f9058bb39f336ae84f019621885a0/results_id: 1 Artifacts of last_good build:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Results ID of last_good: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-release-aarch64-spec2k6-O2/2646 Artifacts of first_bad build:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Results ID of first_bad: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-release-aarch64-spec2k6-O2/2640 Build top page/logs:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Configuration details: Reproduce builds: <cut> mkdir investigate-gcc-0b92cf305dcf34387a8e2564e55ca8948df3b47a cd investigate-gcc-0b92cf305dcf34387a8e2564e55ca8948df3b47a git clone
https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
--fail curl -o artifacts/manifests/build-parameters.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
--fail curl -o artifacts/test.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
--fail chmod +x artifacts/test.sh # Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh # 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/ cd gcc # Reproduce first_bad build git checkout --detach 0b92cf305dcf34387a8e2564e55ca8948df3b47a ../artifacts/test.sh # Reproduce last_good build git checkout --detach 7552c36afa1f9058bb39f336ae84f019621885a0 ../artifacts/test.sh cd .. </cut> History of pending regressions and results:
https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Build log:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Full commit (up to 1000 lines): <cut> commit 0b92cf305dcf34387a8e2564e55ca8948df3b47a Author: Jan Hubicka <hubicka(a)ucw.cz> Date: Tue Oct 1 18:58:35 2019 +0200 invoke.texi (early-inlining-insns-O2): Document. * doc/invoke.texi (early-inlining-insns-O2): Document. (early-inlining-insns): Update. * params.def (early-inlining-insns-O2): New bound. (early-inlining-insns): Update docs. * ipa-inline.c (want_early_inline_function_p): Use new bound. * g++.dg/tree-ssa/pr61034.C: Set early-inlining-insns-O2=14. * g++.dg/tree-ssa/pr8781.C: Likewise. * g++.dg/warn/Wstringop-truncation-1.C: Likewise. * gcc.dg/ipa/pr63416.c: likewise. * gcc.dg/vect/pr66142.c: Likewise. * gcc.dg/tree-ssa/ssa-thread-12.c: Mark compure_idf inline. From-SVN: r276416 --- gcc/ChangeLog | 8 ++++++++ gcc/doc/invoke.texi | 8 ++++++++ gcc/ipa-inline.c | 22 ++++++++++++++-------- gcc/params.def | 6 +++++- gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/g++.dg/tree-ssa/pr61034.C | 2 +- gcc/testsuite/g++.dg/tree-ssa/pr8781.C | 2 +- gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C | 2 +- gcc/testsuite/gcc.dg/ipa/pr63416.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c | 2 +- gcc/testsuite/gcc.dg/vect/pr66142.c | 2 +- 11 files changed, 50 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb4de20ab16..b4c4292c299 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-10-01 Jan Hubicka <hubicka(a)ucw.cz> + + * doc/invoke.texi (early-inlining-insns-O2): Document. + (early-inlining-insns): Update. + * params.def (early-inlining-insns-O2): New bound. + (early-inlining-insns): Update docs. + * ipa-inline.c (want_early_inline_function_p): Use new bound. + 2019-10-01 Oleg Endo <olegendo(a)gcc.gnu.org> PR target/88562 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 83016a5a8ee..4281ee7c614 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11291,9 +11291,17 @@ recursion depth can be guessed from the probability that function recurses via a given call expression. This parameter limits inlining only to call expressions whose probability exceeds the given threshold (in percents). +@item early-inlining-insns-O2 +Specify growth that the early inliner can make. In effect it increases +the amount of inlining for code having a large abstraction penalty. +This is applied to functions compiled with @option{-O1} or @option{-O2} +optimization levels. + @item early-inlining-insns Specify growth that the early inliner can make. In effect it increases the amount of inlining for code having a large abstraction penalty. +This is applied to functions compiled with @option{-O3} or @option{-Ofast} +optimization levels. @item max-early-inliner-iterations Limit of iterations of the early inliner. This basically bounds diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index b62d280eb25..c8689c7d9a8 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -641,6 +641,10 @@ want_early_inline_function_p (struct cgraph_edge *e) { int growth = estimate_edge_growth (e); int n; + int early_inlining_insns = opt_for_fn (e->caller->decl, optimize) >= 3 + ? PARAM_VALUE (PARAM_EARLY_INLINING_INSNS) + : PARAM_VALUE (PARAM_EARLY_INLINING_INSNS_O2); + if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE)) ; @@ -654,26 +658,28 @@ want_early_inline_function_p (struct cgraph_edge *e) growth); want_inline = false; } - else if (growth > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS)) + else if (growth > early_inlining_insns) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt, " will not early inline: %C->%C, " - "growth %i exceeds --param early-inlining-insns\n", - e->caller, callee, - growth); + "growth %i exceeds --param early-inlining-insns%s\n", + e->caller, callee, growth, + opt_for_fn (e->caller->decl, optimize) >= 3 + ? "" : "-O2"); want_inline = false; } else if ((n = num_calls (callee)) != 0 - && growth * (n + 1) > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS)) + && growth * (n + 1) > early_inlining_insns) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt, " will not early inline: %C->%C, " - "growth %i exceeds --param early-inlining-insns " + "growth %i exceeds --param early-inlining-insns%s " "divided by number of calls\n", - e->caller, callee, - growth); + e->caller, callee, growth, + opt_for_fn (e->caller->decl, optimize) >= 3 + ? "" : "-O2"); want_inline = false; } } diff --git a/gcc/params.def b/gcc/params.def index d2d957fc6b1..0acf29b6c4d 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -233,8 +233,12 @@ DEFPARAM(PARAM_IPCP_UNIT_GROWTH, 10, 0, 0) DEFPARAM(PARAM_EARLY_INLINING_INSNS, "early-inlining-insns", - "Maximal estimated growth of function body caused by early inlining of single call.", + "Maximal estimated growth of function body caused by early inlining of single call with -O3 and -Ofast.", 14, 0, 0) +DEFPARAM(PARAM_EARLY_INLINING_INSNS_O2, + "early-inlining-insns-O2", + "Maximal estimated growth of function body caused by early inlining of single call with -O1 and -O2.", + 6, 0, 0) DEFPARAM(PARAM_LARGE_STACK_FRAME, "large-stack-frame", "The size of stack frame to be considered large.", diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index df6105f3d13..0dcaf4b6292 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-10-01 Jan Hubicka <hubicka(a)ucw.cz> + + * g++.dg/tree-ssa/pr61034.C: Set early-inlining-insns-O2=14. + * g++.dg/tree-ssa/pr8781.C: Likewise. + * g++.dg/warn/Wstringop-truncation-1.C: Likewise. + * gcc.dg/ipa/pr63416.c: likewise. + * gcc.dg/vect/pr66142.c: Likewise. + * gcc.dg/tree-ssa/ssa-thread-12.c: Mark compure_idf inline. + 2019-10-01 Jakub Jelinek <jakub(a)redhat.com> PR c++/91925 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr61034.C b/gcc/testsuite/g++.dg/tree-ssa/pr61034.C index 870b2372166..2e3dfecacb4 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr61034.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr61034.C @@ -1,5 +1,5 @@ // { dg-do compile } -// { dg-options "-O2 -fdump-tree-fre3 -fdump-tree-optimized -fdelete-null-pointer-checks" } +// { dg-options "-O2 -fdump-tree-fre3 -fdump-tree-optimized -fdelete-null-pointer-checks --param early-inlining-insns-O2=14" } #define assume(x) if(!(x))__builtin_unreachable() diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C index 1f115b2b26d..5bc1ef03520 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1" } */ +/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1 --param early-inlining-insns-O2=14" } */ int f(); diff --git a/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C b/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C index 83066019772..49dde0a65ba 100644 --- a/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C +++ b/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C @@ -1,7 +1,7 @@ /* PR/tree-optimization/84480 - bogus -Wstringop-truncation despite assignment with an inlined string literal { dg-do compile } - { dg-options "-O2 -Wstringop-truncation" } */ + { dg-options "-O2 -Wstringop-truncation --param early-inlining-insns-O2=14" } */ #include <string.h> diff --git a/gcc/testsuite/gcc.dg/ipa/pr63416.c b/gcc/testsuite/gcc.dg/ipa/pr63416.c index b5374c51fe9..5873954fba3 100644 --- a/gcc/testsuite/gcc.dg/ipa/pr63416.c +++ b/gcc/testsuite/gcc.dg/ipa/pr63416.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized --param early-inlining-insns-O2=14" } */ #define _UNUSED_ __attribute__((__unused__)) typedef int TEST_F30 (int *v); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c index 67526762f2c..216de23d791 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c @@ -56,7 +56,7 @@ bmp_iter_and_compl (bitmap_iterator * bi, unsigned *bit_no) } extern int VEC_int_base_length (VEC_int_base *); -bitmap +inline bitmap compute_idf (bitmap def_blocks, bitmap_head * dfs) { bitmap_iterator bi; diff --git a/gcc/testsuite/gcc.dg/vect/pr66142.c b/gcc/testsuite/gcc.dg/vect/pr66142.c index 8c79f290767..a0316f1f01e 100644 --- a/gcc/testsuite/gcc.dg/vect/pr66142.c +++ b/gcc/testsuite/gcc.dg/vect/pr66142.c @@ -1,6 +1,6 @@ /* PR middle-end/66142 */ /* { dg-do compile } */ -/* { dg-additional-options "-ffast-math -fopenmp-simd" } */ +/* { dg-additional-options "-ffast-math -fopenmp-simd --param early-inlining-insns-O2=14" } */ /* { dg-additional-options "-mavx" { target avx_runtime } } */ struct A { float x, y; }; </cut>
3 years, 4 months
1
0
0
0
[CI-NOTIFY]: TCWG Bisect tcwg_bmk_tk1/gnu-master-arm-spec2k6-O3 - Build # 37 - Successful!
by ci_notify@linaro.org
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_gnu_tk1/gnu-master-arm-spec2k6-O3. So far, this commit has regressed CI configurations: - tcwg_bmk_gnu_tk1/gnu-master-arm-spec2k6-O3 Culprit: <cut> commit 5b759cdcb7f863520346e5bf63fcf1d3746c2cc3 Author: Jason Merrill <jason(a)redhat.com> Date: Sat Jul 10 05:45:02 2021 -0400 c++: pretty-print TYPE_PACK_EXPANSION better gcc/cp/ChangeLog: * ptree.c (cxx_print_type) [TYPE_PACK_EXPANSION]: Also print PACK_EXPANSION_PATTERN. </cut> Results regressed to (for first_bad == 5b759cdcb7f863520346e5bf63fcf1d3746c2cc3) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -5 # true: 0 # benchmark -- -O3_marm artifacts/build-5b759cdcb7f863520346e5bf63fcf1d3746c2cc3/results_id: 1 # 483.xalancbmk,[.] _ZN11xercesc_2_510ValueStore13isDuplicateOf regressed by 111 from (for last_good == 4c4249b71de3b15ba1e176ce90a57fb7bc54b917) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -5 # true: 0 # benchmark -- -O3_marm artifacts/build-4c4249b71de3b15ba1e176ce90a57fb7bc54b917/results_id: 1 Artifacts of last_good build:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
Results ID of last_good: tk1_32/tcwg_bmk_gnu_tk1/bisect-gnu-master-arm-spec2k6-O3/2632 Artifacts of first_bad build:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
Results ID of first_bad: tk1_32/tcwg_bmk_gnu_tk1/bisect-gnu-master-arm-spec2k6-O3/2639 Build top page/logs:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
Configuration details: Reproduce builds: <cut> mkdir investigate-gcc-5b759cdcb7f863520346e5bf63fcf1d3746c2cc3 cd investigate-gcc-5b759cdcb7f863520346e5bf63fcf1d3746c2cc3 git clone
https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
--fail curl -o artifacts/manifests/build-parameters.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
--fail curl -o artifacts/test.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
--fail chmod +x artifacts/test.sh # Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh # 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/ cd gcc # Reproduce first_bad build git checkout --detach 5b759cdcb7f863520346e5bf63fcf1d3746c2cc3 ../artifacts/test.sh # Reproduce last_good build git checkout --detach 4c4249b71de3b15ba1e176ce90a57fb7bc54b917 ../artifacts/test.sh cd .. </cut> History of pending regressions and results:
https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
Build log:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-master-ar…
Full commit (up to 1000 lines): <cut> commit 5b759cdcb7f863520346e5bf63fcf1d3746c2cc3 Author: Jason Merrill <jason(a)redhat.com> Date: Sat Jul 10 05:45:02 2021 -0400 c++: pretty-print TYPE_PACK_EXPANSION better gcc/cp/ChangeLog: * ptree.c (cxx_print_type) [TYPE_PACK_EXPANSION]: Also print PACK_EXPANSION_PATTERN. --- gcc/cp/ptree.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c index 33b73fb24b6..7f140f5f06b 100644 --- a/gcc/cp/ptree.c +++ b/gcc/cp/ptree.c @@ -171,6 +171,7 @@ cxx_print_type (FILE *file, tree node, int indent) return; case TYPE_PACK_EXPANSION: + print_node (file, "pattern", PACK_EXPANSION_PATTERN (node), indent + 4); print_node (file, "args", PACK_EXPANSION_EXTRA_ARGS (node), indent + 4); return; </cut>
3 years, 4 months
1
0
0
0
[CI-NOTIFY]: TCWG Bisect tcwg_kernel/llvm-release-arm-stable-allyesconfig - Build # 4 - Successful!
by ci_notify@linaro.org
Successfully identified regression in *linux* in CI configuration tcwg_kernel/llvm-release-arm-stable-allyesconfig. So far, this commit has regressed CI configurations: - tcwg_kernel/llvm-release-arm-stable-allyesconfig Culprit: <cut> commit 341db343768bc44f3512facc464021730d64071c Author: Linus Walleij <linus.walleij(a)linaro.org> Date: Sun May 23 00:50:39 2021 +0200 power: supply: ab8500: Move to componentized binding [ Upstream commit 1c1f13a006ed0d71bb5664c8b7e3e77a28da3beb ] The driver has problems with the different components of the charging code racing with each other to probe(). This results in all four subdrivers populating battery information to ascertain that it is populated for their own needs for example. Fix this by using component probing and thus expressing to the kernel that these are dependent components. The probes can happen in any order and will only acquire resources such as state container, regulators and interrupts and initialize the data structures, but no execution happens until the .bind() callback is called. The charging driver is the main component and binds first, then bind in order the three subcomponents: ab8500-fg, ab8500-btemp and ab8500-chargalg. Do some housekeeping while we are moving the code around. Like use devm_* for IRQs so as to cut down on some boilerplate. Signed-off-by: Linus Walleij <linus.walleij(a)linaro.org> Signed-off-by: Sebastian Reichel <sebastian.reichel(a)collabora.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> </cut> Results regressed to (for first_bad == 341db343768bc44f3512facc464021730d64071c) # reset_artifacts: -10 # build_abe binutils: -9 # build_llvm: -5 # build_abe qemu: -2 # linux_n_obj: 19634 # First few build errors in logs: # 00:03:07 drivers/power/supply/ab8500_fg.c:3061:32: error: use of undeclared identifier 'np' # 00:03:08 make[3]: *** [drivers/power/supply/ab8500_fg.o] Error 1 # 00:03:10 make[2]: *** [drivers/power/supply] Error 2 # 00:03:10 make[1]: *** [drivers/power] Error 2 # 00:04:05 make: *** [drivers] Error 2 from (for last_good == dc72a15859b2e604abb8a4bff123fbac8a0be92a) # reset_artifacts: -10 # build_abe binutils: -9 # build_llvm: -5 # build_abe qemu: -2 # linux_n_obj: 19722 # linux build successful: all Artifacts of last_good build:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
Artifacts of first_bad build:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
Build top page/logs:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
Configuration details: Reproduce builds: <cut> mkdir investigate-linux-341db343768bc44f3512facc464021730d64071c cd investigate-linux-341db343768bc44f3512facc464021730d64071c git clone
https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
--fail curl -o artifacts/manifests/build-parameters.sh
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
--fail curl -o artifacts/test.sh
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
--fail chmod +x artifacts/test.sh # Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_kernel-build.sh @@ artifacts/manifests/build-baseline.sh # 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 /linux/ ./ ./bisect/baseline/ cd linux # Reproduce first_bad build git checkout --detach 341db343768bc44f3512facc464021730d64071c ../artifacts/test.sh # Reproduce last_good build git checkout --detach dc72a15859b2e604abb8a4bff123fbac8a0be92a ../artifacts/test.sh cd .. </cut> History of pending regressions and results:
https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
Build log:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-arm-stable-a…
Full commit (up to 1000 lines): <cut> commit 341db343768bc44f3512facc464021730d64071c Author: Linus Walleij <linus.walleij(a)linaro.org> Date: Sun May 23 00:50:39 2021 +0200 power: supply: ab8500: Move to componentized binding [ Upstream commit 1c1f13a006ed0d71bb5664c8b7e3e77a28da3beb ] The driver has problems with the different components of the charging code racing with each other to probe(). This results in all four subdrivers populating battery information to ascertain that it is populated for their own needs for example. Fix this by using component probing and thus expressing to the kernel that these are dependent components. The probes can happen in any order and will only acquire resources such as state container, regulators and interrupts and initialize the data structures, but no execution happens until the .bind() callback is called. The charging driver is the main component and binds first, then bind in order the three subcomponents: ab8500-fg, ab8500-btemp and ab8500-chargalg. Do some housekeeping while we are moving the code around. Like use devm_* for IRQs so as to cut down on some boilerplate. Signed-off-by: Linus Walleij <linus.walleij(a)linaro.org> Signed-off-by: Sebastian Reichel <sebastian.reichel(a)collabora.com> Signed-off-by: Sasha Levin <sashal(a)kernel.org> --- drivers/power/supply/ab8500-bm.h | 4 + drivers/power/supply/ab8500_btemp.c | 118 +++++------- drivers/power/supply/ab8500_charger.c | 339 +++++++++++++++++++-------------- drivers/power/supply/ab8500_fg.c | 136 +++++++------ drivers/power/supply/abx500_chargalg.c | 116 ++++++----- 5 files changed, 379 insertions(+), 334 deletions(-) diff --git a/drivers/power/supply/ab8500-bm.h b/drivers/power/supply/ab8500-bm.h index 41c69a4f2a1f..012595a9d269 100644 --- a/drivers/power/supply/ab8500-bm.h +++ b/drivers/power/supply/ab8500-bm.h @@ -730,4 +730,8 @@ int ab8500_bm_of_probe(struct device *dev, struct device_node *np, struct abx500_bm_data *bm); +extern struct platform_driver ab8500_fg_driver; +extern struct platform_driver ab8500_btemp_driver; +extern struct platform_driver abx500_chargalg_driver; + #endif /* _AB8500_CHARGER_H_ */ diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c index fdfcd59fc43e..3598b5a748e7 100644 --- a/drivers/power/supply/ab8500_btemp.c +++ b/drivers/power/supply/ab8500_btemp.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/component.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/slab.h> @@ -932,26 +933,6 @@ static int __maybe_unused ab8500_btemp_suspend(struct device *dev) return 0; } -static int ab8500_btemp_remove(struct platform_device *pdev) -{ - struct ab8500_btemp *di = platform_get_drvdata(pdev); - int i, irq; - - /* Disable interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); - free_irq(irq, di); - } - - /* Delete the work queue */ - destroy_workqueue(di->btemp_wq); - - flush_scheduled_work(); - power_supply_unregister(di->btemp_psy); - - return 0; -} - static char *supply_interface[] = { "ab8500_chargalg", "ab8500_fg", @@ -966,6 +947,40 @@ static const struct power_supply_desc ab8500_btemp_desc = { .external_power_changed = ab8500_btemp_external_power_changed, }; +static int ab8500_btemp_bind(struct device *dev, struct device *master, + void *data) +{ + struct ab8500_btemp *di = dev_get_drvdata(dev); + + /* Create a work queue for the btemp */ + di->btemp_wq = + alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); + if (di->btemp_wq == NULL) { + dev_err(dev, "failed to create work queue\n"); + return -ENOMEM; + } + + /* Kick off periodic temperature measurements */ + ab8500_btemp_periodic(di, true); + + return 0; +} + +static void ab8500_btemp_unbind(struct device *dev, struct device *master, + void *data) +{ + struct ab8500_btemp *di = dev_get_drvdata(dev); + + /* Delete the work queue */ + destroy_workqueue(di->btemp_wq); + flush_scheduled_work(); +} + +static const struct component_ops ab8500_btemp_component_ops = { + .bind = ab8500_btemp_bind, + .unbind = ab8500_btemp_unbind, +}; + static int ab8500_btemp_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1011,14 +1026,6 @@ static int ab8500_btemp_probe(struct platform_device *pdev) psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); psy_cfg.drv_data = di; - /* Create a work queue for the btemp */ - di->btemp_wq = - alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); - if (di->btemp_wq == NULL) { - dev_err(dev, "failed to create work queue\n"); - return -ENOMEM; - } - /* Init work for measuring temperature periodically */ INIT_DEFERRABLE_WORK(&di->btemp_periodic_work, ab8500_btemp_periodic_work); @@ -1031,7 +1038,7 @@ static int ab8500_btemp_probe(struct platform_device *pdev) AB8500_BTEMP_HIGH_TH, &val); if (ret < 0) { dev_err(dev, "%s ab8500 read failed\n", __func__); - goto free_btemp_wq; + return ret; } switch (val) { case BTEMP_HIGH_TH_57_0: @@ -1050,30 +1057,28 @@ static int ab8500_btemp_probe(struct platform_device *pdev) } /* Register BTEMP power supply class */ - di->btemp_psy = power_supply_register(dev, &ab8500_btemp_desc, - &psy_cfg); + di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc, + &psy_cfg); if (IS_ERR(di->btemp_psy)) { dev_err(dev, "failed to register BTEMP psy\n"); - ret = PTR_ERR(di->btemp_psy); - goto free_btemp_wq; + return PTR_ERR(di->btemp_psy); } /* Register interrupts */ for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); - if (irq < 0) { - ret = irq; - goto free_irq; - } + if (irq < 0) + return irq; - ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr, + ret = devm_request_threaded_irq(dev, irq, NULL, + ab8500_btemp_irq[i].isr, IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, ab8500_btemp_irq[i].name, di); if (ret) { dev_err(dev, "failed to request %s IRQ %d: %d\n" , ab8500_btemp_irq[i].name, irq, ret); - goto free_irq; + return ret; } dev_dbg(dev, "Requested %s IRQ %d: %d\n", ab8500_btemp_irq[i].name, irq, ret); @@ -1081,23 +1086,16 @@ static int ab8500_btemp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, di); - /* Kick off periodic temperature measurements */ - ab8500_btemp_periodic(di, true); list_add_tail(&di->node, &ab8500_btemp_list); - return ret; + return component_add(dev, &ab8500_btemp_component_ops); +} -free_irq: - /* We also have to free all successfully registered irqs */ - for (i = i - 1; i >= 0; i--) { - irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); - free_irq(irq, di); - } +static int ab8500_btemp_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &ab8500_btemp_component_ops); - power_supply_unregister(di->btemp_psy); -free_btemp_wq: - destroy_workqueue(di->btemp_wq); - return ret; + return 0; } static SIMPLE_DEV_PM_OPS(ab8500_btemp_pm_ops, ab8500_btemp_suspend, ab8500_btemp_resume); @@ -1107,7 +1105,7 @@ static const struct of_device_id ab8500_btemp_match[] = { { }, }; -static struct platform_driver ab8500_btemp_driver = { +struct platform_driver ab8500_btemp_driver = { .probe = ab8500_btemp_probe, .remove = ab8500_btemp_remove, .driver = { @@ -1116,20 +1114,6 @@ static struct platform_driver ab8500_btemp_driver = { .pm = &ab8500_btemp_pm_ops, }, }; - -static int __init ab8500_btemp_init(void) -{ - return platform_driver_register(&ab8500_btemp_driver); -} - -static void __exit ab8500_btemp_exit(void) -{ - platform_driver_unregister(&ab8500_btemp_driver); -} - -device_initcall(ab8500_btemp_init); -module_exit(ab8500_btemp_exit); - MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy"); MODULE_ALIAS("platform:ab8500-btemp"); diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index a9be10eb2c22..af32cfae9f19 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/component.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/notifier.h> @@ -3276,10 +3277,74 @@ static struct notifier_block charger_nb = { .notifier_call = ab8500_external_charger_prepare, }; -static int ab8500_charger_remove(struct platform_device *pdev) +static char *supply_interface[] = { + "ab8500_chargalg", + "ab8500_fg", + "ab8500_btemp", +}; + +static const struct power_supply_desc ab8500_ac_chg_desc = { + .name = "ab8500_ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .properties = ab8500_charger_ac_props, + .num_properties = ARRAY_SIZE(ab8500_charger_ac_props), + .get_property = ab8500_charger_ac_get_property, +}; + +static const struct power_supply_desc ab8500_usb_chg_desc = { + .name = "ab8500_usb", + .type = POWER_SUPPLY_TYPE_USB, + .properties = ab8500_charger_usb_props, + .num_properties = ARRAY_SIZE(ab8500_charger_usb_props), + .get_property = ab8500_charger_usb_get_property, +}; + +static int ab8500_charger_bind(struct device *dev) { - struct ab8500_charger *di = platform_get_drvdata(pdev); - int i, irq, ret; + struct ab8500_charger *di = dev_get_drvdata(dev); + int ch_stat; + int ret; + + /* Create a work queue for the charger */ + di->charger_wq = alloc_ordered_workqueue("ab8500_charger_wq", + WQ_MEM_RECLAIM); + if (di->charger_wq == NULL) { + dev_err(dev, "failed to create work queue\n"); + return -ENOMEM; + } + + ch_stat = ab8500_charger_detect_chargers(di, false); + + if (ch_stat & AC_PW_CONN) { + if (is_ab8500(di->parent)) + queue_delayed_work(di->charger_wq, + &di->ac_charger_attached_work, + HZ); + } + if (ch_stat & USB_PW_CONN) { + if (is_ab8500(di->parent)) + queue_delayed_work(di->charger_wq, + &di->usb_charger_attached_work, + HZ); + di->vbus_detected = true; + di->vbus_detected_start = true; + queue_work(di->charger_wq, + &di->detect_usb_type_work); + } + + ret = component_bind_all(dev, di); + if (ret) { + dev_err(dev, "can't bind component devices\n"); + return ret; + } + + return 0; +} + +static void ab8500_charger_unbind(struct device *dev) +{ + struct ab8500_charger *di = dev_get_drvdata(dev); + int ret; /* Disable AC charging */ ab8500_charger_ac_en(&di->ac_chg, false, 0, 0); @@ -3287,68 +3352,47 @@ static int ab8500_charger_remove(struct platform_device *pdev) /* Disable USB charging */ ab8500_charger_usb_en(&di->usb_chg, false, 0, 0); - /* Disable interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); - free_irq(irq, di); - } - /* Backup battery voltage and current disable */ ret = abx500_mask_and_set_register_interruptible(di->dev, AB8500_RTC, AB8500_RTC_CTRL_REG, RTC_BUP_CH_ENA, 0); if (ret < 0) dev_err(di->dev, "%s mask and set failed\n", __func__); - usb_unregister_notifier(di->usb_phy, &di->nb); - usb_put_phy(di->usb_phy); - /* Delete the work queue */ destroy_workqueue(di->charger_wq); - /* Unregister external charger enable notifier */ - if (!di->ac_chg.enabled) - blocking_notifier_chain_unregister( - &charger_notifier_list, &charger_nb); - flush_scheduled_work(); - if (di->usb_chg.enabled) - power_supply_unregister(di->usb_chg.psy); - - if (di->ac_chg.enabled && !di->ac_chg.external) - power_supply_unregister(di->ac_chg.psy); - return 0; + /* Unbind fg, btemp, algorithm */ + component_unbind_all(dev, di); } -static char *supply_interface[] = { - "ab8500_chargalg", - "ab8500_fg", - "ab8500_btemp", +static const struct component_master_ops ab8500_charger_comp_ops = { + .bind = ab8500_charger_bind, + .unbind = ab8500_charger_unbind, }; -static const struct power_supply_desc ab8500_ac_chg_desc = { - .name = "ab8500_ac", - .type = POWER_SUPPLY_TYPE_MAINS, - .properties = ab8500_charger_ac_props, - .num_properties = ARRAY_SIZE(ab8500_charger_ac_props), - .get_property = ab8500_charger_ac_get_property, +static struct platform_driver *const ab8500_charger_component_drivers[] = { + &ab8500_fg_driver, + &ab8500_btemp_driver, + &abx500_chargalg_driver, }; -static const struct power_supply_desc ab8500_usb_chg_desc = { - .name = "ab8500_usb", - .type = POWER_SUPPLY_TYPE_USB, - .properties = ab8500_charger_usb_props, - .num_properties = ARRAY_SIZE(ab8500_charger_usb_props), - .get_property = ab8500_charger_usb_get_property, -}; +static int ab8500_charger_compare_dev(struct device *dev, void *data) +{ + return dev == data; +} static int ab8500_charger_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct component_match *match = NULL; struct power_supply_config ac_psy_cfg = {}, usb_psy_cfg = {}; struct ab8500_charger *di; - int irq, i, charger_status, ret = 0, ch_stat; - struct device *dev = &pdev->dev; + int charger_status; + int i, irq; + int ret; di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); if (!di) @@ -3393,6 +3437,38 @@ static int ab8500_charger_probe(struct platform_device *pdev) return ret; } + /* + * VDD ADC supply needs to be enabled from this driver when there + * is a charger connected to avoid erroneous BTEMP_HIGH/LOW + * interrupts during charging + */ + di->regu = devm_regulator_get(dev, "vddadc"); + if (IS_ERR(di->regu)) { + ret = PTR_ERR(di->regu); + dev_err(dev, "failed to get vddadc regulator\n"); + return ret; + } + + /* Request interrupts */ + for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { + irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); + if (irq < 0) + return irq; + + ret = devm_request_threaded_irq(dev, + irq, NULL, ab8500_charger_irq[i].isr, + IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, + ab8500_charger_irq[i].name, di); + + if (ret != 0) { + dev_err(dev, "failed to request %s IRQ %d: %d\n" + , ab8500_charger_irq[i].name, irq, ret); + return ret; + } + dev_dbg(dev, "Requested %s IRQ %d: %d\n", + ab8500_charger_irq[i].name, irq, ret); + } + /* initialize lock */ spin_lock_init(&di->usb_state.usb_lock); mutex_init(&di->usb_ipt_crnt_lock); @@ -3422,11 +3498,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->ac_chg.enabled = di->bm->ac_enabled; di->ac_chg.external = false; - /*notifier for external charger enabling*/ - if (!di->ac_chg.enabled) - blocking_notifier_chain_register( - &charger_notifier_list, &charger_nb); - /* USB supply */ /* ux500_charger sub-class */ di->usb_chg.ops.enable = &ab8500_charger_usb_en; @@ -3442,14 +3513,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) di->usb_chg.external = false; di->usb_state.usb_current = -1; - /* Create a work queue for the charger */ - di->charger_wq = alloc_ordered_workqueue("ab8500_charger_wq", - WQ_MEM_RECLAIM); - if (di->charger_wq == NULL) { - dev_err(dev, "failed to create work queue\n"); - return -ENOMEM; - } - mutex_init(&di->charger_attached_mutex); /* Init work for HW failure check */ @@ -3500,63 +3563,36 @@ static int ab8500_charger_probe(struct platform_device *pdev) INIT_WORK(&di->check_usb_thermal_prot_work, ab8500_charger_check_usb_thermal_prot_work); - /* - * VDD ADC supply needs to be enabled from this driver when there - * is a charger connected to avoid erroneous BTEMP_HIGH/LOW - * interrupts during charging - */ - di->regu = devm_regulator_get(dev, "vddadc"); - if (IS_ERR(di->regu)) { - ret = PTR_ERR(di->regu); - dev_err(dev, "failed to get vddadc regulator\n"); - goto free_charger_wq; - } - /* Initialize OVV, and other registers */ ret = ab8500_charger_init_hw_registers(di); if (ret) { dev_err(dev, "failed to initialize ABB registers\n"); - goto free_charger_wq; + return ret; } /* Register AC charger class */ if (di->ac_chg.enabled) { - di->ac_chg.psy = power_supply_register(dev, + di->ac_chg.psy = devm_power_supply_register(dev, &ab8500_ac_chg_desc, &ac_psy_cfg); if (IS_ERR(di->ac_chg.psy)) { dev_err(dev, "failed to register AC charger\n"); - ret = PTR_ERR(di->ac_chg.psy); - goto free_charger_wq; + return PTR_ERR(di->ac_chg.psy); } } /* Register USB charger class */ if (di->usb_chg.enabled) { - di->usb_chg.psy = power_supply_register(dev, + di->usb_chg.psy = devm_power_supply_register(dev, &ab8500_usb_chg_desc, &usb_psy_cfg); if (IS_ERR(di->usb_chg.psy)) { dev_err(dev, "failed to register USB charger\n"); - ret = PTR_ERR(di->usb_chg.psy); - goto free_ac; + return PTR_ERR(di->usb_chg.psy); } } - di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); - if (IS_ERR_OR_NULL(di->usb_phy)) { - dev_err(dev, "failed to get usb transceiver\n"); - ret = -EINVAL; - goto free_usb; - } - di->nb.notifier_call = ab8500_charger_usb_notifier_call; - ret = usb_register_notifier(di->usb_phy, &di->nb); - if (ret) { - dev_err(dev, "failed to register usb notifier\n"); - goto put_usb_phy; - } - /* Identify the connected charger types during startup */ charger_status = ab8500_charger_detect_chargers(di, true); if (charger_status & AC_PW_CONN) { @@ -3566,78 +3602,86 @@ static int ab8500_charger_probe(struct platform_device *pdev) sysfs_notify(&di->ac_chg.psy->dev.kobj, NULL, "present"); } - if (charger_status & USB_PW_CONN) { - di->vbus_detected = true; - di->vbus_detected_start = true; - queue_work(di->charger_wq, - &di->detect_usb_type_work); - } - - /* Register interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); - if (irq < 0) { - ret = irq; - goto free_irq; - } + platform_set_drvdata(pdev, di); - ret = request_threaded_irq(irq, NULL, ab8500_charger_irq[i].isr, - IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, - ab8500_charger_irq[i].name, di); + /* Create something that will match the subdrivers when we bind */ + for (i = 0; i < ARRAY_SIZE(ab8500_charger_component_drivers); i++) { + struct device_driver *drv = &ab8500_charger_component_drivers[i]->driver; + struct device *p = NULL, *d; - if (ret != 0) { - dev_err(dev, "failed to request %s IRQ %d: %d\n" - , ab8500_charger_irq[i].name, irq, ret); - goto free_irq; + while ((d = platform_find_device_by_driver(p, drv))) { + put_device(p); + component_match_add(dev, &match, + ab8500_charger_compare_dev, d); + p = d; } - dev_dbg(dev, "Requested %s IRQ %d: %d\n", - ab8500_charger_irq[i].name, irq, ret); + put_device(p); + } + if (!match) { + dev_err(dev, "no matching components\n"); + return -ENODEV; + } + if (IS_ERR(match)) { + dev_err(dev, "could not create component match\n"); + return PTR_ERR(match); } - platform_set_drvdata(pdev, di); + /* Notifier for external charger enabling */ + if (!di->ac_chg.enabled) + blocking_notifier_chain_register( + &charger_notifier_list, &charger_nb); - mutex_lock(&di->charger_attached_mutex); - ch_stat = ab8500_charger_detect_chargers(di, false); - - if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) { - if (is_ab8500(di->parent)) - queue_delayed_work(di->charger_wq, - &di->ac_charger_attached_work, - HZ); + di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(di->usb_phy)) { + dev_err(dev, "failed to get usb transceiver\n"); + ret = -EINVAL; + goto out_charger_notifier; } - if ((ch_stat & USB_PW_CONN) == USB_PW_CONN) { - if (is_ab8500(di->parent)) - queue_delayed_work(di->charger_wq, - &di->usb_charger_attached_work, - HZ); + di->nb.notifier_call = ab8500_charger_usb_notifier_call; + ret = usb_register_notifier(di->usb_phy, &di->nb); + if (ret) { + dev_err(dev, "failed to register usb notifier\n"); + goto put_usb_phy; } - mutex_unlock(&di->charger_attached_mutex); - return ret; + ret = component_master_add_with_match(&pdev->dev, + &ab8500_charger_comp_ops, + match); + if (ret) { + dev_err(dev, "failed to add component master\n"); + goto free_notifier; + } -free_irq: - usb_unregister_notifier(di->usb_phy, &di->nb); + return 0; - /* We also have to free all successfully registered irqs */ - for (i = i - 1; i >= 0; i--) { - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); - free_irq(irq, di); - } +free_notifier: + usb_unregister_notifier(di->usb_phy, &di->nb); put_usb_phy: usb_put_phy(di->usb_phy); -free_usb: - if (di->usb_chg.enabled) - power_supply_unregister(di->usb_chg.psy); -free_ac: - if (di->ac_chg.enabled) - power_supply_unregister(di->ac_chg.psy); -free_charger_wq: - destroy_workqueue(di->charger_wq); +out_charger_notifier: + if (!di->ac_chg.enabled) + blocking_notifier_chain_unregister( + &charger_notifier_list, &charger_nb); return ret; } +static int ab8500_charger_remove(struct platform_device *pdev) +{ + struct ab8500_charger *di = platform_get_drvdata(pdev); + + component_master_del(&pdev->dev, &ab8500_charger_comp_ops); + + usb_unregister_notifier(di->usb_phy, &di->nb); + usb_put_phy(di->usb_phy); + if (!di->ac_chg.enabled) + blocking_notifier_chain_unregister( + &charger_notifier_list, &charger_nb); + + return 0; +} + static SIMPLE_DEV_PM_OPS(ab8500_charger_pm_ops, ab8500_charger_suspend, ab8500_charger_resume); static const struct of_device_id ab8500_charger_match[] = { @@ -3657,15 +3701,24 @@ static struct platform_driver ab8500_charger_driver = { static int __init ab8500_charger_init(void) { + int ret; + + ret = platform_register_drivers(ab8500_charger_component_drivers, + ARRAY_SIZE(ab8500_charger_component_drivers)); + if (ret) + return ret; + return platform_driver_register(&ab8500_charger_driver); } static void __exit ab8500_charger_exit(void) { + platform_unregister_drivers(ab8500_charger_component_drivers, + ARRAY_SIZE(ab8500_charger_component_drivers)); platform_driver_unregister(&ab8500_charger_driver); } -subsys_initcall_sync(ab8500_charger_init); +module_init(ab8500_charger_init); module_exit(ab8500_charger_exit); MODULE_LICENSE("GPL v2"); diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index 0c7c01a0d979..acf0f2471c0b 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include <linux/module.h> +#include <linux/component.h> #include <linux/device.h> #include <linux/interrupt.h> #include <linux/platform_device.h> @@ -2980,27 +2981,6 @@ static int __maybe_unused ab8500_fg_suspend(struct device *dev) return 0; } -static int ab8500_fg_remove(struct platform_device *pdev) -{ - int ret = 0; - struct ab8500_fg *di = platform_get_drvdata(pdev); - - list_del(&di->node); - - /* Disable coulomb counter */ - ret = ab8500_fg_coulomb_counter(di, false); - if (ret) - dev_err(di->dev, "failed to disable coulomb counter\n"); - - destroy_workqueue(di->fg_wq); - ab8500_fg_sysfs_exit(di); - - flush_scheduled_work(); - ab8500_fg_sysfs_psy_remove_attrs(di); - power_supply_unregister(di->fg_psy); - return ret; -} - /* ab8500 fg driver interrupts and their respective isr */ static struct ab8500_fg_interrupts ab8500_fg_irq[] = { {"NCONV_ACCU", ab8500_fg_cc_convend_handler}, @@ -3024,11 +3004,50 @@ static const struct power_supply_desc ab8500_fg_desc = { .external_power_changed = ab8500_fg_external_power_changed, }; +static int ab8500_fg_bind(struct device *dev, struct device *master, + void *data) +{ + struct ab8500_fg *di = dev_get_drvdata(dev); + + /* Create a work queue for running the FG algorithm */ + di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM); + if (di->fg_wq == NULL) { + dev_err(dev, "failed to create work queue\n"); + return -ENOMEM; + } + + /* Start the coulomb counter */ + ab8500_fg_coulomb_counter(di, true); + /* Run the FG algorithm */ + queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); + + return 0; +} + +static void ab8500_fg_unbind(struct device *dev, struct device *master, + void *data) +{ + struct ab8500_fg *di = dev_get_drvdata(dev); + int ret; + + /* Disable coulomb counter */ + ret = ab8500_fg_coulomb_counter(di, false); + if (ret) + dev_err(dev, "failed to disable coulomb counter\n"); + + destroy_workqueue(di->fg_wq); + flush_scheduled_work(); +} + +static const struct component_ops ab8500_fg_component_ops = { + .bind = ab8500_fg_bind, + .unbind = ab8500_fg_unbind, +}; + static int ab8500_fg_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; - struct power_supply_config psy_cfg = {}; struct device *dev = &pdev->dev; + struct power_supply_config psy_cfg = {}; struct ab8500_fg *di; int i, irq; int ret = 0; @@ -3074,13 +3093,6 @@ static int ab8500_fg_probe(struct platform_device *pdev) ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_INIT); ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_INIT); - /* Create a work queue for running the FG algorithm */ - di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM); - if (di->fg_wq == NULL) { - dev_err(dev, "failed to create work queue\n"); - return -ENOMEM; - } - /* Init work for running the fg algorithm instantly */ INIT_WORK(&di->fg_work, ab8500_fg_instant_work); @@ -3113,7 +3125,7 @@ static int ab8500_fg_probe(struct platform_device *pdev) ret = ab8500_fg_init_hw_registers(di); if (ret) { dev_err(dev, "failed to initialize registers\n"); - goto free_inst_curr_wq; + return ret; } /* Consider battery unknown until we're informed otherwise */ @@ -3121,15 +3133,13 @@ static int ab8500_fg_probe(struct platform_device *pdev) di->flags.batt_id_received = false; /* Register FG power supply class */ - di->fg_psy = power_supply_register(dev, &ab8500_fg_desc, &psy_cfg); + di->fg_psy = devm_power_supply_register(dev, &ab8500_fg_desc, &psy_cfg); if (IS_ERR(di->fg_psy)) { dev_err(dev, "failed to register FG psy\n"); - ret = PTR_ERR(di->fg_psy); - goto free_inst_curr_wq; + return PTR_ERR(di->fg_psy); } di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); - ab8500_fg_coulomb_counter(di, true); /* * Initialize completion used to notify completion and start @@ -3141,19 +3151,18 @@ static int ab8500_fg_probe(struct platform_device *pdev) /* Register primary interrupt handlers */ for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) { irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); - if (irq < 0) { - ret = irq; - goto free_irq; - } + if (irq < 0) + return irq; - ret = request_threaded_irq(irq, NULL, ab8500_fg_irq[i].isr, + ret = devm_request_threaded_irq(dev, irq, NULL, + ab8500_fg_irq[i].isr, IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, ab8500_fg_irq[i].name, di); if (ret != 0) { dev_err(dev, "failed to request %s IRQ %d: %d\n", ab8500_fg_irq[i].name, irq, ret); - goto free_irq; + return ret; } dev_dbg(dev, "Requested %s IRQ %d: %d\n", ab8500_fg_irq[i].name, irq, ret); @@ -3168,14 +3177,14 @@ static int ab8500_fg_probe(struct platform_device *pdev) ret = ab8500_fg_sysfs_init(di); if (ret) { dev_err(dev, "failed to create sysfs entry\n"); - goto free_irq; + return ret; } ret = ab8500_fg_sysfs_psy_create_attrs(di); if (ret) { dev_err(dev, "failed to create FG psy\n"); ab8500_fg_sysfs_exit(di); - goto free_irq; + return ret; } /* Calibrate the fg first time */ @@ -3185,24 +3194,21 @@ static int ab8500_fg_probe(struct platform_device *pdev) /* Use room temp as default value until we get an update from driver. */ di->bat_temp = 210; - /* Run the FG algorithm */ - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - list_add_tail(&di->node, &ab8500_fg_list); - return ret; + return component_add(dev, &ab8500_fg_component_ops); +} -free_irq: - /* We also have to free all registered irqs */ - while (--i >= 0) { - /* Last assignment of i from primary interrupt handlers */ - irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); - free_irq(irq, di); - } +static int ab8500_fg_remove(struct platform_device *pdev) +{ + int ret = 0; + struct ab8500_fg *di = platform_get_drvdata(pdev); + + component_del(&pdev->dev, &ab8500_fg_component_ops); + list_del(&di->node); + ab8500_fg_sysfs_exit(di); + ab8500_fg_sysfs_psy_remove_attrs(di); - power_supply_unregister(di->fg_psy); -free_inst_curr_wq: - destroy_workqueue(di->fg_wq); return ret; } @@ -3213,7 +3219,7 @@ static const struct of_device_id ab8500_fg_match[] = { { }, }; -static struct platform_driver ab8500_fg_driver = { +struct platform_driver ab8500_fg_driver = { .probe = ab8500_fg_probe, .remove = ab8500_fg_remove, .driver = { @@ -3222,20 +3228,6 @@ static struct platform_driver ab8500_fg_driver = { .pm = &ab8500_fg_pm_ops, }, }; - -static int __init ab8500_fg_init(void) -{ - return platform_driver_register(&ab8500_fg_driver); -} - -static void __exit ab8500_fg_exit(void) -{ - platform_driver_unregister(&ab8500_fg_driver); -} - -subsys_initcall_sync(ab8500_fg_init); -module_exit(ab8500_fg_exit); - MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Johan Palsson, Karl Komierowski"); MODULE_ALIAS("platform:ab8500-fg"); diff --git a/drivers/power/supply/abx500_chargalg.c b/drivers/power/supply/abx500_chargalg.c index f5b792243727..599684ce0e4b 100644 --- a/drivers/power/supply/abx500_chargalg.c +++ b/drivers/power/supply/abx500_chargalg.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/component.h> #include <linux/hrtimer.h> #include <linux/interrupt.h> #include <linux/delay.h> @@ -1943,13 +1944,44 @@ static int __maybe_unused abx500_chargalg_suspend(struct device *dev) return 0; } -static int abx500_chargalg_remove(struct platform_device *pdev) +static char *supply_interface[] = { + "ab8500_fg", +}; + </cut>
3 years, 4 months
4
3
0
0
[CI-NOTIFY]: TCWG Bisect tcwg_kernel/llvm-release-aarch64-next-allmodconfig - Build # 26 - Successful!
by ci_notify@linaro.org
Successfully identified regression in *linux* in CI configuration tcwg_kernel/llvm-release-aarch64-next-allmodconfig. So far, this commit has regressed CI configurations: - tcwg_kernel/llvm-release-aarch64-next-allmodconfig Culprit: <cut> commit 3d463dd5023b5a58b3c37207d65eeb5acbac2be3 Author: Krzysztof Kozlowski <krzysztof.kozlowski(a)canonical.com> Date: Thu Jul 29 12:40:19 2021 +0200 nfc: fdp: constify several pointers Several functions do not modify pointed data so arguments and local variables can be const for correctness and safety. This allows also making file-scope nci_core_get_config_otp_ram_version array const. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski(a)canonical.com> Signed-off-by: David S. Miller <davem(a)davemloft.net> </cut> Results regressed to (for first_bad == 3d463dd5023b5a58b3c37207d65eeb5acbac2be3) # reset_artifacts: -10 # build_abe binutils: -9 # build_llvm: -5 # build_abe qemu: -2 # linux_n_obj: 21802 # First few build errors in logs: # 00:03:45 drivers/nfc/fdp/fdp.c:116:60: error: passing 'const char *' to parameter of type '__u8 *' (aka 'unsigned char *') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers] # 00:03:45 make[3]: *** [drivers/nfc/fdp/fdp.o] Error 1 # 00:03:49 make[2]: *** [drivers/nfc/fdp] Error 2 # 00:04:01 make[1]: *** [drivers/nfc] Error 2 # 00:09:25 make: *** [drivers] Error 2 from (for last_good == c3e26b6dc1b4e3e8f57be4f004b1f2a410c5c468) # reset_artifacts: -10 # build_abe binutils: -9 # build_llvm: -5 # build_abe qemu: -2 # linux_n_obj: 29857 # linux build successful: all # linux boot successful: boot Artifacts of last_good build:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
Artifacts of first_bad build:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
Build top page/logs:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
Configuration details: rr[linux_git]="
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git#cb16362…
" Reproduce builds: <cut> mkdir investigate-linux-3d463dd5023b5a58b3c37207d65eeb5acbac2be3 cd investigate-linux-3d463dd5023b5a58b3c37207d65eeb5acbac2be3 git clone
https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
--fail curl -o artifacts/manifests/build-parameters.sh
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
--fail curl -o artifacts/test.sh
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
--fail chmod +x artifacts/test.sh # Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_kernel-build.sh @@ artifacts/manifests/build-baseline.sh # 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 /linux/ ./ ./bisect/baseline/ cd linux # Reproduce first_bad build git checkout --detach 3d463dd5023b5a58b3c37207d65eeb5acbac2be3 ../artifacts/test.sh # Reproduce last_good build git checkout --detach c3e26b6dc1b4e3e8f57be4f004b1f2a410c5c468 ../artifacts/test.sh cd .. </cut> History of pending regressions and results:
https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
Build log:
https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-release-aarch64-next…
Full commit (up to 1000 lines): <cut> commit 3d463dd5023b5a58b3c37207d65eeb5acbac2be3 Author: Krzysztof Kozlowski <krzysztof.kozlowski(a)canonical.com> Date: Thu Jul 29 12:40:19 2021 +0200 nfc: fdp: constify several pointers Several functions do not modify pointed data so arguments and local variables can be const for correctness and safety. This allows also making file-scope nci_core_get_config_otp_ram_version array const. Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski(a)canonical.com> Signed-off-by: David S. Miller <davem(a)davemloft.net> --- drivers/nfc/fdp/fdp.c | 18 +++++++++--------- drivers/nfc/fdp/fdp.h | 2 +- drivers/nfc/fdp/i2c.c | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c index 3f5fba922c4d..c6b3334f24c9 100644 --- a/drivers/nfc/fdp/fdp.c +++ b/drivers/nfc/fdp/fdp.c @@ -52,7 +52,7 @@ struct fdp_nci_info { u32 limited_otp_version; u8 key_index; - u8 *fw_vsc_cfg; + const u8 *fw_vsc_cfg; u8 clock_type; u32 clock_freq; @@ -65,7 +65,7 @@ struct fdp_nci_info { wait_queue_head_t setup_wq; }; -static u8 nci_core_get_config_otp_ram_version[5] = { +static const u8 nci_core_get_config_otp_ram_version[5] = { 0x04, NCI_PARAM_ID_FW_RAM_VERSION, NCI_PARAM_ID_FW_OTP_VERSION, @@ -111,7 +111,7 @@ static inline int fdp_nci_patch_cmd(struct nci_dev *ndev, u8 type) } static inline int fdp_nci_set_production_data(struct nci_dev *ndev, u8 len, - char *data) + const char *data) { return nci_prop_cmd(ndev, NCI_OP_PROP_SET_PDATA_OID, len, data); } @@ -236,7 +236,7 @@ static int fdp_nci_send_patch(struct nci_dev *ndev, u8 conn_id, u8 type) static int fdp_nci_open(struct nci_dev *ndev) { - struct fdp_nci_info *info = nci_get_drvdata(ndev); + const struct fdp_nci_info *info = nci_get_drvdata(ndev); return info->phy_ops->enable(info->phy); } @@ -260,7 +260,7 @@ static int fdp_nci_request_firmware(struct nci_dev *ndev) { struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - u8 *data; + const u8 *data; int r; r = request_firmware(&info->ram_patch, FDP_RAM_PATCH_NAME, dev); @@ -269,7 +269,7 @@ static int fdp_nci_request_firmware(struct nci_dev *ndev) return r; } - data = (u8 *) info->ram_patch->data; + data = info->ram_patch->data; info->ram_patch_version = data[FDP_FW_HEADER_SIZE] | (data[FDP_FW_HEADER_SIZE + 1] << 8) | @@ -610,9 +610,9 @@ static int fdp_nci_core_get_config_rsp_packet(struct nci_dev *ndev, { struct fdp_nci_info *info = nci_get_drvdata(ndev); struct device *dev = &info->phy->i2c_dev->dev; - struct nci_core_get_config_rsp *rsp = (void *) skb->data; + const struct nci_core_get_config_rsp *rsp = (void *) skb->data; unsigned int i; - u8 *p; + const u8 *p; if (rsp->status == NCI_STATUS_OK) { @@ -691,7 +691,7 @@ static const struct nci_ops nci_ops = { int fdp_nci_probe(struct fdp_i2c_phy *phy, const struct nfc_phy_ops *phy_ops, struct nci_dev **ndevp, int tx_headroom, int tx_tailroom, u8 clock_type, u32 clock_freq, - u8 *fw_vsc_cfg) + const u8 *fw_vsc_cfg) { struct device *dev = &phy->i2c_dev->dev; struct fdp_nci_info *info; diff --git a/drivers/nfc/fdp/fdp.h b/drivers/nfc/fdp/fdp.h index dc048d4b977e..2e9161a4d7bf 100644 --- a/drivers/nfc/fdp/fdp.h +++ b/drivers/nfc/fdp/fdp.h @@ -23,7 +23,7 @@ struct fdp_i2c_phy { int fdp_nci_probe(struct fdp_i2c_phy *phy, const struct nfc_phy_ops *phy_ops, struct nci_dev **ndev, int tx_headroom, int tx_tailroom, - u8 clock_type, u32 clock_freq, u8 *fw_vsc_cfg); + u8 clock_type, u32 clock_freq, const u8 *fw_vsc_cfg); void fdp_nci_remove(struct nci_dev *ndev); #endif /* __LOCAL_FDP_H_ */ diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c index 98e1876c9468..051c43a2a52f 100644 --- a/drivers/nfc/fdp/i2c.c +++ b/drivers/nfc/fdp/i2c.c @@ -36,7 +36,7 @@ print_hex_dump(KERN_DEBUG, prefix": ", DUMP_PREFIX_OFFSET, \ 16, 1, (skb)->data, (skb)->len, 0) -static void fdp_nci_i2c_reset(struct fdp_i2c_phy *phy) +static void fdp_nci_i2c_reset(const struct fdp_i2c_phy *phy) { /* Reset RST/WakeUP for at least 100 micro-second */ gpiod_set_value_cansleep(phy->power_gpio, FDP_POWER_OFF); @@ -47,7 +47,7 @@ static void fdp_nci_i2c_reset(struct fdp_i2c_phy *phy) static int fdp_nci_i2c_enable(void *phy_id) { - struct fdp_i2c_phy *phy = phy_id; + const struct fdp_i2c_phy *phy = phy_id; fdp_nci_i2c_reset(phy); @@ -56,7 +56,7 @@ static int fdp_nci_i2c_enable(void *phy_id) static void fdp_nci_i2c_disable(void *phy_id) { - struct fdp_i2c_phy *phy = phy_id; + const struct fdp_i2c_phy *phy = phy_id; fdp_nci_i2c_reset(phy); } </cut>
3 years, 4 months
3
2
0
0
[CI-NOTIFY]: TCWG Bisect tcwg_bmk_tx1/llvm-master-aarch64-spec2k6-O3_LTO - Build # 25 - Successful!
by ci_notify@linaro.org
Successfully identified regression in *llvm* in CI configuration tcwg_bmk_llvm_tx1/llvm-master-aarch64-spec2k6-O3_LTO. So far, this commit has regressed CI configurations: - tcwg_bmk_llvm_tx1/llvm-master-aarch64-spec2k6-O3_LTO Culprit: <cut> commit 5a9b25e15b4f9707245bb9d1ab56ab99b725505a Author: Sam Clegg <sbc(a)chromium.org> Date: Fri May 14 16:25:04 2021 -0700 [lld][WebAssembly] Refactor input chunk class hierarchy. NFC The main motivation for this refactor is to remove the subclass relationship between the InputSegment and MergeInputSegment and SyntenticMergedInputSegment so that we can use the merging classes for debug sections which are not data segments. In the process of refactoring I also remove all the virtual functions from the class hierarchy and try to reuse techniques used in the ELF linker (see `lld/ELF/InputSections.h`). Differential Revision:
https://reviews.llvm.org/D102546
</cut> Results regressed to (for first_bad == 5a9b25e15b4f9707245bb9d1ab56ab99b725505a) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -O3_LTO -- artifacts/build-5a9b25e15b4f9707245bb9d1ab56ab99b725505a/results_id: 1 # 462.libquantum,libquantum_base.default regressed by 113 from (for last_good == ed9d70781bbd1dc858b9f6913729fcc49a1e4bdf) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -O3_LTO -- artifacts/build-ed9d70781bbd1dc858b9f6913729fcc49a1e4bdf/results_id: 1 Artifacts of last_good build:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Results ID of last_good: tx1_64/tcwg_bmk_llvm_tx1/bisect-llvm-master-aarch64-spec2k6-O3_LTO/2499 Artifacts of first_bad build:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Results ID of first_bad: tx1_64/tcwg_bmk_llvm_tx1/bisect-llvm-master-aarch64-spec2k6-O3_LTO/2539 Build top page/logs:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Configuration details: Reproduce builds: <cut> mkdir investigate-llvm-5a9b25e15b4f9707245bb9d1ab56ab99b725505a cd investigate-llvm-5a9b25e15b4f9707245bb9d1ab56ab99b725505a git clone
https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
--fail curl -o artifacts/manifests/build-parameters.sh
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
--fail curl -o artifacts/test.sh
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
--fail chmod +x artifacts/test.sh # Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh # 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 /llvm/ ./ ./bisect/baseline/ cd llvm # Reproduce first_bad build git checkout --detach 5a9b25e15b4f9707245bb9d1ab56ab99b725505a ../artifacts/test.sh # Reproduce last_good build git checkout --detach ed9d70781bbd1dc858b9f6913729fcc49a1e4bdf ../artifacts/test.sh cd .. </cut> History of pending regressions and results:
https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Build log:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Full commit (up to 1000 lines): <cut> commit 5a9b25e15b4f9707245bb9d1ab56ab99b725505a Author: Sam Clegg <sbc(a)chromium.org> Date: Fri May 14 16:25:04 2021 -0700 [lld][WebAssembly] Refactor input chunk class hierarchy. NFC The main motivation for this refactor is to remove the subclass relationship between the InputSegment and MergeInputSegment and SyntenticMergedInputSegment so that we can use the merging classes for debug sections which are not data segments. In the process of refactoring I also remove all the virtual functions from the class hierarchy and try to reuse techniques used in the ELF linker (see `lld/ELF/InputSections.h`). Differential Revision:
https://reviews.llvm.org/D102546
--- lld/wasm/Driver.cpp | 4 +- lld/wasm/InputChunks.cpp | 99 ++++++++++------ lld/wasm/InputChunks.h | 254 +++++++++++++++++++---------------------- lld/wasm/InputFiles.cpp | 6 +- lld/wasm/InputFiles.h | 2 +- lld/wasm/OutputSections.cpp | 2 +- lld/wasm/OutputSegment.cpp | 27 +++-- lld/wasm/OutputSegment.h | 4 +- lld/wasm/SymbolTable.cpp | 2 +- lld/wasm/SymbolTable.h | 3 +- lld/wasm/Symbols.cpp | 6 +- lld/wasm/Symbols.h | 6 +- lld/wasm/SyntheticSections.cpp | 2 +- lld/wasm/Writer.cpp | 10 +- 14 files changed, 214 insertions(+), 213 deletions(-) diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index a0ba04c4fa1e..6fec9d5b2278 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -800,8 +800,8 @@ static void splitSections() { // before calling finalizeContents(). LLVM_DEBUG(llvm::dbgs() << "splitSections\n"); parallelForEach(symtab->objectFiles, [](ObjFile *file) { - for (InputSegment *seg : file->segments) { - if (auto *s = dyn_cast<MergeInputSegment>(seg)) + for (InputChunk *seg : file->segments) { + if (auto *s = dyn_cast<MergeInputChunk>(seg)) s->splitIntoPieces(); } }); diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp index f73e3362ae8e..b7d1aa25e9c8 100644 --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -57,8 +57,37 @@ StringRef InputChunk::getComdatName() const { return file->getWasmObj()->linkingData().Comdats[index]; } +uint32_t InputChunk::getSize() const { + if (const auto *ms = dyn_cast<SyntheticMergedChunk>(this)) + return ms->builder.getSize(); + + if (const auto *f = dyn_cast<InputFunction>(this)) { + if (config->compressRelocations && f->file) { + return f->getCompressedSize(); + } + } + + return data().size(); +} + +uint32_t InputChunk::getInputSize() const { + if (const auto *f = dyn_cast<InputFunction>(this)) + return f->function->Size; + return getSize(); +} + // Copy this input chunk to an mmap'ed output file and apply relocations. void InputChunk::writeTo(uint8_t *buf) const { + if (const auto *f = dyn_cast<InputFunction>(this)) { + if (file && config->compressRelocations) + return f->writeCompressed(buf); + } else if (const auto *ms = dyn_cast<SyntheticMergedChunk>(this)) { + ms->builder.write(buf + outSecOff); + // Apply relocations + ms->relocate(buf + outSecOff); + return; + } + // Copy contents memcpy(buf + outSecOff, data().data(), data().size()); @@ -73,7 +102,7 @@ void InputChunk::relocate(uint8_t *buf) const { LLVM_DEBUG(dbgs() << "applying relocations: " << toString(this) << " count=" << relocations.size() << "\n"); int32_t inputSectionOffset = getInputSectionOffset(); - auto tombstone = getTombstone(); + uint64_t tombstone = getTombstone(); for (const WasmRelocation &rel : relocations) { uint8_t *loc = buf + rel.Offset - inputSectionOffset; @@ -149,6 +178,14 @@ void InputChunk::writeRelocations(raw_ostream &os) const { } } +uint64_t InputChunk::getTombstone() const { + if (const auto *s = dyn_cast<InputSection>(this)) { + return s->tombstoneValue; + } + + return 0; +} + void InputFunction::setFunctionIndex(uint32_t index) { LLVM_DEBUG(dbgs() << "InputFunction::setFunctionIndex: " << getName() << " -> " << index << "\n"); @@ -235,7 +272,7 @@ void InputFunction::calculateSize() { uint32_t start = getInputSectionOffset(); uint32_t end = start + function->Size; - auto tombstone = getTombstone(); + uint64_t tombstone = getTombstone(); uint32_t lastRelocEnd = start + functionSizeLength; for (const WasmRelocation &rel : relocations) { @@ -259,10 +296,7 @@ void InputFunction::calculateSize() { // Override the default writeTo method so that we can (optionally) write the // compressed version of the function. -void InputFunction::writeTo(uint8_t *buf) const { - if (!file || !config->compressRelocations) - return InputChunk::writeTo(buf); - +void InputFunction::writeCompressed(uint8_t *buf) const { buf += outSecOff; uint8_t *orig = buf; (void)orig; @@ -270,7 +304,7 @@ void InputFunction::writeTo(uint8_t *buf) const { const uint8_t *secStart = file->codeSection->Content.data(); const uint8_t *funcStart = secStart + getInputSectionOffset(); const uint8_t *end = funcStart + function->Size; - auto tombstone = getTombstone(); + uint64_t tombstone = getTombstone(); uint32_t count; decodeULEB128(funcStart, &count); funcStart += count; @@ -294,26 +328,30 @@ void InputFunction::writeTo(uint8_t *buf) const { LLVM_DEBUG(dbgs() << " total: " << (buf + chunkSize - orig) << "\n"); } -uint64_t InputSegment::getOffset(uint64_t offset) const { - if (const MergeInputSegment *ms = dyn_cast<MergeInputSegment>(this)) { - LLVM_DEBUG(dbgs() << "getOffset(merged): " << getName() << "\n"); +uint64_t InputChunk::getOffset(uint64_t offset) const { + return outSecOff + offset; +} + +uint64_t InputChunk::getSegmentOffset(uint64_t offset) const { + if (const auto *ms = dyn_cast<MergeInputChunk>(this)) { + LLVM_DEBUG(dbgs() << "getSegmentOffset(merged): " << getName() << "\n"); LLVM_DEBUG(dbgs() << "offset: " << offset << "\n"); LLVM_DEBUG(dbgs() << "parentOffset: " << ms->getParentOffset(offset) << "\n"); assert(ms->parent); - return ms->parent->getOffset(ms->getParentOffset(offset)); + return ms->parent->getSegmentOffset(ms->getParentOffset(offset)); } return outputSegmentOffset + offset; } -uint64_t InputSegment::getVA(uint64_t offset) const { - return (outputSeg ? outputSeg->startVA : 0) + getOffset(offset); +uint64_t InputChunk::getVA(uint64_t offset) const { + return (outputSeg ? outputSeg->startVA : 0) + getSegmentOffset(offset); } // Generate code to apply relocations to the data section at runtime. // This is only called when generating shared libaries (PIC) where address are // not known at static link time. -void InputSegment::generateRelocationCode(raw_ostream &os) const { +void InputChunk::generateRelocationCode(raw_ostream &os) const { LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName() << " count=" << relocations.size() << "\n"); @@ -324,7 +362,7 @@ void InputSegment::generateRelocationCode(raw_ostream &os) const { ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD; - auto tombstone = getTombstone(); + uint64_t tombstone = getTombstone(); // TODO(sbc): Encode the relocations in the data section and write a loop // here to apply them. for (const WasmRelocation &rel : relocations) { @@ -382,7 +420,7 @@ void InputSegment::generateRelocationCode(raw_ostream &os) const { // Split WASM_SEG_FLAG_STRINGS section. Such a section is a sequence of // null-terminated strings. -void MergeInputSegment::splitStrings(ArrayRef<uint8_t> data) { +void MergeInputChunk::splitStrings(ArrayRef<uint8_t> data) { LLVM_DEBUG(llvm::dbgs() << "splitStrings\n"); size_t off = 0; StringRef s = toStringRef(data); @@ -405,15 +443,15 @@ void MergeInputSegment::splitStrings(ArrayRef<uint8_t> data) { // // Note that this function is called from parallelForEach. This must be // thread-safe (i.e. no memory allocation from the pools). -void MergeInputSegment::splitIntoPieces() { +void MergeInputChunk::splitIntoPieces() { assert(pieces.empty()); // As of now we only support WASM_SEG_FLAG_STRINGS but in the future we // could add other types of splitting (see ELF's splitIntoPieces). - assert(segment->Data.LinkingFlags & WASM_SEG_FLAG_STRINGS); + assert(flags & WASM_SEG_FLAG_STRINGS); splitStrings(data()); } -SegmentPiece *MergeInputSegment::getSegmentPiece(uint64_t offset) { +SectionPiece *MergeInputChunk::getSectionPiece(uint64_t offset) { if (this->data().size() <= offset) fatal(toString(this) + ": offset is outside the section"); @@ -421,36 +459,25 @@ SegmentPiece *MergeInputSegment::getSegmentPiece(uint64_t offset) { // In that case we need to do a binary search of the original section piece // vector. auto it = partition_point( - pieces, [=](SegmentPiece p) { return p.inputOff <= offset; }); + pieces, [=](SectionPiece p) { return p.inputOff <= offset; }); return &it[-1]; } // Returns the offset in an output section for a given input offset. // Because contents of a mergeable section is not contiguous in output, // it is not just an addition to a base output offset. -uint64_t MergeInputSegment::getParentOffset(uint64_t offset) const { +uint64_t MergeInputChunk::getParentOffset(uint64_t offset) const { // If Offset is not at beginning of a section piece, it is not in the map. // In that case we need to search from the original section piece vector. - const SegmentPiece *piece = getSegmentPiece(offset); + const SectionPiece *piece = getSectionPiece(offset); uint64_t addend = offset - piece->inputOff; return piece->outputOff + addend; } -uint32_t SyntheticMergedDataSegment::getSize() const { - return builder.getSize(); -} - -void SyntheticMergedDataSegment::writeTo(uint8_t *buf) const { - builder.write(buf + outSecOff); - - // Apply relocations - relocate(buf + outSecOff); -} - -void SyntheticMergedDataSegment::finalizeContents() { +void SyntheticMergedChunk::finalizeContents() { // Add all string pieces to the string table builder to create section // contents. - for (MergeInputSegment *sec : segments) + for (MergeInputChunk *sec : chunks) for (size_t i = 0, e = sec->pieces.size(); i != e; ++i) if (sec->pieces[i].live) builder.add(sec->getData(i)); @@ -461,7 +488,7 @@ void SyntheticMergedDataSegment::finalizeContents() { // finalize() fixed tail-optimized strings, so we can now get // offsets of strings. Get an offset for each string and save it // to a corresponding SectionPiece for easy access. - for (MergeInputSegment *sec : segments) + for (MergeInputChunk *sec : chunks) for (size_t i = 0, e = sec->pieces.size(); i != e; ++i) if (sec->pieces[i].live) sec->pieces[i].outputOff = builder.getOffset(sec->getData(i)); diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h index 5bf96df695d5..47ed7ccaadcb 100644 --- a/lld/wasm/InputChunks.h +++ b/lld/wasm/InputChunks.h @@ -40,40 +40,68 @@ public: enum Kind { DataSegment, Merge, - MergedSegment, + MergedChunk, Function, SyntheticFunction, Section }; - Kind kind() const { return sectionKind; } + StringRef name; + StringRef debugName; + + StringRef getName() const { return name; } + StringRef getDebugName() const { return debugName; } + Kind kind() const { return (Kind)sectionKind; } - virtual uint32_t getSize() const { return data().size(); } - virtual uint32_t getInputSize() const { return getSize(); }; + uint32_t getSize() const; + uint32_t getInputSize() const; - virtual void writeTo(uint8_t *buf) const; + void writeTo(uint8_t *buf) const; void relocate(uint8_t *buf) const; ArrayRef<WasmRelocation> getRelocations() const { return relocations; } void setRelocations(ArrayRef<WasmRelocation> rs) { relocations = rs; } - uint64_t getOffset(uint64_t offset) const { return outSecOff + offset; } - virtual StringRef getName() const = 0; - virtual StringRef getDebugName() const = 0; - virtual uint32_t getComdat() const = 0; + // Translate an offset in the input section to an offset in the output + // section. + uint64_t getOffset(uint64_t offset) const; + // For data segments, translate and offset into the input segment into + // an offset into the output segment + uint64_t getSegmentOffset(uint64_t offset) const; + uint64_t getVA(uint64_t offset = 0) const; + + uint32_t getComdat() const { return comdat; } StringRef getComdatName() const; - virtual uint32_t getInputSectionOffset() const = 0; + uint32_t getInputSectionOffset() const { return inputSectionOffset; } size_t getNumRelocations() const { return relocations.size(); } void writeRelocations(llvm::raw_ostream &os) const; + void generateRelocationCode(raw_ostream &os) const; + + bool isTLS() const { + // Older object files don't include WASM_SEG_FLAG_TLS and instead + // relied on the naming convention. + return flags & llvm::wasm::WASM_SEG_FLAG_TLS || name.startswith(".tdata") || + name.startswith(".tbss"); + } ObjFile *file; OutputSection *outputSec = nullptr; + uint32_t comdat = UINT32_MAX; + uint32_t inputSectionOffset = 0; + uint32_t alignment; + uint32_t flags; + + // Only applies to data segments. + uint32_t outputSegmentOffset = 0; + const OutputSegment *outputSeg = nullptr; // After assignAddresses is called, this represents the offset from // the beginning of the output section this chunk was assigned to. int32_t outSecOff = 0; + uint8_t sectionKind : 3; + // Signals that the section is part of the output. The garbage collector, // and COMDAT handling can set a sections' Live bit. // If GC is disabled, all sections start out as live by default. @@ -83,14 +111,15 @@ public: unsigned discarded : 1; protected: - InputChunk(ObjFile *f, Kind k) - : file(f), live(!config->gcSections), discarded(false), sectionKind(k) {} - virtual ~InputChunk() = default; - virtual ArrayRef<uint8_t> data() const = 0; - virtual uint64_t getTombstone() const { return 0; } + InputChunk(ObjFile *f, Kind k, StringRef name, uint32_t alignment = 0, + uint32_t flags = 0) + : name(name), file(f), alignment(alignment), flags(flags), sectionKind(k), + live(!config->gcSections), discarded(false) {} + ArrayRef<uint8_t> data() const { return rawData; } + uint64_t getTombstone() const; ArrayRef<WasmRelocation> relocations; - Kind sectionKind; + ArrayRef<uint8_t> rawData; }; // Represents a WebAssembly data segment which can be included as part of @@ -104,64 +133,34 @@ protected: class InputSegment : public InputChunk { public: InputSegment(const WasmSegment *seg, ObjFile *f) - : InputChunk(f, InputChunk::DataSegment), segment(seg) { - alignment = segment->Data.Alignment; - flags = segment->Data.LinkingFlags; - } - - InputSegment(uint32_t alignment, uint32_t flags) - : InputChunk(nullptr, InputChunk::DataSegment), alignment(alignment), - flags(flags) {} - - static bool classof(const InputChunk *c) { - return c->kind() == DataSegment || c->kind() == Merge || - c->kind() == MergedSegment; - } - - void generateRelocationCode(raw_ostream &os) const; - - StringRef getName() const override { return segment->Data.Name; } - StringRef getDebugName() const override { return StringRef(); } - uint32_t getComdat() const override { return segment->Data.Comdat; } - uint32_t getInputSectionOffset() const override { - return segment->SectionOffset; + : InputChunk(f, InputChunk::DataSegment, seg->Data.Name, + seg->Data.Alignment, seg->Data.LinkingFlags), + segment(seg) { + rawData = segment->Data.Content; + comdat = segment->Data.Comdat; + inputSectionOffset = segment->SectionOffset; } - // Translate an offset in the input section to an offset in the output - // section. - uint64_t getOffset(uint64_t offset) const; - - uint64_t getVA(uint64_t offset = 0) const; - - bool isTLS() const { - // Older object files don't include WASM_SEG_FLAG_TLS and instead - // relied on the naming convention. - return flags & llvm::wasm::WASM_SEG_FLAG_TLS || - getName().startswith(".tdata") || getName().startswith(".tbss"); - } + InputSegment(StringRef name, uint32_t alignment, uint32_t flags) + : InputChunk(nullptr, InputChunk::DataSegment, name, alignment, flags) {} - const OutputSegment *outputSeg = nullptr; - uint32_t outputSegmentOffset = 0; - uint32_t alignment = 0; - uint32_t flags = 0; + static bool classof(const InputChunk *c) { return c->kind() == DataSegment; } protected: - ArrayRef<uint8_t> data() const override { return segment->Data.Content; } - const WasmSegment *segment = nullptr; }; -class SyntheticMergedDataSegment; +class SyntheticMergedChunk; // Merge segment handling copied from lld/ELF/InputSection.h. Keep in sync // where possible. -// SegmentPiece represents a piece of splittable segment contents. +// SectionPiece represents a piece of splittable segment contents. // We allocate a lot of these and binary search on them. This means that they // have to be as compact as possible, which is why we don't store the size (can // be found by looking at the next one). -struct SegmentPiece { - SegmentPiece(size_t off, uint32_t hash, bool live) +struct SectionPiece { + SectionPiece(size_t off, uint32_t hash, bool live) : inputOff(off), live(live || !config->gcSections), hash(hash >> 1) {} uint32_t inputOff; @@ -170,13 +169,17 @@ struct SegmentPiece { uint64_t outputOff = 0; }; -static_assert(sizeof(SegmentPiece) == 16, "SectionPiece is too big"); +static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big"); // This corresponds segments marked as WASM_SEG_FLAG_STRINGS. -class MergeInputSegment : public InputSegment { +class MergeInputChunk : public InputChunk { public: - MergeInputSegment(const WasmSegment *seg, ObjFile *f) : InputSegment(seg, f) { - sectionKind = Merge; + MergeInputChunk(const WasmSegment *seg, ObjFile *f) + : InputChunk(f, Merge, seg->Data.Name, seg->Data.Alignment, + seg->Data.LinkingFlags) { + rawData = seg->Data.Content; + comdat = seg->Data.Comdat; + inputSectionOffset = seg->SectionOffset; } static bool classof(const InputChunk *s) { return s->kind() == Merge; } @@ -188,7 +191,7 @@ public: // Splittable sections are handled as a sequence of data // rather than a single large blob of data. - std::vector<SegmentPiece> pieces; + std::vector<SectionPiece> pieces; // Returns I'th piece's data. This function is very hot when // string merging is enabled, so we want to inline. @@ -201,52 +204,43 @@ public: } // Returns the SectionPiece at a given input section offset. - SegmentPiece *getSegmentPiece(uint64_t offset); - const SegmentPiece *getSegmentPiece(uint64_t offset) const { - return const_cast<MergeInputSegment *>(this)->getSegmentPiece(offset); + SectionPiece *getSectionPiece(uint64_t offset); + const SectionPiece *getSectionPiece(uint64_t offset) const { + return const_cast<MergeInputChunk *>(this)->getSectionPiece(offset); } - SyntheticMergedDataSegment *parent = nullptr; + SyntheticMergedChunk *parent = nullptr; private: void splitStrings(ArrayRef<uint8_t> a); }; -// SyntheticMergedDataSegment is a class that allows us to put mergeable +// SyntheticMergedChunk is a class that allows us to put mergeable // sections with different attributes in a single output sections. To do that we -// put them into SyntheticMergedDataSegment synthetic input sections which are +// put them into SyntheticMergedChunk synthetic input sections which are // attached to regular output sections. -class SyntheticMergedDataSegment : public InputSegment { +class SyntheticMergedChunk : public InputChunk { public: - SyntheticMergedDataSegment(StringRef name, uint32_t alignment, uint32_t flags) - : InputSegment(alignment, flags), name(name), - builder(llvm::StringTableBuilder::RAW, 1ULL << alignment) { - sectionKind = InputChunk::MergedSegment; - } + SyntheticMergedChunk(StringRef name, uint32_t alignment, uint32_t flags) + : InputChunk(nullptr, InputChunk::MergedChunk, name, alignment, flags), + builder(llvm::StringTableBuilder::RAW, 1ULL << alignment) {} static bool classof(const InputChunk *c) { - return c->kind() == InputChunk::MergedSegment; + return c->kind() == InputChunk::MergedChunk; } - uint32_t getSize() const override; - - StringRef getName() const override { return name; } - - uint32_t getComdat() const override { return segments[0]->getComdat(); } - - void writeTo(uint8_t *buf) const override; - - void addMergeSegment(MergeInputSegment *ms) { + void addMergeChunk(MergeInputChunk *ms) { + comdat = ms->getComdat(); ms->parent = this; - segments.push_back(ms); + chunks.push_back(ms); } void finalizeContents(); -protected: - std::vector<MergeInputSegment *> segments; - StringRef name; llvm::StringTableBuilder builder; + +protected: + std::vector<MergeInputChunk *> chunks; }; // Represents a single wasm function within and input file. These are @@ -254,44 +248,39 @@ protected: class InputFunction : public InputChunk { public: InputFunction(const WasmSignature &s, const WasmFunction *func, ObjFile *f) - : InputChunk(f, InputChunk::Function), signature(s), function(func), - exportName(func && func->ExportName.hasValue() - ? (*func->ExportName).str() - : llvm::Optional<std::string>()) {} + : InputChunk(f, InputChunk::Function, func->SymbolName), signature(s), + function(func), exportName(func && func->ExportName.hasValue() + ? (*func->ExportName).str() + : llvm::Optional<std::string>()) { + inputSectionOffset = function->CodeSectionOffset; + rawData = + file->codeSection->Content.slice(inputSectionOffset, function->Size); + debugName = function->DebugName; + comdat = function->Comdat; + } + + InputFunction(StringRef name, const WasmSignature &s) + : InputChunk(nullptr, InputChunk::Function, name), signature(s) {} static bool classof(const InputChunk *c) { return c->kind() == InputChunk::Function || c->kind() == InputChunk::SyntheticFunction; } - void writeTo(uint8_t *buf) const override; - StringRef getName() const override { return function->SymbolName; } - StringRef getDebugName() const override { return function->DebugName; } llvm::Optional<StringRef> getExportName() const { return exportName.hasValue() ? llvm::Optional<StringRef>(*exportName) : llvm::Optional<StringRef>(); } void setExportName(std::string exportName) { this->exportName = exportName; } - uint32_t getComdat() const override { return function->Comdat; } uint32_t getFunctionInputOffset() const { return getInputSectionOffset(); } uint32_t getFunctionCodeOffset() const { return function->CodeOffset; } - uint32_t getSize() const override { - if (config->compressRelocations && file) { - assert(compressedSize); - return compressedSize; - } - return data().size(); - } - uint32_t getInputSize() const override { return function->Size; } uint32_t getFunctionIndex() const { return functionIndex.getValue(); } bool hasFunctionIndex() const { return functionIndex.hasValue(); } void setFunctionIndex(uint32_t index); - uint32_t getInputSectionOffset() const override { - return function->CodeSectionOffset; - } uint32_t getTableIndex() const { return tableIndex.getValue(); } bool hasTableIndex() const { return tableIndex.hasValue(); } void setTableIndex(uint32_t index); + void writeCompressed(uint8_t *buf) const; // The size of a given input function can depend on the values of the // LEB relocations within it. This finalizeContents method is called after @@ -301,14 +290,14 @@ public: const WasmSignature &signature; -protected: - ArrayRef<uint8_t> data() const override { - assert(!config->compressRelocations); - return file->codeSection->Content.slice(getInputSectionOffset(), - function->Size); + uint32_t getCompressedSize() const { + assert(compressedSize); + return compressedSize; } const WasmFunction *function; + +protected: llvm::Optional<std::string> exportName; llvm::Optional<uint32_t> functionIndex; llvm::Optional<uint32_t> tableIndex; @@ -320,51 +309,38 @@ class SyntheticFunction : public InputFunction { public: SyntheticFunction(const WasmSignature &s, StringRef name, StringRef debugName = {}) - : InputFunction(s, nullptr, nullptr), name(name), debugName(debugName) { + : InputFunction(name, s) { sectionKind = InputChunk::SyntheticFunction; + this->debugName = debugName; } static bool classof(const InputChunk *c) { return c->kind() == InputChunk::SyntheticFunction; } - StringRef getName() const override { return name; } - StringRef getDebugName() const override { return debugName; } - uint32_t getComdat() const override { return UINT32_MAX; } - - void setBody(ArrayRef<uint8_t> body_) { body = body_; } - -protected: - ArrayRef<uint8_t> data() const override { return body; } - - StringRef name; - StringRef debugName; - ArrayRef<uint8_t> body; + void setBody(ArrayRef<uint8_t> body) { rawData = body; } }; // Represents a single Wasm Section within an input file. class InputSection : public InputChunk { public: InputSection(const WasmSection &s, ObjFile *f) - : InputChunk(f, InputChunk::Section), section(s), tombstoneValue(getTombstoneForSection(s.Name)) { + : InputChunk(f, InputChunk::Section, s.Name), + tombstoneValue(getTombstoneForSection(s.Name)), section(s) { assert(section.Type == llvm::wasm::WASM_SEC_CUSTOM); + comdat = section.Comdat; + rawData = section.Content; } - StringRef getName() const override { return section.Name; } - StringRef getDebugName() const override { return StringRef(); } - uint32_t getComdat() const override { return section.Comdat; } + static bool classof(const InputChunk *c) { + return c->kind() == InputChunk::Section; + } -protected: - ArrayRef<uint8_t> data() const override { return section.Content; } + const uint64_t tombstoneValue; - // Offset within the input section. This is only zero since this chunk - // type represents an entire input section, not part of one. - uint32_t getInputSectionOffset() const override { return 0; } - uint64_t getTombstone() const override { return tombstoneValue; } +protected: static uint64_t getTombstoneForSection(StringRef name); - const WasmSection §ion; - const uint64_t tombstoneValue; }; } // namespace wasm diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index 2cb5d59286e3..c65b05109c3d 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -464,9 +464,9 @@ void ObjFile::parse(bool ignoreComdats) { // Populate `Segments`. for (const WasmSegment &s : wasmObj->dataSegments()) { - InputSegment *seg; + InputChunk *seg; if (shouldMerge(s)) { - seg = make<MergeInputSegment>(&s, this); + seg = make<MergeInputChunk>(&s, this); } else seg = make<InputSegment>(&s, this); seg->discarded = isExcludedByComdat(seg); @@ -568,7 +568,7 @@ Symbol *ObjFile::createDefined(const WasmSymbol &sym) { return symtab->addDefinedFunction(name, flags, this, func); } case WASM_SYMBOL_TYPE_DATA: { - InputSegment *seg = segments[sym.Info.DataRef.Segment]; + InputChunk *seg = segments[sym.Info.DataRef.Segment]; auto offset = sym.Info.DataRef.Offset; auto size = sym.Info.DataRef.Size; if (sym.isBindingLocal()) diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h index dab44cd6830c..b720b889adcc 100644 --- a/lld/wasm/InputFiles.h +++ b/lld/wasm/InputFiles.h @@ -136,7 +136,7 @@ public: std::vector<uint32_t> tableEntries; std::vector<uint32_t> tableEntriesRel; std::vector<bool> keptComdats; - std::vector<InputSegment *> segments; + std::vector<InputChunk *> segments; std::vector<InputFunction *> functions; std::vector<InputGlobal *> globals; std::vector<InputEvent *> events; diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp index 6d91708d326a..780c8e4b2776 100644 --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -178,7 +178,7 @@ void DataSection::finalizeContents() { log("Data segment: size=" + Twine(segment->size) + ", startVA=" + Twine::utohexstr(segment->startVA) + ", name=" + segment->name); - for (InputSegment *inputSeg : segment->inputSegments) { + for (InputChunk *inputSeg : segment->inputSegments) { inputSeg->outputSec = this; inputSeg->outSecOff = segment->sectionOffset + segment->header.size() + inputSeg->outputSegmentOffset; diff --git a/lld/wasm/OutputSegment.cpp b/lld/wasm/OutputSegment.cpp index 899308e87c94..bf3e40c968a0 100644 --- a/lld/wasm/OutputSegment.cpp +++ b/lld/wasm/OutputSegment.cpp @@ -19,7 +19,7 @@ namespace lld { namespace wasm { -void OutputSegment::addInputSegment(InputSegment *inSeg) { +void OutputSegment::addInputSegment(InputChunk *inSeg) { alignment = std::max(alignment, inSeg->alignment); inputSegments.push_back(inSeg); size = llvm::alignTo(size, 1ULL << inSeg->alignment); @@ -33,16 +33,16 @@ void OutputSegment::addInputSegment(InputSegment *inSeg) { // This function scans over the input segments. // -// It removes MergeInputSegments from the input section array and adds +// It removes MergeInputChunks from the input section array and adds // new synthetic sections at the location of the first input section // that it replaces. It then finalizes each synthetic section in order // to compute an output offset for each piece of each input section. void OutputSegment::finalizeInputSegments() { LLVM_DEBUG(llvm::dbgs() << "finalizeInputSegments: " << name << "\n"); - std::vector<SyntheticMergedDataSegment *> mergedSegments; - std::vector<InputSegment *> newSegments; - for (InputSegment *s : inputSegments) { - MergeInputSegment *ms = dyn_cast<MergeInputSegment>(s); + std::vector<SyntheticMergedChunk *> mergedSegments; + std::vector<InputChunk *> newSegments; + for (InputChunk *s : inputSegments) { + MergeInputChunk *ms = dyn_cast<MergeInputChunk>(s); if (!ms) { newSegments.push_back(s); continue; @@ -51,15 +51,14 @@ void OutputSegment::finalizeInputSegments() { // A segment should not make it here unless its alive assert(ms->live); - auto i = - llvm::find_if(mergedSegments, [=](SyntheticMergedDataSegment *seg) { - return seg->flags == ms->flags && seg->alignment == ms->alignment; - }); + auto i = llvm::find_if(mergedSegments, [=](SyntheticMergedChunk *seg) { + return seg->flags == ms->flags && seg->alignment == ms->alignment; + }); if (i == mergedSegments.end()) { LLVM_DEBUG(llvm::dbgs() << "new merge section: " << name << " alignment=" << ms->alignment << "\n"); - SyntheticMergedDataSegment *syn = - make<SyntheticMergedDataSegment>(name, ms->alignment, ms->flags); + SyntheticMergedChunk *syn = + make<SyntheticMergedChunk>(name, ms->alignment, ms->flags); syn->outputSeg = this; mergedSegments.push_back(syn); i = std::prev(mergedSegments.end()); @@ -67,7 +66,7 @@ void OutputSegment::finalizeInputSegments() { } else { LLVM_DEBUG(llvm::dbgs() << "adding to merge section: " << name << "\n"); } - (*i)->addMergeSegment(ms); + (*i)->addMergeChunk(ms); } for (auto *ms : mergedSegments) @@ -75,7 +74,7 @@ void OutputSegment::finalizeInputSegments() { inputSegments = newSegments; size = 0; - for (InputSegment *seg : inputSegments) { + for (InputChunk *seg : inputSegments) { size = llvm::alignTo(size, 1ULL << seg->alignment); LLVM_DEBUG(llvm::dbgs() << "outputSegmentOffset set: " << seg->getName() << " -> " << size << "\n"); diff --git a/lld/wasm/OutputSegment.h b/lld/wasm/OutputSegment.h index 10e28a4a8836..1d5cf9145241 100644 --- a/lld/wasm/OutputSegment.h +++ b/lld/wasm/OutputSegment.h @@ -22,7 +22,7 @@ class OutputSegment { public: OutputSegment(StringRef n) : name(n) {} - void addInputSegment(InputSegment *inSeg); + void addInputSegment(InputChunk *inSeg); void finalizeInputSegments(); bool isTLS() const { return name == ".tdata"; } @@ -35,7 +35,7 @@ public: uint32_t sectionOffset = 0; uint32_t alignment = 0; uint64_t startVA = 0; - std::vector<InputSegment *> inputSegments; + std::vector<InputChunk *> inputSegments; // Sum of the size of the all the input segments uint32_t size = 0; diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp index 56438c7b5d99..7e794a1bd431 100644 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -365,7 +365,7 @@ Symbol *SymbolTable::addDefinedFunction(StringRef name, uint32_t flags, } Symbol *SymbolTable::addDefinedData(StringRef name, uint32_t flags, - InputFile *file, InputSegment *segment, + InputFile *file, InputChunk *segment, uint64_t address, uint64_t size) { LLVM_DEBUG(dbgs() << "addDefinedData:" << name << " addr:" << address << "\n"); diff --git a/lld/wasm/SymbolTable.h b/lld/wasm/SymbolTable.h index 36c776be30f5..bee18ce9c6bd 100644 --- a/lld/wasm/SymbolTable.h +++ b/lld/wasm/SymbolTable.h @@ -54,8 +54,7 @@ public: Symbol *addDefinedFunction(StringRef name, uint32_t flags, InputFile *file, InputFunction *function); Symbol *addDefinedData(StringRef name, uint32_t flags, InputFile *file, - InputSegment *segment, uint64_t address, - uint64_t size); + InputChunk *segment, uint64_t address, uint64_t size); Symbol *addDefinedGlobal(StringRef name, uint32_t flags, InputFile *file, InputGlobal *g); Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file, diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index 00fe754e3eaa..24b7e10dc559 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -160,8 +160,8 @@ void Symbol::markLive() { // (splittable) sections, each piece of data has independent liveness bit. // So we explicitly tell it which offset is in use. if (auto *d = dyn_cast<DefinedData>(this)) { - if (auto *ms = dyn_cast<MergeInputSegment>(c)) { - ms->getSegmentPiece(d->value)->live = true; + if (auto *ms = dyn_cast<MergeInputChunk>(c)) { + ms->getSectionPiece(d->value)->live = true; } } c->live = true; @@ -301,7 +301,7 @@ void DefinedData::setVA(uint64_t value_) { uint64_t DefinedData::getOutputSegmentOffset() const { LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n"); - return segment->getOffset(value); + return segment->getSegmentOffset(value); } uint64_t DefinedData::getOutputSegmentIndex() const { diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index 8bc3be0d2247..ff6eb0ae7ccb 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -278,8 +278,8 @@ protected: class DefinedData : public DataSymbol { public: // Constructor for regular data symbols originating from input files. - DefinedData(StringRef name, uint32_t flags, InputFile *f, - InputSegment *segment, uint64_t value, uint64_t size) + DefinedData(StringRef name, uint32_t flags, InputFile *f, InputChunk *segment, + uint64_t value, uint64_t size) : DataSymbol(name, DefinedDataKind, flags, f), segment(segment), value(value), size(size) {} @@ -298,7 +298,7 @@ public: uint64_t getOutputSegmentIndex() const; uint64_t getSize() const { return size; } - InputSegment *segment = nullptr; + InputChunk *segment = nullptr; uint64_t value = 0; protected: diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp index 4439761df9f9..b10ecc04b4b2 100644 --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -569,7 +569,7 @@ void LinkingSection::writeBody() { continue; StringRef comdat = inputSegments[0]->getComdatName(); #ifndef NDEBUG - for (const InputSegment *isec : inputSegments) + for (const InputChunk *isec : inputSegments) assert(isec->getComdatName() == comdat); #endif if (!comdat.empty()) diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 08149bc605a2..055972560b81 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -460,7 +460,7 @@ void Writer::populateTargetFeatures() { } // Find TLS data segments - auto isTLS = [](InputSegment *segment) { + auto isTLS = [](InputChunk *segment) { return segment->live && segment->isTLS(); }; tlsUsed = tlsUsed || @@ -816,7 +816,7 @@ void Writer::assignIndexes() { out.tableSec->assignIndexes(); } -static StringRef getOutputDataSegmentName(const InputSegment &seg) { +static StringRef getOutputDataSegmentName(const InputChunk &seg) { // We always merge .tbss and .tdata into a single TLS segment so all TLS // symbols are be relative to single __tls_base. if (seg.isTLS()) @@ -852,7 +852,7 @@ OutputSegment *Writer::createOutputSegment(StringRef name) { void Writer::createOutputSegments() { for (ObjFile *file : symtab->objectFiles) { - for (InputSegment *segment : file->segments) { + for (InputChunk *segment : file->segments) { if (!segment->live) continue; StringRef name = getOutputDataSegmentName(*segment); @@ -919,7 +919,7 @@ void Writer::combineOutputSegments() { combined->initFlags = WASM_DATA_SEGMENT_IS_PASSIVE; } bool first = true; - for (InputSegment *inSeg : s->inputSegments) { + for (InputChunk *inSeg : s->inputSegments) { if (first) inSeg->alignment = std::max(inSeg->alignment, s->alignment); first = false; @@ -1201,7 +1201,7 @@ void Writer::createApplyDataRelocationsFunction() { raw_string_ostream os(bodyContent); writeUleb128(os, 0, "num locals"); for (const OutputSegment *seg : segments) - for (const InputSegment *inSeg : seg->inputSegments) + for (const InputChunk *inSeg : seg->inputSegments) inSeg->generateRelocationCode(os); writeU8(os, WASM_OPCODE_END, "END"); </cut>
3 years, 4 months
1
0
0
0
[CI-NOTIFY]: TCWG Bisect tcwg_bmk_apm/gnu-release-aarch64-spec2k6-Os_LTO - Build # 1 - Successful!
by ci_notify@linaro.org
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_gnu_apm/gnu-release-aarch64-spec2k6-Os_LTO. So far, this commit has regressed CI configurations: - tcwg_bmk_gnu_apm/gnu-release-aarch64-spec2k6-Os_LTO Culprit: <cut> commit ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4 Author: Martin Jambor <mjambor(a)suse.cz> Date: Fri Sep 20 00:25:04 2019 +0200 New IPA-SRA 2019-09-20 Martin Jambor <mjambor(a)suse.cz> * coretypes.h (cgraph_edge): Declare. * ipa-param-manipulation.c: Rewrite. * ipa-param-manipulation.h: Likewise. * Makefile.in (GTFILES): Added ipa-param-manipulation.h and ipa-sra.c. (OBJS): Added ipa-sra.o. * cgraph.h (ipa_replace_map): Removed fields old_tree, replace_p and ref_p, added fields param_adjustments and performed_splits. (struct cgraph_clone_info): Remove ags_to_skip and combined_args_to_skip, new field param_adjustments. (cgraph_node::create_clone): Changed parameters to use ipa_param_adjustments. (cgraph_node::create_virtual_clone): Likewise. (cgraph_node::create_virtual_clone_with_body): Likewise. (tree_function_versioning): Likewise. (cgraph_build_function_type_skip_args): Removed. * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Convert to using ipa_param_adjustments. (clone_of_p): Likewise. * cgraphclones.c (cgraph_build_function_type_skip_args): Removed. (build_function_decl_skip_args): Likewise. (duplicate_thunk_for_node): Adjust parameters using ipa_param_body_adjustments, copy param_adjustments instead of args_to_skip. (cgraph_node::create_clone): Convert to using ipa_param_adjustments. (cgraph_node::create_virtual_clone): Likewise. (cgraph_node::create_version_clone_with_body): Likewise. (cgraph_materialize_clone): Likewise. (symbol_table::materialize_all_clones): Likewise. * ipa-fnsummary.c (ipa_fn_summary_t::duplicate): Simplify ipa_replace_map check. * ipa-cp.c (get_replacement_map): Do not initialize removed fields. (initialize_node_lattices): Make aware that some parameters might have already been removed. (want_remove_some_param_p): New function. (create_specialized_node): Convert to using ipa_param_adjustments and deal with possibly pre-existing adjustments. * lto-cgraph.c (output_cgraph_opt_summary_p): Likewise. (output_node_opt_summary): Do not stream removed fields. Stream parameter adjustments instead of argumetns to skip. (input_node_opt_summary): Likewise. (input_node_opt_summary): Likewise. * lto-section-in.c (lto_section_name): Added ipa-sra section. * lto-streamer.h (lto_section_type): Likewise. * tree-inline.h (copy_body_data): New fields killed_new_ssa_names and param_body_adjs. (copy_decl_to_var): Declare. * tree-inline.c (update_clone_info): Do not remap old_tree. (remap_gimple_stmt): Use ipa_param_body_adjustments to modify gimple statements, walk all extra generated statements and remap their operands. (redirect_all_calls): Add killed SSA names to a hash set. (remap_ssa_name): Do not remap killed SSA names. (copy_arguments_for_versioning): Renames to copy_arguments_nochange, half of functionality moved to ipa_param_body_adjustments. (copy_decl_to_var): Make exported. (copy_body): Destroy killed_new_ssa_names hash set. (expand_call_inline): Remap performed splits. (update_clone_info): Likewise. (tree_function_versioning): Simplify tree_map processing. Updated to accept ipa_param_adjustments and use ipa_param_body_adjustments. * omp-simd-clone.c (simd_clone_vector_of_formal_parm_types): Adjust for the new interface. (simd_clone_clauses_extract): Likewise, make args an auto_vec. (simd_clone_compute_base_data_type): Likewise. (simd_clone_init_simd_arrays): Adjust for the new interface. (simd_clone_adjust_argument_types): Likewise. (struct modify_stmt_info): Likewise. (ipa_simd_modify_stmt_ops): Likewise. (ipa_simd_modify_function_body): Likewise. (simd_clone_adjust): Likewise. * tree-sra.c: Removed IPA-SRA. Include tree-sra.h. (type_internals_preclude_sra_p): Make public. * tree-sra.h: New file. * ipa-inline-transform.c (save_inline_function_body): Update to refelct new tree_function_versioning signature. * ipa-prop.c (adjust_agg_replacement_values): Use a helper from ipa_param_adjustments to get current parameter indices. (ipcp_modif_dom_walker::before_dom_children): Likewise. (ipcp_update_bits): Likewise. (ipcp_update_vr): Likewise. * ipa-split.c (split_function): Convert to using ipa_param_adjustments. * ipa-sra.c: New file. * multiple_target.c (create_target_clone): Update to reflet new type of create_version_clone_with_body. * trans-mem.c (ipa_tm_create_version): Update to reflect new type of tree_function_versioning. (modify_function): Update to reflect new type of tree_function_versioning. * params.def (PARAM_IPA_SRA_MAX_REPLACEMENTS): New. * passes.def: Remove old IPA-SRA and add new one. * tree-pass.h (make_pass_early_ipa_sra): Remove declaration. (make_pass_ipa_sra): Declare. * dbgcnt.def: Remove eipa_sra. Added ipa_sra_params and ipa_sra_retvalues. * doc/invoke.texi (ipa-sra-max-replacements): New. testsuite/ * g++.dg/ipa/pr81248.C: Adjust dg-options and dump-scan. * gcc.dg/ipa/ipa-sra-1.c: Likewise. * gcc.dg/ipa/ipa-sra-10.c: Likewise. * gcc.dg/ipa/ipa-sra-11.c: Likewise. * gcc.dg/ipa/ipa-sra-3.c: Likewise. * gcc.dg/ipa/ipa-sra-4.c: Likewise. * gcc.dg/ipa/ipa-sra-5.c: Likewise. * gcc.dg/ipa/ipacost-2.c: Disable ipa-sra. * gcc.dg/ipa/ipcp-agg-9.c: Likewise. * gcc.dg/ipa/pr78121.c: Adjust scan pattern. * gcc.dg/ipa/vrp1.c: Likewise. * gcc.dg/ipa/vrp2.c: Likewise. * gcc.dg/ipa/vrp3.c: Likewise. * gcc.dg/ipa/vrp7.c: Likewise. * gcc.dg/ipa/vrp8.c: Likewise. * gcc.dg/noreorder.c: use noipa attribute instead of noinline. * gcc.dg/ipa/20040703-wpa.c: New test. * gcc.dg/ipa/ipa-sra-12.c: New test. * gcc.dg/ipa/ipa-sra-13.c: Likewise. * gcc.dg/ipa/ipa-sra-14.c: Likewise. * gcc.dg/ipa/ipa-sra-15.c: Likewise. * gcc.dg/ipa/ipa-sra-16.c: Likewise. * gcc.dg/ipa/ipa-sra-17.c: Likewise. * gcc.dg/ipa/ipa-sra-18.c: Likewise. * gcc.dg/ipa/ipa-sra-19.c: Likewise. * gcc.dg/ipa/ipa-sra-20.c: Likewise. * gcc.dg/ipa/ipa-sra-21.c: Likewise. * gcc.dg/ipa/ipa-sra-22.c: Likewise. * gcc.dg/sso/ipa-sra-1.c: Likewise. * g++.dg/ipa/ipa-sra-2.C: Likewise. * g++.dg/ipa/ipa-sra-3.C: Likewise. * gcc.dg/tree-ssa/ipa-cp-1.c: Make return value used. * g++.dg/ipa/devirt-19.C: Add missing return, add -fipa-cp-clone option. * g++.dg/lto/devirt-19_0.C: Add -fipa-cp-clone option. * gcc.dg/ipa/ipa-sra-2.c: Removed. * gcc.dg/ipa/ipa-sra-6.c: Likewise. From-SVN: r275982 </cut> Results regressed to (for first_bad == ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # true: 0 # benchmark -Os_LTO -- artifacts/build-ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4/results_id: 1 # 450.soplex,soplex_base.default regressed by 103 from (for last_good == 6889a3acfeed47265886676c6d43b04ef799fb82) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer: -5 # true: 0 # benchmark -Os_LTO -- artifacts/build-6889a3acfeed47265886676c6d43b04ef799fb82/results_id: 1 Artifacts of last_good build:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
Results ID of last_good: apm_64/tcwg_bmk_gnu_apm/bisect-gnu-release-aarch64-spec2k6-Os_LTO/2526 Artifacts of first_bad build:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
Results ID of first_bad: apm_64/tcwg_bmk_gnu_apm/bisect-gnu-release-aarch64-spec2k6-Os_LTO/2531 Build top page/logs:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
Configuration details: Reproduce builds: <cut> mkdir investigate-gcc-ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4 cd investigate-gcc-ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4 git clone
https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
--fail curl -o artifacts/manifests/build-parameters.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
--fail curl -o artifacts/test.sh
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
--fail chmod +x artifacts/test.sh # Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh # 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/ cd gcc # Reproduce first_bad build git checkout --detach ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4 ../artifacts/test.sh # Reproduce last_good build git checkout --detach 6889a3acfeed47265886676c6d43b04ef799fb82 ../artifacts/test.sh cd .. </cut> History of pending regressions and results:
https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
Build log:
https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_apm-gnu-release-a…
Full commit (up to 1000 lines): <cut> commit ff6686d2e5f797d6c6a36ad14a7084bc1dc350e4 Author: Martin Jambor <mjambor(a)suse.cz> Date: Fri Sep 20 00:25:04 2019 +0200 New IPA-SRA 2019-09-20 Martin Jambor <mjambor(a)suse.cz> * coretypes.h (cgraph_edge): Declare. * ipa-param-manipulation.c: Rewrite. * ipa-param-manipulation.h: Likewise. * Makefile.in (GTFILES): Added ipa-param-manipulation.h and ipa-sra.c. (OBJS): Added ipa-sra.o. * cgraph.h (ipa_replace_map): Removed fields old_tree, replace_p and ref_p, added fields param_adjustments and performed_splits. (struct cgraph_clone_info): Remove ags_to_skip and combined_args_to_skip, new field param_adjustments. (cgraph_node::create_clone): Changed parameters to use ipa_param_adjustments. (cgraph_node::create_virtual_clone): Likewise. (cgraph_node::create_virtual_clone_with_body): Likewise. (tree_function_versioning): Likewise. (cgraph_build_function_type_skip_args): Removed. * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Convert to using ipa_param_adjustments. (clone_of_p): Likewise. * cgraphclones.c (cgraph_build_function_type_skip_args): Removed. (build_function_decl_skip_args): Likewise. (duplicate_thunk_for_node): Adjust parameters using ipa_param_body_adjustments, copy param_adjustments instead of args_to_skip. (cgraph_node::create_clone): Convert to using ipa_param_adjustments. (cgraph_node::create_virtual_clone): Likewise. (cgraph_node::create_version_clone_with_body): Likewise. (cgraph_materialize_clone): Likewise. (symbol_table::materialize_all_clones): Likewise. * ipa-fnsummary.c (ipa_fn_summary_t::duplicate): Simplify ipa_replace_map check. * ipa-cp.c (get_replacement_map): Do not initialize removed fields. (initialize_node_lattices): Make aware that some parameters might have already been removed. (want_remove_some_param_p): New function. (create_specialized_node): Convert to using ipa_param_adjustments and deal with possibly pre-existing adjustments. * lto-cgraph.c (output_cgraph_opt_summary_p): Likewise. (output_node_opt_summary): Do not stream removed fields. Stream parameter adjustments instead of argumetns to skip. (input_node_opt_summary): Likewise. (input_node_opt_summary): Likewise. * lto-section-in.c (lto_section_name): Added ipa-sra section. * lto-streamer.h (lto_section_type): Likewise. * tree-inline.h (copy_body_data): New fields killed_new_ssa_names and param_body_adjs. (copy_decl_to_var): Declare. * tree-inline.c (update_clone_info): Do not remap old_tree. (remap_gimple_stmt): Use ipa_param_body_adjustments to modify gimple statements, walk all extra generated statements and remap their operands. (redirect_all_calls): Add killed SSA names to a hash set. (remap_ssa_name): Do not remap killed SSA names. (copy_arguments_for_versioning): Renames to copy_arguments_nochange, half of functionality moved to ipa_param_body_adjustments. (copy_decl_to_var): Make exported. (copy_body): Destroy killed_new_ssa_names hash set. (expand_call_inline): Remap performed splits. (update_clone_info): Likewise. (tree_function_versioning): Simplify tree_map processing. Updated to accept ipa_param_adjustments and use ipa_param_body_adjustments. * omp-simd-clone.c (simd_clone_vector_of_formal_parm_types): Adjust for the new interface. (simd_clone_clauses_extract): Likewise, make args an auto_vec. (simd_clone_compute_base_data_type): Likewise. (simd_clone_init_simd_arrays): Adjust for the new interface. (simd_clone_adjust_argument_types): Likewise. (struct modify_stmt_info): Likewise. (ipa_simd_modify_stmt_ops): Likewise. (ipa_simd_modify_function_body): Likewise. (simd_clone_adjust): Likewise. * tree-sra.c: Removed IPA-SRA. Include tree-sra.h. (type_internals_preclude_sra_p): Make public. * tree-sra.h: New file. * ipa-inline-transform.c (save_inline_function_body): Update to refelct new tree_function_versioning signature. * ipa-prop.c (adjust_agg_replacement_values): Use a helper from ipa_param_adjustments to get current parameter indices. (ipcp_modif_dom_walker::before_dom_children): Likewise. (ipcp_update_bits): Likewise. (ipcp_update_vr): Likewise. * ipa-split.c (split_function): Convert to using ipa_param_adjustments. * ipa-sra.c: New file. * multiple_target.c (create_target_clone): Update to reflet new type of create_version_clone_with_body. * trans-mem.c (ipa_tm_create_version): Update to reflect new type of tree_function_versioning. (modify_function): Update to reflect new type of tree_function_versioning. * params.def (PARAM_IPA_SRA_MAX_REPLACEMENTS): New. * passes.def: Remove old IPA-SRA and add new one. * tree-pass.h (make_pass_early_ipa_sra): Remove declaration. (make_pass_ipa_sra): Declare. * dbgcnt.def: Remove eipa_sra. Added ipa_sra_params and ipa_sra_retvalues. * doc/invoke.texi (ipa-sra-max-replacements): New. testsuite/ * g++.dg/ipa/pr81248.C: Adjust dg-options and dump-scan. * gcc.dg/ipa/ipa-sra-1.c: Likewise. * gcc.dg/ipa/ipa-sra-10.c: Likewise. * gcc.dg/ipa/ipa-sra-11.c: Likewise. * gcc.dg/ipa/ipa-sra-3.c: Likewise. * gcc.dg/ipa/ipa-sra-4.c: Likewise. * gcc.dg/ipa/ipa-sra-5.c: Likewise. * gcc.dg/ipa/ipacost-2.c: Disable ipa-sra. * gcc.dg/ipa/ipcp-agg-9.c: Likewise. * gcc.dg/ipa/pr78121.c: Adjust scan pattern. * gcc.dg/ipa/vrp1.c: Likewise. * gcc.dg/ipa/vrp2.c: Likewise. * gcc.dg/ipa/vrp3.c: Likewise. * gcc.dg/ipa/vrp7.c: Likewise. * gcc.dg/ipa/vrp8.c: Likewise. * gcc.dg/noreorder.c: use noipa attribute instead of noinline. * gcc.dg/ipa/20040703-wpa.c: New test. * gcc.dg/ipa/ipa-sra-12.c: New test. * gcc.dg/ipa/ipa-sra-13.c: Likewise. * gcc.dg/ipa/ipa-sra-14.c: Likewise. * gcc.dg/ipa/ipa-sra-15.c: Likewise. * gcc.dg/ipa/ipa-sra-16.c: Likewise. * gcc.dg/ipa/ipa-sra-17.c: Likewise. * gcc.dg/ipa/ipa-sra-18.c: Likewise. * gcc.dg/ipa/ipa-sra-19.c: Likewise. * gcc.dg/ipa/ipa-sra-20.c: Likewise. * gcc.dg/ipa/ipa-sra-21.c: Likewise. * gcc.dg/ipa/ipa-sra-22.c: Likewise. * gcc.dg/sso/ipa-sra-1.c: Likewise. * g++.dg/ipa/ipa-sra-2.C: Likewise. * g++.dg/ipa/ipa-sra-3.C: Likewise. * gcc.dg/tree-ssa/ipa-cp-1.c: Make return value used. * g++.dg/ipa/devirt-19.C: Add missing return, add -fipa-cp-clone option. * g++.dg/lto/devirt-19_0.C: Add -fipa-cp-clone option. * gcc.dg/ipa/ipa-sra-2.c: Removed. * gcc.dg/ipa/ipa-sra-6.c: Likewise. From-SVN: r275982 --- gcc/ChangeLog | 98 + gcc/Makefile.in | 3 +- gcc/cgraph.c | 127 +- gcc/cgraph.h | 45 +- gcc/cgraphclones.c | 213 +- gcc/coretypes.h | 1 + gcc/dbgcnt.def | 3 +- gcc/doc/invoke.texi | 5 + gcc/ipa-cp.c | 172 +- gcc/ipa-fnsummary.c | 4 +- gcc/ipa-inline-transform.c | 3 +- gcc/ipa-param-manipulation.c | 2093 +++++++++++---- gcc/ipa-param-manipulation.h | 449 +++- gcc/ipa-prop.c | 103 +- gcc/ipa-split.c | 32 +- gcc/ipa-sra.c | 4049 ++++++++++++++++++++++++++++++ gcc/lto-cgraph.c | 121 +- gcc/lto-section-in.c | 3 +- gcc/lto-streamer.h | 1 + gcc/multiple_target.c | 5 +- gcc/omp-simd-clone.c | 229 +- gcc/params.def | 7 + gcc/passes.def | 2 +- gcc/testsuite/ChangeLog | 40 + gcc/testsuite/g++.dg/ipa/devirt-19.C | 5 +- gcc/testsuite/g++.dg/ipa/ipa-sra-1.C | 46 + gcc/testsuite/g++.dg/ipa/ipa-sra-2.C | 19 + gcc/testsuite/g++.dg/ipa/ipa-sra-3.C | 9 + gcc/testsuite/g++.dg/ipa/pr81248.C | 4 +- gcc/testsuite/g++.dg/lto/devirt-19_0.C | 2 +- gcc/testsuite/gcc.dg/ipa/20040703-wpa.c | 151 ++ gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c | 4 +- gcc/testsuite/gcc.dg/ipa/ipa-sra-10.c | 4 +- gcc/testsuite/gcc.dg/ipa/ipa-sra-11.c | 6 +- gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c | 50 + gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c | 49 + gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c | 60 + gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c | 61 + gcc/testsuite/gcc.dg/ipa/ipa-sra-16.c | 74 + gcc/testsuite/gcc.dg/ipa/ipa-sra-17.c | 102 + gcc/testsuite/gcc.dg/ipa/ipa-sra-18.c | 49 + gcc/testsuite/gcc.dg/ipa/ipa-sra-19.c | 31 + gcc/testsuite/gcc.dg/ipa/ipa-sra-2.c | 51 - gcc/testsuite/gcc.dg/ipa/ipa-sra-20.c | 38 + gcc/testsuite/gcc.dg/ipa/ipa-sra-21.c | 33 + gcc/testsuite/gcc.dg/ipa/ipa-sra-22.c | 56 + gcc/testsuite/gcc.dg/ipa/ipa-sra-3.c | 7 +- gcc/testsuite/gcc.dg/ipa/ipa-sra-4.c | 8 +- gcc/testsuite/gcc.dg/ipa/ipa-sra-5.c | 4 +- gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c | 33 - gcc/testsuite/gcc.dg/ipa/ipacost-2.c | 4 +- gcc/testsuite/gcc.dg/ipa/ipcp-agg-9.c | 2 +- gcc/testsuite/gcc.dg/ipa/pr78121.c | 2 +- gcc/testsuite/gcc.dg/ipa/vrp1.c | 4 +- gcc/testsuite/gcc.dg/ipa/vrp2.c | 4 +- gcc/testsuite/gcc.dg/ipa/vrp3.c | 2 +- gcc/testsuite/gcc.dg/ipa/vrp7.c | 2 +- gcc/testsuite/gcc.dg/ipa/vrp8.c | 2 +- gcc/testsuite/gcc.dg/noreorder.c | 6 +- gcc/testsuite/gcc.dg/sso/ipa-sra-1.c | 57 + gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c | 2 +- gcc/trans-mem.c | 3 +- gcc/tree-inline.c | 385 ++- gcc/tree-inline.h | 10 + gcc/tree-pass.h | 2 +- gcc/tree-sra.c | 1859 +------------- gcc/tree-sra.h | 31 + 67 files changed, 7998 insertions(+), 3143 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9dfb64643c1..6f34d1a90c4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,101 @@ +2019-09-20 Martin Jambor <mjambor(a)suse.cz> + + * coretypes.h (cgraph_edge): Declare. + * ipa-param-manipulation.c: Rewrite. + * ipa-param-manipulation.h: Likewise. + * Makefile.in (GTFILES): Added ipa-param-manipulation.h and ipa-sra.c. + (OBJS): Added ipa-sra.o. + * cgraph.h (ipa_replace_map): Removed fields old_tree, replace_p + and ref_p, added fields param_adjustments and performed_splits. + (struct cgraph_clone_info): Remove ags_to_skip and + combined_args_to_skip, new field param_adjustments. + (cgraph_node::create_clone): Changed parameters to use + ipa_param_adjustments. + (cgraph_node::create_virtual_clone): Likewise. + (cgraph_node::create_virtual_clone_with_body): Likewise. + (tree_function_versioning): Likewise. + (cgraph_build_function_type_skip_args): Removed. + * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Convert to + using ipa_param_adjustments. + (clone_of_p): Likewise. + * cgraphclones.c (cgraph_build_function_type_skip_args): Removed. + (build_function_decl_skip_args): Likewise. + (duplicate_thunk_for_node): Adjust parameters using + ipa_param_body_adjustments, copy param_adjustments instead of + args_to_skip. + (cgraph_node::create_clone): Convert to using ipa_param_adjustments. + (cgraph_node::create_virtual_clone): Likewise. + (cgraph_node::create_version_clone_with_body): Likewise. + (cgraph_materialize_clone): Likewise. + (symbol_table::materialize_all_clones): Likewise. + * ipa-fnsummary.c (ipa_fn_summary_t::duplicate): Simplify + ipa_replace_map check. + * ipa-cp.c (get_replacement_map): Do not initialize removed fields. + (initialize_node_lattices): Make aware that some parameters might have + already been removed. + (want_remove_some_param_p): New function. + (create_specialized_node): Convert to using ipa_param_adjustments and + deal with possibly pre-existing adjustments. + * lto-cgraph.c (output_cgraph_opt_summary_p): Likewise. + (output_node_opt_summary): Do not stream removed fields. Stream + parameter adjustments instead of argumetns to skip. + (input_node_opt_summary): Likewise. + (input_node_opt_summary): Likewise. + * lto-section-in.c (lto_section_name): Added ipa-sra section. + * lto-streamer.h (lto_section_type): Likewise. + * tree-inline.h (copy_body_data): New fields killed_new_ssa_names and + param_body_adjs. + (copy_decl_to_var): Declare. + * tree-inline.c (update_clone_info): Do not remap old_tree. + (remap_gimple_stmt): Use ipa_param_body_adjustments to modify gimple + statements, walk all extra generated statements and remap their + operands. + (redirect_all_calls): Add killed SSA names to a hash set. + (remap_ssa_name): Do not remap killed SSA names. + (copy_arguments_for_versioning): Renames to copy_arguments_nochange, + half of functionality moved to ipa_param_body_adjustments. + (copy_decl_to_var): Make exported. + (copy_body): Destroy killed_new_ssa_names hash set. + (expand_call_inline): Remap performed splits. + (update_clone_info): Likewise. + (tree_function_versioning): Simplify tree_map processing. Updated to + accept ipa_param_adjustments and use ipa_param_body_adjustments. + * omp-simd-clone.c (simd_clone_vector_of_formal_parm_types): Adjust + for the new interface. + (simd_clone_clauses_extract): Likewise, make args an auto_vec. + (simd_clone_compute_base_data_type): Likewise. + (simd_clone_init_simd_arrays): Adjust for the new interface. + (simd_clone_adjust_argument_types): Likewise. + (struct modify_stmt_info): Likewise. + (ipa_simd_modify_stmt_ops): Likewise. + (ipa_simd_modify_function_body): Likewise. + (simd_clone_adjust): Likewise. + * tree-sra.c: Removed IPA-SRA. Include tree-sra.h. + (type_internals_preclude_sra_p): Make public. + * tree-sra.h: New file. + * ipa-inline-transform.c (save_inline_function_body): Update to + refelct new tree_function_versioning signature. + * ipa-prop.c (adjust_agg_replacement_values): Use a helper from + ipa_param_adjustments to get current parameter indices. + (ipcp_modif_dom_walker::before_dom_children): Likewise. + (ipcp_update_bits): Likewise. + (ipcp_update_vr): Likewise. + * ipa-split.c (split_function): Convert to using ipa_param_adjustments. + * ipa-sra.c: New file. + * multiple_target.c (create_target_clone): Update to reflet new type + of create_version_clone_with_body. + * trans-mem.c (ipa_tm_create_version): Update to reflect new type of + tree_function_versioning. + (modify_function): Update to reflect new type of + tree_function_versioning. + * params.def (PARAM_IPA_SRA_MAX_REPLACEMENTS): New. + * passes.def: Remove old IPA-SRA and add new one. + * tree-pass.h (make_pass_early_ipa_sra): Remove declaration. + (make_pass_ipa_sra): Declare. + * dbgcnt.def: Remove eipa_sra. Added ipa_sra_params and + ipa_sra_retvalues. + * doc/invoke.texi (ipa-sra-max-replacements): New. + 2019-09-19 Martin Sebor <msebor(a)redhat.com> PR middle-end/91631 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 152df9fa9b3..2cf0c79c977 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1368,6 +1368,7 @@ OBJS = \ init-regs.o \ internal-fn.o \ ipa-cp.o \ + ipa-sra.o \ ipa-devirt.o \ ipa-fnsummary.o \ ipa-polymorphic-call.o \ @@ -2527,7 +2528,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/reload.h $(srcdir)/caller-save.c $(srcdir)/symtab.c \ $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \ $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-utils.h \ - $(srcdir)/dbxout.c \ + $(srcdir)/ipa-param-manipulation.h $(srcdir)/ipa-sra.c $(srcdir)/dbxout.c \ $(srcdir)/signop.h \ $(srcdir)/dwarf2out.h \ $(srcdir)/dwarf2asm.c \ diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 843891e9e56..331b363c175 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1342,7 +1342,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void) if (flag_checking && decl) { cgraph_node *node = cgraph_node::get (decl); - gcc_assert (!node || !node->clone.combined_args_to_skip); + gcc_assert (!node || !node->clone.param_adjustments); } if (symtab->dump_file) @@ -1350,25 +1350,36 @@ cgraph_edge::redirect_call_stmt_to_callee (void) fprintf (symtab->dump_file, "updating call of %s -> %s: ", e->caller->dump_name (), e->callee->dump_name ()); print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags); - if (e->callee->clone.combined_args_to_skip) + if (e->callee->clone.param_adjustments) + e->callee->clone.param_adjustments->dump (symtab->dump_file); + unsigned performed_len + = vec_safe_length (e->caller->clone.performed_splits); + if (performed_len > 0) + fprintf (symtab->dump_file, "Performed splits records:\n"); + for (unsigned i = 0; i < performed_len; i++) { - fprintf (symtab->dump_file, " combined args to skip: "); - dump_bitmap (symtab->dump_file, - e->callee->clone.combined_args_to_skip); + ipa_param_performed_split *sm + = &(*e->caller->clone.performed_splits)[i]; + print_node_brief (symtab->dump_file, " dummy_decl: ", sm->dummy_decl, + TDF_UID); + fprintf (symtab->dump_file, ", unit_offset: %u\n", sm->unit_offset); } } - if (e->callee->clone.combined_args_to_skip) + if (ipa_param_adjustments *padjs = e->callee->clone.param_adjustments) { - int lp_nr; + /* We need to defer cleaning EH info on the new statement to + fixup-cfg. We may not have dominator information at this point + and thus would end up with unreachable blocks and have no way + to communicate that we need to run CFG cleanup then. */ + int lp_nr = lookup_stmt_eh_lp (e->call_stmt); + if (lp_nr != 0) + remove_stmt_from_eh_lp (e->call_stmt); - new_stmt = e->call_stmt; - if (e->callee->clone.combined_args_to_skip) - new_stmt - = gimple_call_copy_skip_args (new_stmt, - e->callee->clone.combined_args_to_skip); tree old_fntype = gimple_call_fntype (e->call_stmt); - gimple_call_set_fndecl (new_stmt, e->callee->decl); + new_stmt = padjs->modify_call (e->call_stmt, + e->caller->clone.performed_splits, + e->callee->decl, false); cgraph_node *origin = e->callee; while (origin->clone_of) origin = origin->clone_of; @@ -1379,92 +1390,12 @@ cgraph_edge::redirect_call_stmt_to_callee (void) gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl)); else { - bitmap skip = e->callee->clone.combined_args_to_skip; - tree t = cgraph_build_function_type_skip_args (old_fntype, skip, - false); - gimple_call_set_fntype (new_stmt, t); - } - - if (gimple_vdef (new_stmt) - && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME) - SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; - - gsi = gsi_for_stmt (e->call_stmt); - - /* For optimized away parameters, add on the caller side - before the call - DEBUG D#X => parm_Y(D) - stmts and associate D#X with parm in decl_debug_args_lookup - vector to say for debug info that if parameter parm had been passed, - it would have value parm_Y(D). */ - if (e->callee->clone.combined_args_to_skip && MAY_HAVE_DEBUG_BIND_STMTS) - { - vec<tree, va_gc> **debug_args - = decl_debug_args_lookup (e->callee->decl); - tree old_decl = gimple_call_fndecl (e->call_stmt); - if (debug_args && old_decl) - { - tree parm; - unsigned i = 0, num; - unsigned len = vec_safe_length (*debug_args); - unsigned nargs = gimple_call_num_args (e->call_stmt); - for (parm = DECL_ARGUMENTS (old_decl), num = 0; - parm && num < nargs; - parm = DECL_CHAIN (parm), num++) - if (bitmap_bit_p (e->callee->clone.combined_args_to_skip, num) - && is_gimple_reg (parm)) - { - unsigned last = i; - - while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm)) - i += 2; - if (i >= len) - { - i = 0; - while (i < last - && (**debug_args)[i] != DECL_ORIGIN (parm)) - i += 2; - if (i >= last) - continue; - } - tree ddecl = (**debug_args)[i + 1]; - tree arg = gimple_call_arg (e->call_stmt, num); - if (!useless_type_conversion_p (TREE_TYPE (ddecl), - TREE_TYPE (arg))) - { - tree rhs1; - if (!fold_convertible_p (TREE_TYPE (ddecl), arg)) - continue; - if (TREE_CODE (arg) == SSA_NAME - && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg)) - && (rhs1 - = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg))) - && useless_type_conversion_p (TREE_TYPE (ddecl), - TREE_TYPE (rhs1))) - arg = rhs1; - else - arg = fold_convert (TREE_TYPE (ddecl), arg); - } - - gimple *def_temp - = gimple_build_debug_bind (ddecl, unshare_expr (arg), - e->call_stmt); - gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT); - } - } + tree new_fntype = padjs->build_new_function_type (old_fntype, true); + gimple_call_set_fntype (new_stmt, new_fntype); } - gsi_replace (&gsi, new_stmt, false); - /* We need to defer cleaning EH info on the new statement to - fixup-cfg. We may not have dominator information at this point - and thus would end up with unreachable blocks and have no way - to communicate that we need to run CFG cleanup then. */ - lp_nr = lookup_stmt_eh_lp (e->call_stmt); if (lp_nr != 0) - { - remove_stmt_from_eh_lp (e->call_stmt); - add_stmt_to_eh_lp (new_stmt, lp_nr); - } + add_stmt_to_eh_lp (new_stmt, lp_nr); } else { @@ -3014,8 +2945,8 @@ clone_of_p (cgraph_node *node, cgraph_node *node2) return true; node = node->callees->callee->ultimate_alias_target (); - if (!node2->clone.args_to_skip - || !bitmap_bit_p (node2->clone.args_to_skip, 0)) + if (!node2->clone.param_adjustments + || node2->clone.param_adjustments->first_param_intact_p ()) return false; if (node2->former_clone_of == node->decl) return true; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 4c54210123a..1da6cab54b0 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "profile-count.h" #include "ipa-ref.h" #include "plugin-api.h" +#include "ipa-param-manipulation.h" extern void debuginfo_early_init (void); extern void debuginfo_init (void); @@ -740,23 +741,31 @@ struct GTY(()) cgraph_global_info { will be replaced by another tree while versioning. */ struct GTY(()) ipa_replace_map { - /* The tree that will be replaced. */ - tree old_tree; /* The new (replacing) tree. */ tree new_tree; /* Parameter number to replace, when old_tree is NULL. */ int parm_num; - /* True when a substitution should be done, false otherwise. */ - bool replace_p; - /* True when we replace a reference to old_tree. */ - bool ref_p; }; struct GTY(()) cgraph_clone_info { + /* Constants discovered by IPA-CP, i.e. which parameter should be replaced + with what. */ vec<ipa_replace_map *, va_gc> *tree_map; - bitmap args_to_skip; - bitmap combined_args_to_skip; + /* Parameter modification that IPA-SRA decided to perform. */ + ipa_param_adjustments *param_adjustments; + /* Lists of dummy-decl and offset pairs representing split formal parameters + in the caller. Offsets of all new replacements are enumerated, those + coming from the same original parameter have the same dummy decl stored + along with them. + + Dummy decls sit in call statement arguments followed by new parameter + decls (or their SSA names) in between (caller) clone materialization and + call redirection. Redirection then recognizes the dummy variable and + together with the stored offsets can reconstruct what exactly the new + parameter decls represent and can leave in place only those that the + callee expects. */ + vec<ipa_param_performed_split, va_gc> *performed_splits; }; enum cgraph_simd_clone_arg_type @@ -976,15 +985,16 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node vec<cgraph_edge *> redirect_callers, bool call_duplication_hook, cgraph_node *new_inlined_to, - bitmap args_to_skip, const char *suffix = NULL); + ipa_param_adjustments *param_adjustments, + const char *suffix = NULL); /* Create callgraph node clone with new declaration. The actual body will be copied later at compilation stage. The name of the new clone will be constructed from the name of the original node, SUFFIX and NUM_SUFFIX. */ cgraph_node *create_virtual_clone (vec<cgraph_edge *> redirect_callers, vec<ipa_replace_map *, va_gc> *tree_map, - bitmap args_to_skip, const char * suffix, - unsigned num_suffix); + ipa_param_adjustments *param_adjustments, + const char * suffix, unsigned num_suffix); /* cgraph node being removed from symbol table; see if its entry can be replaced by other inline clone. */ @@ -1033,9 +1043,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node Return the new version's cgraph node. */ cgraph_node *create_version_clone_with_body (vec<cgraph_edge *> redirect_callers, - vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip, - bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block, - const char *clone_name, tree target_attributes = NULL_TREE); + vec<ipa_replace_map *, va_gc> *tree_map, + ipa_param_adjustments *param_adjustments, + bitmap bbs_to_copy, basic_block new_entry_block, const char *clone_name, + tree target_attributes = NULL_TREE); /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab corresponding to cgraph_node. */ @@ -2459,14 +2470,12 @@ tree clone_function_name (tree decl, const char *suffix, tree clone_function_name (tree decl, const char *suffix); void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *, - bool, bitmap, bool, bitmap, basic_block); + ipa_param_adjustments *, + bool, bitmap, basic_block); void dump_callgraph_transformation (const cgraph_node *original, const cgraph_node *clone, const char *suffix); -tree cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip, - bool skip_return); - /* In cgraphbuild.c */ int compute_call_stmt_bb_frequency (tree, basic_block bb); void record_references_in_initializer (tree, bool); diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index fa753697c78..909407b9a71 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -142,96 +142,6 @@ cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid, return new_edge; } -/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the - return value if SKIP_RETURN is true. */ - -tree -cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip, - bool skip_return) -{ - tree new_type = NULL; - tree args, new_args = NULL; - tree new_reversed; - int i = 0; - - for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node; - args = TREE_CHAIN (args), i++) - if (!args_to_skip || !bitmap_bit_p (args_to_skip, i)) - new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args); - - new_reversed = nreverse (new_args); - if (args) - { - if (new_reversed) - TREE_CHAIN (new_args) = void_list_node; - else - new_reversed = void_list_node; - } - - /* Use copy_node to preserve as much as possible from original type - (debug info, attribute lists etc.) - Exception is METHOD_TYPEs must have THIS argument. - When we are asked to remove it, we need to build new FUNCTION_TYPE - instead. */ - if (TREE_CODE (orig_type) != METHOD_TYPE - || !args_to_skip - || !bitmap_bit_p (args_to_skip, 0)) - { - new_type = build_distinct_type_copy (orig_type); - TYPE_ARG_TYPES (new_type) = new_reversed; - } - else - { - new_type - = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type), - new_reversed)); - TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type); - } - - if (skip_return) - TREE_TYPE (new_type) = void_type_node; - - return new_type; -} - -/* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the - return value if SKIP_RETURN is true. - - Arguments from DECL_ARGUMENTS list can't be removed now, since they are - linked by TREE_CHAIN directly. The caller is responsible for eliminating - them when they are being duplicated (i.e. copy_arguments_for_versioning). */ - -static tree -build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip, - bool skip_return) -{ - tree new_decl = copy_node (orig_decl); - tree new_type; - - new_type = TREE_TYPE (orig_decl); - if (prototype_p (new_type) - || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type)))) - new_type - = cgraph_build_function_type_skip_args (new_type, args_to_skip, - skip_return); - TREE_TYPE (new_decl) = new_type; - - /* For declarations setting DECL_VINDEX (i.e. methods) - we expect first argument to be THIS pointer. */ - if (args_to_skip && bitmap_bit_p (args_to_skip, 0)) - DECL_VINDEX (new_decl) = NULL_TREE; - - /* When signature changes, we need to clear builtin info. */ - if (fndecl_built_in_p (new_decl) - && args_to_skip - && !bitmap_empty_p (args_to_skip)) - set_decl_built_in_function (new_decl, NOT_BUILT_IN, 0); - /* The FE might have information and assumptions about the other - arguments. */ - DECL_LANG_SPECIFIC (new_decl) = NULL; - return new_decl; -} - /* Set flags of NEW_NODE and its decl. NEW_NODE is a newly created private clone or its thunk. */ @@ -281,35 +191,21 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node) return cs->caller; tree new_decl; - if (!node->clone.args_to_skip) - new_decl = copy_node (thunk->decl); - else + if (node->clone.param_adjustments) { /* We do not need to duplicate this_adjusting thunks if we have removed this. */ if (thunk->thunk.this_adjusting - && bitmap_bit_p (node->clone.args_to_skip, 0)) + && !node->clone.param_adjustments->first_param_intact_p ()) return node; - new_decl = build_function_decl_skip_args (thunk->decl, - node->clone.args_to_skip, - false); - } - - tree *link = &DECL_ARGUMENTS (new_decl); - int i = 0; - for (tree pd = DECL_ARGUMENTS (thunk->decl); pd; pd = DECL_CHAIN (pd), i++) - { - if (!node->clone.args_to_skip - || !bitmap_bit_p (node->clone.args_to_skip, i)) - { - tree nd = copy_node (pd); - DECL_CONTEXT (nd) = new_decl; - *link = nd; - link = &DECL_CHAIN (nd); - } + new_decl = copy_node (thunk->decl); + ipa_param_body_adjustments body_adj (node->clone.param_adjustments, + new_decl); + body_adj.modify_formal_parameters (); } - *link = NULL_TREE; + else + new_decl = copy_node (thunk->decl); gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl)); gcc_checking_assert (!DECL_INITIAL (new_decl)); @@ -331,8 +227,7 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node) new_thunk->thunk = thunk->thunk; new_thunk->unique_name = in_lto_p; new_thunk->former_clone_of = thunk->decl; - new_thunk->clone.args_to_skip = node->clone.args_to_skip; - new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip; + new_thunk->clone.param_adjustments = node->clone.param_adjustments; cgraph_edge *e = new_thunk->create_edge (node, NULL, new_thunk->count); symtab->call_edge_duplication_hooks (thunk->callees, e); @@ -415,7 +310,11 @@ dump_callgraph_transformation (const cgraph_node *original, If the new node is being inlined into another one, NEW_INLINED_TO should be the outline function the new one is (even indirectly) inlined to. All hooks will see this in node's global.inlined_to, when invoked. Can be NULL if the - node is not inlined. */ + node is not inlined. + + If PARAM_ADJUSTMENTS is non-NULL, the parameter manipulation information + will be overwritten by the new structure. Otherwise the new node will + share parameter manipulation information with the original node. */ cgraph_node * cgraph_node::create_clone (tree new_decl, profile_count prof_count, @@ -423,7 +322,8 @@ cgraph_node::create_clone (tree new_decl, profile_count prof_count, vec<cgraph_edge *> redirect_callers, bool call_duplication_hook, cgraph_node *new_inlined_to, - bitmap args_to_skip, const char *suffix) + ipa_param_adjustments *param_adjustments, + const char *suffix) { cgraph_node *new_node = symtab->create_empty (); cgraph_edge *e; @@ -467,19 +367,13 @@ cgraph_node::create_clone (tree new_decl, profile_count prof_count, new_node->merged_comdat = merged_comdat; new_node->thunk = thunk; + if (param_adjustments) + new_node->clone.param_adjustments = param_adjustments; + else + new_node->clone.param_adjustments = clone.param_adjustments; new_node->clone.tree_map = NULL; - new_node->clone.args_to_skip = args_to_skip; + new_node->clone.performed_splits = vec_safe_copy (clone.performed_splits); new_node->split_part = split_part; - if (!args_to_skip) - new_node->clone.combined_args_to_skip = clone.combined_args_to_skip; - else if (clone.combined_args_to_skip) - { - new_node->clone.combined_args_to_skip = BITMAP_GGC_ALLOC (); - bitmap_ior (new_node->clone.combined_args_to_skip, - clone.combined_args_to_skip, args_to_skip); - } - else - new_node->clone.combined_args_to_skip = args_to_skip; FOR_EACH_VEC_ELT (redirect_callers, i, e) { @@ -621,8 +515,8 @@ clone_function_name (tree decl, const char *suffix) cgraph_node * cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers, vec<ipa_replace_map *, va_gc> *tree_map, - bitmap args_to_skip, const char * suffix, - unsigned num_suffix) + ipa_param_adjustments *param_adjustments, + const char * suffix, unsigned num_suffix) { tree old_decl = decl; cgraph_node *new_node = NULL; @@ -632,13 +526,16 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers, char *name; gcc_checking_assert (local.versionable); - gcc_assert (local.can_change_signature || !args_to_skip); + /* TODO: It would be nice if we could recognize that param_adjustments do not + actually perform any changes, but at the moment let's require it simply + does not exist. */ + gcc_assert (local.can_change_signature || !param_adjustments); /* Make a new FUNCTION_DECL tree node */ - if (!args_to_skip) + if (!param_adjustments) new_decl = copy_node (old_decl); else - new_decl = build_function_decl_skip_args (old_decl, args_to_skip, false); + new_decl = param_adjustments->adjust_decl (old_decl); /* These pointers represent function body and will be populated only when clone is materialized. */ @@ -662,7 +559,8 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers, SET_DECL_RTL (new_decl, NULL); new_node = create_clone (new_decl, count, false, - redirect_callers, false, NULL, args_to_skip, suffix); + redirect_callers, false, NULL, param_adjustments, + suffix); /* Update the properties. Make clone visible only within this translation unit. Make sure @@ -1021,9 +919,10 @@ cgraph_node::create_version_clone (tree new_decl, cgraph_node * cgraph_node::create_version_clone_with_body (vec<cgraph_edge *> redirect_callers, - vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip, - bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block, - const char *suffix, tree target_attributes) + vec<ipa_replace_map *, va_gc> *tree_map, + ipa_param_adjustments *param_adjustments, + bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix, + tree target_attributes) { tree old_decl = decl; cgraph_node *new_version_node = NULL; @@ -1032,14 +931,16 @@ cgraph_node::create_version_clone_with_body if (!tree_versionable_function_p (old_decl)) return NULL; - gcc_assert (local.can_change_signature || !args_to_skip); + /* TODO: Restore an assert that we do not change signature if + local.can_change_signature is false. We cannot just check that + param_adjustments is NULL because unfortunately ipa-split removes return + values from such functions. */ /* Make a new FUNCTION_DECL tree node for the new version. */ - if (!args_to_skip && !skip_return) - new_decl = copy_node (old_decl); + if (param_adjustments) + new_decl = param_adjustments->adjust_decl (old_decl); else - new_decl - = build_function_decl_skip_args (old_decl, args_to_skip, skip_return); + new_decl = copy_node (old_decl); /* Generate a new name for the new version. */ DECL_NAME (new_decl) = clone_function_name_numbered (old_decl, suffix); @@ -1076,8 +977,8 @@ cgraph_node::create_version_clone_with_body new_version_node->ipa_transforms_to_apply = ipa_transforms_to_apply.copy (); /* Copy the OLD_VERSION_NODE function tree to the new version. */ - tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip, - skip_return, bbs_to_copy, new_entry_block); + tree_function_versioning (old_decl, new_decl, tree_map, param_adjustments, + false, bbs_to_copy, new_entry_block); /* Update the new version's properties. Make The new version visible only within this translation unit. Make sure @@ -1117,9 +1018,8 @@ cgraph_materialize_clone (cgraph_node *node) node->former_clone_of = node->clone_of->former_clone_of; /* Copy the OLD_VERSION_NODE function tree to the new version. */ tree_function_versioning (node->clone_of->decl, node->decl, - node->clone.tree_map, true, - node->clone.args_to_skip, false, - NULL, NULL); + node->clone.tree_map, node->clone.param_adjustments, + true, NULL, NULL); if (symtab->dump_file) { dump_function_to_file (node->clone_of->decl, symtab->dump_file, @@ -1194,28 +1094,15 @@ symbol_table::materialize_all_clones (void) { ipa_replace_map *replace_info; replace_info = (*node->clone.tree_map)[i]; - print_generic_expr (symtab->dump_file, - replace_info->old_tree); - fprintf (symtab->dump_file, " -> "); + fprintf (symtab->dump_file, "%i -> ", + (*node->clone.tree_map)[i]->parm_num); print_generic_expr (symtab->dump_file, replace_info->new_tree); - fprintf (symtab->dump_file, "%s%s;", - replace_info->replace_p ? "(replace)":"", - replace_info->ref_p ? "(ref)":""); } fprintf (symtab->dump_file, "\n"); } - if (node->clone.args_to_skip) - { - fprintf (symtab->dump_file, " args_to_skip: "); - dump_bitmap (symtab->dump_file, - node->clone.args_to_skip); - } - if (node->clone.args_to_skip) - { - fprintf (symtab->dump_file, " combined_args_to_skip:"); - dump_bitmap (symtab->dump_file, node->clone.combined_args_to_skip); - } + if (node->clone.param_adjustments) + node->clone.param_adjustments->dump (symtab->dump_file); } cgraph_materialize_clone (node); stabilized = false; diff --git a/gcc/coretypes.h b/gcc/coretypes.h index fc0e09b2000..257de226326 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -141,6 +141,7 @@ struct gomp_teams; struct symtab_node; struct cgraph_node; struct varpool_node; +struct cgraph_edge; union section; typedef union section section; diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def index ef981aa6967..7c9daafe35d 100644 --- a/gcc/dbgcnt.def +++ b/gcc/dbgcnt.def @@ -156,7 +156,6 @@ DEBUG_COUNTER (df_byte_scan) DEBUG_COUNTER (dse) DEBUG_COUNTER (dse1) DEBUG_COUNTER (dse2) -DEBUG_COUNTER (eipa_sra) DEBUG_COUNTER (gcse2_delete) DEBUG_COUNTER (global_alloc_at_func) DEBUG_COUNTER (global_alloc_at_reg) @@ -168,6 +167,8 @@ DEBUG_COUNTER (if_after_combine) DEBUG_COUNTER (if_after_reload) DEBUG_COUNTER (if_conversion) DEBUG_COUNTER (if_conversion_tree) +DEBUG_COUNTER (ipa_sra_params) +DEBUG_COUNTER (ipa_sra_retvalues) DEBUG_COUNTER (ira_move) DEBUG_COUNTER (local_alloc_for_sched) DEBUG_COUNTER (merged_ipa_icf) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6d67c121be0..83016a5a8ee 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11870,6 +11870,11 @@ parameters only when their cumulative size is less or equal to @option{ipa-sra-ptr-growth-factor} times the size of the original pointer parameter. +@item ipa-sra-max-replacements +Maximum pieces of an aggregate that IPA-SRA tracks. As a +consequence, it is also the maximum number of replacements of a formal +parameter. + @item sra-max-scalarization-size-Ospeed @itemx sra-max-scalarization-size-Osize The two Scalar Reduction of Aggregates passes (SRA and IPA-SRA) aim to diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 33d52fe5537..b4fb74e097e 100644 </cut>
3 years, 4 months
1
0
0
0
[CI-NOTIFY]: TCWG Bisect tcwg_bmk_tk1/llvm-release-arm-spec2k6-O2 - Build # 14 - Successful!
by ci_notify@linaro.org
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_llvm_tk1/llvm-release-arm-spec2k6-O2. So far, this commit has regressed CI configurations: - tcwg_bmk_llvm_tk1/llvm-release-arm-spec2k6-O2 Culprit: <cut> commit 0b92cf305dcf34387a8e2564e55ca8948df3b47a Author: Jan Hubicka <hubicka(a)ucw.cz> Date: Tue Oct 1 18:58:35 2019 +0200 invoke.texi (early-inlining-insns-O2): Document. * doc/invoke.texi (early-inlining-insns-O2): Document. (early-inlining-insns): Update. * params.def (early-inlining-insns-O2): New bound. (early-inlining-insns): Update docs. * ipa-inline.c (want_early_inline_function_p): Use new bound. * g++.dg/tree-ssa/pr61034.C: Set early-inlining-insns-O2=14. * g++.dg/tree-ssa/pr8781.C: Likewise. * g++.dg/warn/Wstringop-truncation-1.C: Likewise. * gcc.dg/ipa/pr63416.c: likewise. * gcc.dg/vect/pr66142.c: Likewise. * gcc.dg/tree-ssa/ssa-thread-12.c: Mark compure_idf inline. From-SVN: r276416 </cut> Results regressed to (for first_bad == 0b92cf305dcf34387a8e2564e55ca8948df3b47a) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -O2_marm -- artifacts/build-0b92cf305dcf34387a8e2564e55ca8948df3b47a/results_id: 1 # 447.dealII,[.] _ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_ba regressed by 806 from (for last_good == 7552c36afa1f9058bb39f336ae84f019621885a0) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -O2_marm -- artifacts/build-7552c36afa1f9058bb39f336ae84f019621885a0/results_id: 1 Artifacts of last_good build:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Results ID of last_good: tk1_32/tcwg_bmk_llvm_tk1/bisect-llvm-release-arm-spec2k6-O2/2493 Artifacts of first_bad build:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Results ID of first_bad: tk1_32/tcwg_bmk_llvm_tk1/bisect-llvm-release-arm-spec2k6-O2/2500 Build top page/logs:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Configuration details: Reproduce builds: <cut> mkdir investigate-gcc-0b92cf305dcf34387a8e2564e55ca8948df3b47a cd investigate-gcc-0b92cf305dcf34387a8e2564e55ca8948df3b47a git clone
https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
--fail curl -o artifacts/manifests/build-parameters.sh
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
--fail curl -o artifacts/test.sh
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
--fail chmod +x artifacts/test.sh # Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh # 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/ cd gcc # Reproduce first_bad build git checkout --detach 0b92cf305dcf34387a8e2564e55ca8948df3b47a ../artifacts/test.sh # Reproduce last_good build git checkout --detach 7552c36afa1f9058bb39f336ae84f019621885a0 ../artifacts/test.sh cd .. </cut> History of pending regressions and results:
https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Build log:
https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Full commit (up to 1000 lines): <cut> commit 0b92cf305dcf34387a8e2564e55ca8948df3b47a Author: Jan Hubicka <hubicka(a)ucw.cz> Date: Tue Oct 1 18:58:35 2019 +0200 invoke.texi (early-inlining-insns-O2): Document. * doc/invoke.texi (early-inlining-insns-O2): Document. (early-inlining-insns): Update. * params.def (early-inlining-insns-O2): New bound. (early-inlining-insns): Update docs. * ipa-inline.c (want_early_inline_function_p): Use new bound. * g++.dg/tree-ssa/pr61034.C: Set early-inlining-insns-O2=14. * g++.dg/tree-ssa/pr8781.C: Likewise. * g++.dg/warn/Wstringop-truncation-1.C: Likewise. * gcc.dg/ipa/pr63416.c: likewise. * gcc.dg/vect/pr66142.c: Likewise. * gcc.dg/tree-ssa/ssa-thread-12.c: Mark compure_idf inline. From-SVN: r276416 --- gcc/ChangeLog | 8 ++++++++ gcc/doc/invoke.texi | 8 ++++++++ gcc/ipa-inline.c | 22 ++++++++++++++-------- gcc/params.def | 6 +++++- gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/g++.dg/tree-ssa/pr61034.C | 2 +- gcc/testsuite/g++.dg/tree-ssa/pr8781.C | 2 +- gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C | 2 +- gcc/testsuite/gcc.dg/ipa/pr63416.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c | 2 +- gcc/testsuite/gcc.dg/vect/pr66142.c | 2 +- 11 files changed, 50 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb4de20ab16..b4c4292c299 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2019-10-01 Jan Hubicka <hubicka(a)ucw.cz> + + * doc/invoke.texi (early-inlining-insns-O2): Document. + (early-inlining-insns): Update. + * params.def (early-inlining-insns-O2): New bound. + (early-inlining-insns): Update docs. + * ipa-inline.c (want_early_inline_function_p): Use new bound. + 2019-10-01 Oleg Endo <olegendo(a)gcc.gnu.org> PR target/88562 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 83016a5a8ee..4281ee7c614 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11291,9 +11291,17 @@ recursion depth can be guessed from the probability that function recurses via a given call expression. This parameter limits inlining only to call expressions whose probability exceeds the given threshold (in percents). +@item early-inlining-insns-O2 +Specify growth that the early inliner can make. In effect it increases +the amount of inlining for code having a large abstraction penalty. +This is applied to functions compiled with @option{-O1} or @option{-O2} +optimization levels. + @item early-inlining-insns Specify growth that the early inliner can make. In effect it increases the amount of inlining for code having a large abstraction penalty. +This is applied to functions compiled with @option{-O3} or @option{-Ofast} +optimization levels. @item max-early-inliner-iterations Limit of iterations of the early inliner. This basically bounds diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index b62d280eb25..c8689c7d9a8 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -641,6 +641,10 @@ want_early_inline_function_p (struct cgraph_edge *e) { int growth = estimate_edge_growth (e); int n; + int early_inlining_insns = opt_for_fn (e->caller->decl, optimize) >= 3 + ? PARAM_VALUE (PARAM_EARLY_INLINING_INSNS) + : PARAM_VALUE (PARAM_EARLY_INLINING_INSNS_O2); + if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE)) ; @@ -654,26 +658,28 @@ want_early_inline_function_p (struct cgraph_edge *e) growth); want_inline = false; } - else if (growth > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS)) + else if (growth > early_inlining_insns) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt, " will not early inline: %C->%C, " - "growth %i exceeds --param early-inlining-insns\n", - e->caller, callee, - growth); + "growth %i exceeds --param early-inlining-insns%s\n", + e->caller, callee, growth, + opt_for_fn (e->caller->decl, optimize) >= 3 + ? "" : "-O2"); want_inline = false; } else if ((n = num_calls (callee)) != 0 - && growth * (n + 1) > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS)) + && growth * (n + 1) > early_inlining_insns) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt, " will not early inline: %C->%C, " - "growth %i exceeds --param early-inlining-insns " + "growth %i exceeds --param early-inlining-insns%s " "divided by number of calls\n", - e->caller, callee, - growth); + e->caller, callee, growth, + opt_for_fn (e->caller->decl, optimize) >= 3 + ? "" : "-O2"); want_inline = false; } } diff --git a/gcc/params.def b/gcc/params.def index d2d957fc6b1..0acf29b6c4d 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -233,8 +233,12 @@ DEFPARAM(PARAM_IPCP_UNIT_GROWTH, 10, 0, 0) DEFPARAM(PARAM_EARLY_INLINING_INSNS, "early-inlining-insns", - "Maximal estimated growth of function body caused by early inlining of single call.", + "Maximal estimated growth of function body caused by early inlining of single call with -O3 and -Ofast.", 14, 0, 0) +DEFPARAM(PARAM_EARLY_INLINING_INSNS_O2, + "early-inlining-insns-O2", + "Maximal estimated growth of function body caused by early inlining of single call with -O1 and -O2.", + 6, 0, 0) DEFPARAM(PARAM_LARGE_STACK_FRAME, "large-stack-frame", "The size of stack frame to be considered large.", diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index df6105f3d13..0dcaf4b6292 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-10-01 Jan Hubicka <hubicka(a)ucw.cz> + + * g++.dg/tree-ssa/pr61034.C: Set early-inlining-insns-O2=14. + * g++.dg/tree-ssa/pr8781.C: Likewise. + * g++.dg/warn/Wstringop-truncation-1.C: Likewise. + * gcc.dg/ipa/pr63416.c: likewise. + * gcc.dg/vect/pr66142.c: Likewise. + * gcc.dg/tree-ssa/ssa-thread-12.c: Mark compure_idf inline. + 2019-10-01 Jakub Jelinek <jakub(a)redhat.com> PR c++/91925 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr61034.C b/gcc/testsuite/g++.dg/tree-ssa/pr61034.C index 870b2372166..2e3dfecacb4 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr61034.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr61034.C @@ -1,5 +1,5 @@ // { dg-do compile } -// { dg-options "-O2 -fdump-tree-fre3 -fdump-tree-optimized -fdelete-null-pointer-checks" } +// { dg-options "-O2 -fdump-tree-fre3 -fdump-tree-optimized -fdelete-null-pointer-checks --param early-inlining-insns-O2=14" } #define assume(x) if(!(x))__builtin_unreachable() diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C index 1f115b2b26d..5bc1ef03520 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1" } */ +/* { dg-options "-O -fno-tree-sra -fdump-tree-fre1 --param early-inlining-insns-O2=14" } */ int f(); diff --git a/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C b/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C index 83066019772..49dde0a65ba 100644 --- a/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C +++ b/gcc/testsuite/g++.dg/warn/Wstringop-truncation-1.C @@ -1,7 +1,7 @@ /* PR/tree-optimization/84480 - bogus -Wstringop-truncation despite assignment with an inlined string literal { dg-do compile } - { dg-options "-O2 -Wstringop-truncation" } */ + { dg-options "-O2 -Wstringop-truncation --param early-inlining-insns-O2=14" } */ #include <string.h> diff --git a/gcc/testsuite/gcc.dg/ipa/pr63416.c b/gcc/testsuite/gcc.dg/ipa/pr63416.c index b5374c51fe9..5873954fba3 100644 --- a/gcc/testsuite/gcc.dg/ipa/pr63416.c +++ b/gcc/testsuite/gcc.dg/ipa/pr63416.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-tree-optimized --param early-inlining-insns-O2=14" } */ #define _UNUSED_ __attribute__((__unused__)) typedef int TEST_F30 (int *v); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c index 67526762f2c..216de23d791 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-12.c @@ -56,7 +56,7 @@ bmp_iter_and_compl (bitmap_iterator * bi, unsigned *bit_no) } extern int VEC_int_base_length (VEC_int_base *); -bitmap +inline bitmap compute_idf (bitmap def_blocks, bitmap_head * dfs) { bitmap_iterator bi; diff --git a/gcc/testsuite/gcc.dg/vect/pr66142.c b/gcc/testsuite/gcc.dg/vect/pr66142.c index 8c79f290767..a0316f1f01e 100644 --- a/gcc/testsuite/gcc.dg/vect/pr66142.c +++ b/gcc/testsuite/gcc.dg/vect/pr66142.c @@ -1,6 +1,6 @@ /* PR middle-end/66142 */ /* { dg-do compile } */ -/* { dg-additional-options "-ffast-math -fopenmp-simd" } */ +/* { dg-additional-options "-ffast-math -fopenmp-simd --param early-inlining-insns-O2=14" } */ /* { dg-additional-options "-mavx" { target avx_runtime } } */ struct A { float x, y; }; </cut>
3 years, 4 months
1
0
0
0
← Newer
1
2
3
4
5
6
7
8
9
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
Results per page:
10
25
50
100
200