summaryrefslogtreecommitdiffstats
path: root/libgfortran
diff options
context:
space:
mode:
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-30 09:02:01 +0000
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-30 09:02:01 +0000
commit4055b3674a094901edee337be5e2001c274f2845 (patch)
tree6f3af1ff5e03befb8f48fd165af7da8a30aacf8e /libgfortran
parentc557b81edd3c8fcb8f44ca7a2180309917116a17 (diff)
downloadppe42-gcc-4055b3674a094901edee337be5e2001c274f2845.tar.gz
ppe42-gcc-4055b3674a094901edee337be5e2001c274f2845.zip
2009-08-30 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151225 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog22
-rw-r--r--libgfortran/generated/pack_c10.c62
-rw-r--r--libgfortran/generated/pack_c16.c62
-rw-r--r--libgfortran/generated/pack_c4.c62
-rw-r--r--libgfortran/generated/pack_c8.c62
-rw-r--r--libgfortran/generated/pack_i1.c62
-rw-r--r--libgfortran/generated/pack_i16.c62
-rw-r--r--libgfortran/generated/pack_i2.c62
-rw-r--r--libgfortran/generated/pack_i4.c62
-rw-r--r--libgfortran/generated/pack_i8.c62
-rw-r--r--libgfortran/generated/pack_r10.c62
-rw-r--r--libgfortran/generated/pack_r16.c62
-rw-r--r--libgfortran/generated/pack_r4.c62
-rw-r--r--libgfortran/generated/pack_r8.c62
-rw-r--r--libgfortran/intrinsics/pack_generic.c55
-rw-r--r--libgfortran/m4/pack.m462
-rw-r--r--libgfortran/runtime/bounds.c2
17 files changed, 95 insertions, 852 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 8ef88c0d025..f1ac312833b 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,25 @@
+2009-08-30 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.
+
2009-08-25 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libfortran/34670
diff --git a/libgfortran/generated/pack_c10.c b/libgfortran/generated/pack_c10.c
index 008fb5c9236..cc66c538e1c 100644
--- a/libgfortran/generated/pack_c10.c
+++ b/libgfortran/generated/pack_c10.c
@@ -138,7 +138,7 @@ pack_c10 (gfc_array_c10 *ret, const gfc_array_c10 *array,
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. */
@@ -155,62 +155,10 @@ pack_c10 (gfc_array_c10 *ret, const gfc_array_c10 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_c16.c b/libgfortran/generated/pack_c16.c
index e7d039f5bec..9397262dd06 100644
--- a/libgfortran/generated/pack_c16.c
+++ b/libgfortran/generated/pack_c16.c
@@ -138,7 +138,7 @@ pack_c16 (gfc_array_c16 *ret, const gfc_array_c16 *array,
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. */
@@ -155,62 +155,10 @@ pack_c16 (gfc_array_c16 *ret, const gfc_array_c16 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_c4.c b/libgfortran/generated/pack_c4.c
index fe1f68d4225..093bdcc9a1d 100644
--- a/libgfortran/generated/pack_c4.c
+++ b/libgfortran/generated/pack_c4.c
@@ -138,7 +138,7 @@ pack_c4 (gfc_array_c4 *ret, const gfc_array_c4 *array,
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. */
@@ -155,62 +155,10 @@ pack_c4 (gfc_array_c4 *ret, const gfc_array_c4 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_c8.c b/libgfortran/generated/pack_c8.c
index f5a27eca6f5..7971e2ba135 100644
--- a/libgfortran/generated/pack_c8.c
+++ b/libgfortran/generated/pack_c8.c
@@ -138,7 +138,7 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
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. */
@@ -155,62 +155,10 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_i1.c b/libgfortran/generated/pack_i1.c
index edc895082a4..3e4647dbd55 100644
--- a/libgfortran/generated/pack_i1.c
+++ b/libgfortran/generated/pack_i1.c
@@ -138,7 +138,7 @@ pack_i1 (gfc_array_i1 *ret, const gfc_array_i1 *array,
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. */
@@ -155,62 +155,10 @@ pack_i1 (gfc_array_i1 *ret, const gfc_array_i1 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_i16.c b/libgfortran/generated/pack_i16.c
index 8f38a2747ec..99d3491c38f 100644
--- a/libgfortran/generated/pack_i16.c
+++ b/libgfortran/generated/pack_i16.c
@@ -138,7 +138,7 @@ pack_i16 (gfc_array_i16 *ret, const gfc_array_i16 *array,
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. */
@@ -155,62 +155,10 @@ pack_i16 (gfc_array_i16 *ret, const gfc_array_i16 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_i2.c b/libgfortran/generated/pack_i2.c
index 149e9f6f67d..e796d169f76 100644
--- a/libgfortran/generated/pack_i2.c
+++ b/libgfortran/generated/pack_i2.c
@@ -138,7 +138,7 @@ pack_i2 (gfc_array_i2 *ret, const gfc_array_i2 *array,
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. */
@@ -155,62 +155,10 @@ pack_i2 (gfc_array_i2 *ret, const gfc_array_i2 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_i4.c b/libgfortran/generated/pack_i4.c
index dad10d62d46..91ce99fe4fd 100644
--- a/libgfortran/generated/pack_i4.c
+++ b/libgfortran/generated/pack_i4.c
@@ -138,7 +138,7 @@ pack_i4 (gfc_array_i4 *ret, const gfc_array_i4 *array,
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. */
@@ -155,62 +155,10 @@ pack_i4 (gfc_array_i4 *ret, const gfc_array_i4 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_i8.c b/libgfortran/generated/pack_i8.c
index 0a23aa5b72f..e49d8c29e95 100644
--- a/libgfortran/generated/pack_i8.c
+++ b/libgfortran/generated/pack_i8.c
@@ -138,7 +138,7 @@ pack_i8 (gfc_array_i8 *ret, const gfc_array_i8 *array,
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. */
@@ -155,62 +155,10 @@ pack_i8 (gfc_array_i8 *ret, const gfc_array_i8 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_r10.c b/libgfortran/generated/pack_r10.c
index e4bbe6fabcf..f70c932640e 100644
--- a/libgfortran/generated/pack_r10.c
+++ b/libgfortran/generated/pack_r10.c
@@ -138,7 +138,7 @@ pack_r10 (gfc_array_r10 *ret, const gfc_array_r10 *array,
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. */
@@ -155,62 +155,10 @@ pack_r10 (gfc_array_r10 *ret, const gfc_array_r10 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_r16.c b/libgfortran/generated/pack_r16.c
index 7dff30b7006..ff2ad6e7eed 100644
--- a/libgfortran/generated/pack_r16.c
+++ b/libgfortran/generated/pack_r16.c
@@ -138,7 +138,7 @@ pack_r16 (gfc_array_r16 *ret, const gfc_array_r16 *array,
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. */
@@ -155,62 +155,10 @@ pack_r16 (gfc_array_r16 *ret, const gfc_array_r16 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_r4.c b/libgfortran/generated/pack_r4.c
index 51d46a27218..0c08b8c8c94 100644
--- a/libgfortran/generated/pack_r4.c
+++ b/libgfortran/generated/pack_r4.c
@@ -138,7 +138,7 @@ pack_r4 (gfc_array_r4 *ret, const gfc_array_r4 *array,
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. */
@@ -155,62 +155,10 @@ pack_r4 (gfc_array_r4 *ret, const gfc_array_r4 *array,
}
}
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)
{
diff --git a/libgfortran/generated/pack_r8.c b/libgfortran/generated/pack_r8.c
index 582c2b9aeb1..2b307e29a2b 100644
--- a/libgfortran/generated/pack_r8.c
+++ b/libgfortran/generated/pack_r8.c
@@ -138,7 +138,7 @@ pack_r8 (gfc_array_r8 *ret, const gfc_array_r8 *array,
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. */
@@ -155,62 +155,10 @@ pack_r8 (gfc_array_r8 *ret, const gfc_array_r8 *array,
}
}
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)
{
diff --git a/libgfortran/intrinsics/pack_generic.c b/libgfortran/intrinsics/pack_generic.c
index b611d777101..eb52f069d40 100644
--- a/libgfortran/intrinsics/pack_generic.c
+++ b/libgfortran/intrinsics/pack_generic.c
@@ -132,7 +132,7 @@ pack_internal (gfc_array_char *ret, const gfc_array_char *array,
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, const gfc_array_char *array,
{
/* 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)
diff --git a/libgfortran/m4/pack.m4 b/libgfortran/m4/pack.m4
index 910ffdcaac1..c5fd2fd817d 100644
--- a/libgfortran/m4/pack.m4
+++ b/libgfortran/m4/pack.m4
@@ -139,7 +139,7 @@ pack_'rtype_code` ('rtype` *ret, const 'rtype` *array,
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 'rtype` *array,
}
}
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)
{
diff --git a/libgfortran/runtime/bounds.c b/libgfortran/runtime/bounds.c
index 2d2ed76e6b8..35bfa1e2a46 100644
--- a/libgfortran/runtime/bounds.c
+++ b/libgfortran/runtime/bounds.c
@@ -237,7 +237,7 @@ index_type count_0 (const gfc_array_l1 * array)
extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
count[n] = 0;
- if (extent[n] < 0)
+ if (extent[n] <= 0)
return 0;
}
OpenPOWER on IntegriCloud