OSDN Git Service

2006-12-21 Daniel Franke <franke.daniel@gmail.com>
authordfranke <dfranke@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Dec 2006 22:29:08 +0000 (22:29 +0000)
committerdfranke <dfranke@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Dec 2006 22:29:08 +0000 (22:29 +0000)
PR libgomp/28209
* libgomp.texi: New file.
* configure.ac: Add --enable-generated-files-in-srcdir option.
* Makefile.am: Add info, dvi, pdf, html targets. On request, copy
files to srcdir.
* Makefile.in: Regenerated.
* config.h.in: Regenerated.
* testsuite/Makefile.in: Regenerated.
* NOTES: Removed.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120122 138bc75d-0d04-0410-961f-82ee72b054a4

libgomp/ChangeLog
libgomp/Makefile.am
libgomp/Makefile.in
libgomp/NOTES [deleted file]
libgomp/config.h.in
libgomp/configure.ac
libgomp/libgomp.texi [new file with mode: 0644]
libgomp/testsuite/Makefile.in

index 92b5600..cf2efab 100644 (file)
@@ -1,3 +1,15 @@
+2006-12-21  Daniel Franke  <franke.daniel@gmail.com>
+
+       PR libgomp/28209
+       * libgomp.texi: New file.
+       * configure.ac: Add --enable-generated-files-in-srcdir option.
+       * Makefile.am: Add info, dvi, pdf, html targets. On request, copy
+       files to srcdir.
+       * Makefile.in: Regenerated.
+       * config.h.in: Regenerated.
+       * testsuite/Makefile.in: Regenerated.
+       * NOTES: Removed.
+
 2006-12-04  Daniel Franke  <franke.daniel@gmail.com>
 
        PR libgomp/29949
index 6e84a4b..ee2669c 100644 (file)
@@ -50,7 +50,35 @@ fortran.o: libgomp_f.h
 env.lo: libgomp_f.h
 env.o: libgomp_f.h
 
+
 # No install-html target
 .PHONY: install-html
 install-html:
 
+
+# Automake Documentation:
+# If your package has Texinfo files in many directories, you can use the
+# variable TEXINFO_TEX to tell Automake where to find the canonical
+# `texinfo.tex' for your package. The value of this variable should be
+# the relative path from the current `Makefile.am' to `texinfo.tex'.
+TEXINFO_TEX   = ../gcc/doc/include/texinfo.tex
+
+# Defines info, dvi, pdf and html targets
+MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include
+info_TEXINFOS = libgomp.texi
+
+# AM_CONDITIONAL on configure option --generated-files-in-srcdir
+if GENINSRC
+STAMP_GENINSRC = stamp-geninsrc
+else
+STAMP_GENINSRC =
+endif
+
+all-local: $(STAMP_GENINSRC)
+
+stamp-geninsrc: libgomp.info
+       -cp -p $(top_builddir)/libgomp.info $(srcdir)/libgomp.info
+       touch $@
+
+CLEANFILES = stamp-geninsrc libgomp.info
+MAINTAINERCLEANFILES = $(srcdir)/libgomp.info
index 3c101c9..ad8820e 100644 (file)
@@ -51,6 +51,7 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/enable.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
+       $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/stdint.m4 \
        $(top_srcdir)/../config/tls.m4 $(top_srcdir)/acinclude.m4 \
        $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
@@ -68,7 +69,7 @@ am__vpath_adj = case $$p in \
     *) f=$$p;; \
   esac;
 am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
-am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(infodir)" \
        "$(DESTDIR)$(fincludedir)" "$(DESTDIR)$(libsubincludedir)" \
        "$(DESTDIR)$(toolexeclibdir)"
 toolexeclibLTLIBRARIES_INSTALL = $(INSTALL)
@@ -98,6 +99,18 @@ MULTIDIRS =
 MULTISUBDIR = 
 MULTIDO = true
 MULTICLEAN = true
+INFO_DEPS = libgomp.info
+am__TEXINFO_TEX_DIR = $(srcdir)/../gcc/doc/include
+DVIS = libgomp.dvi
+PDFS = libgomp.pdf
+PSS = libgomp.ps
+HTMLS = libgomp.html
+TEXINFOS = libgomp.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
        html-recursive info-recursive install-data-recursive \
        install-exec-recursive install-info-recursive \
@@ -148,6 +161,9 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+GENINSRC_FALSE = @GENINSRC_FALSE@
+GENINSRC_TRUE = @GENINSRC_TRUE@
+GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -190,11 +206,8 @@ USE_FORTRAN_TRUE = @USE_FORTRAN_TRUE@
 VERSION = @VERSION@
 XCFLAGS = @XCFLAGS@
 XLDFLAGS = @XLDFLAGS@
-ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_FC = @ac_ct_FC@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
 am__include = @am__include@
@@ -210,6 +223,9 @@ build_os = @build_os@
 build_vendor = @build_vendor@
 config_path = @config_path@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 enable_shared = @enable_shared@
 enable_static = @enable_static@
 exec_prefix = @exec_prefix@
@@ -218,6 +234,7 @@ host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
@@ -225,13 +242,16 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 libtool_VERSION = @libtool_VERSION@
 link_gomp = @link_gomp@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 multi_basedir = @multi_basedir@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@
@@ -266,11 +286,28 @@ libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
 nodist_noinst_HEADERS = libgomp_f.h
 nodist_libsubinclude_HEADERS = omp.h
 @USE_FORTRAN_TRUE@nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod
+
+# Automake Documentation:
+# If your package has Texinfo files in many directories, you can use the
+# variable TEXINFO_TEX to tell Automake where to find the canonical
+# `texinfo.tex' for your package. The value of this variable should be
+# the relative path from the current `Makefile.am' to `texinfo.tex'.
+TEXINFO_TEX = ../gcc/doc/include/texinfo.tex
+
+# Defines info, dvi, pdf and html targets
+MAKEINFOFLAGS = -I $(srcdir)/../gcc/doc/include
+info_TEXINFOS = libgomp.texi
+@GENINSRC_FALSE@STAMP_GENINSRC = 
+
+# AM_CONDITIONAL on configure option --generated-files-in-srcdir
+@GENINSRC_TRUE@STAMP_GENINSRC = stamp-geninsrc
+CLEANFILES = stamp-geninsrc libgomp.info
+MAINTAINERCLEANFILES = $(srcdir)/libgomp.info
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
+.SUFFIXES: .c .dvi .lo .o .obj .ps
 am--refresh:
        @:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
@@ -434,7 +471,101 @@ distclean-multi:
        $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
 maintainer-clean-multi:
        $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
+
+libgomp.info: libgomp.texi 
+       restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+       rm -rf $$backupdir && mkdir $$backupdir && \
+       if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+         for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+           if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+         done; \
+       else :; fi && \
+       if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+        -o $@ `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi; \
+       then \
+         rc=0; \
+       else \
+         rc=$$?; \
+         $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+       fi; \
+       rm -rf $$backupdir; exit $$rc
+
+libgomp.dvi: libgomp.texi  
+       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+       $(TEXI2DVI) -o $@ `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi
+
+libgomp.pdf: libgomp.texi  
+       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+       $(TEXI2PDF) -o $@ `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi
+
+libgomp.html: libgomp.texi  
+       rm -rf $(@:.html=.htp)
+       if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+        -o $(@:.html=.htp) `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi; \
+       then \
+         rm -rf $@; \
+         if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+           mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+       else \
+         if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+           rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+         exit 1; \
+       fi
+.dvi.ps:
+       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       $(DVIPS) -o $@ $<
+
 uninstall-info-am:
+       @$(PRE_UNINSTALL)
+       @if (install-info --version && \
+            install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+         list='$(INFO_DEPS)'; \
+         for file in $$list; do \
+           relfile=`echo "$$file" | sed 's|^.*/||'`; \
+           echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+           install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+         done; \
+       else :; fi
+       @$(NORMAL_UNINSTALL)
+       @list='$(INFO_DEPS)'; \
+       for file in $$list; do \
+         relfile=`echo "$$file" | sed 's|^.*/||'`; \
+         relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+         (if cd "$(DESTDIR)$(infodir)"; then \
+            echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+            rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+          else :; fi); \
+       done
+
+dist-info: $(INFO_DEPS)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       list='$(INFO_DEPS)'; \
+       for base in $$list; do \
+         case $$base in \
+           $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+         esac; \
+         if test -f $$base; then d=.; else d=$(srcdir); fi; \
+         for file in $$d/$$base*; do \
+           relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+           test -f $(distdir)/$$relfile || \
+             cp -p $$file $(distdir)/$$relfile; \
+         done; \
+       done
+
+mostlyclean-aminfo:
+       -rm -rf libgomp.aux libgomp.cp libgomp.cps libgomp.fn libgomp.fns libgomp.ky \
+         libgomp.kys libgomp.log libgomp.pg libgomp.pgs libgomp.tmp \
+         libgomp.toc libgomp.tp libgomp.tps libgomp.vr libgomp.vrs \
+         libgomp.dvi libgomp.pdf libgomp.ps libgomp.html
+
+maintainer-clean-aminfo:
+       @list='$(INFO_DEPS)'; for i in $$list; do \
+         i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+         echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+         rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+       done
 install-nodist_fincludeHEADERS: $(nodist_finclude_HEADERS)
        @$(NORMAL_INSTALL)
        test -z "$(fincludedir)" || $(mkdir_p) "$(DESTDIR)$(fincludedir)"
@@ -664,6 +795,9 @@ distdir: $(DISTFILES)
              || exit 1; \
          fi; \
        done
+       $(MAKE) $(AM_MAKEFLAGS) \
+         top_distdir="$(top_distdir)" distdir="$(distdir)" \
+         dist-info
        -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
          ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
          ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
@@ -763,10 +897,11 @@ distcleancheck: distclean
               exit 1; } >&2
 check-am: all-am
 check: check-recursive
-all-am: Makefile $(LTLIBRARIES) all-multi $(HEADERS) config.h
+all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) all-multi $(HEADERS) \
+               config.h all-local
 installdirs: installdirs-recursive
 installdirs-am:
-       for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(fincludedir)" "$(DESTDIR)$(libsubincludedir)" "$(DESTDIR)$(toolexeclibdir)"; do \
+       for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(fincludedir)" "$(DESTDIR)$(libsubincludedir)" "$(DESTDIR)$(toolexeclibdir)"; do \
          test -z "$$dir" || $(mkdir_p) "$$dir"; \
        done
 install: install-recursive
@@ -786,6 +921,7 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
        -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -793,6 +929,7 @@ distclean-generic:
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
        @echo "it deletes files that may require special tools to rebuild."
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
 clean: clean-multi clean-recursive
 
 clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \
@@ -807,15 +944,17 @@ distclean-am: clean-am distclean-compile distclean-generic \
 
 dvi: dvi-recursive
 
-dvi-am:
+dvi-am: $(DVIS)
 
 html: html-recursive
 
+html-am: $(HTMLS)
+
 info: info-recursive
 
-info-am:
+info-am: $(INFO_DEPS)
 
-install-data-am: install-nodist_fincludeHEADERS \
+install-data-am: install-info-am install-nodist_fincludeHEADERS \
        install-nodist_libsubincludeHEADERS
 
 install-exec-am: install-multi install-nodist_toolexeclibHEADERS \
@@ -823,6 +962,36 @@ install-exec-am: install-multi install-nodist_toolexeclibHEADERS \
 
 install-info: install-info-recursive
 
+install-info-am: $(INFO_DEPS)
+       @$(NORMAL_INSTALL)
+       test -z "$(infodir)" || $(mkdir_p) "$(DESTDIR)$(infodir)"
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       list='$(INFO_DEPS)'; \
+       for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+         esac; \
+         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+         for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+                       $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+           if test -f $$ifile; then \
+             relfile=`echo "$$ifile" | sed 's|^.*/||'`; \
+             echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \
+             $(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \
+           else : ; fi; \
+         done; \
+       done
+       @$(POST_INSTALL)
+       @if (install-info --version && \
+            install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+         list='$(INFO_DEPS)'; \
+         for file in $$list; do \
+           relfile=`echo "$$file" | sed 's|^.*/||'`; \
+           echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+           install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+         done; \
+       else : ; fi
 install-man:
 
 installcheck-am:
@@ -832,20 +1001,21 @@ maintainer-clean: maintainer-clean-multi maintainer-clean-recursive
        -rm -rf $(top_srcdir)/autom4te.cache
        -rm -rf ./$(DEPDIR)
        -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+       maintainer-clean-generic
 
 mostlyclean: mostlyclean-multi mostlyclean-recursive
 
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-       mostlyclean-libtool
+mostlyclean-am: mostlyclean-aminfo mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool
 
 pdf: pdf-recursive
 
-pdf-am:
+pdf-am: $(PDFS)
 
 ps: ps-recursive
 
-ps-am:
+ps-am: $(PSS)
 
 uninstall-am: uninstall-info-am uninstall-nodist_fincludeHEADERS \
        uninstall-nodist_libsubincludeHEADERS \
@@ -854,11 +1024,12 @@ uninstall-am: uninstall-info-am uninstall-nodist_fincludeHEADERS \
 
 uninstall-info: uninstall-info-recursive
 
-.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am all-multi \
-       am--refresh check check-am clean clean-generic clean-libtool \
-       clean-multi clean-recursive clean-toolexeclibLTLIBRARIES ctags \
-       ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
-       dist-tarZ dist-zip distcheck distclean distclean-compile \
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am all-local \
+       all-multi am--refresh check check-am clean clean-generic \
+       clean-libtool clean-multi clean-recursive \
+       clean-toolexeclibLTLIBRARIES ctags ctags-recursive dist \
+       dist-all dist-bzip2 dist-gzip dist-info dist-shar dist-tarZ \
+       dist-zip distcheck distclean distclean-compile \
        distclean-generic distclean-hdr distclean-libtool \
        distclean-multi distclean-recursive distclean-tags \
        distcleancheck distdir distuninstallcheck dvi dvi-am html \
@@ -870,12 +1041,12 @@ uninstall-info: uninstall-info-recursive
        install-nodist_toolexeclibHEADERS install-strip \
        install-toolexeclibLTLIBRARIES installcheck installcheck-am \
        installdirs installdirs-am maintainer-clean \
-       maintainer-clean-generic maintainer-clean-multi \
-       maintainer-clean-recursive mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool mostlyclean-multi \
-       mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
-       uninstall uninstall-am uninstall-info-am \
-       uninstall-nodist_fincludeHEADERS \
+       maintainer-clean-aminfo maintainer-clean-generic \
+       maintainer-clean-multi maintainer-clean-recursive mostlyclean \
+       mostlyclean-aminfo mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool mostlyclean-multi mostlyclean-recursive \
+       pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+       uninstall-info-am uninstall-nodist_fincludeHEADERS \
        uninstall-nodist_libsubincludeHEADERS \
        uninstall-nodist_toolexeclibHEADERS \
        uninstall-toolexeclibLTLIBRARIES
@@ -893,6 +1064,12 @@ env.o: libgomp_f.h
 # No install-html target
 .PHONY: install-html
 install-html:
+
+all-local: $(STAMP_GENINSRC)
+
+stamp-geninsrc: libgomp.info
+       -cp -p $(top_builddir)/libgomp.info $(srcdir)/libgomp.info
+       touch $@
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/libgomp/NOTES b/libgomp/NOTES
deleted file mode 100644 (file)
index 753363c..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-Notes on the external ABI presented by libgomp.  This ought to get
-transformed into proper documentation at some point.
-
-Implementing MASTER construct
-
-       if (omp_get_thread_num () == 0)
-         block
-
-       Alternately, we generate two copies of the parallel subfunction
-       and only include this in the version run by the master thread.
-       Surely that's not worthwhile though...
-
-Implementing CRITICAL construct
-
-       Without a specified name,
-
-       void GOMP_critical_start (void);
-       void GOMP_critical_end (void);
-
-       so that we don't get COPY relocations from libgomp to the main
-       application.
-
-       With a specified name, use omp_set_lock and omp_unset_lock with
-       name being transformed into a variable declared like
-
-               omp_lock_t gomp_critical_user_<name>
-                       __attribute__((common))
-
-       Ideally the ABI would specify that all zero is a valid unlocked
-       state, and so we wouldn't actually need to initialize this at
-       startup.
-
-Implementing ATOMIC construct
-
-       The target should implement the __sync builtins.
-
-       Failing that we could add
-
-       void GOMP_atomic_enter (void)
-       void GOMP_atomic_exit (void)
-
-       which reuses the regular lock code, but with yet another lock
-       object private to the library.
-
-Implementing FLUSH construct
-
-       Expands to the __sync_synchronize builtin.
-
-Implementing BARRIER construct
-
-       void GOMP_barrier (void)
-
-Implementing THREADPRIVATE construct
-
-       In _most_ cases we can map this directly to __thread.  Except
-       that OMP allows constructors for C++ objects.  We can either
-       refuse to support this (how often is it used?) or we can 
-       implement something akin to .ctors.
-
-       Even more ideally, this ctor feature is handled by extensions
-       to the main pthreads library.  Failing that, we can have a set
-       of entry points to register ctor functions to be called.
-
-Implementing PRIVATE clause
-
-       In association with a PARALLEL, or within the lexical extent
-       of a PARALLEL block, the variable becomes a local variable in
-       the parallel subfunction.
-
-       In association with FOR or SECTIONS blocks, create a new
-       automatic variable within the current function.  This preserves
-       the semantic of new variable creation.
-
-Implementing FIRSTPRIVATE, LASTPRIVATE, COPYIN, COPYPRIVATE clauses
-
-       Seems simple enough for PARALLEL blocks.  Create a private 
-       struct for communicating between parent and subfunction.
-       In the parent, copy in values for scalar and "small" structs;
-       copy in addresses for others TREE_ADDRESSABLE types.  In the 
-       subfunction, copy the value into the local variable.
-
-       Not clear at all what to do with bare FOR or SECTION blocks.
-       The only thing I can figure is that we do something like
-
-
-               #pragma omp for firstprivate(x) lastprivate(y)
-               for (int i = 0; i < n; ++i)
-                 body;
-
-               =>
-
-               {
-                 int x = x, y;
-
-                 // for stuff
-
-                 if (i == n)
-                   y = y;
-               }
-
-       where the "x=x" and "y=y" assignments actually have different
-       uids for the two variables, i.e. not something you could write
-       directly in C.  Presumably this only makes sense if the "outer"
-       x and y are global variables.
-
-       COPYPRIVATE would work the same way, except the structure 
-       broadcast would have to happen via SINGLE machinery instead.
-
-Implementing REDUCTION clause
-
-       The private struct mentioned above should have a pointer to
-       an array of the type of the variable, indexed by the thread's
-       team_id.  The thread stores its final value into the array,
-       and after the barrier the master thread iterates over the
-       array to collect the values.
-
-Implementing PARALLEL construct
-
-       #pragma omp parallel
-       {
-         body;
-       }
-
-       =>
-
-       void subfunction (void *data)
-       {
-         use data;
-         body;
-       }
-
-       setup data;
-       GOMP_parallel_start (subfunction, &data, num_threads);
-       subfunction (&data);
-       GOMP_parallel_end ();
-
-  void GOMP_parallel_start (void (*fn)(void *), void *data,
-                           unsigned num_threads)
-
-       The FN argument is the subfunction to be run in parallel.
-
-       The DATA argument is a pointer to a structure used to 
-       communicate data in and out of the subfunction, as discussed
-       above wrt FIRSTPRIVATE et al.
-
-       The NUM_THREADS argument is 1 if an IF clause is present
-       and false, or the value of the NUM_THREADS clause, if
-       present, or 0.
-
-       The function needs to create the appropriate number of
-       threads and/or launch them from the dock.  It needs to
-       create the team structure and assign team ids.
-
-  void GOMP_parallel_end (void)
-
-       Tears down the team and return us to the previous
-       omp_in_parallel() state.
-
-Implementing FOR construct
-
-       #pragma omp parallel for
-       for (i = lb; i <= ub; i++)
-         body;
-
-       =>
-
-       void subfunction (void *data)
-       {
-         long _s0, _e0;
-         while (GOMP_loop_static_next (&_s0, &_e0))
-           {
-             long _e1 = _e0, i;
-             for (i = _s0; i < _e1; i++)
-               body;
-           }
-         GOMP_loop_end_nowait ();
-       }
-
-       GOMP_parallel_loop_static (subfunction, NULL, 0, lb, ub+1, 1, 0);
-       subfunction (NULL);
-       GOMP_parallel_end ();
-
-       #pragma omp for schedule(runtime)
-       for (i = 0; i < n; i++)
-         body;
-
-       =>
-
-       {
-         long i, _s0, _e0;
-         if (GOMP_loop_runtime_start (0, n, 1, &_s0, &_e0))
-           do {
-             long _e1 = _e0;
-             for (i = _s0, i < _e0; i++)
-               body;
-           } while (GOMP_loop_runtime_next (&_s0, _&e0));
-         GOMP_loop_end ();
-       }
-
-       Note that while it looks like there is trickyness to propagating
-       a non-constant STEP, there isn't really.  We're explicitly allowed
-       to evaluate it as many times as we want, and any variables involved
-       should automatically be handled as PRIVATE or SHARED like any other
-       variables.  So the expression should remain evaluable in the 
-       subfunction.  We can also pull it into a local variable if we like,
-       but since its supposed to remain unchanged, we can also not if we like.
-
-       If we have SCHEDULE(STATIC), and no ORDERED, then we ought to be
-       able to get away with no work-sharing context at all, since we can
-       simply perform the arithmetic directly in each thread to divide up
-       the iterations.  Which would mean that we wouldn't need to call any
-       of these routines.
-
-       There are separate routines for handling loops with an ORDERED
-       clause.  Bookkeeping for that is non-trivial...
-
-Implementing ORDERED construct
-
-       void GOMP_ordered_start (void)
-       void GOMP_ordered_end (void)
-
-Implementing SECTIONS construct
-
-       #pragma omp sections
-       {
-         #pragma omp section
-         stmt1;
-         #pragma omp section
-         stmt2;
-         #pragma omp section
-         stmt3;
-       }
-
-       =>
-       
-       for (i = GOMP_sections_start (3); i != 0; i = GOMP_sections_next ())
-         switch (i)
-           {
-           case 1:
-             stmt1;
-             break;
-           case 2:
-             stmt2;
-             break;
-           case 3:
-             stmt3;
-             break;
-           }
-       GOMP_barrier ();
-
-Implementing SINGLE construct
-
-       #pragma omp single
-       {
-         body;
-       }
-
-       =>
-
-       if (GOMP_single_start ())
-         body;
-       GOMP_barrier ();
-
-
-       #pragma omp single copyprivate(x)
-       body;
-
-       =>
-
-       datap = GOMP_single_copy_start ();
-       if (datap == NULL)
-         {
-           body;
-           data.x = x;
-           GOMP_single_copy_end (&data);
-         }
-       else
-         x = datap->x;
-       GOMP_barrier ();
index 0c15993..0f33b00 100644 (file)
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
-/* The size of `char', as computed by sizeof. */
+/* The size of `char', as computed by sizeof. */
 #undef SIZEOF_CHAR
 
-/* The size of `int', as computed by sizeof. */
+/* The size of `int', as computed by sizeof. */
 #undef SIZEOF_INT
 
-/* The size of `long', as computed by sizeof. */
+/* The size of `long', as computed by sizeof. */
 #undef SIZEOF_LONG
 
-/* The size of `short', as computed by sizeof. */
+/* The size of `short', as computed by sizeof. */
 #undef SIZEOF_SHORT
 
-/* The size of `void *', as computed by sizeof. */
+/* The size of `void *', as computed by sizeof. */
 #undef SIZEOF_VOID_P
 
 /* Define to 1 if you have the ANSI C header files. */
index d6f960e..e42facc 100644 (file)
@@ -21,6 +21,20 @@ LIBGOMP_ENABLE(linux-futex, default, ,
   permit yes|no|default)
 AC_MSG_RESULT($enable_linux_futex)
 
+# We would like our source tree to be readonly. However when releases or
+# pre-releases are generated, the flex/bison generated files as well as the
+# various formats of manuals need to be included along with the rest of the
+# sources.  Therefore we have --enable-generated-files-in-srcdir to do 
+# just that.
+AC_MSG_CHECKING([for --enable-generated-files-in-srcdir])
+LIBGOMP_ENABLE(generated-files-in-srcdir, no, ,
+   [put copies of generated files in source dir intended for creating source 
+    tarballs for users without texinfo bison or flex.],
+   permit yes|no)
+AC_MSG_RESULT($enable_generated_files_in_srcdir)
+AM_CONDITIONAL(GENINSRC, test "$enable_generated_files_in_srcdir" = yes)
+
+
 # -------
 # -------
 
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
new file mode 100644 (file)
index 0000000..77cf094
--- /dev/null
@@ -0,0 +1,1342 @@
+\input texinfo @c -*-texinfo-*-
+
+@c %**start of header
+@setfilename libgomp.info
+@settitle GNU libgomp
+@c %**end of header
+
+
+@copying
+Copyright @copyright{} 2006 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'' and ``Funding
+Free Software'', the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below).  A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+
+(a) The FSF's Front-Cover Text is:
+
+     A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+     You have freedom to copy and modify this GNU Manual, like GNU
+     software.  Copies published by the Free Software Foundation raise
+     funds for GNU development.
+@end copying
+
+@ifinfo
+@dircategory GNU Libraries
+@direntry
+* libgomp: (libgomp).                    GNU OpenMP runtime library
+@end direntry
+
+This manual documents the GNU implementation of the OpenMP API for 
+multi-platform shared-memory parallel programming in C/C++ and Fortran.
+
+Published by the Free Software Foundation
+51 Franklin Street, Fifth Floor
+Boston, MA 02110-1301 USA
+
+@insertcopying
+@end ifinfo
+
+
+@setchapternewpage odd
+
+@titlepage
+@title The GNU OpenMP Implementation
+@page
+@vskip 0pt plus 1filll
+@comment For the @value{version-GCC} Version*
+@sp 1
+Published by the Free Software Foundation @*
+51 Franklin Street, Fifth Floor@*
+Boston, MA 02110-1301, USA@*
+@sp 1
+@insertcopying
+@end titlepage
+
+@summarycontents
+@contents
+@page
+
+
+@node Top
+@top Introduction
+@cindex Introduction
+
+This manual documents the usage of libgomp, the GNU implementation of the 
+@uref{http://www.openmp.org, OpenMP} Application Programming Interface (API)
+for multi-platform shared-memory parallel programming in C/C++ and Fortran.
+
+
+
+@comment
+@comment  When you add a new menu item, please keep the right hand
+@comment  aligned to the same column.  Do not use tabs.  This provides
+@comment  better formatting.
+@comment
+@menu
+* Enabling OpenMP::            How to enable OpenMP for your applications.
+* Runtime Library Routines::   The OpenMP runtime application programming 
+                               interface.
+* Environment Variables::      Influencing runtime behavior with environment 
+                               variables.
+* The libgomp ABI::            Notes on the external ABI presented by libgomp.
+* Reporting Bugs::             How to report bugs in GNU OpenMP.
+* Copying::                    GNU general public license says
+                               how you can copy and share libgomp.
+* GNU Free Documentation License::
+                               How you can copy and share this manual.
+* Funding::                    How to help assure continued work for free 
+                               software.
+* Index::                      Index of this documentation.
+@end menu
+
+
+@c ---------------------------------------------------------------------
+@c Enabling OpenMP
+@c ---------------------------------------------------------------------
+
+@node Enabling OpenMP
+@chapter Enabling OpenMP
+
+To activate the OpenMP extensions for C/C++ and Fortran, the compile-time 
+flag @command{-fopenmp} must be specified. This enables the OpenMP directive
+@code{#pragma omp} in C/C++ and @code{!$omp} directives in free form, 
+@code{c$omp}, @code{*$omp} and @code{!$omp} directives in fixed form, 
+@code{!$} conditional compilation sentinels in free form and @code{c$},
+@code{*$} and @code{!$} sentinels in fixed form, for Fortran. The flag also
+arranges for automatic linking of the OpenMP runtime library 
+(@ref{Runtime Library Routines}).
+
+A complete description of all OpenMP directives accepted may be found in 
+the @uref{http://www.openmp.org, OpenMP Application Program Interface} manual,
+version 2.5.
+
+
+@c ---------------------------------------------------------------------
+@c Runtime Library Routines
+@c ---------------------------------------------------------------------
+
+@node Runtime Library Routines
+@chapter Runtime Library Routines
+
+The runtime routines described here are defined by section 3 of the OpenMP 
+specifications in version 2.5.
+
+Control threads, processors and the parallel environment.
+
+@menu
+* omp_get_dynamic::          Dynamic teams setting
+* omp_get_max_threads::      Maximum number of threads
+* omp_get_nested::           Nested parallel regions
+* omp_get_num_procs::        Number of processors online
+* omp_get_num_threads::      Size of the active team
+* omp_get_thread_num::       Current thread ID
+* omp_in_parallel::          Whether a parallel region is active
+* omp_set_dynamic::          Enable/disable dynamic teams
+* omp_set_nested::           Enable/disable nested parallel regions
+* omp_set_num_threads::      Set upper team size limit
+@end menu
+
+Initialize, set, test, unset and destroy simple and nested locks.
+
+@menu
+* omp_init_lock::            Initialize simple lock
+* omp_set_lock::             Wait for and set simple lock
+* omp_test_lock::            Test and set simple lock if available
+* omp_unset_lock::           Unset simple lock
+* omp_destroy_lock::         Destroy simple lock
+* omp_init_nest_lock::       Initialize nested lock
+* omp_set_nest_lock::        Wait for and set simple lock
+* omp_test_nest_lock::       Test and set nested lock if available
+* omp_unset_nest_lock::      Unset nested lock
+* omp_destroy_nest_lock::    Destroy nested lock
+@end menu
+
+Portable, thread-based, wall clock timer.
+
+@menu
+* omp_get_wtick::            Get timer precision.
+* omp_get_wtime::            Elapsed wall clock time.
+@end menu
+
+@node omp_get_dynamic
+@section @code{omp_get_dynamic} -- Dynamic teams setting
+@table @asis
+@item @emph{Description}:
+This function returns @code{true} if enabled, @code{false} otherwise. 
+Here, @code{true} and @code{false} represent their language-specific 
+counterparts.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_get_dynamic();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{logical function omp_get_dynamic()}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_set_dynamic}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.8.
+@end table
+
+
+
+@node omp_get_max_threads
+@section @code{omp_get_max_threads} -- Maximum number of threads
+@table @asis
+@item @emph{Description}:
+Return the maximum number of threads used for parallel regions that do
+not use the clause @code{num_threads}.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_get_max_threads();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{integer function omp_get_max_threads()}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_set_num_threads}, @ref{omp_set_dynamic}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.3.
+@end table
+
+
+
+@node omp_get_nested
+@section @code{omp_get_nested} -- Nested parallel regions
+@table @asis
+@item @emph{Description}:
+This function returns @code{true} if nested parallel regions are
+enabled, @code{false} otherwise. Here, @code{true} and @code{false} 
+represent their language-specific counterparts.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_get_nested();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{integer function omp_get_nested()}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_set_nested}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.10.
+@end table
+
+
+
+@node omp_get_num_procs
+@section @code{omp_get_num_procs} -- Number of processors online
+@table @asis
+@item @emph{Description}:
+Returns the number of processors online.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_get_num_procs();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{integer function omp_get_num_procs()}
+@end multitable
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.5.
+@end table
+
+
+
+@node omp_get_num_threads
+@section @code{omp_get_num_threads} -- Size of the active team
+@table @asis
+@item @emph{Description}:
+The number of threads in the current team. In a sequential section of 
+the program @code{omp_get_num_threads} returns 1.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_get_num_threads();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{integer function omp_get_num_threads()}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_get_max_threads}, @ref{omp_set_num_threads}, @ref{OMP_NUM_THREADS}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.2.
+@end table
+
+
+
+@node omp_get_thread_num 
+@section @code{omp_get_thread_num} -- Current thread ID
+@table @asis
+@item @emph{Description}:
+Unique thread identification number. In a sequential parts of the program, 
+@code{omp_get_thread_num} always returns 0. In parallel regions the return
+value varies from 0 to @code{omp_get_max_threads}-1 inclusive. The return 
+value of the master thread of a team is always 0.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_get_thread_num();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{integer function omp_get_thread_num()}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_get_max_threads}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.4.
+@end table
+
+
+
+@node omp_in_parallel
+@section @code{omp_in_parallel} -- Whether a parallel region is active
+@table @asis
+@item @emph{Description}:
+This function returns @code{true} if currently running in parallel, 
+@code{false} otherwise. Here, @code{true} and @code{false} represent 
+their language-specific counterparts.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_in_parallel();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{logical function omp_in_parallel()}
+@end multitable
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.6.
+@end table
+
+
+@node omp_set_dynamic
+@section @code{omp_set_dynamic} -- Enable/disable dynamic teams
+@table @asis
+@item @emph{Description}:
+Enable or disable the dynamic adjustment of the number of threads 
+within a team. The function takes the language-specific equivalent
+of @code{true} and @code{false}, where @code{true} enables dynamic 
+adjustment of team sizes and @code{false} disables it.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_set_dynamic(int);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_set_dynamic(set)}
+@item                   @tab @code{integer, intent(in) :: set}
+@end multitable
+
+@item @emph{See also}:
+@ref{OMP_DYNAMIC}, @ref{omp_get_dynamic}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.7.
+@end table
+
+
+
+@node omp_set_nested
+@section @code{omp_set_nested} -- Enable/disable nested parallel regions
+@table @asis
+@item @emph{Description}:
+Enable or disable nested parallel regions, i. e. whether team members
+are allowed to create new teams. The function takes the language-specific 
+equivalent of @code{true} and @code{false}, where @code{true} enables 
+dynamic adjustment of team sizes and @code{false} disables it.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_set_dynamic(int);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_set_dynamic(set)}
+@item                   @tab @code{integer, intent(in) :: set}
+@end multitable
+
+@item @emph{See also}:
+@ref{OMP_NESTED}, @ref{omp_get_nested}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.9.
+@end table
+
+
+
+@node omp_set_num_threads
+@section @code{omp_set_num_threads} -- Set upper team size limit
+@table @asis
+@item @emph{Description}:
+Specifies the number of threads used by default in subsequent parallel 
+sections, if those do not specify a @code{num_threads} clause. The 
+argument of @code{omp_set_num_threads} shall be a positive integer. 
+
+If the argument is negative integer or zero, the application will crash or
+stop, respectively. An enhancement request was filed,
+@uref{http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29949, PR29949}.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_set_num_threads(int);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_set_num_threads(set)}
+@item                   @tab @code{integer, intent(in) :: set}
+@end multitable
+
+@item @emph{See also}:
+@ref{OMP_NUM_THREADS}, @ref{omp_get_num_threads}, @ref{omp_get_max_threads}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.2.1.
+@end table
+
+
+
+@node omp_init_lock
+@section @code{omp_init_lock} -- Initialize simple lock
+@table @asis
+@item @emph{Description}:
+Initialize a simple lock. After initialization, the lock is in 
+an unlocked state.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_init_lock(omp_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_init_lock(lock)}
+@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_destroy_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.1.
+@end table
+
+
+
+@node omp_set_lock
+@section @code{omp_set_lock} -- Wait for and set simple lock
+@table @asis
+@item @emph{Description}:
+Before setting a simple lock, the lock variable must be initialized by 
+@code{omp_init_lock}. The calling thread is blocked until the lock 
+is available. If the lock is already held by the current thread, 
+a deadlock occurs.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_set_lock(omp_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_set_lock(lock)}
+@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_init_lock}, @ref{omp_test_lock}, @ref{omp_unset_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.3.
+@end table
+
+
+
+@node omp_test_lock
+@section @code{omp_test_lock} -- Test and set simple lock if available
+@table @asis
+@item @emph{Description}:
+Before setting a simple lock, the lock variable must be initialized by 
+@code{omp_init_lock}. Contrary to @code{omp_set_lock}, @code{omp_test_lock} 
+does not block if the lock is not available. This function returns 
+@code{true} upon success,@code{false} otherwise. Here, @code{true} and 
+@code{false} represent their language-specific counterparts.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_test_lock(omp_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_test_lock(lock)}
+@item                   @tab @code{logical(omp_logical_kind) :: omp_test_lock}
+@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_init_lock}, @ref{omp_set_lock}, @ref{omp_set_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.5.
+@end table
+
+
+
+@node omp_unset_lock
+@section @code{omp_unset_lock} -- Unset simple lock
+@table @asis
+@item @emph{Description}:
+A simple lock about to be unset must have been locked by @code{omp_set_lock}
+or @code{omp_test_lock} before. In addition, the lock must be held by the 
+thread calling @code{omp_unset_lock}. Then, the lock becomes unlocked. If one 
+ore more threads attempted to set the lock before, one of them is chosen to, 
+again, set the lock for itself.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_unset_lock(omp_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_unset_lock(lock)}
+@item                   @tab @code{integer(omp_lock_kind), intent(out) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_set_lock}, @ref{omp_test_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.4.
+@end table
+
+
+
+@node omp_destroy_lock
+@section @code{omp_destroy_lock} -- Destroy simple lock
+@table @asis
+@item @emph{Description}:
+Destroy a simple lock. In order to be destroyed, a simple lock must be 
+in the unlocked state. 
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_destroy_lock(omp_lock_t *);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_destroy_lock(lock)}
+@item                   @tab @code{integer(omp_lock_kind), intent(inout) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_init_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.2.
+@end table
+
+
+
+@node omp_init_nest_lock
+@section @code{omp_init_nest_lock} -- Initialize nested lock
+@table @asis
+@item @emph{Description}:
+Initialize a nested lock. After initialization, the lock is in 
+an unlocked state and the nesting count is set to zero.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_init_nest_lock(omp_nest_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_init_nest_lock(lock)}
+@item                   @tab @code{integer(omp_nest_lock_kind), intent(out) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_destroy_nest_lock}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.1.
+@end table
+
+
+@node omp_set_nest_lock
+@section @code{omp_set_nest_lock} -- Wait for and set simple lock
+@table @asis
+@item @emph{Description}:
+Before setting a nested lock, the lock variable must be initialized by 
+@code{omp_init_nest_lock}. The calling thread is blocked until the lock 
+is available. If the lock is already held by the current thread, the 
+nesting count for the lock in incremented.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_set_nest_lock(omp_nest_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_set_nest_lock(lock)}
+@item                   @tab @code{integer(omp_nest_lock_kind), intent(out) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_init_nest_lock}, @ref{omp_unset_nest_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.3.
+@end table
+
+
+
+@node omp_test_nest_lock
+@section @code{omp_test_nest_lock} -- Test and set nested lock if available
+@table @asis
+@item @emph{Description}:
+Before setting a nested lock, the lock variable must be initialized by 
+@code{omp_init_nest_lock}. Contrary to @code{omp_set_nest_lock}, 
+@code{omp_test_nest_lock} does not block if the lock is not available. 
+If the lock is already held by the current thread, the new nesting count 
+is returned. Otherwise, the return value equals zero.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_test_nest_lock(omp_nest_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{integer function omp_test_nest_lock(lock)}
+@item                   @tab @code{integer(omp_integer_kind) :: omp_test_nest_lock}
+@item                   @tab @code{integer(omp_nest_lock_kind), intent(inout) :: lock}
+@end multitable
+
+
+@item @emph{See also}:
+@ref{omp_init_lock}, @ref{omp_set_lock}, @ref{omp_set_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.5.
+@end table
+
+
+
+@node omp_unset_nest_lock
+@section @code{omp_unset_nest_lock} -- Unset nested lock
+@table @asis
+@item @emph{Description}:
+A nested lock about to be unset must have been locked by @code{omp_set_nested_lock}
+or @code{omp_test_nested_lock} before. In addition, the lock must be held by the 
+thread calling @code{omp_unset_nested_lock}. If the nesting count drops to zero, the 
+lock becomes unlocked. If one ore more threads attempted to set the lock before, 
+one of them is chosen to, again, set the lock for itself.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_unset_nest_lock(omp_nest_lock_t *lock);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_unset_nest_lock(lock)}
+@item                   @tab @code{integer(omp_nest_lock_kind), intent(out) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_set_nest_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.4.
+@end table
+
+
+
+@node omp_destroy_nest_lock
+@section @code{omp_destroy_nest_lock} -- Destroy nested lock
+@table @asis
+@item @emph{Description}:
+Destroy a nested lock. In order to be destroyed, a nested lock must be 
+in the unlocked state and its nesting count must equal zero.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void omp_destroy_nest_lock(omp_nest_lock_t *);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{subroutine omp_destroy_nest_lock(lock)}
+@item                   @tab @code{integer(omp_nest_lock_kind), intent(inout) :: lock}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_init_lock}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.3.2.
+@end table
+
+
+
+@node omp_get_wtick
+@section @code{omp_get_wtick} -- Get timer precision
+@table @asis
+@item @emph{Description}:
+Gets the timer precision, i. e. the number of seconds between two 
+successive clock ticks.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{double omp_get_wtick();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{double precision function omp_get_wtick()}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_get_wtime}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.4.2.
+@end table
+
+
+
+@node omp_get_wtime
+@section @code{omp_get_wtime} -- Elapsed wall clock time
+@table @asis
+@item @emph{Description}:
+Elapsed wall clock time in seconds. The time is measured per thread, no 
+guarantee can bee made that two distinct threads measure the same time.
+Time is measured from some "time in the past". On POSIX compliant systems 
+the seconds since the Epoch (00:00:00 UTC, January 1, 1970) are returned.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{double omp_get_wtime();}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{double precision function omp_get_wtime()}
+@end multitable
+
+@item @emph{See also}:
+@ref{omp_get_wtick}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 3.4.1.
+@end table
+
+
+
+@c ---------------------------------------------------------------------
+@c Environment Variables
+@c ---------------------------------------------------------------------
+
+@node Environment Variables
+@chapter Environment Variables
+
+The variables @env{OMP_DYNAMIC}, @env{OMP_NESTED}, @env{OMP_NUM_THREADS} and 
+@env{OMP_SCHEDULE} are defined by section 4 of the OpenMP specifications in 
+version 2.5, while @env{GOMP_CPU_AFFINITY} and @env{GOMP_STACKSIZE} are GNU 
+extensions.
+
+@menu
+* OMP_DYNAMIC::        Dynamic adjustment of threads
+* OMP_NESTED::         Nested parallel regions
+* OMP_NUM_THREADS::    Specifies the number of threads to use
+* OMP_SCHEDULE::       How threads are scheduled
+* GOMP_CPU_AFFINITY::  Bind threads to specific CPUs
+* GOMP_STACKSIZE::     Set default thread stack size
+@end menu
+
+
+@node OMP_DYNAMIC
+@section @env{OMP_DYNAMIC} -- Dynamic adjustment of threads
+@cindex Environment Variable
+@table @asis
+@item @emph{Description}:
+Enable or disable the dynamic adjustment of the number of threads 
+within a team. The value of this environment variable shall be 
+@code{TRUE} or @code{FALSE}.
+
+@item @emph{See also}:
+@ref{omp_set_dynamic}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 4.3
+@end table
+
+
+
+@node OMP_NESTED
+@section @env{OMP_NESTED} -- Nested parallel regions
+@cindex Environment Variable
+@table @asis
+@item @emph{Description}:
+Enable or disable nested parallel regions, i. e. whether team members
+are allowed to create new teams. The value of this environment variable 
+shall be @code{TRUE} or @code{FALSE}.
+
+@item @emph{See also}:
+@ref{omp_set_nested}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 4.4
+@end table
+
+
+
+@node OMP_NUM_THREADS
+@section @env{OMP_NUM_THREADS} -- Specifies the number of threads to use
+@cindex Environment Variable
+@table @asis
+@item @emph{Description}:
+Specifies the number of threads to use in parallel regions. If undefined
+one thread per CPU online is used. The value of this variable shall be 
+positive integer. 
+
+@item @emph{See also}:
+@ref{omp_set_num_threads}
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 4.2
+@end table
+
+
+
+@node OMP_SCHEDULE
+@section @env{OMP_SCHEDULE} -- How threads are scheduled
+@cindex Environment Variable
+@table @asis
+@item @emph{Description}:
+Allows to specify @code{schedule type} and @code{chunk size}. 
+The value of the variable shall have the form: @code{type[,chunk]} where
+@code{type} is one of @code{static}, @code{dynamic} or @code{guided}. 
+The optional @code{chunk size} shall be a positive integer. 
+
+@item @emph{Reference}: 
+@uref{http://www.openmp.org/, OpenMP specifications v2.5}, section 4.1
+@end table
+
+
+
+@node GOMP_CPU_AFFINITY
+@section @env{GOMP_CPU_AFFINITY} -- Bind threads to specific CPUs
+@cindex Environment Variable
+@table @asis
+@item @emph{Description}:
+A patch for this extension has been submitted, but was not yet applied at the
+time of writing.
+
+@item @emph{Reference}: 
+@uref{http://gcc.gnu.org/ml/gcc-patches/2006-05/msg00982.html, 
+GCC Patches Mailinglist}
+@uref{http://gcc.gnu.org/ml/gcc-patches/2006-05/msg01133.html,
+GCC Patches Mailinglist}
+@end table
+
+
+
+@node GOMP_STACKSIZE
+@section @env{GOMP_STACKSIZE} -- Set default thread stack size
+@cindex Environment Variable
+@table @asis
+@item @emph{Description}:
+Set the default thread stack size in kilobytes. This is in opposition 
+to @code{pthread_attr_setstacksize} which gets the number of bytes as an 
+argument. If the stacksize can not be set due to system constraints, an 
+error is reported and the initial stacksize is left unchanged.
+
+@item @emph{Reference}: 
+@uref{http://gcc.gnu.org/ml/gcc-patches/2006-06/msg00493.html, 
+GCC Patches Mailinglist}, 
+@uref{http://gcc.gnu.org/ml/gcc-patches/2006-06/msg00496.html,
+GCC Patches Mailinglist}
+@end table
+
+
+
+@c ---------------------------------------------------------------------
+@c The libgomp ABI
+@c ---------------------------------------------------------------------
+
+@node The libgomp ABI
+@chapter The libgomp ABI
+
+The following sections present notes on the external ABI as 
+presented by libgomp. Only maintainers should need them.
+
+@menu
+* Implementing MASTER construct::
+* Implementing CRITICAL construct::
+* Implementing ATOMIC construct::
+* Implementing FLUSH construct::
+* Implementing BARRIER construct::
+* Implementing THREADPRIVATE construct::
+* Implementing PRIVATE clause::
+* Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses::
+* Implementing REDUCTION clause::
+* Implementing PARALLEL construct::
+* Implementing FOR construct::
+* Implementing ORDERED construct::
+* Implementing SECTIONS construct::
+* Implementing SINGLE construct::
+@end menu
+
+
+@node Implementing MASTER construct
+@section Implementing MASTER construct
+
+@smallexample
+if (omp_get_thread_num () == 0)
+  block
+@end smallexample
+
+Alternately, we generate two copies of the parallel subfunction
+and only include this in the version run by the master thread.
+Surely that's not worthwhile though...
+
+
+
+@node Implementing CRITICAL construct
+@section Implementing CRITICAL construct
+
+Without a specified name,
+
+@smallexample
+  void GOMP_critical_start (void);
+  void GOMP_critical_end (void);
+@end smallexample
+
+so that we don't get COPY relocations from libgomp to the main
+application.
+
+With a specified name, use omp_set_lock and omp_unset_lock with
+name being transformed into a variable declared like
+
+@smallexample
+  omp_lock_t gomp_critical_user_<name> __attribute__((common))
+@end smallexample
+
+Ideally the ABI would specify that all zero is a valid unlocked
+state, and so we wouldn't actually need to initialize this at
+startup.
+
+
+
+@node Implementing ATOMIC construct
+@section Implementing ATOMIC construct
+
+The target should implement the @code{__sync} builtins.
+
+Failing that we could add
+
+@smallexample
+  void GOMP_atomic_enter (void)
+  void GOMP_atomic_exit (void)
+@end smallexample
+
+which reuses the regular lock code, but with yet another lock
+object private to the library.
+
+
+
+@node Implementing FLUSH construct
+@section Implementing FLUSH construct
+
+Expands to the @code{__sync_synchronize} builtin.
+
+
+
+@node Implementing BARRIER construct
+@section Implementing BARRIER construct
+
+@smallexample
+  void GOMP_barrier (void)
+@end smallexample
+
+
+@node Implementing THREADPRIVATE construct
+@section Implementing THREADPRIVATE construct
+
+In _most_ cases we can map this directly to @code{__thread}.  Except
+that OMP allows constructors for C++ objects.  We can either
+refuse to support this (how often is it used?) or we can 
+implement something akin to .ctors.
+
+Even more ideally, this ctor feature is handled by extensions
+to the main pthreads library.  Failing that, we can have a set
+of entry points to register ctor functions to be called.
+
+
+
+@node Implementing PRIVATE clause
+@section Implementing PRIVATE clause
+
+In association with a PARALLEL, or within the lexical extent
+of a PARALLEL block, the variable becomes a local variable in
+the parallel subfunction.
+
+In association with FOR or SECTIONS blocks, create a new
+automatic variable within the current function.  This preserves
+the semantic of new variable creation.
+
+
+
+@node Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses
+@section Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses
+
+Seems simple enough for PARALLEL blocks.  Create a private 
+struct for communicating between parent and subfunction.
+In the parent, copy in values for scalar and "small" structs;
+copy in addresses for others TREE_ADDRESSABLE types.  In the 
+subfunction, copy the value into the local variable.
+
+Not clear at all what to do with bare FOR or SECTION blocks.
+The only thing I can figure is that we do something like
+
+@smallexample
+#pragma omp for firstprivate(x) lastprivate(y)
+for (int i = 0; i < n; ++i)
+  body;
+@end smallexample
+
+which becomes
+
+@smallexample
+@{
+  int x = x, y;
+
+  // for stuff
+
+  if (i == n)
+    y = y;
+@}
+@end smallexample
+
+where the "x=x" and "y=y" assignments actually have different
+uids for the two variables, i.e. not something you could write
+directly in C.  Presumably this only makes sense if the "outer"
+x and y are global variables.
+
+COPYPRIVATE would work the same way, except the structure 
+broadcast would have to happen via SINGLE machinery instead.
+
+
+
+@node Implementing REDUCTION clause
+@section Implementing REDUCTION clause
+
+The private struct mentioned in the previous section should have 
+a pointer to an array of the type of the variable, indexed by the 
+thread's @var{team_id}.  The thread stores its final value into the 
+array, and after the barrier the master thread iterates over the
+array to collect the values.
+
+
+@node Implementing PARALLEL construct
+@section Implementing PARALLEL construct
+
+@smallexample
+  #pragma omp parallel
+  @{
+    body;
+  @}
+@end smallexample
+
+becomes
+
+@smallexample
+  void subfunction (void *data)
+  @{
+    use data;
+    body;
+  @}
+
+  setup data;
+  GOMP_parallel_start (subfunction, &data, num_threads);
+  subfunction (&data);
+  GOMP_parallel_end ();
+@end smallexample
+
+@smallexample
+  void GOMP_parallel_start (void (*fn)(void *), void *data, unsigned num_threads)
+@end smallexample
+
+The @var{FN} argument is the subfunction to be run in parallel.
+
+The @var{DATA} argument is a pointer to a structure used to 
+communicate data in and out of the subfunction, as discussed
+above wrt FIRSTPRIVATE et al.
+
+The @var{NUM_THREADS} argument is 1 if an IF clause is present
+and false, or the value of the NUM_THREADS clause, if
+present, or 0.
+
+The function needs to create the appropriate number of
+threads and/or launch them from the dock.  It needs to
+create the team structure and assign team ids.
+
+@smallexample
+  void GOMP_parallel_end (void)
+@end smallexample
+
+Tears down the team and returns us to the previous @code{omp_in_parallel()} state.
+
+
+
+@node Implementing FOR construct
+@section Implementing FOR construct
+
+@smallexample
+  #pragma omp parallel for
+  for (i = lb; i <= ub; i++)
+    body;
+@end smallexample
+
+becomes
+
+@smallexample
+  void subfunction (void *data)
+  @{
+    long _s0, _e0;
+    while (GOMP_loop_static_next (&_s0, &_e0))
+    @{
+      long _e1 = _e0, i;
+      for (i = _s0; i < _e1; i++)
+        body;
+    @}
+    GOMP_loop_end_nowait ();
+  @}
+
+  GOMP_parallel_loop_static (subfunction, NULL, 0, lb, ub+1, 1, 0);
+  subfunction (NULL);
+  GOMP_parallel_end ();
+@end smallexample
+
+@smallexample
+  #pragma omp for schedule(runtime)
+  for (i = 0; i < n; i++)
+    body;
+@end smallexample
+
+becomes
+
+@smallexample
+  @{
+    long i, _s0, _e0;
+    if (GOMP_loop_runtime_start (0, n, 1, &_s0, &_e0))
+      do @{
+        long _e1 = _e0;
+        for (i = _s0, i < _e0; i++)
+          body;
+      @} while (GOMP_loop_runtime_next (&_s0, _&e0));
+    GOMP_loop_end ();
+  @}
+@end smallexample
+
+Note that while it looks like there is trickyness to propagating
+a non-constant STEP, there isn't really.  We're explicitly allowed
+to evaluate it as many times as we want, and any variables involved
+should automatically be handled as PRIVATE or SHARED like any other
+variables.  So the expression should remain evaluable in the 
+subfunction.  We can also pull it into a local variable if we like,
+but since its supposed to remain unchanged, we can also not if we like.
+
+If we have SCHEDULE(STATIC), and no ORDERED, then we ought to be
+able to get away with no work-sharing context at all, since we can
+simply perform the arithmetic directly in each thread to divide up
+the iterations.  Which would mean that we wouldn't need to call any
+of these routines.
+
+There are separate routines for handling loops with an ORDERED
+clause.  Bookkeeping for that is non-trivial...
+
+
+
+@node Implementing ORDERED construct
+@section Implementing ORDERED construct
+
+@smallexample
+  void GOMP_ordered_start (void)
+  void GOMP_ordered_end (void)
+@end smallexample
+
+
+
+@node Implementing SECTIONS construct
+@section Implementing SECTIONS construct
+
+A block as 
+
+@smallexample
+  #pragma omp sections
+  @{
+    #pragma omp section
+    stmt1;
+    #pragma omp section
+    stmt2;
+    #pragma omp section
+    stmt3;
+  @}
+@end smallexample
+
+becomes
+
+@smallexample
+  for (i = GOMP_sections_start (3); i != 0; i = GOMP_sections_next ())
+    switch (i)
+      @{
+      case 1:
+        stmt1;
+        break;
+      case 2:
+        stmt2;
+        break;
+      case 3:
+        stmt3;
+        break;
+      @}
+  GOMP_barrier ();
+@end smallexample
+
+
+@node Implementing SINGLE construct
+@section Implementing SINGLE construct
+
+A block like 
+
+@smallexample
+  #pragma omp single
+  @{
+    body;
+  @}
+@end smallexample
+
+becomes
+
+@smallexample
+  if (GOMP_single_start ())
+    body;
+  GOMP_barrier ();
+@end smallexample
+
+while 
+
+@smallexample
+  #pragma omp single copyprivate(x)
+    body;
+@end smallexample
+
+becomes
+
+@smallexample
+  datap = GOMP_single_copy_start ();
+  if (datap == NULL)
+    @{
+      body;
+      data.x = x;
+      GOMP_single_copy_end (&data);
+    @}
+  else
+    x = datap->x;
+  GOMP_barrier ();
+@end smallexample
+
+
+
+@c ---------------------------------------------------------------------
+@c 
+@c ---------------------------------------------------------------------
+
+@node Reporting Bugs
+@chapter Reporting Bugs
+
+Bugs in the GNU OpenMP implementation should be reported via 
+@uref{http://gcc.gnu.org/bugzilla/, bugzilla}. In all cases, please add 
+"openmp" to the keywords field in the bug report.
+
+
+
+@c ---------------------------------------------------------------------
+@c GNU General Public License
+@c ---------------------------------------------------------------------
+
+@include gpl.texi
+
+
+
+@c ---------------------------------------------------------------------
+@c GNU Free Documentation License
+@c ---------------------------------------------------------------------
+
+@include fdl.texi
+
+
+
+@c ---------------------------------------------------------------------
+@c Funding Free Software
+@c ---------------------------------------------------------------------
+
+@include funding.texi
+
+@c ---------------------------------------------------------------------
+@c Index
+@c ---------------------------------------------------------------------
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye
index 01227b6..df20ea4 100644 (file)
@@ -42,6 +42,7 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/enable.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
+       $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/stdint.m4 \
        $(top_srcdir)/../config/tls.m4 $(top_srcdir)/acinclude.m4 \
        $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
@@ -79,6 +80,9 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+GENINSRC_FALSE = @GENINSRC_FALSE@
+GENINSRC_TRUE = @GENINSRC_TRUE@
+GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -121,11 +125,8 @@ USE_FORTRAN_TRUE = @USE_FORTRAN_TRUE@
 VERSION = @VERSION@
 XCFLAGS = @XCFLAGS@
 XLDFLAGS = @XLDFLAGS@
-ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_FC = @ac_ct_FC@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
 am__include = @am__include@
@@ -141,6 +142,9 @@ build_os = @build_os@
 build_vendor = @build_vendor@
 config_path = @config_path@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 enable_shared = @enable_shared@
 enable_static = @enable_static@
 exec_prefix = @exec_prefix@
@@ -149,6 +153,7 @@ host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
@@ -156,13 +161,16 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 libtool_VERSION = @libtool_VERSION@
 link_gomp = @link_gomp@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 multi_basedir = @multi_basedir@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@