Patchwork [Fortran-dev] Merged from trunk; [patch, committed] ISO_Fortran_binding.h

login
register
mail settings
Submitter Tobias Burnus
Date March 6, 2012, 5:02 p.m.
Message ID <4F564327.7060502@net-b.de>
Download mbox | patch
Permalink /patch/144961/
State New
Headers show

Comments

Tobias Burnus - March 6, 2012, 5:02 p.m.
Dear Paul, dear all,

I have merged (Rev. 184999) the trunk (Rev. 184980) to the fortran-dev 
branch, which now followed GCC 4.8.

Additionally, I have committed to the fortran-dev branch (Rev. 185004) 
the first rough and incomplete version of ISO_Fortran_binding.h, which 
tries to follow TS 29113. In terms of the generated code, it should 
mostly be a no op, except that GFC_DIMENSION_SET now also sets the extent.

(See attachment. I wrote it some weeks ago, but I think it makes sense 
to have it already in svn despite its embryonic state.)

The library currently does not set "sm" - thus, it breaks if the 
compiler itself expects this. The library currently also only handles 
the old ubound/stride - thus, if the compiler does not properly set 
those, it will also fail. I have not checked what the compiler currently 
uses. At least in simple cases, it sets both the old ubound/stride and 
the new sm/extent.

The "sm" information needs the element size in bytes. In order to obtain 
it, it is insufficient to modify only libgfortran.h's macros - thus, a 
larger patch is required. Most convenient would be if one could directly 
convert the code to only use sm/extent, but it should be also possible 
to write the code such that also ubound/stride are set.

But before starting this, the compiler itself needs to be in a 
reasonable state such that one can easily assign the breakage. - It 
might be, but I have not looked at the generated code for more than a 
year. - Additional, new code (inline sum and other features) might have 
to be first updated, though, updating after the library changes might be 
also possible.

Tobias

PS: I do *not* intent to work on fortran-dev in the next weeks. However, 
I might work on it during the 4.8 development.

Patch

Index: libgfortran/ChangeLog.fortran-dev
===================================================================
--- libgfortran/ChangeLog.fortran-dev	(revision 184980)
+++ libgfortran/ChangeLog.fortran-dev	(working copy)
@@ -1,3 +1,10 @@ 
+2012-03-06  Tobias Burnus  <burnus@net-b.de>
+
+	* ISO_Fortran_binding.h: New.
+	* libgfortran.h: Include it.
+	(descriptor_dimension): Replace by a CFI_dim_t typedef.
+	(GFC_DIMENSION_SET): Also set extent.
+
 2010-09-01  Paul Thomas  <pault@gcc.gnu.org>
 
 	* libgfortran.h: Add 'sm' and 'extent' fields to structure
Index: libgfortran/libgfortran.h
===================================================================
--- libgfortran/libgfortran.h	(revision 184980)
+++ libgfortran/libgfortran.h	(working copy)
@@ -319,26 +319,13 @@  internal_proto(big_endian);
 # endif
 #endif
 
-typedef struct descriptor_dimension
-{
-  index_type _stride;
-  index_type _lbound;
-  index_type _ubound;
-  index_type _sm;
-  index_type _extent;
-}
 
-descriptor_dimension;
+#include "ISO_Fortran_binding.h"
 
-#define GFC_ARRAY_DESCRIPTOR(r, type) \
-struct {\
-  type *data;\
-  size_t offset;\
-  index_type dtype;\
-  index_type size;\
-  descriptor_dimension dim[r];\
-}
+typedef CFI_dim_t descriptor_dimension;
+#define GFC_ARRAY_DESCRIPTOR(r, type) CFI_GFC_CDESC_T (r, type)
 
+
 /* Commonly used array descriptor types.  */
 typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, void) gfc_array_void;
 typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, char) gfc_array_char;
@@ -381,23 +368,31 @@  typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS,
 #define GFC_DESCRIPTOR_DATA(desc) ((desc)->data)
 #define GFC_DESCRIPTOR_DTYPE(desc) ((desc)->dtype)
 
-#define GFC_DIMENSION_LBOUND(dim) ((dim)._lbound)
+#define GFC_DIMENSION_LBOUND(dim) ((dim).lower_bound)
+/* Old. */
 #define GFC_DIMENSION_UBOUND(dim) ((dim)._ubound)
-#define GFC_DIMENSION_STRIDE(dim) ((dim)._stride)
-#define GFC_DIMENSION_EXTENT(dim) ((dim)._ubound + 1 - (dim)._lbound)
+#define GFC_DIMENSION_EXTENT(dim) ((dim).ubound + 1 - (dim).lower_bound)
+
+/* New. */
+/*
+  #define GFC_DIMENSION_UBOUND(dim) ((dim).lower_bound + (dim).extent - 1)
+  #define GFC_DIMENSION_EXTENT(dim) ((dim).extent)
+*/
+
 #define GFC_DIMENSION_SET(dim,lb,ub,str) \
   do \
     { \
-      (dim)._lbound = lb;			\
+      (dim).lower_bound = lb;			\
       (dim)._ubound = ub;			\
+      (dim).extent = ub-lb+1;			\
       (dim)._stride = str;			\
     } while (0)
 	    
 
-#define GFC_DESCRIPTOR_LBOUND(desc,i) ((desc)->dim[i]._lbound)
+#define GFC_DESCRIPTOR_LBOUND(desc,i) ((desc)->dim[i].lower_bound)
 #define GFC_DESCRIPTOR_UBOUND(desc,i) ((desc)->dim[i]._ubound)
 #define GFC_DESCRIPTOR_EXTENT(desc,i) ((desc)->dim[i]._ubound + 1 \
-				      - (desc)->dim[i]._lbound)
+				      - (desc)->dim[i].lower_bound)
 #define GFC_DESCRIPTOR_EXTENT_BYTES(desc,i) \
   (GFC_DESCRIPTOR_EXTENT(desc,i) * GFC_DESCRIPTOR_SIZE(desc))
 
Index: libgfortran/ISO_Fortran_binding.h
===================================================================
--- libgfortran/ISO_Fortran_binding.h	(revision 0)
+++ libgfortran/ISO_Fortran_binding.h	(working copy)
@@ -0,0 +1,176 @@ 
+/* ISO_Fortran_binding.h of GCC's GNU Fortran compiler.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU Fortran runtime library (libgfortran)
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libgfortran 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libquadmath; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+
+/* Definitions as defined by ISO/IEC Technical Specification TS 29113
+   on Further Interoperability of Fortran with C.
+   Note: The technical specification only mandates the presence of certain
+   members; there might be additional compiler-specific fields.  */
+
+
+#ifndef ISO_FORTRAN_BINDING_H
+#define ISO_FORTRAN_BINDING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>  /* For size_t and ptrdiff_t.  */
+
+
+/* Constants, defined as macros.  */
+
+#define CFI_VERSION 1
+#define CFI_MAX_RANK 15
+
+#define CFI_attribute_pointer 1
+#define CFI_attribute_allocatable 2
+#define CFI_attribute_other 3
+
+
+/* FIXME: Those values have to match the compiler itself.
+   "NOTE 8.5: The specifiers for two intrinsic types can have the same value.
+    For example, CFI_type_int and CFI_type_int32_t might have the same value."
+
+   "The value for CFI_type_other shall be negative and distinct from all other
+    type specifiers. CFI_type_struct specifies a C structure that is
+    interoperable with a Fortran derived type; its value shall be positive and
+    distinct from all other type specifiers. If a C type is not interoperable
+    with a Fortran type and kind supported by the Fortran processor, its macro
+    shall evaluate to a negative value.  Otherwise, the value for an intrinsic
+    type shall be positive."  */
+
+#define CFI_type_signed_char 1
+#define CFI_type_short 2
+#define CFI_type_int 3
+#define CFI_type_long 4
+#define CFI_type_long_long 5
+#define CFI_type_size_t 6
+#define CFI_type_int8_t 7
+#define CFI_type_int16_t 8
+#define CFI_type_int32_t 9
+#define CFI_type_int64_t 10
+#define CFI_type_int_least8_t 11
+#define CFI_type_int_least16_t 12
+#define CFI_type_int_least32_t 13 
+#define CFI_type_int_least64_t 14
+#define CFI_type_int_fast8_t 15
+#define CFI_type_int_fast16_t 16
+#define CFI_type_int_fast32_t 17
+#define CFI_type_int_fast64_t 18
+#define CFI_type_intmax_t 19
+#define CFI_type_intptr_t 20
+#define CFI_type_ptrdiff_t 21
+#define CFI_type_float 22
+#define CFI_type_double 23
+#define CFI_type_long_double 24
+#define CFI_type_float_Complex 25
+#define CFI_type_double_Complex 26
+#define CFI_type_long_double_Complex 27
+#define CFI_type_Bool 28
+#define CFI_type_char 29
+#define CFI_type_cptr 30
+#define CFI_type_cfunptr 31
+#define CFI_type_struct 32
+#define CFI_type_other -5
+
+#define CFI_SUCCESS 0
+#define CFI_ERROR_BASE_ADDR_NULL 1
+#define CFI_ERROR_BASE_ADDR_NOT_NULL 2
+#define CFI_INVALID_ELEM_LEN 3
+#define CFI_INVALID_RANK 4
+#define CFI_INVALID_TYPE 5
+#define CFI_INVALID_ATTRIBUTE 6
+#define CFI_INVALID_EXTENT 7
+#define CFI_INVALID_DESCRIPTOR 8
+#define CFI_ERROR_MEM_ALLOCATION 9
+#define CFI_ERROR_OUT_OF_BOUNDS 10
+
+
+/* Types definitions.  */
+
+typedef ptrdiff_t CFI_index_t;
+typedef int32_t CFI_attribute_t;
+typedef int32_t CFI_type_t;
+typedef int32_t CFI_rank_t;
+
+typedef struct CFI_dim_t
+{
+  CFI_index_t _stride;	/* gfortran extension. */
+  CFI_index_t lower_bound;
+  CFI_index_t _ubound;	/* gfortran extension. */
+  CFI_index_t sm;
+  CFI_index_t extent;
+}
+CFI_dim_t;
+
+typedef struct CFI_cdesc_t
+{
+  void *data; /* FIXME: Should be "base_addr".  */
+  size_t elem_len;
+  int version;
+  CFI_rank_t rank;
+  CFI_type_t type;
+  CFI_attribute_t attribute;
+  /*FIXME: corank? Other information? Padding? Or not needed
+    due to "version"?  */
+  CFI_dim_t dim[CFI_MAX_RANK]; /* Must be last field */
+}
+CFI_cdesc_t;
+
+
+/* gfortran extension: Type-specific array descriptor.
+   FIXME: Shall be the same as CFI_cdesc_t at the end.  */
+
+#define CFI_GFC_CDESC_T(r, type) \
+struct {\
+  type *data;\
+  size_t offset;\
+  CFI_index_t dtype;\
+  CFI_index_t size;\
+  CFI_dim_t dim[r];\
+}
+
+#define CFI_CDESC_T(r) CFI_GFC_CDESC_T (r, void)
+
+
+/* Functions. */
+
+void *CFI_address (const CFI_cdesc_t *dv, const CFI_index_t subscripts[]);
+int CFI_allocate (CFI_cdesc_t *dv, const CFI_index_t lower_bounds[],
+		  const CFI_index_t upper_bounds[], size_t elem_len);
+int CFI_deallocate (CFI_cdesc_t *dv);
+int CFI_establish (CFI_cdesc_t *dv, void *base_addr, CFI_attribute_t attribute,
+		   CFI_type_t type, size_t elem_len, CFI_rank_t rank,
+		   const CFI_index_t extents[]);
+int CFI_is_contiguous (const CFI_cdesc_t *dv);
+int CFI_section (CFI_cdesc_t *result, const CFI_cdesc_t *source,
+		 const CFI_index_t lower_bounds[],
+		 const CFI_index_t upper_bounds[],
+		 const CFI_index_t strides[]);
+int CFI_select_part (CFI_cdesc_t *result, const CFI_cdesc_t *source,
+		     size_t displacement, size_t elem_len);
+int CFI_setpointer (CFI_cdesc_t *result, CFI_cdesc_t *source,
+		    const CFI_index_t lower_bounds[]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* ISO_FORTRAN_BINDING_H */