Successfully identified regression in *gcc* in CI configuration tcwg_gcc_bootstrap/master-arm-bootstrap. So far, this commit has regressed CI configurations: - tcwg_gcc_bootstrap/master-arm-bootstrap
Culprit: <cut> commit e4f16e9f357a38ec702fb69a0ffab9d292a6af9b Author: Thomas Schwinge thomas@codesourcery.com Date: Fri Aug 13 17:53:12 2021 +0200
Add more self-tests for 'hash_map' with Value type with non-trivial constructor/destructor
... to document the current behavior.
gcc/ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Extend. (test_map_of_type_with_ctor_and_dtor_expand): Add function. (hash_map_tests_c_tests): Call it. </cut>
Results regressed to (for first_bad == e4f16e9f357a38ec702fb69a0ffab9d292a6af9b) # reset_artifacts: -10 # true: 0 # build_abe binutils: 1 # First few build errors in logs: # 00:02:51 cc1: internal compiler error: in fail, at selftest.c:47 # 00:02:51 cc1plus: internal compiler error: in fail, at selftest.c:47 # 00:02:51 make[3]: *** [s-selftest-c] Error 1 # 00:02:51 make[3]: *** [s-selftest-c++] Error 1 # 00:02:51 make[2]: *** [all-stage1-gcc] Error 2 # 00:02:51 make[1]: *** [stage1-bubble] Error 2 # 00:02:51 make: *** [all] Error 2
from (for last_good == 602fca427df6c5f7452677cfcdd16a5b9a3ca86a) # reset_artifacts: -10 # true: 0 # build_abe binutils: 1 # build_abe bootstrap: 2
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Build top page/logs: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/
Configuration details:
Reproduce builds: <cut> mkdir investigate-gcc-e4f16e9f357a38ec702fb69a0ffab9d292a6af9b cd investigate-gcc-e4f16e9f357a38ec702fb69a0ffab9d292a6af9b
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_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_gnu-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 e4f16e9f357a38ec702fb69a0ffab9d292a6af9b ../artifacts/test.sh
# Reproduce last_good build git checkout --detach 602fca427df6c5f7452677cfcdd16a5b9a3ca86a ../artifacts/test.sh
cd .. </cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/c...
Artifacts: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Build log: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/c...
Full commit (up to 1000 lines): <cut> commit e4f16e9f357a38ec702fb69a0ffab9d292a6af9b Author: Thomas Schwinge thomas@codesourcery.com Date: Fri Aug 13 17:53:12 2021 +0200
Add more self-tests for 'hash_map' with Value type with non-trivial constructor/destructor
... to document the current behavior.
gcc/ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Extend. (test_map_of_type_with_ctor_and_dtor_expand): Add function. (hash_map_tests_c_tests): Call it. --- gcc/hash-map-tests.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+)
diff --git a/gcc/hash-map-tests.c b/gcc/hash-map-tests.c index 5b6b192cd28..257f2be0c26 100644 --- a/gcc/hash-map-tests.c +++ b/gcc/hash-map-tests.c @@ -278,6 +278,156 @@ test_map_of_type_with_ctor_and_dtor ()
ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); } + + + /* Verify basic construction and destruction of Value objects. */ + { + /* Configure, arbitrary. */ + const size_t N_init = 0; + const int N_elem = 28; + + void *a[N_elem]; + for (size_t i = 0; i < N_elem; ++i) + a[i] = &a[i]; + + val_t::ndefault = 0; + val_t::ncopy = 0; + val_t::nassign = 0; + val_t::ndtor = 0; + Map m (N_init); + ASSERT_EQ (val_t::ndefault + + val_t::ncopy + + val_t::nassign + + val_t::ndtor, 0); + + for (int i = 0; i < N_elem; ++i) + { + m.get_or_insert (a[i]); + ASSERT_EQ (val_t::ndefault, 1 + i); + ASSERT_EQ (val_t::ncopy, 0); + ASSERT_EQ (val_t::nassign, 0); + ASSERT_EQ (val_t::ndtor, i); + + m.remove (a[i]); + ASSERT_EQ (val_t::ndefault, 1 + i); + ASSERT_EQ (val_t::ncopy, 0); + ASSERT_EQ (val_t::nassign, 0); + ASSERT_EQ (val_t::ndtor, 1 + i); + } + } +} + +/* Verify aspects of 'hash_table::expand'. */ + +static void +test_map_of_type_with_ctor_and_dtor_expand (bool remove_some_inline) +{ + /* Configure, so that hash table expansion triggers a few times. */ + const size_t N_init = 0; + const int N_elem = 70; + size_t expand_c_expected = 4; + size_t expand_c = 0; + + void *a[N_elem]; + for (size_t i = 0; i < N_elem; ++i) + a[i] = &a[i]; + + typedef hash_map <void *, val_t> Map; + + /* Note that we are starting with a fresh 'Map'. Even if an existing one has + been cleared out completely, there remain 'deleted' elements, and these + would disturb the following logic, where we don't have access to the + actual 'm_n_deleted' value. */ + size_t m_n_deleted = 0; + + val_t::ndefault = 0; + val_t::ncopy = 0; + val_t::nassign = 0; + val_t::ndtor = 0; + Map m (N_init); + + /* In the following, in particular related to 'expand', we're adapting from + the internal logic of 'hash_table', glossing over "some details" not + relevant for this testing here. */ + + /* Per 'hash_table::hash_table'. */ + size_t m_size; + { + unsigned int size_prime_index_ = hash_table_higher_prime_index (N_init); + m_size = prime_tab[size_prime_index_].prime; + } + + int n_expand_moved = 0; + + for (int i = 0; i < N_elem; ++i) + { + size_t elts = m.elements (); + + /* Per 'hash_table::find_slot_with_hash'. */ + size_t m_n_elements = elts + m_n_deleted; + bool expand = m_size * 3 <= m_n_elements * 4; + + m.get_or_insert (a[i]); + if (expand) + { + ++expand_c; + + /* Per 'hash_table::expand'. */ + { + unsigned int nindex = hash_table_higher_prime_index (elts * 2); + m_size = prime_tab[nindex].prime; + } + m_n_deleted = 0; + + /* All non-deleted elements have been moved. */ + n_expand_moved += i; + if (remove_some_inline) + n_expand_moved -= (i + 2) / 3; + } + + ASSERT_EQ (val_t::ndefault, 1 + i); + ASSERT_EQ (val_t::ncopy, n_expand_moved); + ASSERT_EQ (val_t::nassign, 0); + if (remove_some_inline) + ASSERT_EQ (val_t::ndtor, (i + 2) / 3); + else + ASSERT_EQ (val_t::ndtor, 0); + + /* Remove some inline. This never triggers an 'expand' here, but via + 'm_n_deleted' does influence any following one. */ + if (remove_some_inline + && !(i % 3)) + { + m.remove (a[i]); + /* Per 'hash_table::remove_elt_with_hash'. */ + m_n_deleted++; + + ASSERT_EQ (val_t::ndefault, 1 + i); + ASSERT_EQ (val_t::ncopy, n_expand_moved); + ASSERT_EQ (val_t::nassign, 0); + ASSERT_EQ (val_t::ndtor, 1 + (i + 2) / 3); + } + } + ASSERT_EQ (expand_c, expand_c_expected); + + int ndefault = val_t::ndefault; + int ncopy = val_t::ncopy; + int nassign = val_t::nassign; + int ndtor = val_t::ndtor; + + for (int i = 0; i < N_elem; ++i) + { + if (remove_some_inline + && !(i % 3)) + continue; + + m.remove (a[i]); + ++ndtor; + ASSERT_EQ (val_t::ndefault, ndefault); + ASSERT_EQ (val_t::ncopy, ncopy); + ASSERT_EQ (val_t::nassign, nassign); + ASSERT_EQ (val_t::ndtor, ndtor); + } }
/* Test calling empty on a hash_map that has a key type with non-zero @@ -309,6 +459,8 @@ hash_map_tests_c_tests () test_map_of_strings_to_int (); test_map_of_int_to_strings (); test_map_of_type_with_ctor_and_dtor (); + test_map_of_type_with_ctor_and_dtor_expand (false); + test_map_of_type_with_ctor_and_dtor_expand (true); test_nonzero_empty_key (); }
</cut>
Hi!
On 2021-08-19T17:41:17+0000, ci_notify@linaro.org wrote:
Successfully identified regression in *gcc* in CI configuration tcwg_gcc_bootstrap/master-arm-bootstrap. So far, this commit has regressed CI configurations:
- tcwg_gcc_bootstrap/master-arm-bootstrap
Culprit:
<cut> commit e4f16e9f357a38ec702fb69a0ffab9d292a6af9b Author: Thomas Schwinge <thomas@codesourcery.com> Date: Fri Aug 13 17:53:12 2021 +0200
Add more self-tests for 'hash_map' with Value type with non-trivial constructor/destructor ... to document the current behavior. gcc/ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Extend. (test_map_of_type_with_ctor_and_dtor_expand): Add function. (hash_map_tests_c_tests): Call it.
</cut>
Confirming: correctly identified the culprit. ;-)
See also https://gcc.gnu.org/PR101959 "[12 Regression] hash_map self test bootstrap failure".
Fixed yesterday via commit bb04a03c6f9bacc890118b9e12b657503093c2f8 "Make 'gcc/hash-map-tests.c:test_map_of_type_with_ctor_and_dtor_expand' work on 32-bit architectures [PR101959]".
Grüße Thomas
Results regressed to (for first_bad == e4f16e9f357a38ec702fb69a0ffab9d292a6af9b) # reset_artifacts: -10 # true: 0 # build_abe binutils: 1 # First few build errors in logs: # 00:02:51 cc1: internal compiler error: in fail, at selftest.c:47 # 00:02:51 cc1plus: internal compiler error: in fail, at selftest.c:47 # 00:02:51 make[3]: *** [s-selftest-c] Error 1 # 00:02:51 make[3]: *** [s-selftest-c++] Error 1 # 00:02:51 make[2]: *** [all-stage1-gcc] Error 2 # 00:02:51 make[1]: *** [stage1-bubble] Error 2 # 00:02:51 make: *** [all] Error 2
from (for last_good == 602fca427df6c5f7452677cfcdd16a5b9a3ca86a) # reset_artifacts: -10 # true: 0 # build_abe binutils: 1 # build_abe bootstrap: 2
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Build top page/logs: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/
Configuration details:
Reproduce builds:
<cut> mkdir investigate-gcc-e4f16e9f357a38ec702fb69a0ffab9d292a6af9b cd investigate-gcc-e4f16e9f357a38ec702fb69a0ffab9d292a6af9b
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_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_gnu-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 e4f16e9f357a38ec702fb69a0ffab9d292a6af9b ../artifacts/test.sh
# Reproduce last_good build git checkout --detach 602fca427df6c5f7452677cfcdd16a5b9a3ca86a ../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/c...
Artifacts: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Build log: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/c...
Full commit (up to 1000 lines):
<cut> commit e4f16e9f357a38ec702fb69a0ffab9d292a6af9b Author: Thomas Schwinge <thomas@codesourcery.com> Date: Fri Aug 13 17:53:12 2021 +0200
Add more self-tests for 'hash_map' with Value type with non-trivial constructor/destructor ... to document the current behavior. gcc/ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Extend. (test_map_of_type_with_ctor_and_dtor_expand): Add function. (hash_map_tests_c_tests): Call it.
gcc/hash-map-tests.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+)
diff --git a/gcc/hash-map-tests.c b/gcc/hash-map-tests.c index 5b6b192cd28..257f2be0c26 100644 --- a/gcc/hash-map-tests.c +++ b/gcc/hash-map-tests.c @@ -278,6 +278,156 @@ test_map_of_type_with_ctor_and_dtor ()
ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
}
- /* Verify basic construction and destruction of Value objects. */
- {
- /* Configure, arbitrary. */
- const size_t N_init = 0;
- const int N_elem = 28;
- void *a[N_elem];
- for (size_t i = 0; i < N_elem; ++i)
a[i] = &a[i];
- val_t::ndefault = 0;
- val_t::ncopy = 0;
- val_t::nassign = 0;
- val_t::ndtor = 0;
- Map m (N_init);
- ASSERT_EQ (val_t::ndefault
+ val_t::ncopy
+ val_t::nassign
+ val_t::ndtor, 0);
- for (int i = 0; i < N_elem; ++i)
{
m.get_or_insert (a[i]);
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, 0);
ASSERT_EQ (val_t::nassign, 0);
ASSERT_EQ (val_t::ndtor, i);
m.remove (a[i]);
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, 0);
ASSERT_EQ (val_t::nassign, 0);
ASSERT_EQ (val_t::ndtor, 1 + i);
}
- }
+}
+/* Verify aspects of 'hash_table::expand'. */
+static void +test_map_of_type_with_ctor_and_dtor_expand (bool remove_some_inline) +{
- /* Configure, so that hash table expansion triggers a few times. */
- const size_t N_init = 0;
- const int N_elem = 70;
- size_t expand_c_expected = 4;
- size_t expand_c = 0;
- void *a[N_elem];
- for (size_t i = 0; i < N_elem; ++i)
- a[i] = &a[i];
- typedef hash_map <void *, val_t> Map;
- /* Note that we are starting with a fresh 'Map'. Even if an existing one has
been cleared out completely, there remain 'deleted' elements, and these
would disturb the following logic, where we don't have access to the
actual 'm_n_deleted' value. */
- size_t m_n_deleted = 0;
- val_t::ndefault = 0;
- val_t::ncopy = 0;
- val_t::nassign = 0;
- val_t::ndtor = 0;
- Map m (N_init);
- /* In the following, in particular related to 'expand', we're adapting from
the internal logic of 'hash_table', glossing over "some details" not
relevant for this testing here. */
- /* Per 'hash_table::hash_table'. */
- size_t m_size;
- {
- unsigned int size_prime_index_ = hash_table_higher_prime_index (N_init);
- m_size = prime_tab[size_prime_index_].prime;
- }
- int n_expand_moved = 0;
- for (int i = 0; i < N_elem; ++i)
- {
size_t elts = m.elements ();
/* Per 'hash_table::find_slot_with_hash'. */
size_t m_n_elements = elts + m_n_deleted;
bool expand = m_size * 3 <= m_n_elements * 4;
m.get_or_insert (a[i]);
if (expand)
{
++expand_c;
/* Per 'hash_table::expand'. */
{
unsigned int nindex = hash_table_higher_prime_index (elts * 2);
m_size = prime_tab[nindex].prime;
}
m_n_deleted = 0;
/* All non-deleted elements have been moved. */
n_expand_moved += i;
if (remove_some_inline)
n_expand_moved -= (i + 2) / 3;
}
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, n_expand_moved);
ASSERT_EQ (val_t::nassign, 0);
if (remove_some_inline)
ASSERT_EQ (val_t::ndtor, (i + 2) / 3);
else
ASSERT_EQ (val_t::ndtor, 0);
/* Remove some inline. This never triggers an 'expand' here, but via
'm_n_deleted' does influence any following one. */
if (remove_some_inline
&& !(i % 3))
{
m.remove (a[i]);
/* Per 'hash_table::remove_elt_with_hash'. */
m_n_deleted++;
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, n_expand_moved);
ASSERT_EQ (val_t::nassign, 0);
ASSERT_EQ (val_t::ndtor, 1 + (i + 2) / 3);
}
- }
- ASSERT_EQ (expand_c, expand_c_expected);
- int ndefault = val_t::ndefault;
- int ncopy = val_t::ncopy;
- int nassign = val_t::nassign;
- int ndtor = val_t::ndtor;
- for (int i = 0; i < N_elem; ++i)
- {
if (remove_some_inline
&& !(i % 3))
continue;
m.remove (a[i]);
++ndtor;
ASSERT_EQ (val_t::ndefault, ndefault);
ASSERT_EQ (val_t::ncopy, ncopy);
ASSERT_EQ (val_t::nassign, nassign);
ASSERT_EQ (val_t::ndtor, ndtor);
- }
}
/* Test calling empty on a hash_map that has a key type with non-zero @@ -309,6 +459,8 @@ hash_map_tests_c_tests () test_map_of_strings_to_int (); test_map_of_int_to_strings (); test_map_of_type_with_ctor_and_dtor ();
- test_map_of_type_with_ctor_and_dtor_expand (false);
- test_map_of_type_with_ctor_and_dtor_expand (true); test_nonzero_empty_key ();
}
</cut>
----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
Hi Thomas,
Thanks!
This CI should get faster turn around times soon; our goal is to get notifications to developers within 24 hours of bad commit hitting trunk.
-- Maxim Kuvyrkov https://www.linaro.org
On 19 Aug 2021, at 21:01, Thomas Schwinge thomas@codesourcery.com wrote:
Hi!
On 2021-08-19T17:41:17+0000, ci_notify@linaro.org wrote:
Successfully identified regression in *gcc* in CI configuration tcwg_gcc_bootstrap/master-arm-bootstrap. So far, this commit has regressed CI configurations:
- tcwg_gcc_bootstrap/master-arm-bootstrap
Culprit:
<cut> commit e4f16e9f357a38ec702fb69a0ffab9d292a6af9b Author: Thomas Schwinge <thomas@codesourcery.com> Date: Fri Aug 13 17:53:12 2021 +0200
Add more self-tests for 'hash_map' with Value type with non-trivial constructor/destructor
... to document the current behavior.
gcc/ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Extend. (test_map_of_type_with_ctor_and_dtor_expand): Add function. (hash_map_tests_c_tests): Call it.
</cut>
Confirming: correctly identified the culprit. ;-)
See also https://gcc.gnu.org/PR101959 "[12 Regression] hash_map self test bootstrap failure".
Fixed yesterday via commit bb04a03c6f9bacc890118b9e12b657503093c2f8 "Make 'gcc/hash-map-tests.c:test_map_of_type_with_ctor_and_dtor_expand' work on 32-bit architectures [PR101959]".
Grüße Thomas
Results regressed to (for first_bad == e4f16e9f357a38ec702fb69a0ffab9d292a6af9b) # reset_artifacts: -10 # true: 0 # build_abe binutils: 1 # First few build errors in logs: # 00:02:51 cc1: internal compiler error: in fail, at selftest.c:47 # 00:02:51 cc1plus: internal compiler error: in fail, at selftest.c:47 # 00:02:51 make[3]: *** [s-selftest-c] Error 1 # 00:02:51 make[3]: *** [s-selftest-c++] Error 1 # 00:02:51 make[2]: *** [all-stage1-gcc] Error 2 # 00:02:51 make[1]: *** [stage1-bubble] Error 2 # 00:02:51 make: *** [all] Error 2
from (for last_good == 602fca427df6c5f7452677cfcdd16a5b9a3ca86a) # reset_artifacts: -10 # true: 0 # build_abe binutils: 1 # build_abe bootstrap: 2
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Build top page/logs: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/
Configuration details:
Reproduce builds:
<cut> mkdir investigate-gcc-e4f16e9f357a38ec702fb69a0ffab9d292a6af9b cd investigate-gcc-e4f16e9f357a38ec702fb69a0ffab9d292a6af9b
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_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... --fail chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_gnu-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 e4f16e9f357a38ec702fb69a0ffab9d292a6af9b ../artifacts/test.sh
# Reproduce last_good build git checkout --detach 602fca427df6c5f7452677cfcdd16a5b9a3ca86a ../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/c...
Artifacts: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/a... Build log: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap/1/c...
Full commit (up to 1000 lines):
<cut> commit e4f16e9f357a38ec702fb69a0ffab9d292a6af9b Author: Thomas Schwinge <thomas@codesourcery.com> Date: Fri Aug 13 17:53:12 2021 +0200
Add more self-tests for 'hash_map' with Value type with non-trivial constructor/destructor
... to document the current behavior.
gcc/ * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Extend. (test_map_of_type_with_ctor_and_dtor_expand): Add function. (hash_map_tests_c_tests): Call it.
gcc/hash-map-tests.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+)
diff --git a/gcc/hash-map-tests.c b/gcc/hash-map-tests.c index 5b6b192cd28..257f2be0c26 100644 --- a/gcc/hash-map-tests.c +++ b/gcc/hash-map-tests.c @@ -278,6 +278,156 @@ test_map_of_type_with_ctor_and_dtor ()
ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
}
- /* Verify basic construction and destruction of Value objects. */
- {
- /* Configure, arbitrary. */
- const size_t N_init = 0;
- const int N_elem = 28;
- void *a[N_elem];
- for (size_t i = 0; i < N_elem; ++i)
a[i] = &a[i];
- val_t::ndefault = 0;
- val_t::ncopy = 0;
- val_t::nassign = 0;
- val_t::ndtor = 0;
- Map m (N_init);
- ASSERT_EQ (val_t::ndefault
+ val_t::ncopy
+ val_t::nassign
+ val_t::ndtor, 0);
- for (int i = 0; i < N_elem; ++i)
{
m.get_or_insert (a[i]);
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, 0);
ASSERT_EQ (val_t::nassign, 0);
ASSERT_EQ (val_t::ndtor, i);
m.remove (a[i]);
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, 0);
ASSERT_EQ (val_t::nassign, 0);
ASSERT_EQ (val_t::ndtor, 1 + i);
}
- }
+}
+/* Verify aspects of 'hash_table::expand'. */
+static void +test_map_of_type_with_ctor_and_dtor_expand (bool remove_some_inline) +{
- /* Configure, so that hash table expansion triggers a few times. */
- const size_t N_init = 0;
- const int N_elem = 70;
- size_t expand_c_expected = 4;
- size_t expand_c = 0;
- void *a[N_elem];
- for (size_t i = 0; i < N_elem; ++i)
- a[i] = &a[i];
- typedef hash_map <void *, val_t> Map;
- /* Note that we are starting with a fresh 'Map'. Even if an existing one has
been cleared out completely, there remain 'deleted' elements, and these
would disturb the following logic, where we don't have access to the
actual 'm_n_deleted' value. */
- size_t m_n_deleted = 0;
- val_t::ndefault = 0;
- val_t::ncopy = 0;
- val_t::nassign = 0;
- val_t::ndtor = 0;
- Map m (N_init);
- /* In the following, in particular related to 'expand', we're adapting from
the internal logic of 'hash_table', glossing over "some details" not
relevant for this testing here. */
- /* Per 'hash_table::hash_table'. */
- size_t m_size;
- {
- unsigned int size_prime_index_ = hash_table_higher_prime_index (N_init);
- m_size = prime_tab[size_prime_index_].prime;
- }
- int n_expand_moved = 0;
- for (int i = 0; i < N_elem; ++i)
- {
size_t elts = m.elements ();
/* Per 'hash_table::find_slot_with_hash'. */
size_t m_n_elements = elts + m_n_deleted;
bool expand = m_size * 3 <= m_n_elements * 4;
m.get_or_insert (a[i]);
if (expand)
{
++expand_c;
/* Per 'hash_table::expand'. */
{
unsigned int nindex = hash_table_higher_prime_index (elts * 2);
m_size = prime_tab[nindex].prime;
}
m_n_deleted = 0;
/* All non-deleted elements have been moved. */
n_expand_moved += i;
if (remove_some_inline)
n_expand_moved -= (i + 2) / 3;
}
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, n_expand_moved);
ASSERT_EQ (val_t::nassign, 0);
if (remove_some_inline)
ASSERT_EQ (val_t::ndtor, (i + 2) / 3);
else
ASSERT_EQ (val_t::ndtor, 0);
/* Remove some inline. This never triggers an 'expand' here, but via
'm_n_deleted' does influence any following one. */
if (remove_some_inline
&& !(i % 3))
{
m.remove (a[i]);
/* Per 'hash_table::remove_elt_with_hash'. */
m_n_deleted++;
ASSERT_EQ (val_t::ndefault, 1 + i);
ASSERT_EQ (val_t::ncopy, n_expand_moved);
ASSERT_EQ (val_t::nassign, 0);
ASSERT_EQ (val_t::ndtor, 1 + (i + 2) / 3);
}
- }
- ASSERT_EQ (expand_c, expand_c_expected);
- int ndefault = val_t::ndefault;
- int ncopy = val_t::ncopy;
- int nassign = val_t::nassign;
- int ndtor = val_t::ndtor;
- for (int i = 0; i < N_elem; ++i)
- {
if (remove_some_inline
&& !(i % 3))
continue;
m.remove (a[i]);
++ndtor;
ASSERT_EQ (val_t::ndefault, ndefault);
ASSERT_EQ (val_t::ncopy, ncopy);
ASSERT_EQ (val_t::nassign, nassign);
ASSERT_EQ (val_t::ndtor, ndtor);
- }
}
/* Test calling empty on a hash_map that has a key type with non-zero @@ -309,6 +459,8 @@ hash_map_tests_c_tests () test_map_of_strings_to_int (); test_map_of_int_to_strings (); test_map_of_type_with_ctor_and_dtor ();
- test_map_of_type_with_ctor_and_dtor_expand (false);
- test_map_of_type_with_ctor_and_dtor_expand (true); test_nonzero_empty_key ();
}
</cut>
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 _______________________________________________ linaro-toolchain mailing list linaro-toolchain@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-toolchain
linaro-toolchain@lists.linaro.org