diff mbox series

Building math-vector-fortran.h in glibc

Message ID b73850db18de6197a5e3ae6c963ef13d0ee9aa83.camel@marvell.com
State New
Headers show
Series Building math-vector-fortran.h in glibc | expand

Commit Message

Steve Ellcey Jan. 18, 2019, 4:08 p.m. UTC
Martin,

I have been working with libmvec on aarch64 and I took your glibc script
to create math-vector-fortran.h and incorporated it into the glibc
math Makefile to try it out.  The patch is attached to this email.

The main thing I noticed is that your script was specifically grepping
for __DECL_SIMD_x86_64 and when I created a math-vector.h file for
Aarch64 I used __DECL_SIMD_AARCH64 so I had to change the script.

I don't think we want a different script for each target so we need to
find some way to deal with this.  Either use a common name on all
platforms, which I think is OK since this should be an internal
macro name that is not used by end users or find a way to generalize
the match regardless of the name.

The other thought I had was, instead of scanning math-vector.h,
have the script preprocess math.h itself and then look for simd
attributes after preprocessing.  I think that would make the scanner
more complex though.

Steve Ellcey
sellcey@marvell.com

Comments

Steve Ellcey Jan. 18, 2019, 5:35 p.m. UTC | #1
Following up to my own email, here is a new version of the glibc patch
to create math-vector-fortran.h.  The original one put it in
usr/include/math-vector-fortran.h.  This one puts it in
usr/include/finclude/math-vector-fortran.h so that the Fortran compiler
finds it automatically.

Steve Ellcey
sellcey@marvell.com
diff --git a/math/Makefile b/math/Makefile
index 76e8eda..480f85f 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -30,6 +30,11 @@ headers		:= math.h bits/mathcalls.h bits/mathinline.h \
 		   bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \
 		   bits/long-double.h bits/mathcalls-helper-functions.h \
 		   bits/floatn.h bits/floatn-common.h bits/mathcalls-narrow.h
+ifeq ($(build-mathvec),yes)
+headers		+= finclude/math-vector-fortran.h
+generated	+= finclude/math-vector-fortran.h
+generated-dirs	+= finclude
+endif
 
 # FPU support code.
 aux		:= setfpucw fpu_control
@@ -220,6 +225,11 @@ $(inst_libdir)/libm.a: $(common-objpfx)format.lds \
 	 echo 'GROUP ( $(libdir)/libm-$(version).a $(libdir)/libmvec.a )' \
 	) > $@.new
 	mv -f $@.new $@
+
+math_vector_header = $(wildcard $(sysdirs:%=%/bits/math-vector.h))
+$(objpfx)finclude/math-vector-fortran.h:
+	$(make-target-directory)
+	cat $(math_vector_header) | $(PYTHON) gen-fortran-math-vector.py > $(objpfx)finclude/math-vector-fortran.h
 endif
 
 # Rules for the test suite.
diff --git a/math/gen-fortran-math-vector.py b/math/gen-fortran-math-vector.py
index e69de29..0fc6c4a 100644
--- a/math/gen-fortran-math-vector.py
+++ b/math/gen-fortran-math-vector.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import fileinput
+
+# sample declarations:
+#  define __DECL_SIMD_cos __DECL_SIMD_AARCH64
+
+for line in fileinput.input():
+    parts = [x for x in line.strip().split(' ') if x]
+    s = '__DECL_SIMD_'
+    if (len(parts) == 4 and parts[1] == 'define'
+        and parts[-1] == '__DECL_SIMD_AARCH64'):
+            fn = parts[2]
+            assert fn.startswith(s)
+            fn =fn[len(s):]
+            print('!GCC$ builtin (%s) attributes simd (notinbranch)' % fn)
diff --git a/sysdeps/aarch64/fpu/bits/math-vector.h b/sysdeps/aarch64/fpu/bits/math-vector.h
index e69de29..0b271ee 100644
--- a/sysdeps/aarch64/fpu/bits/math-vector.h
+++ b/sysdeps/aarch64/fpu/bits/math-vector.h
@@ -0,0 +1,75 @@
+/* Platform-specific SIMD declarations of math functions.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_H
+# error "Never include <bits/math-vector.h> directly;\
+ include <math.h> instead."
+#endif
+
+/* Get default empty definitions for simd declarations.  */
+#include <bits/libm-simd-decl-stubs.h>
+
+#if defined __FAST_MATH__
+# if defined _OPENMP && _OPENMP >= 201307
+/* OpenMP case.  */
+#  define __DECL_SIMD_AARCH64 _Pragma ("omp declare simd notinbranch")
+# elif __GNUC_PREREQ (6,0)
+/* W/o OpenMP use GCC 6.* __attribute__ ((__simd__)).  */
+#  define __DECL_SIMD_AARCH64 __attribute__ ((__simd__ ("notinbranch")))
+# endif
+
+# ifdef __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_cos
+#  define __DECL_SIMD_cos __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_cosf
+#  define __DECL_SIMD_cosf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp
+#  define __DECL_SIMD_exp __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_expf
+#  define __DECL_SIMD_expf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp2
+#  define __DECL_SIMD_exp2 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp2f
+#  define __DECL_SIMD_exp2f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp10
+#  define __DECL_SIMD_exp10 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp10f
+#  define __DECL_SIMD_exp10f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log
+#  define __DECL_SIMD_log __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_logf
+#  define __DECL_SIMD_logf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log2
+#  define __DECL_SIMD_log2 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log2f
+#  define __DECL_SIMD_log2f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log10
+#  define __DECL_SIMD_log10 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log10f
+#  define __DECL_SIMD_log10f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_pow
+#  define __DECL_SIMD_pow __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_powf
+#  define __DECL_SIMD_powf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_sin
+#  define __DECL_SIMD_sin __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_sinf
+#  define __DECL_SIMD_sinf __DECL_SIMD_AARCH64
+# endif
+
+#endif
Joseph Myers Jan. 18, 2019, 9:14 p.m. UTC | #2
On Fri, 18 Jan 2019, Steve Ellcey wrote:

> The other thought I had was, instead of scanning math-vector.h,
> have the script preprocess math.h itself and then look for simd
> attributes after preprocessing.  I think that would make the scanner
> more complex though.

I think that's the right approach to avoid depending on 
architecture-specific header contents.

The x86 header has an __x86_64__ because there's no libmvec support for 
32-bit, but in general you could have support for libmvec for multiple 
ABIs for an architecture, but with different sets of functions, in which 
case you need to generate the right header contents for each ABI, which 
preprocessing will give you.

Note also that (subject to any changes following Jakub's comments) you 
need to put the header in the right, multilib-specific directory in which 
the compiler will search for it - that is, including the output of the 
compiler with -print-multi-directory (with the present search logic).
Martin Liška Jan. 21, 2019, 8:04 a.m. UTC | #3
On 1/18/19 5:08 PM, Steve Ellcey wrote:
> Martin,

Hey.

> 
> I have been working with libmvec on aarch64 and I took your glibc script
> to create math-vector-fortran.h and incorporated it into the glibc
> math Makefile to try it out.  The patch is attached to this email.
> 
> The main thing I noticed is that your script was specifically grepping
> for __DECL_SIMD_x86_64 and when I created a math-vector.h file for
> Aarch64 I used __DECL_SIMD_AARCH64 so I had to change the script.
> 
> I don't think we want a different script for each target so we need to
> find some way to deal with this.  Either use a common name on all
> platforms, which I think is OK since this should be an internal
> macro name that is not used by end users or find a way to generalize
> the match regardless of the name.
> 
> The other thought I had was, instead of scanning math-vector.h,
> have the script preprocess math.h itself and then look for simd
> attributes after preprocessing.  I think that would make the scanner
> more complex though.
> 
> Steve Ellcey
> sellcey@marvell.com
> 

Thank you for working on that. I tend to write the header files by hand
for both x86_64 and aarch64. Would be probably easier than maintaining
a python script.

I'm still waiting for final version of target filter directive, as discussed here:
https://gcc.gnu.org/ml/gcc-patches/2019-01/msg01168.html

Btw. is there a chance we can catch the upcoming glibc release with the header files?

Thanks,
Martin
diff mbox series

Patch

diff --git a/math/Makefile b/math/Makefile
index 76e8eda..13d4496 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -30,6 +30,10 @@  headers		:= math.h bits/mathcalls.h bits/mathinline.h \
 		   bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \
 		   bits/long-double.h bits/mathcalls-helper-functions.h \
 		   bits/floatn.h bits/floatn-common.h bits/mathcalls-narrow.h
+ifeq ($(build-mathvec),yes)
+headers		+= math-vector-fortran.h
+generated	+= math-vector-fortran.h
+endif
 
 # FPU support code.
 aux		:= setfpucw fpu_control
@@ -220,6 +224,10 @@  $(inst_libdir)/libm.a: $(common-objpfx)format.lds \
 	 echo 'GROUP ( $(libdir)/libm-$(version).a $(libdir)/libmvec.a )' \
 	) > $@.new
 	mv -f $@.new $@
+
+math_vector_header = $(wildcard $(sysdirs:%=%/bits/math-vector.h))
+$(objpfx)math-vector-fortran.h:
+	cat $(math_vector_header) | $(PYTHON) gen-fortran-math-vector.py > $(objpfx)math-vector-fortran.h
 endif
 
 # Rules for the test suite.
diff --git a/math/gen-fortran-math-vector.py b/math/gen-fortran-math-vector.py
index e69de29..0fc6c4a 100644
--- a/math/gen-fortran-math-vector.py
+++ b/math/gen-fortran-math-vector.py
@@ -0,0 +1,16 @@ 
+#!/usr/bin/env python3
+
+import fileinput
+
+# sample declarations:
+#  define __DECL_SIMD_cos __DECL_SIMD_AARCH64
+
+for line in fileinput.input():
+    parts = [x for x in line.strip().split(' ') if x]
+    s = '__DECL_SIMD_'
+    if (len(parts) == 4 and parts[1] == 'define'
+        and parts[-1] == '__DECL_SIMD_AARCH64'):
+            fn = parts[2]
+            assert fn.startswith(s)
+            fn =fn[len(s):]
+            print('!GCC$ builtin (%s) attributes simd (notinbranch)' % fn)
diff --git a/sysdeps/aarch64/fpu/bits/math-vector.h b/sysdeps/aarch64/fpu/bits/math-vector.h
index e69de29..0b271ee 100644
--- a/sysdeps/aarch64/fpu/bits/math-vector.h
+++ b/sysdeps/aarch64/fpu/bits/math-vector.h
@@ -0,0 +1,75 @@ 
+/* Platform-specific SIMD declarations of math functions.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MATH_H
+# error "Never include <bits/math-vector.h> directly;\
+ include <math.h> instead."
+#endif
+
+/* Get default empty definitions for simd declarations.  */
+#include <bits/libm-simd-decl-stubs.h>
+
+#if defined __FAST_MATH__
+# if defined _OPENMP && _OPENMP >= 201307
+/* OpenMP case.  */
+#  define __DECL_SIMD_AARCH64 _Pragma ("omp declare simd notinbranch")
+# elif __GNUC_PREREQ (6,0)
+/* W/o OpenMP use GCC 6.* __attribute__ ((__simd__)).  */
+#  define __DECL_SIMD_AARCH64 __attribute__ ((__simd__ ("notinbranch")))
+# endif
+
+# ifdef __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_cos
+#  define __DECL_SIMD_cos __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_cosf
+#  define __DECL_SIMD_cosf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp
+#  define __DECL_SIMD_exp __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_expf
+#  define __DECL_SIMD_expf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp2
+#  define __DECL_SIMD_exp2 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp2f
+#  define __DECL_SIMD_exp2f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp10
+#  define __DECL_SIMD_exp10 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_exp10f
+#  define __DECL_SIMD_exp10f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log
+#  define __DECL_SIMD_log __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_logf
+#  define __DECL_SIMD_logf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log2
+#  define __DECL_SIMD_log2 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log2f
+#  define __DECL_SIMD_log2f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log10
+#  define __DECL_SIMD_log10 __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_log10f
+#  define __DECL_SIMD_log10f __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_pow
+#  define __DECL_SIMD_pow __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_powf
+#  define __DECL_SIMD_powf __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_sin
+#  define __DECL_SIMD_sin __DECL_SIMD_AARCH64
+#  undef __DECL_SIMD_sinf
+#  define __DECL_SIMD_sinf __DECL_SIMD_AARCH64
+# endif
+
+#endif