This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, libfortran] Use functon for counting true values
- From: Thomas Koenig <tkoenig at netcologne dot de>
- To: fortran at gcc dot gnu dot org
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 29 Aug 2009 21:36:24 +0200
- Subject: [patch, libfortran] Use functon for counting true values
Hello world,
this patch uses the new count_0 function for the pack intrinsic.
Incidentally, it also fixes a bug discovered in count_0 during
regression testing of this patch :-) No test case, because
no new functionality.
OK for trunk?
Thomas
2009-08-29 Thomas Koenig <tkoenig@gcc.gnu.org>
* m4/pack.m4 (pack_'rtype_code`): Use count_0 for counting true
values in a logical array. Mark bounds checking tests as
unlikely.
* intrinsics/pack_generic.c (pack_internal): Likewise.
* runtime/bounds.c (count_0): Fix off-by-one error in detecting
empty arrays.
* generated/pack_c4.c: Regenerated.
* generated/pack_c8.c: Regenerated.
* generated/pack_c10.c: Regenerated.
* generated/pack_c16.c: Regenerated.
* generated/pack_i1.c: Regenerated.
* generated/pack_i16.c: Regenerated.
* generated/pack_i2.c: Regenerated.
* generated/pack_i4.c: Regenerated.
* generated/pack_i8.c: Regenerated.
* generated/pack_r4.c: Regenerated.
* generated/pack_r8.c: Regenerated.
* generated/pack_r10.c: Regenerated.
* generated/pack_r16.c: Regenerated.
Index: intrinsics/pack_generic.c
===================================================================
--- intrinsics/pack_generic.c (revision 151132)
+++ intrinsics/pack_generic.c (working copy)
@@ -132,7 +132,7 @@ pack_internal (gfc_array_char *ret, cons
if (mstride[0] == 0)
mstride[0] = mask_kind;
- if (ret->data == NULL || compile_options.bounds_check)
+ if (ret->data == NULL || unlikely (compile_options.bounds_check))
{
/* Count the elements, either for allocating memory or
for bounds checking. */
@@ -147,58 +147,7 @@ pack_internal (gfc_array_char *ret, cons
{
/* We have to count the true elements in MASK. */
- /* TODO: We could speed up pack easily in the case of only
- few .TRUE. entries in MASK, by keeping track of where we
- would be in the source array during the initial traversal
- of MASK, and caching the pointers to those elements. Then,
- supposed the number of elements is small enough, we would
- only have to traverse the list, and copy those elements
- into the result array. In the case of datatypes which fit
- in one of the integer types we could also cache the
- value instead of a pointer to it.
- This approach might be bad from the point of view of
- cache behavior in the case where our cache is not big
- enough to hold all elements that have to be copied. */
-
- const GFC_LOGICAL_1 *m = mptr;
-
- total = 0;
- if (zero_sized)
- m = NULL;
-
- while (m)
- {
- /* Test this element. */
- if (*m)
- total++;
-
- /* Advance to the next element. */
- m += mstride[0];
- count[0]++;
- n = 0;
- while (count[n] == extent[n])
- {
- /* When we get to the end of a dimension, reset it
- and increment the next dimension. */
- count[n] = 0;
- /* We could precalculate this product, but this is a
- less frequently used path so probably not worth
- it. */
- m -= mstride[n] * extent[n];
- n++;
- if (n >= dim)
- {
- /* Break out of the loop. */
- m = NULL;
- break;
- }
- else
- {
- count[n]++;
- m += mstride[n];
- }
- }
- }
+ total = count_0 (mask);
}
if (ret->data == NULL)
Index: m4/pack.m4
===================================================================
--- m4/pack.m4 (revision 151132)
+++ m4/pack.m4 (working copy)
@@ -139,7 +139,7 @@ pack_'rtype_code` ('rtype` *ret, const '
else
sptr = array->data;
- if (ret->data == NULL || compile_options.bounds_check)
+ if (ret->data == NULL || unlikely (compile_options.bounds_check))
{
/* Count the elements, either for allocating memory or
for bounds checking. */
@@ -156,62 +156,10 @@ pack_'rtype_code` ('rtype` *ret, const '
}
}
else
- {
- /* We have to count the true elements in MASK. */
-
- /* TODO: We could speed up pack easily in the case of only
- few .TRUE. entries in MASK, by keeping track of where we
- would be in the source array during the initial traversal
- of MASK, and caching the pointers to those elements. Then,
- supposed the number of elements is small enough, we would
- only have to traverse the list, and copy those elements
- into the result array. In the case of datatypes which fit
- in one of the integer types we could also cache the
- value instead of a pointer to it.
- This approach might be bad from the point of view of
- cache behavior in the case where our cache is not big
- enough to hold all elements that have to be copied. */
-
- const GFC_LOGICAL_1 *m = mptr;
-
- total = 0;
- if (zero_sized)
- m = NULL;
-
- while (m)
- {
- /* Test this element. */
- if (*m)
- total++;
-
- /* Advance to the next element. */
- m += mstride[0];
- count[0]++;
- n = 0;
- while (count[n] == extent[n])
- {
- /* When we get to the end of a dimension, reset it
- and increment the next dimension. */
- count[n] = 0;
- /* We could precalculate this product, but this is a
- less frequently used path so probably not worth
- it. */
- m -= mstride[n] * extent[n];
- n++;
- if (n >= dim)
- {
- /* Break out of the loop. */
- m = NULL;
- break;
- }
- else
- {
- count[n]++;
- m += mstride[n];
- }
- }
- }
- }
+ {
+ /* We have to count the true elements in MASK. */
+ total = count_0 (mask);
+ }
if (ret->data == NULL)
{
Index: runtime/bounds.c
===================================================================
--- runtime/bounds.c (revision 151132)
+++ runtime/bounds.c (working copy)
@@ -237,7 +237,7 @@ index_type count_0 (const gfc_array_l1 *
extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
count[n] = 0;
- if (extent[n] < 0)
+ if (extent[n] <= 0)
return 0;
}