OSDN Git Service

PR 43839
[pf3gnuchains/gcc-fork.git] / libgfortran / generated / pack_c8.c
index 1a4e78e..7971e2b 100644 (file)
@@ -1,5 +1,5 @@
 /* Specific implementation of the PACK intrinsic
-   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Paul Brook <paul@nowt.org>
 
 This file is part of the GNU Fortran 95 runtime library (libgfortran).
@@ -7,26 +7,21 @@ This file is part of the GNU Fortran 95 runtime library (libgfortran).
 Libgfortran is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public
 License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-In addition to the permissions in the GNU General Public License, the
-Free Software Foundation gives you unlimited permission to link the
-compiled version of this file into combinations with other programs,
-and to distribute those combinations without any restriction coming
-from the use of this file.  (The General Public License restrictions
-do apply in other respects; for example, they cover modification of
-the file, and distribution when not linked into a combine
-executable.)
+version 3 of the License, or (at your option) any later version.
 
 Ligbfortran is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public
-License along with libgfortran; see the file COPYING.  If not,
-write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
 
 #include "libgfortran.h"
 #include <stdlib.h>
@@ -82,7 +77,7 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
 {
   /* r.* indicates the return array.  */
   index_type rstride0;
-  GFC_COMPLEX_8 *rptr;
+  GFC_COMPLEX_8 * restrict rptr;
   /* s.* indicates the source array.  */
   index_type sstride[GFC_MAX_DIMENSIONS];
   index_type sstride0;
@@ -127,11 +122,11 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
   for (n = 0; n < dim; n++)
     {
       count[n] = 0;
-      extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound;
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
       if (extent[n] <= 0)
        zero_sized = 1;
-      sstride[n] = array->dim[n].stride;
-      mstride[n] = mask->dim[n].stride * mask_kind;
+      sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
+      mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
     }
   if (sstride[0] == 0)
     sstride[0] = 1;
@@ -143,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.  */
@@ -152,7 +147,7 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
        {
          /* The return array will have as many
             elements as there are in VECTOR.  */
-         total = vector->dim[0].ubound + 1 - vector->dim[0].lbound;
+         total = GFC_DESCRIPTOR_EXTENT(vector,0);
          if (total < 0)
            {
              total = 0;
@@ -160,69 +155,15 @@ 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)
        {
          /* Setup the array descriptor.  */
-         ret->dim[0].lbound = 0;
-         ret->dim[0].ubound = total - 1;
-         ret->dim[0].stride = 1;
+         GFC_DIMENSION_SET(ret->dim[0], 0, total-1, 1);
 
          ret->offset = 0;
          if (total == 0)
@@ -239,7 +180,7 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
          /* We come here because of range checking.  */
          index_type ret_extent;
 
-         ret_extent = ret->dim[0].ubound + 1 - ret->dim[0].lbound;
+         ret_extent = GFC_DESCRIPTOR_EXTENT(ret,0);
          if (total != ret_extent)
            runtime_error ("Incorrect extent in return value of PACK intrinsic;"
                           " is %ld, should be %ld", (long int) total,
@@ -247,7 +188,7 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
        }
     }
 
-  rstride0 = ret->dim[0].stride;
+  rstride0 = GFC_DESCRIPTOR_STRIDE(ret,0);
   if (rstride0 == 0)
     rstride0 = 1;
   sstride0 = sstride[0];
@@ -296,11 +237,11 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array,
   /* Add any remaining elements from VECTOR.  */
   if (vector)
     {
-      n = vector->dim[0].ubound + 1 - vector->dim[0].lbound;
+      n = GFC_DESCRIPTOR_EXTENT(vector,0);
       nelem = ((rptr - ret->data) / rstride0);
       if (n > nelem)
         {
-          sstride0 = vector->dim[0].stride;
+          sstride0 = GFC_DESCRIPTOR_STRIDE(vector,0);
           if (sstride0 == 0)
             sstride0 = 1;