Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,5 @@
---
BasedOnStyle: LLVM
AlignTrailingComments: false
SortIncludes: false
...

View File

@@ -0,0 +1,393 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
message(FATAL_ERROR "Direct configuration not supported, please use parent directory!")
endif()
# Add cmake directory to search for custom cmake functions
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
# Set libomp version
set(LIBOMP_VERSION_MAJOR 5)
set(LIBOMP_VERSION_MINOR 0)
# These include files are in the cmake/ subdirectory
include(LibompUtils)
include(LibompGetArchitecture)
include(LibompHandleFlags)
include(LibompDefinitions)
# Determine the target architecture
if(${OPENMP_STANDALONE_BUILD})
# If adding a new architecture, take a look at cmake/LibompGetArchitecture.cmake
libomp_get_architecture(LIBOMP_DETECTED_ARCH)
set(LIBOMP_ARCH ${LIBOMP_DETECTED_ARCH} CACHE STRING
"The architecture to build for (x86_64/i386/arm/ppc64/ppc64le/aarch64/mic/mips/mips64).")
# Should assertions be enabled? They are on by default.
set(LIBOMP_ENABLE_ASSERTIONS TRUE CACHE BOOL
"enable assertions?")
else() # Part of LLVM build
# Determine the native architecture from LLVM.
string(TOLOWER "${LLVM_TARGET_ARCH}" LIBOMP_NATIVE_ARCH)
if( LIBOMP_NATIVE_ARCH STREQUAL "host" )
string(REGEX MATCH "^[^-]*" LIBOMP_NATIVE_ARCH ${LLVM_HOST_TRIPLE})
endif ()
if(LIBOMP_NATIVE_ARCH MATCHES "i[2-6]86")
set(LIBOMP_ARCH i386)
elseif(LIBOMP_NATIVE_ARCH STREQUAL "x86")
set(LIBOMP_ARCH i386)
elseif(LIBOMP_NATIVE_ARCH STREQUAL "amd64")
set(LIBOMP_ARCH x86_64)
elseif(LIBOMP_NATIVE_ARCH STREQUAL "x86_64")
set(LIBOMP_ARCH x86_64)
elseif(LIBOMP_NATIVE_ARCH MATCHES "powerpc64le")
set(LIBOMP_ARCH ppc64le)
elseif(LIBOMP_NATIVE_ARCH MATCHES "powerpc")
set(LIBOMP_ARCH ppc64)
elseif(LIBOMP_NATIVE_ARCH MATCHES "aarch64")
set(LIBOMP_ARCH aarch64)
elseif(LIBOMP_NATIVE_ARCH MATCHES "arm64")
set(LIBOMP_ARCH aarch64)
elseif(LIBOMP_NATIVE_ARCH MATCHES "arm")
set(LIBOMP_ARCH arm)
else()
# last ditch effort
libomp_get_architecture(LIBOMP_ARCH)
endif ()
set(LIBOMP_ENABLE_ASSERTIONS ${LLVM_ENABLE_ASSERTIONS})
endif()
libomp_check_variable(LIBOMP_ARCH 32e x86_64 32 i386 arm ppc64 ppc64le aarch64 mic mips mips64)
set(LIBOMP_LIB_TYPE normal CACHE STRING
"Performance,Profiling,Stubs library (normal/profile/stubs)")
libomp_check_variable(LIBOMP_LIB_TYPE normal profile stubs)
set(LIBOMP_OMP_VERSION 50 CACHE STRING
"The OpenMP version (50/45/40/30)")
libomp_check_variable(LIBOMP_OMP_VERSION 50 45 40 30)
# Set the OpenMP Year and Month assiociated with version
if(${LIBOMP_OMP_VERSION} GREATER 50 OR ${LIBOMP_OMP_VERSION} EQUAL 50)
set(LIBOMP_OMP_YEAR_MONTH 201611)
elseif(${LIBOMP_OMP_VERSION} GREATER 45 OR ${LIBOMP_OMP_VERSION} EQUAL 45)
set(LIBOMP_OMP_YEAR_MONTH 201511)
elseif(${LIBOMP_OMP_VERSION} GREATER 40 OR ${LIBOMP_OMP_VERSION} EQUAL 40)
set(LIBOMP_OMP_YEAR_MONTH 201307)
elseif(${LIBOMP_OMP_VERSION} GREATER 30 OR ${LIBOMP_OMP_VERSION} EQUAL 30)
set(LIBOMP_OMP_YEAR_MONTH 201107)
else()
set(LIBOMP_OMP_YEAR_MONTH 200505)
endif()
set(LIBOMP_MIC_ARCH knc CACHE STRING
"Intel(R) Many Integrated Core Architecture (Intel(R) MIC Architecture) (knf/knc). Ignored if not Intel(R) MIC Architecture build.")
if("${LIBOMP_ARCH}" STREQUAL "mic")
libomp_check_variable(LIBOMP_MIC_ARCH knf knc)
endif()
set(LIBOMP_FORTRAN_MODULES FALSE CACHE BOOL
"Create Fortran module files? (requires fortran compiler)")
# - Support for universal fat binary builds on Mac
# - Having this extra variable allows people to build this library as a universal library
# without forcing a universal build of the llvm/clang compiler.
set(LIBOMP_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}" CACHE STRING
"For Mac builds, semicolon separated list of architectures to build for universal fat binary.")
set(CMAKE_OSX_ARCHITECTURES ${LIBOMP_OSX_ARCHITECTURES})
# Should @rpath be used for dynamic libraries on Mac?
# The if(NOT DEFINED) is there to guard a cached value of the variable if one
# exists so there is no interference with what the user wants. Also, no cache entry
# is created so there are no inadvertant effects on other parts of LLVM.
if(NOT DEFINED CMAKE_MACOSX_RPATH)
set(CMAKE_MACOSX_RPATH TRUE)
endif()
# User specified flags. These are appended to the configured flags.
set(LIBOMP_CFLAGS "" CACHE STRING
"Appended user specified C compiler flags.")
set(LIBOMP_CXXFLAGS "" CACHE STRING
"Appended user specified C++ compiler flags.")
set(LIBOMP_CPPFLAGS "" CACHE STRING
"Appended user specified C preprocessor flags.")
set(LIBOMP_ASMFLAGS "" CACHE STRING
"Appended user specified assembler flags.")
set(LIBOMP_LDFLAGS "" CACHE STRING
"Appended user specified linker flags.")
set(LIBOMP_LIBFLAGS "" CACHE STRING
"Appended user specified linked libs flags. (e.g., -lm)")
set(LIBOMP_FFLAGS "" CACHE STRING
"Appended user specified Fortran compiler flags. These are only used if LIBOMP_FORTRAN_MODULES==TRUE.")
# Should the libomp library and generated headers be copied into the original source exports/ directory
# Turning this to FALSE aids parallel builds to not interfere with each other.
# Currently, the testsuite module expects the just built OpenMP library to be located inside the exports/
# directory. TODO: have testsuite run under llvm-lit directly. We can then get rid of copying to exports/
set(LIBOMP_COPY_EXPORTS TRUE CACHE STRING
"Should exports be copied into source exports/ directory?")
# HWLOC-support
set(LIBOMP_USE_HWLOC FALSE CACHE BOOL
"Use Hwloc (http://www.open-mpi.org/projects/hwloc/) library for affinity?")
set(LIBOMP_HWLOC_INSTALL_DIR /usr/local CACHE PATH
"Install path for hwloc library")
# Get the build number from kmp_version.cpp
libomp_get_build_number("${CMAKE_CURRENT_SOURCE_DIR}" LIBOMP_VERSION_BUILD)
math(EXPR LIBOMP_VERSION_BUILD_YEAR "${LIBOMP_VERSION_BUILD}/10000")
math(EXPR LIBOMP_VERSION_BUILD_MONTH_DAY "${LIBOMP_VERSION_BUILD}%10000")
# Currently don't record any timestamps
set(LIBOMP_BUILD_DATE "No_Timestamp")
# Architecture
set(IA32 FALSE)
set(INTEL64 FALSE)
set(ARM FALSE)
set(AARCH64 FALSE)
set(PPC64BE FALSE)
set(PPC64LE FALSE)
set(PPC64 FALSE)
set(MIC FALSE)
set(MIPS64 FALSE)
set(MIPS FALSE)
if("${LIBOMP_ARCH}" STREQUAL "i386" OR "${LIBOMP_ARCH}" STREQUAL "32") # IA-32 architecture
set(IA32 TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "x86_64" OR "${LIBOMP_ARCH}" STREQUAL "32e") # Intel(R) 64 architecture
set(INTEL64 TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "arm") # ARM architecture
set(ARM TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "ppc64") # PPC64BE architecture
set(PPC64BE TRUE)
set(PPC64 TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "ppc64le") # PPC64LE architecture
set(PPC64LE TRUE)
set(PPC64 TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "aarch64") # AARCH64 architecture
set(AARCH64 TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "mic") # Intel(R) Many Integrated Core Architecture
set(MIC TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "mips") # MIPS architecture
set(MIPS TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "mips64") # MIPS64 architecture
set(MIPS64 TRUE)
endif()
# Set some flags based on build_type
set(RELEASE_BUILD FALSE)
set(DEBUG_BUILD FALSE)
set(RELWITHDEBINFO_BUILD FALSE)
set(MINSIZEREL_BUILD FALSE)
string(TOLOWER "${CMAKE_BUILD_TYPE}" libomp_build_type_lowercase)
if("${libomp_build_type_lowercase}" STREQUAL "release")
set(RELEASE_BUILD TRUE)
elseif("${libomp_build_type_lowercase}" STREQUAL "debug")
set(DEBUG_BUILD TRUE)
elseif("${libomp_build_type_lowercase}" STREQUAL "relwithdebinfo")
set(RELWITHDEBINFO_BUILD TRUE)
elseif("${libomp_build_type_lowercase}" STREQUAL "minsizerel")
set(MINSIZEREL_BUILD TRUE)
endif()
# Include itt notify interface?
set(LIBOMP_USE_ITT_NOTIFY TRUE CACHE BOOL
"Enable ITT notify?")
# normal, profile, stubs library.
set(NORMAL_LIBRARY FALSE)
set(STUBS_LIBRARY FALSE)
set(PROFILE_LIBRARY FALSE)
if("${LIBOMP_LIB_TYPE}" STREQUAL "normal")
set(NORMAL_LIBRARY TRUE)
elseif("${LIBOMP_LIB_TYPE}" STREQUAL "profile")
set(PROFILE_LIBRARY TRUE)
elseif("${LIBOMP_LIB_TYPE}" STREQUAL "stubs")
set(STUBS_LIBRARY TRUE)
endif()
# Setting directory names
set(LIBOMP_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LIBOMP_SRC_DIR ${LIBOMP_BASE_DIR}/src)
set(LIBOMP_TOOLS_DIR ${LIBOMP_BASE_DIR}/tools)
set(LIBOMP_INC_DIR ${LIBOMP_SRC_DIR}/include/${LIBOMP_OMP_VERSION})
set(LIBOMP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
# Enabling Fortran if it is needed
if(${LIBOMP_FORTRAN_MODULES})
enable_language(Fortran)
endif()
# Enable MASM Compiler if it is needed (Windows only)
if(WIN32)
enable_language(ASM_MASM)
endif()
# Getting legal type/arch
libomp_get_legal_type(LIBOMP_LEGAL_TYPE)
libomp_get_legal_arch(LIBOMP_LEGAL_ARCH)
# Compiler flag checks, library checks, threading check, etc.
include(config-ix)
# Is there a quad precision data type available?
# TODO: Make this a real feature check
set(LIBOMP_USE_QUAD_PRECISION "${LIBOMP_HAVE_QUAD_PRECISION}" CACHE BOOL
"Should 128-bit precision entry points be built?")
if(LIBOMP_USE_QUAD_PRECISION AND (NOT LIBOMP_HAVE_QUAD_PRECISION))
libomp_error_say("128-bit quad precision functionality requested but not available")
endif()
# libgomp drop-in compatibility requires versioned symbols
set(LIBOMP_USE_VERSION_SYMBOLS "${LIBOMP_HAVE_VERSION_SYMBOLS}" CACHE BOOL
"Should version symbols be used? These provide binary compatibility with libgomp.")
if(LIBOMP_USE_VERSION_SYMBOLS AND (NOT LIBOMP_HAVE_VERSION_SYMBOLS))
libomp_error_say("Version symbols functionality requested but not available")
endif()
# On multinode systems, larger alignment is desired to avoid false sharing
set(LIBOMP_USE_INTERNODE_ALIGNMENT FALSE CACHE BOOL
"Should larger alignment (4096 bytes) be used for some locks and data structures?")
# Build code that allows the OpenMP library to conveniently interface with debuggers
set(LIBOMP_USE_DEBUGGER FALSE CACHE BOOL
"Enable debugger interface code?")
# Should we link to C++ library?
set(LIBOMP_USE_STDCPPLIB FALSE CACHE BOOL
"Should we link to C++ library?")
# Intel(R) Transactional Synchronization Extensions (Intel(R) TSX) based locks have
# __asm code which can be troublesome for some compilers. This feature is also x86 specific.
# TODO: Make this a real feature check
set(LIBOMP_USE_ADAPTIVE_LOCKS "${LIBOMP_HAVE_ADAPTIVE_LOCKS}" CACHE BOOL
"Should Intel(R) TSX lock be compiled (adaptive lock in kmp_lock.cpp). These are x86 specific.")
if(LIBOMP_USE_ADAPTIVE_LOCKS AND (NOT LIBOMP_HAVE_ADAPTIVE_LOCKS))
libomp_error_say("Adaptive locks (Intel(R) TSX) functionality is only supported on x86 Architecture")
endif()
# - stats-gathering enables OpenMP stats where things like the number of
# parallel regions, clock ticks spent in particular openmp regions are recorded.
set(LIBOMP_STATS FALSE CACHE BOOL
"Stats-Gathering functionality?")
if(LIBOMP_STATS AND (NOT LIBOMP_HAVE_STATS))
libomp_error_say("Stats-gathering functionality requested but not available")
endif()
# The stats functionality requires the std c++ library
if(LIBOMP_STATS)
set(LIBOMP_USE_STDCPPLIB TRUE)
endif()
# Shared library can be switched to a static library
set(LIBOMP_ENABLE_SHARED TRUE CACHE BOOL
"Shared library instead of static library?")
if(WIN32 AND NOT LIBOMP_ENABLE_SHARED)
libomp_error_say("Static libraries requested but not available on Windows")
endif()
if(LIBOMP_USE_ITT_NOTIFY AND NOT LIBOMP_ENABLE_SHARED)
message(STATUS "ITT Notify not supported for static libraries - forcing ITT Notify off")
set(LIBOMP_USE_ITT_NOTIFY FALSE)
endif()
if(LIBOMP_USE_VERSION_SYMBOLS AND (NOT LIBOMP_ENABLE_SHARED) )
message(STATUS "Version symbols not supported for static libraries - forcing Version symbols functionality off")
set (LIBOMP_USE_VERSION_SYMBOLS FALSE)
endif()
# OMPT-support defaults to ON for OpenMP 5.0+ and if the requirements in
# cmake/config-ix.cmake are fulfilled.
set(OMPT_DEFAULT FALSE)
if ((${LIBOMP_OMP_VERSION} GREATER 49) AND (LIBOMP_HAVE_OMPT_SUPPORT))
set(OMPT_DEFAULT TRUE)
endif()
set(LIBOMP_OMPT_SUPPORT ${OMPT_DEFAULT} CACHE BOOL
"OMPT-support?")
set(LIBOMP_OMPT_DEBUG FALSE CACHE BOOL
"Trace OMPT initialization?")
set(LIBOMP_OMPT_OPTIONAL TRUE CACHE BOOL
"OMPT-optional?")
if(LIBOMP_OMPT_SUPPORT AND (NOT LIBOMP_HAVE_OMPT_SUPPORT))
libomp_error_say("OpenMP Tools Interface requested but not available in this implementation")
endif()
if(LIBOMP_OMPT_SUPPORT AND (${LIBOMP_OMP_VERSION} LESS 50))
libomp_error_say("OpenMP Tools Interface only available with OpenMP 5.0, LIBOMP_OMP_VERSION is ${LIBOMP_OMP_VERSION}")
endif()
# TSAN-support
set(LIBOMP_TSAN_SUPPORT FALSE CACHE BOOL
"TSAN-support?")
if(LIBOMP_TSAN_SUPPORT AND (NOT LIBOMP_HAVE_TSAN_SUPPORT))
libomp_error_say("TSAN functionality requested but not available")
endif()
# Error check hwloc support after config-ix has run
if(LIBOMP_USE_HWLOC AND (NOT LIBOMP_HAVE_HWLOC))
libomp_error_say("Hwloc requested but not available")
endif()
# Setting final library name
set(LIBOMP_DEFAULT_LIB_NAME libomp)
if(${PROFILE_LIBRARY})
set(LIBOMP_DEFAULT_LIB_NAME ${LIBOMP_DEFAULT_LIB_NAME}prof)
endif()
if(${STUBS_LIBRARY})
set(LIBOMP_DEFAULT_LIB_NAME ${LIBOMP_DEFAULT_LIB_NAME}stubs)
endif()
set(LIBOMP_LIB_NAME ${LIBOMP_DEFAULT_LIB_NAME} CACHE STRING "Base OMP library name")
if(${LIBOMP_ENABLE_SHARED})
set(LIBOMP_LIBRARY_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
set(LIBOMP_LIBRARY_KIND SHARED)
set(LIBOMP_INSTALL_KIND LIBRARY)
else()
set(LIBOMP_LIBRARY_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
set(LIBOMP_LIBRARY_KIND STATIC)
set(LIBOMP_INSTALL_KIND ARCHIVE)
endif()
set(LIBOMP_LIB_FILE ${LIBOMP_LIB_NAME}${LIBOMP_LIBRARY_SUFFIX})
# Optional backwards compatibility aliases.
set(LIBOMP_INSTALL_ALIASES TRUE CACHE BOOL
"Install libgomp and libiomp5 library aliases for backwards compatibility")
# Print configuration after all variables are set.
if(${OPENMP_STANDALONE_BUILD})
libomp_say("Operating System -- ${CMAKE_SYSTEM_NAME}")
libomp_say("Target Architecture -- ${LIBOMP_ARCH}")
if(${MIC})
libomp_say("Intel(R) MIC Architecture -- ${LIBOMP_MIC_ARCH}")
endif()
libomp_say("Build Type -- ${CMAKE_BUILD_TYPE}")
libomp_say("OpenMP Version -- ${LIBOMP_OMP_VERSION}")
libomp_say("Library Kind -- ${LIBOMP_LIBRARY_KIND}")
libomp_say("Library Type -- ${LIBOMP_LIB_TYPE}")
libomp_say("Fortran Modules -- ${LIBOMP_FORTRAN_MODULES}")
# will say development if all zeros
if(${LIBOMP_VERSION_BUILD} STREQUAL 00000000)
set(LIBOMP_BUILD Development)
else()
set(LIBOMP_BUILD ${LIBOMP_VERSION_BUILD})
endif()
libomp_say("Build -- ${LIBOMP_BUILD}")
libomp_say("Use Stats-gathering -- ${LIBOMP_STATS}")
libomp_say("Use Debugger-support -- ${LIBOMP_USE_DEBUGGER}")
libomp_say("Use ITT notify -- ${LIBOMP_USE_ITT_NOTIFY}")
libomp_say("Use OMPT-support -- ${LIBOMP_OMPT_SUPPORT}")
if(${LIBOMP_OMPT_SUPPORT})
libomp_say("Use OMPT-optional -- ${LIBOMP_OMPT_OPTIONAL}")
endif()
libomp_say("Use Adaptive locks -- ${LIBOMP_USE_ADAPTIVE_LOCKS}")
libomp_say("Use quad precision -- ${LIBOMP_USE_QUAD_PRECISION}")
libomp_say("Use TSAN-support -- ${LIBOMP_TSAN_SUPPORT}")
libomp_say("Use Hwloc library -- ${LIBOMP_USE_HWLOC}")
endif()
add_subdirectory(src)
add_subdirectory(test)

View File

@@ -0,0 +1,116 @@
README for the LLVM* OpenMP* Runtime Library
============================================
How to Build Documentation
==========================
The main documentation is in Doxygen* format, and this distribution
should come with pre-built PDF documentation in doc/Reference.pdf.
However, an HTML version can be built by executing:
% doxygen doc/doxygen/config
in the runtime directory.
That will produce HTML documentation in the doc/doxygen/generated
directory, which can be accessed by pointing a web browser at the
index.html file there.
If you don't have Doxygen installed, you can download it from
www.doxygen.org.
How to Build the LLVM* OpenMP* Runtime Library
==============================================
In-tree build:
$ cd where-you-want-to-live
Check out openmp into llvm/projects
$ cd where-you-want-to-build
$ mkdir build && cd build
$ cmake path/to/llvm -DCMAKE_C_COMPILER=<C compiler> -DCMAKE_CXX_COMPILER=<C++ compiler>
$ make omp
Out-of-tree build:
$ cd where-you-want-to-live
Check out openmp
$ cd where-you-want-to-live/openmp/runtime
$ mkdir build && cd build
$ cmake path/to/openmp -DCMAKE_C_COMPILER=<C compiler> -DCMAKE_CXX_COMPILER=<C++ compiler>
$ make
For details about building, please look at README.rst in the parent directory.
Architectures Supported
=======================
* IA-32 architecture
* Intel(R) 64 architecture
* Intel(R) Many Integrated Core Architecture
* ARM* architecture
* Aarch64 (64-bit ARM) architecture
* IBM(R) Power architecture (big endian)
* IBM(R) Power architecture (little endian)
* MIPS and MIPS64 architecture
Supported RTL Build Configurations
==================================
Supported Architectures: IA-32 architecture, Intel(R) 64, and
Intel(R) Many Integrated Core Architecture
----------------------------------------------
| icc/icl | gcc | clang |
--------------|---------------|----------------------------|
| Linux* OS | Yes(1,5) | Yes(2,4) | Yes(4,6,7) |
| FreeBSD* | No | No | Yes(4,6,7,8) |
| OS X* | Yes(1,3,4) | No | Yes(4,6,7) |
| Windows* OS | Yes(1,4) | No | No |
------------------------------------------------------------
(1) On IA-32 architecture and Intel(R) 64, icc/icl versions 12.x are
supported (12.1 is recommended).
(2) GCC* version 4.7 is supported.
(3) For icc on OS X*, OS X* version 10.5.8 is supported.
(4) Intel(R) Many Integrated Core Architecture not supported.
(5) On Intel(R) Many Integrated Core Architecture, icc/icl versions 13.0
or later are required.
(6) Clang* version 3.3 is supported.
(7) Clang* currently does not offer a software-implemented 128 bit extended
precision type. Thus, all entry points reliant on this type are removed
from the library and cannot be called in the user program. The following
functions are not available:
__kmpc_atomic_cmplx16_*
__kmpc_atomic_float16_*
__kmpc_atomic_*_fp
(8) Community contribution provided AS IS, not tested by Intel.
Supported Architectures: IBM(R) Power 7 and Power 8
-----------------------------
| gcc | clang |
--------------|------------|--------------|
| Linux* OS | Yes(1,2) | Yes(3,4) |
-------------------------------------------
(1) On Power 7, gcc version 4.8.2 is supported.
(2) On Power 8, gcc version 4.8.2 is supported.
(3) On Power 7, clang version 3.7 is supported.
(4) On Power 8, clang version 3.7 is supported.
Front-end Compilers that work with this RTL
===========================================
The following compilers are known to do compatible code generation for
this RTL: clang (from the OpenMP development branch at
http://clang-omp.github.io/ ), Intel compilers, GCC. See the documentation
for more details.
-----------------------------------------------------------------------
Notices
=======
*Other names and brands may be claimed as the property of others.

View File

@@ -0,0 +1,73 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# Checking a fortran compiler flag
# There is no real trivial way to do this in CMake, so we implement it here
# this will have ${boolean} = TRUE if the flag succeeds, otherwise false.
function(libomp_check_fortran_flag flag boolean)
if(NOT DEFINED "${boolean}")
set(retval TRUE)
set(fortran_source
" program hello
print *, \"Hello World!\"
end program hello")
set(failed_regexes "[Ee]rror;[Uu]nknown;[Ss]kipping")
if(CMAKE_VERSION VERSION_GREATER 3.1 OR CMAKE_VERSION VERSION_EQUAL 3.1)
include(CheckFortranSourceCompiles)
check_fortran_source_compiles("${fortran_source}" ${boolean} FAIL_REGEX "${failed_regexes}")
set(${boolean} ${${boolean}} PARENT_SCOPE)
return()
else()
# Our manual check for cmake versions that don't have CheckFortranSourceCompiles
set(base_dir ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/fortran_flag_check)
file(MAKE_DIRECTORY ${base_dir})
file(WRITE ${base_dir}/fortran_source.f "${fortran_source}")
message(STATUS "Performing Test ${boolean}")
execute_process(
COMMAND ${CMAKE_Fortran_COMPILER} "${flag}" ${base_dir}/fortran_source.f
WORKING_DIRECTORY ${base_dir}
RESULT_VARIABLE exit_code
OUTPUT_VARIABLE OUTPUT
ERROR_VARIABLE OUTPUT
)
if(${exit_code} EQUAL 0)
foreach(regex IN LISTS failed_regexes)
if("${OUTPUT}" MATCHES ${regex})
set(retval FALSE)
endif()
endforeach()
else()
set(retval FALSE)
endif()
if(${retval})
set(${boolean} 1 CACHE INTERNAL "Test ${boolean}")
message(STATUS "Performing Test ${boolean} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Fortran Compiler Flag test ${boolean} succeeded with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${fortran_source}\n")
else()
set(${boolean} "" CACHE INTERNAL "Test ${boolean}")
message(STATUS "Performing Test ${boolean} - Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Fortran Compiler Flag test ${boolean} failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${fortran_source}\n")
endif()
endif()
set(${boolean} ${retval} PARENT_SCOPE)
endif()
endfunction()

View File

@@ -0,0 +1,68 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# Checking a linker flag to build a shared library
# There is no real trivial way to do this in CMake, so we implement it here
# this will have ${boolean} = TRUE if the flag succeeds, otherwise FALSE.
function(libomp_check_linker_flag flag boolean)
if(NOT DEFINED "${boolean}")
set(retval TRUE)
set(library_source
"int foo(int a) { return a*a; }")
set(cmake_source
"cmake_minimum_required(VERSION 2.8)
project(foo C)
set(CMAKE_SHARED_LINKER_FLAGS \"${flag}\")
add_library(foo SHARED src_to_link.c)")
set(failed_regexes "[Ee]rror;[Uu]nknown;[Ss]kipping;LINK : warning")
set(base_dir ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/link_flag_check_${boolean})
file(MAKE_DIRECTORY ${base_dir})
file(MAKE_DIRECTORY ${base_dir}/build)
file(WRITE ${base_dir}/src_to_link.c "${library_source}")
file(WRITE ${base_dir}/CMakeLists.txt "${cmake_source}")
message(STATUS "Performing Test ${boolean}")
try_compile(
try_compile_result
${base_dir}/build
${base_dir}
foo
OUTPUT_VARIABLE OUTPUT)
if(try_compile_result)
foreach(regex IN LISTS failed_regexes)
if("${OUTPUT}" MATCHES ${regex})
set(retval FALSE)
endif()
endforeach()
else()
set(retval FALSE)
endif()
if(${retval})
set(${boolean} 1 CACHE INTERNAL "Test ${boolean}")
message(STATUS "Performing Test ${boolean} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C Linker Flag test ${boolean} succeeded with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${library_source}\n")
else()
set(${boolean} "" CACHE INTERNAL "Test ${boolean}")
message(STATUS "Performing Test ${boolean} - Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C Linker Flag test ${boolean} failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${library_source}\n")
endif()
set(${boolean} ${retval} PARENT_SCOPE)
endif()
endfunction()

View File

@@ -0,0 +1,32 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
function(libomp_get_definitions_flags cppflags)
set(cppflags_local)
if(WIN32)
libomp_append(cppflags_local "-D _CRT_SECURE_NO_WARNINGS")
libomp_append(cppflags_local "-D _CRT_SECURE_NO_DEPRECATE")
libomp_append(cppflags_local "-D _WINDOWS")
libomp_append(cppflags_local "-D _WINNT")
libomp_append(cppflags_local "-D _WIN32_WINNT=0x0501")
libomp_append(cppflags_local "-D _USRDLL")
libomp_append(cppflags_local "-D _ITERATOR_DEBUG_LEVEL=0" IF_TRUE DEBUG_BUILD)
libomp_append(cppflags_local "-D _DEBUG" IF_TRUE DEBUG_BUILD)
else()
libomp_append(cppflags_local "-D _GNU_SOURCE")
libomp_append(cppflags_local "-D _REENTRANT")
endif()
# CMake doesn't include CPPFLAGS from environment, but we will.
set(${cppflags} ${cppflags_local} ${LIBOMP_CPPFLAGS} $ENV{CPPFLAGS} PARENT_SCOPE)
endfunction()

View File

@@ -0,0 +1,99 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# LibompExports.cmake
# Copy library and header files into the exports/ subdirectory after library build
# Create the suffix for the export directory
# - Only add to suffix when not a default value
# - Example suffix: .deb.30.s1
# final export directory: exports/lin_32e.deb.30.s1/lib
# - These suffixes imply the build is a Debug, OpenMP 3.0, Stats-Gathering version of the library
set(libomp_suffix)
libomp_append(libomp_suffix .deb DEBUG_BUILD)
libomp_append(libomp_suffix .dia RELWITHDEBINFO_BUILD)
libomp_append(libomp_suffix .min MINSIZEREL_BUILD)
if(NOT "${LIBOMP_OMP_VERSION}" STREQUAL "45")
libomp_append(libomp_suffix .${LIBOMP_OMP_VERSION})
endif()
libomp_append(libomp_suffix .s1 LIBOMP_STATS)
libomp_append(libomp_suffix .ompt LIBOMP_OMPT_SUPPORT)
if(${LIBOMP_OMPT_SUPPORT})
libomp_append(libomp_suffix .optional LIBOMP_OMPT_OPTIONAL)
endif()
string(REPLACE ";" "" libomp_suffix "${libomp_suffix}")
# Set exports locations
if(${MIC})
set(libomp_platform "${LIBOMP_PERL_SCRIPT_OS}_${LIBOMP_MIC_ARCH}") # e.g., lin_knf, lin_knc
else()
if(${IA32})
set(libomp_platform "${LIBOMP_PERL_SCRIPT_OS}_32")
elseif(${INTEL64})
set(libomp_platform "${LIBOMP_PERL_SCRIPT_OS}_32e")
else()
set(libomp_platform "${LIBOMP_PERL_SCRIPT_OS}_${LIBOMP_ARCH}") # e.g., lin_arm, lin_ppc64
endif()
endif()
set(LIBOMP_EXPORTS_DIR "${LIBOMP_BASE_DIR}/exports")
set(LIBOMP_EXPORTS_PLATFORM_DIR "${LIBOMP_EXPORTS_DIR}/${libomp_platform}${libomp_suffix}")
set(LIBOMP_EXPORTS_CMN_DIR "${LIBOMP_EXPORTS_DIR}/common${libomp_suffix}/include")
set(LIBOMP_EXPORTS_INC_DIR "${LIBOMP_EXPORTS_PLATFORM_DIR}/include")
set(LIBOMP_EXPORTS_MOD_DIR "${LIBOMP_EXPORTS_PLATFORM_DIR}/include_compat")
set(LIBOMP_EXPORTS_LIB_DIR "${LIBOMP_EXPORTS_DIR}/${libomp_platform}${libomp_suffix}/lib")
# Put headers in exports/ directory post build
add_custom_command(TARGET omp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_CMN_DIR}
COMMAND ${CMAKE_COMMAND} -E copy omp.h ${LIBOMP_EXPORTS_CMN_DIR}
)
if(${LIBOMP_OMPT_SUPPORT})
add_custom_command(TARGET omp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ompt.h ${LIBOMP_EXPORTS_CMN_DIR}
)
endif()
if(${LIBOMP_FORTRAN_MODULES})
add_custom_command(TARGET libomp-mod POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_MOD_DIR}
COMMAND ${CMAKE_COMMAND} -E copy omp_lib.mod ${LIBOMP_EXPORTS_MOD_DIR}
COMMAND ${CMAKE_COMMAND} -E copy omp_lib_kinds.mod ${LIBOMP_EXPORTS_MOD_DIR}
)
add_custom_command(TARGET omp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy omp_lib.h ${LIBOMP_EXPORTS_CMN_DIR}
)
endif()
# Copy OpenMP library into exports/ directory post build
if(WIN32)
get_target_property(LIBOMP_OUTPUT_DIRECTORY omp RUNTIME_OUTPUT_DIRECTORY)
else()
get_target_property(LIBOMP_OUTPUT_DIRECTORY omp LIBRARY_OUTPUT_DIRECTORY)
endif()
if(NOT LIBOMP_OUTPUT_DIRECTORY)
set(LIBOMP_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
add_custom_command(TARGET omp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_LIB_DIR}
COMMAND ${CMAKE_COMMAND} -E copy ${LIBOMP_OUTPUT_DIRECTORY}/${LIBOMP_LIB_FILE} ${LIBOMP_EXPORTS_LIB_DIR}
)
# Copy Windows import library into exports/ directory post build
if(WIN32)
get_target_property(LIBOMPIMP_OUTPUT_DIRECTORY ompimp ARCHIVE_OUTPUT_DIRECTORY)
if(NOT LIBOMPIMP_OUTPUT_DIRECTORY)
set(LIBOMPIMP_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
add_custom_command(TARGET ompimp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_LIB_DIR}
COMMAND ${CMAKE_COMMAND} -E copy ${LIBOMPIMP_OUTPUT_DIRECTORY}/${LIBOMP_IMP_LIB_FILE} ${LIBOMP_EXPORTS_LIB_DIR}
)
endif()

View File

@@ -0,0 +1,70 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# Determine the architecture from predefined compiler macros
# The architecture name can only contain alphanumeric characters and underscores (i.e., C identifier)
# void get_architecture(string* return_arch)
# - Returns the architecture in return_arch
function(libomp_get_architecture return_arch)
set(detect_arch_src_txt "
#if defined(__KNC__)
#error ARCHITECTURE=mic
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
#error ARCHITECTURE=x86_64
#elif defined(__i386) || defined(__i386__) || defined(__IA32__) || defined(_M_I86) || defined(_M_IX86) || defined(__X86__) || defined(_X86_)
#error ARCHITECTURE=i386
#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
#error ARCHITECTURE=arm
#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6ZK__)
#error ARCHITECTURE=arm
#elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
#error ARCHITECTURE=arm
#elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
#error ARCHITECTURE=arm
#elif defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__)
#error ARCHITECTURE=arm
#elif defined(__ARM_ARCH_2__)
#error ARCHITECTURE=arm
#elif defined(__arm__) || defined(_M_ARM) || defined(_ARM)
#error ARCHITECTURE=arm
#elif defined(__aarch64__)
#error ARCHITECTURE=aarch64
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)
#error ARCHITECTURE=ppc64le
#elif defined(__powerpc64__)
#error ARCHITECTURE=ppc64
#elif defined(__mips__) && defined(__mips64)
#error ARCHITECTURE=mips64
#elif defined(__mips__) && !defined(__mips64)
#error ARCHITECTURE=mips
#else
#error ARCHITECTURE=UnknownArchitecture
#endif
")
# Write out ${detect_arch_src_txt} to a file within the cmake/ subdirectory
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libomp_detect_arch.c" ${detect_arch_src_txt})
# Try to compile using the C Compiler. It will always error out with an #error directive, so store error output to ${local_architecture}
try_run(run_dummy compile_dummy "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/libomp_detect_arch.c" COMPILE_OUTPUT_VARIABLE local_architecture)
# Match the important architecture line and store only that matching string in ${local_architecture}
string(REGEX MATCH "ARCHITECTURE=([a-zA-Z0-9_]+)" local_architecture "${local_architecture}")
# Get rid of the ARCHITECTURE= part of the string
string(REPLACE "ARCHITECTURE=" "" local_architecture "${local_architecture}")
# set the return value to the architecture detected (e.g., 32e, 32, arm, ppc64, etc.)
set(${return_arch} "${local_architecture}" PARENT_SCOPE)
# Remove ${detect_arch_src_txt} from cmake/ subdirectory
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/libomp_detect_arch.c")
endfunction()

View File

@@ -0,0 +1,207 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# Setup the flags correctly for cmake (covert to string)
# Pretty them up (STRIP any beginning and trailing whitespace,
# remove duplicates, remove empty entries)
macro(libomp_setup_flags flags)
if(NOT "${${flags}}" STREQUAL "") # if flags are empty, don't do anything
set(flags_local)
list(REMOVE_DUPLICATES ${flags}) # remove duplicates
list(REMOVE_ITEM ${flags} "") # remove empty items
libomp_list_to_string("${${flags}}" flags_local)
string(STRIP "${flags_local}" flags_local)
set(${flags} "${flags_local}")
endif()
endmacro()
# Gets flags common to both the C and C++ compiler
function(libomp_get_c_and_cxxflags_common flags)
set(flags_local)
libomp_append(flags_local -fno-exceptions LIBOMP_HAVE_FNO_EXCEPTIONS_FLAG)
libomp_append(flags_local -fno-rtti LIBOMP_HAVE_FNO_RTTI_FLAG)
libomp_append(flags_local -Wno-sign-compare LIBOMP_HAVE_WNO_SIGN_COMPARE_FLAG)
libomp_append(flags_local -Wno-unused-function LIBOMP_HAVE_WNO_UNUSED_FUNCTION_FLAG)
libomp_append(flags_local -Wno-unused-local-typedef LIBOMP_HAVE_WNO_UNUSED_LOCAL_TYPEDEF_FLAG)
libomp_append(flags_local -Wno-unused-value LIBOMP_HAVE_WNO_UNUSED_VALUE_FLAG)
libomp_append(flags_local -Wno-unused-variable LIBOMP_HAVE_WNO_UNUSED_VARIABLE_FLAG)
libomp_append(flags_local -Wno-switch LIBOMP_HAVE_WNO_SWITCH_FLAG)
libomp_append(flags_local -Wno-covered-switch-default LIBOMP_HAVE_WNO_COVERED_SWITCH_DEFAULT_FLAG)
libomp_append(flags_local -Wno-deprecated-register LIBOMP_HAVE_WNO_DEPRECATED_REGISTER_FLAG)
libomp_append(flags_local -Wno-gnu-anonymous-struct LIBOMP_HAVE_WNO_GNU_ANONYMOUS_STRUCT_FLAG)
libomp_append(flags_local -Wno-unknown-pragmas LIBOMP_HAVE_WNO_UNKNOWN_PRAGMAS_FLAG)
libomp_append(flags_local -Wno-missing-field-initializers LIBOMP_HAVE_WNO_MISSING_FIELD_INITIALIZERS_FLAG)
libomp_append(flags_local -Wno-missing-braces LIBOMP_HAVE_WNO_MISSING_BRACES_FLAG)
libomp_append(flags_local -Wno-comment LIBOMP_HAVE_WNO_COMMENT_FLAG)
libomp_append(flags_local -Wno-self-assign LIBOMP_HAVE_WNO_SELF_ASSIGN_FLAG)
libomp_append(flags_local -Wno-vla-extension LIBOMP_HAVE_WNO_VLA_EXTENSION_FLAG)
libomp_append(flags_local -Wno-format-pedantic LIBOMP_HAVE_WNO_FORMAT_PEDANTIC_FLAG)
libomp_append(flags_local /GS LIBOMP_HAVE_GS_FLAG)
libomp_append(flags_local /EHsc LIBOMP_HAVE_EHSC_FLAG)
libomp_append(flags_local /Oy- LIBOMP_HAVE_OY__FLAG)
# Intel(R) C Compiler flags
libomp_append(flags_local /Qsafeseh LIBOMP_HAVE_QSAFESEH_FLAG)
libomp_append(flags_local -Qoption,cpp,--extended_float_types LIBOMP_HAVE_EXTENDED_FLOAT_TYPES_FLAG)
libomp_append(flags_local -Qlong_double LIBOMP_HAVE_LONG_DOUBLE_FLAG)
libomp_append(flags_local -Qdiag-disable:177 LIBOMP_HAVE_DIAG_DISABLE_177_FLAG)
if(${RELEASE_BUILD} OR ${RELWITHDEBINFO_BUILD})
libomp_append(flags_local -Qinline-min-size=1 LIBOMP_HAVE_INLINE_MIN_SIZE_FLAG)
endif()
# Architectural C and C++ flags
if(${IA32})
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
libomp_append(flags_local -m32 LIBOMP_HAVE_M32_FLAG)
endif()
libomp_append(flags_local /arch:SSE2 LIBOMP_HAVE_ARCH_SSE2_FLAG)
libomp_append(flags_local -msse2 LIBOMP_HAVE_MSSE2_FLAG)
libomp_append(flags_local -falign-stack=maintain-16-byte LIBOMP_HAVE_FALIGN_STACK_FLAG)
elseif(${MIC})
libomp_append(flags_local -mmic LIBOMP_HAVE_MMIC_FLAG)
libomp_append(flags_local -ftls-model=initial-exec LIBOMP_HAVE_FTLS_MODEL_FLAG)
libomp_append(flags_local "-opt-streaming-stores never" LIBOMP_HAVE_OPT_STREAMING_STORES_FLAG)
endif()
set(${flags} ${flags_local} PARENT_SCOPE)
endfunction()
# C compiler flags
function(libomp_get_cflags cflags)
set(cflags_local)
libomp_get_c_and_cxxflags_common(cflags_local)
# flags only for the C Compiler
libomp_append(cflags_local /TP LIBOMP_HAVE_TP_FLAG)
libomp_append(cflags_local "-x c++" LIBOMP_HAVE_X_CPP_FLAG)
set(cflags_local ${cflags_local} ${LIBOMP_CFLAGS})
libomp_setup_flags(cflags_local)
set(${cflags} ${cflags_local} PARENT_SCOPE)
endfunction()
# C++ compiler flags
function(libomp_get_cxxflags cxxflags)
set(cxxflags_local)
libomp_get_c_and_cxxflags_common(cxxflags_local)
set(cxxflags_local ${cxxflags_local} ${LIBOMP_CXXFLAGS})
libomp_setup_flags(cxxflags_local)
set(${cxxflags} ${cxxflags_local} PARENT_SCOPE)
endfunction()
# Assembler flags
function(libomp_get_asmflags asmflags)
set(asmflags_local)
libomp_append(asmflags_local "-x assembler-with-cpp" LIBOMP_HAVE_X_ASSEMBLER_WITH_CPP_FLAG)
# Architectural assembler flags
if(${IA32})
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
libomp_append(asmflags_local -m32 LIBOMP_HAVE_M32_FLAG)
endif()
libomp_append(asmflags_local /safeseh LIBOMP_HAVE_SAFESEH_MASM_FLAG)
libomp_append(asmflags_local /coff LIBOMP_HAVE_COFF_MASM_FLAG)
elseif(${MIC})
libomp_append(asmflags_local -mmic LIBOMP_HAVE_MMIC_FLAG)
endif()
set(asmflags_local ${asmflags_local} ${LIBOMP_ASMFLAGS})
libomp_setup_flags(asmflags_local)
set(${asmflags} ${asmflags_local} PARENT_SCOPE)
endfunction()
# Linker flags
function(libomp_get_ldflags ldflags)
set(ldflags_local)
libomp_append(ldflags_local "${CMAKE_LINK_DEF_FILE_FLAG}${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_LIB_NAME}.def"
IF_DEFINED CMAKE_LINK_DEF_FILE_FLAG)
libomp_append(ldflags_local "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}${LIBOMP_VERSION_MAJOR}.${LIBOMP_VERSION_MINOR}"
IF_DEFINED CMAKE_C_OSX_CURRENT_VERSION_FLAG)
libomp_append(ldflags_local "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}${LIBOMP_VERSION_MAJOR}.${LIBOMP_VERSION_MINOR}"
IF_DEFINED CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG)
libomp_append(ldflags_local -Wl,--warn-shared-textrel LIBOMP_HAVE_WARN_SHARED_TEXTREL_FLAG)
libomp_append(ldflags_local -Wl,--as-needed LIBOMP_HAVE_AS_NEEDED_FLAG)
libomp_append(ldflags_local "-Wl,--version-script=${LIBOMP_SRC_DIR}/exports_so.txt" LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
libomp_append(ldflags_local -static-libgcc LIBOMP_HAVE_STATIC_LIBGCC_FLAG)
libomp_append(ldflags_local -Wl,-z,noexecstack LIBOMP_HAVE_Z_NOEXECSTACK_FLAG)
libomp_append(ldflags_local -Wl,-fini=__kmp_internal_end_fini LIBOMP_HAVE_FINI_FLAG)
libomp_append(ldflags_local -no-intel-extensions LIBOMP_HAVE_NO_INTEL_EXTENSIONS_FLAG)
libomp_append(ldflags_local -static-intel LIBOMP_HAVE_STATIC_INTEL_FLAG)
libomp_append(ldflags_local /SAFESEH LIBOMP_HAVE_SAFESEH_FLAG)
# Architectural linker flags
if(${IA32})
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
libomp_append(ldflags_local -m32 LIBOMP_HAVE_M32_FLAG)
endif()
libomp_append(ldflags_local -msse2 LIBOMP_HAVE_MSSE2_FLAG)
elseif(${MIC})
libomp_append(ldflags_local -mmic LIBOMP_HAVE_MMIC_FLAG)
libomp_append(ldflags_local -Wl,-x LIBOMP_HAVE_X_FLAG)
endif()
set(ldflags_local ${ldflags_local} ${LIBOMP_LDFLAGS})
libomp_setup_flags(ldflags_local)
set(${ldflags} ${ldflags_local} PARENT_SCOPE)
endfunction()
# Library flags
function(libomp_get_libflags libflags)
set(libflags_local)
libomp_append(libflags_local "${CMAKE_THREAD_LIBS_INIT}")
libomp_append(libflags_local "${LIBOMP_HWLOC_LIBRARY}" LIBOMP_USE_HWLOC)
if(${IA32})
libomp_append(libflags_local -lirc_pic LIBOMP_HAVE_IRC_PIC_LIBRARY)
endif()
IF(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
libomp_append(libflags_local -lm)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
set(libflags_local ${libflags_local} ${LIBOMP_LIBFLAGS})
libomp_setup_flags(libflags_local)
set(${libflags} ${libflags_local} PARENT_SCOPE)
endfunction()
# Fortran flags
function(libomp_get_fflags fflags)
set(fflags_local)
if(${IA32})
libomp_append(fflags_local -m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)
endif()
set(fflags_local ${fflags_local} ${LIBOMP_FFLAGS})
libomp_setup_flags(fflags_local)
set(${fflags} ${fflags_local} PARENT_SCOPE)
endfunction()
# Perl generate-defs.pl flags (For Windows only)
function(libomp_get_gdflags gdflags)
set(gdflags_local)
if(${IA32})
set(libomp_gdflag_arch arch_32)
elseif(${INTEL64})
set(libomp_gdflag_arch arch_32e)
else()
set(libomp_gdflag_arch arch_${LIBOMP_ARCH})
endif()
libomp_append(gdflags_local "-D ${libomp_gdflag_arch}")
libomp_append(gdflags_local "-D msvc_compat")
libomp_append(gdflags_local "-D norm" NORMAL_LIBRARY)
libomp_append(gdflags_local "-D prof" PROFILE_LIBRARY)
libomp_append(gdflags_local "-D stub" STUBS_LIBRARY)
libomp_append(gdflags_local "-D HAVE_QUAD" LIBOMP_USE_QUAD_PRECISION)
libomp_append(gdflags_local "-D USE_DEBUGGER" LIBOMP_USE_DEBUGGER)
if(${LIBOMP_OMP_VERSION} GREATER 50 OR ${LIBOMP_OMP_VERSION} EQUAL 50)
libomp_append(gdflags_local "-D OMP_50")
endif()
if(${LIBOMP_OMP_VERSION} GREATER 45 OR ${LIBOMP_OMP_VERSION} EQUAL 45)
libomp_append(gdflags_local "-D OMP_45")
endif()
if(${LIBOMP_OMP_VERSION} GREATER 40 OR ${LIBOMP_OMP_VERSION} EQUAL 40)
libomp_append(gdflags_local "-D OMP_40")
endif()
if(${LIBOMP_OMP_VERSION} GREATER 30 OR ${LIBOMP_OMP_VERSION} EQUAL 30)
libomp_append(gdflags_local "-D OMP_30")
endif()
if(${DEBUG_BUILD} OR ${RELWITHDEBINFO_BUILD})
libomp_append(gdflags_local "-D KMP_DEBUG")
endif()
set(${gdflags} ${gdflags_local} PARENT_SCOPE)
endfunction()

View File

@@ -0,0 +1,228 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# The following micro-tests are small tests to perform on the library just created.
# There are currently five micro-tests:
# (1) test-touch
# - Compile and run a small program using newly created libomp library
# - Fails if test-touch.c does not compile or if test-touch.c does not run after compilation
# - Program dependencies: gcc or g++, grep, bourne shell
# - Available for all Unix,Mac,Windows builds. Not available on Intel(R) MIC Architecture builds.
# (2) test-relo
# - Tests dynamic libraries for position-dependent code (can not have any position dependent code)
# - Fails if TEXTREL is in output of readelf -d libomp.so command
# - Program dependencies: readelf, grep, bourne shell
# - Available for Unix, Intel(R) MIC Architecture dynamic library builds. Not available otherwise.
# (3) test-execstack
# - Tests if stack is executable
# - Fails if stack is executable. Should only be readable and writable. Not exectuable.
# - Program dependencies: perl, readelf
# - Available for Unix dynamic library builds. Not available otherwise.
# (4) test-instr (Intel(R) MIC Architecutre only)
# - Tests Intel(R) MIC Architecture libraries for valid instruction set
# - Fails if finds invalid instruction for Intel(R) MIC Architecture (wasn't compiled with correct flags)
# - Program dependencies: perl, objdump
# - Available for Intel(R) MIC Architecture and i386 builds. Not available otherwise.
# (5) test-deps
# - Tests newly created libomp for library dependencies
# - Fails if sees a dependence not listed in td_exp variable below
# - Program dependencies: perl, (unix)readelf, (mac)otool[64], (windows)link.exe
# - Available for Unix,Mac,Windows, Intel(R) MIC Architecture dynamic builds and Windows
# static builds. Not available otherwise.
# get library location
if(WIN32)
get_target_property(LIBOMP_OUTPUT_DIRECTORY omp RUNTIME_OUTPUT_DIRECTORY)
get_target_property(LIBOMPIMP_OUTPUT_DIRECTORY ompimp ARCHIVE_OUTPUT_DIRECTORY)
if(NOT LIBOMPIMP_OUTPUT_DIRECTORY)
set(LIBOMPIMP_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
else()
get_target_property(LIBOMP_OUTPUT_DIRECTORY omp LIBRARY_OUTPUT_DIRECTORY)
endif()
if(NOT LIBOMP_OUTPUT_DIRECTORY)
set(LIBOMP_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
# test-touch
find_program(LIBOMP_SHELL sh)
if(WIN32)
if(LIBOMP_SHELL)
set(libomp_test_touch_targets test-touch-md/.success test-touch-mt/.success)
endif()
# pick test-touch compiler
set(libomp_test_touch_compiler ${CMAKE_C_COMPILER})
# test-touch compilation flags
libomp_append(libomp_test_touch_cflags /nologo)
libomp_append(libomp_test_touch_libs ${LIBOMPIMP_OUTPUT_DIRECTORY}/${LIBOMP_IMP_LIB_FILE})
if(${IA32})
libomp_append(libomp_test_touch_ldflags /safeseh)
endif()
else() # (Unix based systems, Intel(R) MIC Architecture, and Mac)
if(LIBOMP_SHELL)
set(libomp_test_touch_targets test-touch-rt/.success)
endif()
# pick test-touch compiler
if(${LIBOMP_USE_STDCPPLIB})
set(libomp_test_touch_compiler ${CMAKE_CXX_COMPILER})
else()
set(libomp_test_touch_compiler ${CMAKE_C_COMPILER})
endif()
# test-touch compilation flags
libomp_append(libomp_test_touch_libs "${CMAKE_THREAD_LIBS_INIT}")
if(${IA32})
libomp_append(libomp_test_touch_cflags -m32 LIBOMP_HAVE_M32_FLAG)
endif()
libomp_append(libomp_test_touch_libs ${LIBOMP_OUTPUT_DIRECTORY}/${LIBOMP_LIB_FILE})
libomp_append(libomp_test_touch_libs "${LIBOMP_HWLOC_LIBRARY}" LIBOMP_USE_HWLOC)
if(APPLE)
set(libomp_test_touch_env "DYLD_LIBRARY_PATH=.:${LIBOMP_OUTPUT_DIRECTORY}:$ENV{DYLD_LIBRARY_PATH}")
libomp_append(libomp_test_touch_ldflags "-Wl,-rpath,${LIBOMP_HWLOC_LIBRARY_DIR}" LIBOMP_USE_HWLOC)
else()
set(libomp_test_touch_env "LD_LIBRARY_PATH=.:${LIBOMP_OUTPUT_DIRECTORY}:$ENV{LD_LIBRARY_PATH}")
libomp_append(libomp_test_touch_ldflags "-Wl,-rpath=${LIBOMP_HWLOC_LIBRARY_DIR}" LIBOMP_USE_HWLOC)
endif()
endif()
macro(libomp_test_touch_recipe test_touch_dir)
set(libomp_test_touch_dependencies ${LIBOMP_SRC_DIR}/test-touch.c omp)
set(libomp_test_touch_exe ${test_touch_dir}/test-touch${CMAKE_EXECUTABLE_SUFFIX})
set(libomp_test_touch_obj ${test_touch_dir}/test-touch${CMAKE_C_OUTPUT_EXTENSION})
if(WIN32)
if(${RELEASE_BUILD} OR ${RELWITHDEBINFO_BUILD})
if(${test_touch_dir} MATCHES "test-touch-mt")
libomp_append(libomp_test_touch_cflags /MT)
else()
libomp_append(libomp_test_touch_cflags /MD)
endif()
else()
if(${test_touch_dir} MATCHES "test-touch-mt")
libomp_append(libomp_test_touch_cflags /MTd)
else()
libomp_append(libomp_test_touch_cflags /MDd)
endif()
endif()
set(libomp_test_touch_out_flags -Fe${libomp_test_touch_exe} -Fo${libomp_test_touch_obj})
list(APPEND libomp_test_touch_dependencies ompimp)
else()
set(libomp_test_touch_out_flags -o ${libomp_test_touch_exe})
endif()
add_custom_command(
OUTPUT ${test_touch_dir}/.success ${libomp_test_touch_exe} ${libomp_test_touch_obj}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${test_touch_dir}
COMMAND ${CMAKE_COMMAND} -E remove -f ${test_touch_dir}/*
COMMAND ${libomp_test_touch_compiler} ${libomp_test_touch_out_flags} ${libomp_test_touch_cflags}
${LIBOMP_SRC_DIR}/test-touch.c ${libomp_test_touch_ldflags} ${libomp_test_touch_libs}
COMMAND ${LIBOMP_SHELL} -c \"${libomp_test_touch_env} ${libomp_test_touch_exe}\"
COMMAND ${CMAKE_COMMAND} -E touch ${test_touch_dir}/.success
DEPENDS ${libomp_test_touch_dependencies}
)
endmacro()
libomp_append(libomp_test_touch_env "KMP_VERSION=1")
add_custom_target(libomp-test-touch DEPENDS ${libomp_test_touch_targets})
if(WIN32)
libomp_test_touch_recipe(test-touch-mt)
libomp_test_touch_recipe(test-touch-md)
else()
libomp_test_touch_recipe(test-touch-rt)
endif()
# test-relo
add_custom_target(libomp-test-relo DEPENDS test-relo/.success)
add_custom_command(
OUTPUT test-relo/.success test-relo/readelf.log
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/test-relo
COMMAND readelf -d ${LIBOMP_OUTPUT_DIRECTORY}/${LIBOMP_LIB_FILE} > test-relo/readelf.log
COMMAND grep -e TEXTREL test-relo/readelf.log \; test $$? -eq 1
COMMAND ${CMAKE_COMMAND} -E touch test-relo/.success
DEPENDS omp
)
# test-execstack
add_custom_target(libomp-test-execstack DEPENDS test-execstack/.success)
add_custom_command(
OUTPUT test-execstack/.success
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/test-execstack
COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/check-execstack.pl
--arch=${LIBOMP_PERL_SCRIPT_ARCH} ${LIBOMP_OUTPUT_DIRECTORY}/${LIBOMP_LIB_FILE}
COMMAND ${CMAKE_COMMAND} -E touch test-execstack/.success
DEPENDS omp
)
# test-instr
add_custom_target(libomp-test-instr DEPENDS test-instr/.success)
add_custom_command(
OUTPUT test-instr/.success
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/test-instr
COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/check-instruction-set.pl --os=${LIBOMP_PERL_SCRIPT_OS}
--arch=${LIBOMP_PERL_SCRIPT_ARCH} --show --mic-arch=${LIBOMP_MIC_ARCH} ${LIBOMP_OUTPUT_DIRECTORY}/${LIBOMP_LIB_FILE}
COMMAND ${CMAKE_COMMAND} -E touch test-instr/.success
DEPENDS omp ${LIBOMP_TOOLS_DIR}/check-instruction-set.pl
)
# test-deps
add_custom_target(libomp-test-deps DEPENDS test-deps/.success)
set(libomp_expected_library_deps)
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(libomp_expected_library_deps libc.so.7 libthr.so.3)
libomp_append(libomp_expected_library_deps libhwloc.so.5 LIBOMP_USE_HWLOC)
elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
set(libomp_expected_library_deps libc.so.12 libpthread.so.1 libm.so.0)
libomp_append(libomp_expected_library_deps libhwloc.so.5 LIBOMP_USE_HWLOC)
elseif(APPLE)
set(libomp_expected_library_deps /usr/lib/libSystem.B.dylib)
elseif(WIN32)
set(libomp_expected_library_deps kernel32.dll)
libomp_append(libomp_expected_library_deps psapi.dll LIBOMP_OMPT_SUPPORT)
else()
if(${MIC})
set(libomp_expected_library_deps libc.so.6 libpthread.so.0 libdl.so.2)
if("${LIBOMP_MIC_ARCH}" STREQUAL "knf")
libomp_append(libomp_expected_library_deps ld-linux-l1om.so.2)
libomp_append(libomp_expected_library_deps libgcc_s.so.1)
elseif("${LIBOMP_MIC_ARCH}" STREQUAL "knc")
libomp_append(libomp_expected_library_deps ld-linux-k1om.so.2)
endif()
else()
set(libomp_expected_library_deps libdl.so.2 libgcc_s.so.1)
if(${IA32})
libomp_append(libomp_expected_library_deps libc.so.6)
libomp_append(libomp_expected_library_deps ld-linux.so.2)
elseif(${INTEL64})
libomp_append(libomp_expected_library_deps libc.so.6)
libomp_append(libomp_expected_library_deps ld-linux-x86-64.so.2)
elseif(${ARM})
libomp_append(libomp_expected_library_deps libc.so.6)
libomp_append(libomp_expected_library_deps libffi.so.6)
libomp_append(libomp_expected_library_deps libffi.so.5)
libomp_append(libomp_expected_library_deps ld-linux-armhf.so.3)
elseif(${PPC64})
libomp_append(libomp_expected_library_deps libc.so.6)
libomp_append(libomp_expected_library_deps ld64.so.1)
elseif(${MIPS} OR ${MIPS64})
libomp_append(libomp_expected_library_deps libc.so.6)
libomp_append(libomp_expected_library_deps ld.so.1)
endif()
libomp_append(libomp_expected_library_deps libpthread.so.0 IF_FALSE STUBS_LIBRARY)
libomp_append(libomp_expected_library_deps libhwloc.so.5 LIBOMP_USE_HWLOC)
endif()
libomp_append(libomp_expected_library_deps libstdc++.so.6 LIBOMP_USE_STDCPPLIB)
libomp_append(libomp_expected_library_deps libm.so.6 LIBOMP_STATS)
endif()
# Perl script expects comma separated list
string(REPLACE ";" "," libomp_expected_library_deps "${libomp_expected_library_deps}")
add_custom_command(
OUTPUT test-deps/.success
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/test-deps
COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/check-depends.pl --os=${LIBOMP_PERL_SCRIPT_OS}
--arch=${LIBOMP_PERL_SCRIPT_ARCH} --expected="${libomp_expected_library_deps}" ${LIBOMP_OUTPUT_DIRECTORY}/${LIBOMP_LIB_FILE}
COMMAND ${CMAKE_COMMAND} -E touch test-deps/.success
DEPENDS omp ${LIBOMP_TOOLS_DIR}/check-depends.pl
)

View File

@@ -0,0 +1,195 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# void libomp_say(string message_to_user);
# - prints out message_to_user
macro(libomp_say message_to_user)
message(STATUS "LIBOMP: ${message_to_user}")
endmacro()
# void libomp_warning_say(string message_to_user);
# - prints out message_to_user with a warning
macro(libomp_warning_say message_to_user)
message(WARNING "LIBOMP: ${message_to_user}")
endmacro()
# void libomp_error_say(string message_to_user);
# - prints out message_to_user with an error and exits cmake
macro(libomp_error_say message_to_user)
message(FATAL_ERROR "LIBOMP: ${message_to_user}")
endmacro()
# libomp_append(<flag> <flags_list> [(IF_TRUE | IF_FALSE | IF_TRUE_1_0 ) BOOLEAN])
#
# libomp_append(<flag> <flags_list>)
# - unconditionally appends <flag> to the list of definitions
#
# libomp_append(<flag> <flags_list> <BOOLEAN>)
# - appends <flag> to the list of definitions if BOOLEAN is true
#
# libomp_append(<flag> <flags_list> IF_TRUE <BOOLEAN>)
# - appends <flag> to the list of definitions if BOOLEAN is true
#
# libomp_append(<flag> <flags_list> IF_FALSE <BOOLEAN>)
# - appends <flag> to the list of definitions if BOOLEAN is false
#
# libomp_append(<flag> <flags_list> IF_DEFINED <VARIABLE>)
# - appends <flag> to the list of definitions if VARIABLE is defined
#
# libomp_append(<flag> <flags_list> IF_TRUE_1_0 <BOOLEAN>)
# - appends <flag>=1 to the list of definitions if <BOOLEAN> is true, <flag>=0 otherwise
# e.g., libomp_append("-D USE_FEATURE" IF_TRUE_1_0 HAVE_FEATURE)
# appends "-D USE_FEATURE=1" if HAVE_FEATURE is true
# or "-D USE_FEATURE=0" if HAVE_FEATURE is false
macro(libomp_append flags flag)
if(NOT (${ARGC} EQUAL 2 OR ${ARGC} EQUAL 3 OR ${ARGC} EQUAL 4))
libomp_error_say("libomp_append: takes 2, 3, or 4 arguments")
endif()
if(${ARGC} EQUAL 2)
list(APPEND ${flags} "${flag}")
elseif(${ARGC} EQUAL 3)
if(${ARGV2})
list(APPEND ${flags} "${flag}")
endif()
else()
if(${ARGV2} STREQUAL "IF_TRUE")
if(${ARGV3})
list(APPEND ${flags} "${flag}")
endif()
elseif(${ARGV2} STREQUAL "IF_FALSE")
if(NOT ${ARGV3})
list(APPEND ${flags} "${flag}")
endif()
elseif(${ARGV2} STREQUAL "IF_DEFINED")
if(DEFINED ${ARGV3})
list(APPEND ${flags} "${flag}")
endif()
elseif(${ARGV2} STREQUAL "IF_TRUE_1_0")
if(${ARGV3})
list(APPEND ${flags} "${flag}=1")
else()
list(APPEND ${flags} "${flag}=0")
endif()
else()
libomp_error_say("libomp_append: third argument must be one of IF_TRUE, IF_FALSE, IF_DEFINED, IF_TRUE_1_0")
endif()
endif()
endmacro()
# void libomp_get_legal_arch(string* return_arch_string);
# - returns (through return_arch_string) the formal architecture
# string or warns user of unknown architecture
function(libomp_get_legal_arch return_arch_string)
if(${IA32})
set(${return_arch_string} "IA-32" PARENT_SCOPE)
elseif(${INTEL64})
set(${return_arch_string} "Intel(R) 64" PARENT_SCOPE)
elseif(${MIC})
set(${return_arch_string} "Intel(R) Many Integrated Core Architecture" PARENT_SCOPE)
elseif(${ARM})
set(${return_arch_string} "ARM" PARENT_SCOPE)
elseif(${PPC64BE})
set(${return_arch_string} "PPC64BE" PARENT_SCOPE)
elseif(${PPC64LE})
set(${return_arch_string} "PPC64LE" PARENT_SCOPE)
elseif(${AARCH64})
set(${return_arch_string} "AARCH64" PARENT_SCOPE)
elseif(${MIPS})
set(${return_arch_string} "MIPS" PARENT_SCOPE)
elseif(${MIPS64})
set(${return_arch_string} "MIPS64" PARENT_SCOPE)
else()
set(${return_arch_string} "${LIBOMP_ARCH}" PARENT_SCOPE)
libomp_warning_say("libomp_get_legal_arch(): Warning: Unknown architecture: Using ${LIBOMP_ARCH}")
endif()
endfunction()
# void libomp_check_variable(string var, ...);
# - runs through all values checking if ${var} == value
# - uppercase and lowercase do not matter
# - if the var is found, then just print it out
# - if the var is not found, then error out
function(libomp_check_variable var)
set(valid_flag 0)
string(TOLOWER "${${var}}" var_lower)
foreach(value IN LISTS ARGN)
string(TOLOWER "${value}" value_lower)
if("${var_lower}" STREQUAL "${value_lower}")
set(valid_flag 1)
set(the_value "${value}")
endif()
endforeach()
if(${valid_flag} EQUAL 0)
libomp_error_say("libomp_check_variable(): ${var} = ${${var}} is unknown")
endif()
endfunction()
# void libomp_get_build_number(string src_dir, string* return_build_number);
# - grab the eight digit build number (or 00000000) from kmp_version.cpp
function(libomp_get_build_number src_dir return_build_number)
# sets file_lines_list to a list of all lines in kmp_version.cpp
file(STRINGS "${src_dir}/src/kmp_version.cpp" file_lines_list)
# runs through each line in kmp_version.cpp
foreach(line IN LISTS file_lines_list)
# if the line begins with "#define KMP_VERSION_BUILD" then we take not of the build number
string(REGEX MATCH "^[ \t]*#define[ \t]+KMP_VERSION_BUILD" valid "${line}")
if(NOT "${valid}" STREQUAL "") # if we matched "#define KMP_VERSION_BUILD", then grab the build number
string(REGEX REPLACE "^[ \t]*#define[ \t]+KMP_VERSION_BUILD[ \t]+([0-9]+)" "\\1"
build_number "${line}"
)
endif()
endforeach()
set(${return_build_number} "${build_number}" PARENT_SCOPE) # return build number
endfunction()
# void libomp_get_legal_type(string* return_legal_type);
# - set the legal type name Performance/Profiling/Stub
function(libomp_get_legal_type return_legal_type)
if(${NORMAL_LIBRARY})
set(${return_legal_type} "Performance" PARENT_SCOPE)
elseif(${PROFILE_LIBRARY})
set(${return_legal_type} "Profiling" PARENT_SCOPE)
elseif(${STUBS_LIBRARY})
set(${return_legal_type} "Stub" PARENT_SCOPE)
endif()
endfunction()
# void libomp_add_suffix(string suffix, list<string>* list_of_items);
# - returns list_of_items with suffix appended to all items
# - original list is modified
function(libomp_add_suffix suffix list_of_items)
set(local_list "")
foreach(item IN LISTS "${list_of_items}")
if(NOT "${item}" STREQUAL "")
list(APPEND local_list "${item}${suffix}")
endif()
endforeach()
set(${list_of_items} "${local_list}" PARENT_SCOPE)
endfunction()
# void libomp_list_to_string(list<string> list_of_things, string* return_string);
# - converts a list to a space separated string
function(libomp_list_to_string list_of_things return_string)
string(REPLACE ";" " " output_variable "${list_of_things}")
set(${return_string} "${output_variable}" PARENT_SCOPE)
endfunction()
# void libomp_string_to_list(string str, list<string>* return_list);
# - converts a string to a semicolon separated list
# - what it really does is just string_replace all running whitespace to a semicolon
# - in cmake, a list is strings separated by semicolons: i.e., list of four items, list = "item1;item2;item3;item4"
function(libomp_string_to_list str return_list)
set(outstr)
string(REGEX REPLACE "[ \t]+" ";" outstr "${str}")
set(${return_list} "${outstr}" PARENT_SCOPE)
endfunction()

View File

@@ -0,0 +1,280 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
include(CheckCCompilerFlag)
include(CheckCSourceCompiles)
include(CheckCXXCompilerFlag)
include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckIncludeFiles)
include(LibompCheckLinkerFlag)
include(LibompCheckFortranFlag)
# Check for versioned symbols
function(libomp_check_version_symbols retval)
set(source_code
"#include <stdio.h>
void func1() { printf(\"Hello\"); }
void func2() { printf(\"World\"); }
__asm__(\".symver func1, func@VER1\");
__asm__(\".symver func2, func@VER2\");
int main() {
func1();
func2();
return 0;
}")
set(version_script_source "VER1 { }; VER2 { } VER1;")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt "${version_script_source}")
set(CMAKE_REQUIRED_FLAGS -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt)
check_c_source_compiles("${source_code}" ${retval})
set(${retval} ${${retval}} PARENT_SCOPE)
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt)
endfunction()
# Includes the architecture flag in both compile and link phase
function(libomp_check_architecture_flag flag retval)
set(CMAKE_REQUIRED_FLAGS "${flag}")
check_c_compiler_flag("${flag}" ${retval})
set(${retval} ${${retval}} PARENT_SCOPE)
endfunction()
# Checking C, CXX, Linker Flags
check_cxx_compiler_flag(-fno-exceptions LIBOMP_HAVE_FNO_EXCEPTIONS_FLAG)
check_cxx_compiler_flag(-fno-rtti LIBOMP_HAVE_FNO_RTTI_FLAG)
check_c_compiler_flag("-x c++" LIBOMP_HAVE_X_CPP_FLAG)
check_c_compiler_flag(-Wunused-function LIBOMP_HAVE_WNO_UNUSED_FUNCTION_FLAG)
check_c_compiler_flag(-Wunused-local-typedef LIBOMP_HAVE_WNO_UNUSED_LOCAL_TYPEDEF_FLAG)
check_c_compiler_flag(-Wunused-value LIBOMP_HAVE_WNO_UNUSED_VALUE_FLAG)
check_c_compiler_flag(-Wunused-variable LIBOMP_HAVE_WNO_UNUSED_VARIABLE_FLAG)
check_c_compiler_flag(-Wswitch LIBOMP_HAVE_WNO_SWITCH_FLAG)
check_c_compiler_flag(-Wcovered-switch-default LIBOMP_HAVE_WNO_COVERED_SWITCH_DEFAULT_FLAG)
check_c_compiler_flag(-Wdeprecated-register LIBOMP_HAVE_WNO_DEPRECATED_REGISTER_FLAG)
check_c_compiler_flag(-Wsign-compare LIBOMP_HAVE_WNO_SIGN_COMPARE_FLAG)
check_c_compiler_flag(-Wgnu-anonymous-struct LIBOMP_HAVE_WNO_GNU_ANONYMOUS_STRUCT_FLAG)
check_c_compiler_flag(-Wunknown-pragmas LIBOMP_HAVE_WNO_UNKNOWN_PRAGMAS_FLAG)
check_c_compiler_flag(-Wmissing-field-initializers LIBOMP_HAVE_WNO_MISSING_FIELD_INITIALIZERS_FLAG)
check_c_compiler_flag(-Wmissing-braces LIBOMP_HAVE_WNO_MISSING_BRACES_FLAG)
check_c_compiler_flag(-Wcomment LIBOMP_HAVE_WNO_COMMENT_FLAG)
check_c_compiler_flag(-Wself-assign LIBOMP_HAVE_WNO_SELF_ASSIGN_FLAG)
check_c_compiler_flag(-Wvla-extension LIBOMP_HAVE_WNO_VLA_EXTENSION_FLAG)
check_c_compiler_flag(-Wformat-pedantic LIBOMP_HAVE_WNO_FORMAT_PEDANTIC_FLAG)
check_c_compiler_flag(-msse2 LIBOMP_HAVE_MSSE2_FLAG)
check_c_compiler_flag(-ftls-model=initial-exec LIBOMP_HAVE_FTLS_MODEL_FLAG)
libomp_check_architecture_flag(-mmic LIBOMP_HAVE_MMIC_FLAG)
libomp_check_architecture_flag(-m32 LIBOMP_HAVE_M32_FLAG)
if(WIN32)
# Check Windows MSVC style flags.
check_c_compiler_flag(/TP LIBOMP_HAVE_TP_FLAG)
check_cxx_compiler_flag(/EHsc LIBOMP_HAVE_EHSC_FLAG)
check_cxx_compiler_flag(/GS LIBOMP_HAVE_GS_FLAG)
check_cxx_compiler_flag(/Oy- LIBOMP_HAVE_Oy__FLAG)
check_cxx_compiler_flag(/arch:SSE2 LIBOMP_HAVE_ARCH_SSE2_FLAG)
check_cxx_compiler_flag(/Qsafeseh LIBOMP_HAVE_QSAFESEH_FLAG)
# It is difficult to create a dummy masm assembly file
# and then check the MASM assembler to see if these flags exist and work,
# so we assume they do for Windows.
set(LIBOMP_HAVE_SAFESEH_MASM_FLAG TRUE)
set(LIBOMP_HAVE_COFF_MASM_FLAG TRUE)
# Change Windows flags /MDx to /MTx
foreach(libomp_lang IN ITEMS C CXX)
foreach(libomp_btype IN ITEMS DEBUG RELWITHDEBINFO RELEASE MINSIZEREL)
string(REPLACE "/MD" "/MT"
CMAKE_${libomp_lang}_FLAGS_${libomp_btype}
"${CMAKE_${libomp_lang}_FLAGS_${libomp_btype}}"
)
endforeach()
endforeach()
else()
# It is difficult to create a dummy assembly file that compiles into an
# exectuable for every architecture and then check the C compiler to
# see if -x assembler-with-cpp exists and works, so we assume it does for non-Windows.
set(LIBOMP_HAVE_X_ASSEMBLER_WITH_CPP_FLAG TRUE)
endif()
if(${LIBOMP_FORTRAN_MODULES})
libomp_check_fortran_flag(-m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)
endif()
# Check linker flags
if(WIN32)
libomp_check_linker_flag(/SAFESEH LIBOMP_HAVE_SAFESEH_FLAG)
elseif(NOT APPLE)
libomp_check_linker_flag(-Wl,-x LIBOMP_HAVE_X_FLAG)
libomp_check_linker_flag(-Wl,--warn-shared-textrel LIBOMP_HAVE_WARN_SHARED_TEXTREL_FLAG)
libomp_check_linker_flag(-Wl,--as-needed LIBOMP_HAVE_AS_NEEDED_FLAG)
libomp_check_linker_flag("-Wl,--version-script=${LIBOMP_SRC_DIR}/exports_so.txt" LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
libomp_check_linker_flag(-static-libgcc LIBOMP_HAVE_STATIC_LIBGCC_FLAG)
libomp_check_linker_flag(-Wl,-z,noexecstack LIBOMP_HAVE_Z_NOEXECSTACK_FLAG)
libomp_check_linker_flag(-Wl,-fini=__kmp_internal_end_fini LIBOMP_HAVE_FINI_FLAG)
endif()
# Check Intel(R) C Compiler specific flags
if(CMAKE_C_COMPILER_ID STREQUAL "Intel")
check_cxx_compiler_flag(/Qlong_double LIBOMP_HAVE_LONG_DOUBLE_FLAG)
check_cxx_compiler_flag(/Qdiag-disable:177 LIBOMP_HAVE_DIAG_DISABLE_177_FLAG)
check_cxx_compiler_flag(/Qinline-min-size=1 LIBOMP_HAVE_INLINE_MIN_SIZE_FLAG)
check_cxx_compiler_flag(-Qoption,cpp,--extended_float_types LIBOMP_HAVE_EXTENDED_FLOAT_TYPES_FLAG)
check_cxx_compiler_flag(-falign-stack=maintain-16-byte LIBOMP_HAVE_FALIGN_STACK_FLAG)
check_cxx_compiler_flag("-opt-streaming-stores never" LIBOMP_HAVE_OPT_STREAMING_STORES_FLAG)
libomp_check_linker_flag(-static-intel LIBOMP_HAVE_STATIC_INTEL_FLAG)
libomp_check_linker_flag(-no-intel-extensions LIBOMP_HAVE_NO_INTEL_EXTENSIONS_FLAG)
check_library_exists(irc_pic _intel_fast_memcpy "" LIBOMP_HAVE_IRC_PIC_LIBRARY)
endif()
# Checking Threading requirements
find_package(Threads REQUIRED)
if(WIN32)
if(NOT CMAKE_USE_WIN32_THREADS_INIT)
libomp_error_say("Need Win32 thread interface on Windows.")
endif()
else()
if(NOT CMAKE_USE_PTHREADS_INIT)
libomp_error_say("Need pthread interface on Unix-like systems.")
endif()
endif()
# Find perl executable
# Perl is used to create omp.h (and other headers) along with kmp_i18n_id.inc and kmp_i18n_default.inc
find_package(Perl REQUIRED)
# The perl scripts take the --os=/--arch= flags which expect a certain format for operating systems and arch's.
# Until the perl scripts are removed, the most portable way to handle this is to have all operating systems that
# are neither Windows nor Mac (Most Unix flavors) be considered lin to the perl scripts. This is rooted
# in that all the Perl scripts check the operating system and will fail if it isn't "valid". This
# temporary solution lets us avoid trying to enumerate all the possible OS values inside the Perl modules.
if(WIN32)
set(LIBOMP_PERL_SCRIPT_OS win)
elseif(APPLE)
set(LIBOMP_PERL_SCRIPT_OS mac)
else()
set(LIBOMP_PERL_SCRIPT_OS lin)
endif()
if(IA32)
set(LIBOMP_PERL_SCRIPT_ARCH 32)
elseif(MIC)
set(LIBOMP_PERL_SCRIPT_ARCH mic)
elseif(INTEL64)
set(LIBOMP_PERL_SCRIPT_ARCH 32e)
else()
set(LIBOMP_PERL_SCRIPT_ARCH ${LIBOMP_ARCH})
endif()
# Checking features
# Check if version symbol assembler directives are supported
libomp_check_version_symbols(LIBOMP_HAVE_VERSION_SYMBOLS)
# Check if quad precision types are available
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(LIBOMP_HAVE_QUAD_PRECISION TRUE)
elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel")
if(LIBOMP_HAVE_EXTENDED_FLOAT_TYPES_FLAG)
set(LIBOMP_HAVE_QUAD_PRECISION TRUE)
else()
set(LIBOMP_HAVE_QUAD_PRECISION TRUE)
endif()
else()
set(LIBOMP_HAVE_QUAD_PRECISION FALSE)
endif()
# Check if adaptive locks are available
if((${IA32} OR ${INTEL64}) AND NOT MSVC)
set(LIBOMP_HAVE_ADAPTIVE_LOCKS TRUE)
else()
set(LIBOMP_HAVE_ADAPTIVE_LOCKS FALSE)
endif()
# Check if stats-gathering is available
if(${LIBOMP_STATS})
check_c_source_compiles(
"__thread int x;
int main(int argc, char** argv)
{ x = argc; return x; }"
LIBOMP_HAVE___THREAD)
check_c_source_compiles(
"int main(int argc, char** argv)
{ unsigned long long t = __builtin_readcyclecounter(); return 0; }"
LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)
if(NOT LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)
if(${IA32} OR ${INTEL64} OR ${MIC})
check_include_file(x86intrin.h LIBOMP_HAVE_X86INTRIN_H)
libomp_append(CMAKE_REQUIRED_DEFINITIONS -DLIBOMP_HAVE_X86INTRIN_H LIBOMP_HAVE_X86INTRIN_H)
check_c_source_compiles(
"#ifdef LIBOMP_HAVE_X86INTRIN_H
# include <x86intrin.h>
#endif
int main(int argc, char** argv) { unsigned long long t = __rdtsc(); return 0; }" LIBOMP_HAVE___RDTSC)
set(CMAKE_REQUIRED_DEFINITIONS)
endif()
endif()
if(LIBOMP_HAVE___THREAD AND (LIBOMP_HAVE___RDTSC OR LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER))
set(LIBOMP_HAVE_STATS TRUE)
else()
set(LIBOMP_HAVE_STATS FALSE)
endif()
endif()
# Check if OMPT support is available
# Currently, __builtin_frame_address() is required for OMPT
# Weak attribute is required for Unices (except Darwin), LIBPSAPI is used for Windows
check_c_source_compiles("int main(int argc, char** argv) {
void* p = __builtin_frame_address(0);
return 0;}" LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
check_c_source_compiles("__attribute__ ((weak)) int foo(int a) { return a*a; }
int main(int argc, char** argv) {
return foo(argc);}" LIBOMP_HAVE_WEAK_ATTRIBUTE)
check_include_files("windows.h;psapi.h" LIBOMP_HAVE_PSAPI_H)
check_library_exists(psapi EnumProcessModules "" LIBOMP_HAVE_LIBPSAPI)
if(LIBOMP_HAVE_PSAPI_H AND LIBOMP_HAVE_LIBPSAPI)
set(LIBOMP_HAVE_PSAPI TRUE)
endif()
if(NOT LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
else()
if( # hardware architecture supported?
((LIBOMP_ARCH STREQUAL x86_64) OR
(LIBOMP_ARCH STREQUAL i386) OR
# (LIBOMP_ARCH STREQUAL arm) OR
(LIBOMP_ARCH STREQUAL aarch64) OR
(LIBOMP_ARCH STREQUAL ppc64le) OR
(LIBOMP_ARCH STREQUAL ppc64))
AND # OS supported?
((WIN32 AND LIBOMP_HAVE_PSAPI) OR APPLE OR (NOT WIN32 AND LIBOMP_HAVE_WEAK_ATTRIBUTE)))
set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
else()
set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
endif()
endif()
# Check if HWLOC support is available
if(${LIBOMP_USE_HWLOC})
set(CMAKE_REQUIRED_INCLUDES ${LIBOMP_HWLOC_INSTALL_DIR}/include)
check_include_file(hwloc.h LIBOMP_HAVE_HWLOC_H)
set(CMAKE_REQUIRED_INCLUDES)
find_library(LIBOMP_HWLOC_LIBRARY
NAMES hwloc libhwloc
HINTS ${LIBOMP_HWLOC_INSTALL_DIR}/lib)
if(LIBOMP_HWLOC_LIBRARY)
check_library_exists(${LIBOMP_HWLOC_LIBRARY} hwloc_topology_init
${LIBOMP_HWLOC_INSTALL_DIR}/lib LIBOMP_HAVE_LIBHWLOC)
get_filename_component(LIBOMP_HWLOC_LIBRARY_DIR ${LIBOMP_HWLOC_LIBRARY} PATH)
endif()
if(LIBOMP_HAVE_HWLOC_H AND LIBOMP_HAVE_LIBHWLOC AND LIBOMP_HWLOC_LIBRARY)
set(LIBOMP_HAVE_HWLOC TRUE)
else()
set(LIBOMP_HAVE_HWLOC FALSE)
libomp_say("Could not find hwloc")
endif()
endif()
# Check if ThreadSanitizer support is available
if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux" AND ${INTEL64})
set(LIBOMP_HAVE_TSAN_SUPPORT TRUE)
else()
set(LIBOMP_HAVE_TSAN_SUPPORT FALSE)
endif()

View File

@@ -0,0 +1 @@
e97c40ce16b3c8f8dabf35150de8c61daefabd30

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
% Latex header for doxygen 1.8.3.1
\documentclass{book}
\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry}
\usepackage{makeidx}
\usepackage{natbib}
\usepackage{graphicx}
\usepackage{multicol}
\usepackage{float}
\usepackage{listings}
\usepackage{color}
\usepackage{ifthen}
\usepackage[table]{xcolor}
\usepackage{textcomp}
\usepackage{alltt}
\usepackage{ifpdf}
\ifpdf
\usepackage[pdftex,
pagebackref=true,
colorlinks=true,
linkcolor=blue,
unicode
]{hyperref}
\else
\usepackage[ps2pdf,
pagebackref=true,
colorlinks=true,
linkcolor=blue,
unicode
]{hyperref}
\usepackage{pspicture}
\fi
\usepackage[utf8]{inputenc}
\usepackage{mathptmx}
\usepackage[scaled=.90]{helvet}
\usepackage{courier}
\usepackage{sectsty}
\usepackage{amssymb}
\usepackage[titles]{tocloft}
\usepackage{doxygen}
\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left }
\makeindex
\setcounter{tocdepth}{3}
\renewcommand{\footrulewidth}{0.4pt}
\renewcommand{\familydefault}{\sfdefault}
\hfuzz=15pt
\setlength{\emergencystretch}{15pt}
\hbadness=750
\tolerance=750
\begin{document}
\hypersetup{pageanchor=false,citecolor=blue}
\begin{titlepage}
\vspace*{7cm}
\begin{center}
{\Large LLVM OpenMP\textsuperscript{*} Runtime Library }\\
\vspace*{1cm}
{\large Generated by Doxygen $doxygenversion }\\
\vspace*{0.5cm}
{\small $datetime }\\
\end{center}
\end{titlepage}
{\bf Trademarks}
The OpenMP name and the OpenMP logo are registered trademarks of the OpenMP Architecture Review Board.
Intel, Xeon, and Intel Xeon Phi are trademarks of Intel Corporation in the U.S. and/or other countries.
This document is Copyright \textcopyright~\the\year the LLVM Project. It is
subject to the same license terms as the LLVM OpenMP runtime.
\textsuperscript{*} Other names and brands may be claimed as the property of others.
\clearemptydoublepage
\pagenumbering{roman}
\tableofcontents
\clearemptydoublepage
\pagenumbering{arabic}
\hypersetup{pageanchor=true,citecolor=blue}

View File

@@ -0,0 +1,332 @@
// This file does not contain any code; it just contains additional text and formatting
// for doxygen.
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
/*! @mainpage LLVM&nbsp; OpenMP* Runtime Library Interface
@section sec_intro Introduction
This document describes the interface provided by the
LLVM &nbsp;OpenMP\other runtime library to the compiler.
Routines that are directly called as simple functions by user code are
not currently described here, since their definition is in the OpenMP
specification available from http://openmp.org
The aim here is to explain the interface from the compiler to the runtime.
The overall design is described, and each function in the interface
has its own description. (At least, that's the ambition, we may not be there yet).
@section sec_building Quickly Building the Runtime
For the impatient, we cover building the runtime as the first topic here.
CMake is used to build the OpenMP runtime. For details and a full list of options for the CMake build system,
see <tt>README.rst</tt> in the source code repository. These instructions will provide the most typical build.
In-LLVM-tree build:.
@code
$ cd where-you-want-to-live
Check out openmp into llvm/projects
$ cd where-you-want-to-build
$ mkdir build && cd build
$ cmake path/to/llvm -DCMAKE_C_COMPILER=<C compiler> -DCMAKE_CXX_COMPILER=<C++ compiler>
$ make omp
@endcode
Out-of-LLVM-tree build:
@code
$ cd where-you-want-to-live
Check out openmp
$ cd where-you-want-to-live/openmp
$ mkdir build && cd build
$ cmake path/to/openmp -DCMAKE_C_COMPILER=<C compiler> -DCMAKE_CXX_COMPILER=<C++ compiler>
$ make
@endcode
@section sec_supported Supported RTL Build Configurations
The architectures supported are IA-32 architecture, Intel&reg;&nbsp; 64, and
Intel&reg;&nbsp; Many Integrated Core Architecture. The build configurations
supported are shown in the table below.
<table border=1>
<tr><th> <th>icc/icl<th>gcc<th>clang
<tr><td>Linux\other OS<td>Yes(1,5)<td>Yes(2,4)<td>Yes(4,6,7)
<tr><td>FreeBSD\other<td>Yes(1,5)<td>Yes(2,4)<td>Yes(4,6,7,8)
<tr><td>OS X\other<td>Yes(1,3,4)<td>No<td>Yes(4,6,7)
<tr><td>Windows\other OS<td>Yes(1,4)<td>No<td>No
</table>
(1) On IA-32 architecture and Intel&reg;&nbsp; 64, icc/icl versions 12.x
are supported (12.1 is recommended).<br>
(2) gcc version 4.7 is supported.<br>
(3) For icc on OS X\other, OS X\other version 10.5.8 is supported.<br>
(4) Intel&reg;&nbsp; Many Integrated Core Architecture not supported.<br>
(5) On Intel&reg;&nbsp; Many Integrated Core Architecture, icc/icl versions 13.0 or later are required.<br>
(6) Clang\other version 3.3 is supported.<br>
(7) Clang\other currently does not offer a software-implemented 128 bit extended
precision type. Thus, all entry points reliant on this type are removed
from the library and cannot be called in the user program. The following
functions are not available:
@code
__kmpc_atomic_cmplx16_*
__kmpc_atomic_float16_*
__kmpc_atomic_*_fp
@endcode
(8) Community contribution provided AS IS, not tested by Intel.
Supported Architectures: IBM(R) Power 7 and Power 8
<table border=1>
<tr><th> <th>gcc<th>clang
<tr><td>Linux\other OS<td>Yes(1,2)<td>Yes(3,4)
</table>
(1) On Power 7, gcc version 4.8.2 is supported.<br>
(2) On Power 8, gcc version 4.8.2 is supported.<br>
(3) On Power 7, clang version 3.7 is supported.<br>
(4) On Power 8, clang version 3.7 is supported.<br>
@section sec_frontend Front-end Compilers that work with this RTL
The following compilers are known to do compatible code generation for
this RTL: icc/icl, gcc. Code generation is discussed in more detail
later in this document.
@section sec_outlining Outlining
The runtime interface is based on the idea that the compiler
"outlines" sections of code that are to run in parallel into separate
functions that can then be invoked in multiple threads. For instance,
simple code like this
@code
void foo()
{
#pragma omp parallel
{
... do something ...
}
}
@endcode
is converted into something that looks conceptually like this (where
the names used are merely illustrative; the real library function
names will be used later after we've discussed some more issues...)
@code
static void outlinedFooBody()
{
... do something ...
}
void foo()
{
__OMP_runtime_fork(outlinedFooBody, (void*)0); // Not the real function name!
}
@endcode
@subsection SEC_SHAREDVARS Addressing shared variables
In real uses of the OpenMP\other API there are normally references
from the outlined code to shared variables that are in scope in the containing function.
Therefore the containing function must be able to address
these variables. The runtime supports two alternate ways of doing
this.
@subsubsection SEC_SEC_OT Current Technique
The technique currently supported by the runtime library is to receive
a separate pointer to each shared variable that can be accessed from
the outlined function. This is what is shown in the example below.
We hope soon to provide an alternative interface to support the
alternate implementation described in the next section. The
alternative implementation has performance advantages for small
parallel regions that have many shared variables.
@subsubsection SEC_SEC_PT Future Technique
The idea is to treat the outlined function as though it
were a lexically nested function, and pass it a single argument which
is the pointer to the parent's stack frame. Provided that the compiler
knows the layout of the parent frame when it is generating the outlined
function it can then access the up-level variables at appropriate
offsets from the parent frame. This is a classical compiler technique
from the 1960s to support languages like Algol (and its descendants)
that support lexically nested functions.
The main benefit of this technique is that there is no code required
at the fork point to marshal the arguments to the outlined function.
Since the runtime knows statically how many arguments must be passed to the
outlined function, it can easily copy them to the thread's stack
frame. Therefore the performance of the fork code is independent of
the number of shared variables that are accessed by the outlined
function.
If it is hard to determine the stack layout of the parent while generating the
outlined code, it is still possible to use this approach by collecting all of
the variables in the parent that are accessed from outlined functions into
a single `struct` which is placed on the stack, and whose address is passed
to the outlined functions. In this way the offsets of the shared variables
are known (since they are inside the struct) without needing to know
the complete layout of the parent stack-frame. From the point of view
of the runtime either of these techniques is equivalent, since in either
case it only has to pass a single argument to the outlined function to allow
it to access shared variables.
A scheme like this is how gcc\other generates outlined functions.
@section SEC_INTERFACES Library Interfaces
The library functions used for specific parts of the OpenMP\other language implementation
are documented in different modules.
- @ref BASIC_TYPES fundamental types used by the runtime in many places
- @ref DEPRECATED functions that are in the library but are no longer required
- @ref STARTUP_SHUTDOWN functions for initializing and finalizing the runtime
- @ref PARALLEL functions for implementing `omp parallel`
- @ref THREAD_STATES functions for supporting thread state inquiries
- @ref WORK_SHARING functions for work sharing constructs such as `omp for`, `omp sections`
- @ref THREADPRIVATE functions to support thread private data, copyin etc
- @ref SYNCHRONIZATION functions to support `omp critical`, `omp barrier`, `omp master`, reductions etc
- @ref ATOMIC_OPS functions to support atomic operations
- @ref STATS_GATHERING macros to support developer profiling of libomp
- Documentation on tasking has still to be written...
@section SEC_EXAMPLES Examples
@subsection SEC_WORKSHARING_EXAMPLE Work Sharing Example
This example shows the code generated for a parallel for with reduction and dynamic scheduling.
@code
extern float foo( void );
int main () {
int i;
float r = 0.0;
#pragma omp parallel for schedule(dynamic) reduction(+:r)
for ( i = 0; i < 10; i ++ ) {
r += foo();
}
}
@endcode
The transformed code looks like this.
@code
extern float foo( void );
int main () {
static int zero = 0;
auto int gtid;
auto float r = 0.0;
__kmpc_begin( & loc3, 0 );
// The gtid is not actually required in this example so could be omitted;
// We show its initialization here because it is often required for calls into
// the runtime and should be locally cached like this.
gtid = __kmpc_global thread num( & loc3 );
__kmpc_fork call( & loc7, 1, main_7_parallel_3, & r );
__kmpc_end( & loc0 );
return 0;
}
struct main_10_reduction_t_5 { float r_10_rpr; };
static kmp_critical_name lck = { 0 };
static ident_t loc10; // loc10.flags should contain KMP_IDENT_ATOMIC_REDUCE bit set
// if compiler has generated an atomic reduction.
void main_7_parallel_3( int *gtid, int *btid, float *r_7_shp ) {
auto int i_7_pr;
auto int lower, upper, liter, incr;
auto struct main_10_reduction_t_5 reduce;
reduce.r_10_rpr = 0.F;
liter = 0;
__kmpc_dispatch_init_4( & loc7,*gtid, 35, 0, 9, 1, 1 );
while ( __kmpc_dispatch_next_4( & loc7, *gtid, & liter, & lower, & upper, & incr ) ) {
for( i_7_pr = lower; upper >= i_7_pr; i_7_pr ++ )
reduce.r_10_rpr += foo();
}
switch( __kmpc_reduce_nowait( & loc10, *gtid, 1, 4, & reduce, main_10_reduce_5, & lck ) ) {
case 1:
*r_7_shp += reduce.r_10_rpr;
__kmpc_end_reduce_nowait( & loc10, *gtid, & lck );
break;
case 2:
__kmpc_atomic_float4_add( & loc10, *gtid, r_7_shp, reduce.r_10_rpr );
break;
default:;
}
}
void main_10_reduce_5( struct main_10_reduction_t_5 *reduce_lhs,
struct main_10_reduction_t_5 *reduce_rhs )
{
reduce_lhs->r_10_rpr += reduce_rhs->r_10_rpr;
}
@endcode
@defgroup BASIC_TYPES Basic Types
Types that are used throughout the runtime.
@defgroup DEPRECATED Deprecated Functions
Functions in this group are for backwards compatibility only, and
should not be used in new code.
@defgroup STARTUP_SHUTDOWN Startup and Shutdown
These functions are for library initialization and shutdown.
@defgroup PARALLEL Parallel (fork/join)
These functions are used for implementing <tt>\#pragma omp parallel</tt>.
@defgroup THREAD_STATES Thread Information
These functions return information about the currently executing thread.
@defgroup WORK_SHARING Work Sharing
These functions are used for implementing
<tt>\#pragma omp for</tt>, <tt>\#pragma omp sections</tt>, <tt>\#pragma omp single</tt> and
<tt>\#pragma omp master</tt> constructs.
When handling loops, there are different functions for each of the signed and unsigned 32 and 64 bit integer types
which have the name suffixes `_4`, `_4u`, `_8` and `_8u`. The semantics of each of the functions is the same,
so they are only described once.
Static loop scheduling is handled by @ref __kmpc_for_static_init_4 and friends. Only a single call is needed,
since the iterations to be executed by any give thread can be determined as soon as the loop parameters are known.
Dynamic scheduling is handled by the @ref __kmpc_dispatch_init_4 and @ref __kmpc_dispatch_next_4 functions.
The init function is called once in each thread outside the loop, while the next function is called each
time that the previous chunk of work has been exhausted.
@defgroup SYNCHRONIZATION Synchronization
These functions are used for implementing barriers.
@defgroup THREADPRIVATE Thread private data support
These functions support copyin/out and thread private data.
@defgroup STATS_GATHERING Statistics Gathering from OMPTB
These macros support profiling the libomp library. Use --stats=on when building with build.pl to enable
and then use the KMP_* macros to profile (through counts or clock ticks) libomp during execution of an OpenMP program.
@section sec_stats_env_vars Environment Variables
This section describes the environment variables relevant to stats-gathering in libomp
@code
KMP_STATS_FILE
@endcode
This environment variable is set to an output filename that will be appended *NOT OVERWRITTEN* if it exists. If this environment variable is undefined, the statistics will be output to stderr
@code
KMP_STATS_THREADS
@endcode
This environment variable indicates to print thread-specific statistics as well as aggregate statistics. Each thread's statistics will be shown as well as the collective sum of all threads. The values "true", "on", "1", "yes" will all indicate to print per thread statistics.
@defgroup TASKING Tasking support
These functions support tasking constructs.
@defgroup USER User visible functions
These functions can be called directly by the user, but are runtime library specific, rather than being OpenMP interfaces.
*/

View File

@@ -0,0 +1,332 @@
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# Configure omp.h, kmp_config.h and ompt.h if necessary
configure_file(${LIBOMP_INC_DIR}/omp.h.var omp.h @ONLY)
configure_file(kmp_config.h.cmake kmp_config.h @ONLY)
if(${LIBOMP_OMPT_SUPPORT})
configure_file(${LIBOMP_INC_DIR}/ompt.h.var ompt.h @ONLY)
endif()
# Generate message catalog files: kmp_i18n_id.inc and kmp_i18n_default.inc
add_custom_command(
OUTPUT kmp_i18n_id.inc
COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/message-converter.pl --os=${LIBOMP_PERL_SCRIPT_OS}
--prefix=kmp_i18n --enum=kmp_i18n_id.inc ${LIBOMP_SRC_DIR}/i18n/en_US.txt
DEPENDS ${LIBOMP_SRC_DIR}/i18n/en_US.txt ${LIBOMP_TOOLS_DIR}/message-converter.pl
)
add_custom_command(
OUTPUT kmp_i18n_default.inc
COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/message-converter.pl --os=${LIBOMP_PERL_SCRIPT_OS}
--prefix=kmp_i18n --default=kmp_i18n_default.inc ${LIBOMP_SRC_DIR}/i18n/en_US.txt
DEPENDS ${LIBOMP_SRC_DIR}/i18n/en_US.txt ${LIBOMP_TOOLS_DIR}/message-converter.pl
)
# Set the -D definitions for all sources
# UNICODE and _UNICODE are set in LLVM's CMake system. They affect the
# ittnotify code and should only be set when compiling ittnotify_static.c
# on Windows (done below).
# TODO: Fix the UNICODE usage in ittnotify code for Windows.
remove_definitions(-DUNICODE -D_UNICODE)
libomp_get_definitions_flags(LIBOMP_CONFIGURED_DEFINITIONS_FLAGS)
add_definitions(${LIBOMP_CONFIGURED_DEFINITIONS_FLAGS})
# Set the -I includes for all sources
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${LIBOMP_SRC_DIR}
${LIBOMP_SRC_DIR}/i18n
${LIBOMP_INC_DIR}
${LIBOMP_SRC_DIR}/thirdparty/ittnotify
)
if(${LIBOMP_USE_HWLOC})
include_directories(${LIBOMP_HWLOC_INSTALL_DIR}/include)
endif()
# Getting correct source files to build library
set(LIBOMP_CFILES)
set(LIBOMP_CXXFILES)
set(LIBOMP_ASMFILES)
if(${STUBS_LIBRARY})
set(LIBOMP_CFILES kmp_stub.cpp)
else()
# Get C++ files
set(LIBOMP_CXXFILES
kmp_alloc.cpp
kmp_atomic.cpp
kmp_csupport.cpp
kmp_debug.cpp
kmp_itt.cpp
kmp_environment.cpp
kmp_error.cpp
kmp_global.cpp
kmp_i18n.cpp
kmp_io.cpp
kmp_runtime.cpp
kmp_settings.cpp
kmp_str.cpp
kmp_tasking.cpp
kmp_taskq.cpp
kmp_threadprivate.cpp
kmp_utility.cpp
kmp_barrier.cpp
kmp_wait_release.cpp
kmp_affinity.cpp
kmp_dispatch.cpp
kmp_lock.cpp
kmp_sched.cpp
)
if(WIN32)
# Windows specific files
libomp_append(LIBOMP_CXXFILES z_Windows_NT_util.cpp)
libomp_append(LIBOMP_CXXFILES z_Windows_NT-586_util.cpp)
libomp_append(LIBOMP_ASMFILES z_Windows_NT-586_asm.asm) # Windows assembly file
else()
# Unix specific files
libomp_append(LIBOMP_CXXFILES z_Linux_util.cpp)
libomp_append(LIBOMP_CXXFILES kmp_gsupport.cpp)
libomp_append(LIBOMP_ASMFILES z_Linux_asm.S) # Unix assembly file
endif()
libomp_append(LIBOMP_CFILES thirdparty/ittnotify/ittnotify_static.c LIBOMP_USE_ITT_NOTIFY)
libomp_append(LIBOMP_CXXFILES kmp_debugger.cpp LIBOMP_USE_DEBUGGER)
libomp_append(LIBOMP_CXXFILES kmp_stats.cpp LIBOMP_STATS)
libomp_append(LIBOMP_CXXFILES kmp_stats_timing.cpp LIBOMP_STATS)
if(${LIBOMP_OMP_VERSION} GREATER 40 OR ${LIBOMP_OMP_VERSION} EQUAL 40)
libomp_append(LIBOMP_CXXFILES kmp_taskdeps.cpp)
libomp_append(LIBOMP_CXXFILES kmp_cancel.cpp)
endif()
endif()
# Files common to stubs and normal library
libomp_append(LIBOMP_CXXFILES kmp_ftn_cdecl.cpp)
libomp_append(LIBOMP_CXXFILES kmp_ftn_extra.cpp)
libomp_append(LIBOMP_CXXFILES kmp_version.cpp)
libomp_append(LIBOMP_CXXFILES ompt-general.cpp IF_TRUE LIBOMP_OMPT_SUPPORT)
libomp_append(LIBOMP_CXXFILES tsan_annotations.cpp IF_TRUE LIBOMP_TSAN_SUPPORT)
set(LIBOMP_SOURCE_FILES ${LIBOMP_CFILES} ${LIBOMP_CXXFILES} ${LIBOMP_ASMFILES})
# For Windows, there is a resource file (.rc -> .res) that is also compiled
libomp_append(LIBOMP_SOURCE_FILES libomp.rc WIN32)
# Get compiler and assembler flags
libomp_get_cflags(LIBOMP_CONFIGURED_CFLAGS)
libomp_get_cxxflags(LIBOMP_CONFIGURED_CXXFLAGS)
libomp_get_asmflags(LIBOMP_CONFIGURED_ASMFLAGS)
# Set the compiler flags for each type of source
set_source_files_properties(${LIBOMP_CFILES} PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_CFLAGS}")
set_source_files_properties(${LIBOMP_CXXFILES} PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_CXXFLAGS}")
set_source_files_properties(${LIBOMP_ASMFILES} PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_ASMFLAGS}")
# Let the compiler handle the assembly files on Unix-like systems
if(NOT WIN32)
set_source_files_properties(${LIBOMP_ASMFILES} PROPERTIES LANGUAGE C)
endif()
# Remove any cmake-automatic linking of the standard C++ library.
# We neither need (nor want) the standard C++ library dependency even though we compile c++ files.
if(NOT ${LIBOMP_USE_STDCPPLIB})
set(LIBOMP_LINKER_LANGUAGE C)
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES)
else()
set(LIBOMP_LINKER_LANGUAGE CXX)
endif()
# Add the OpenMP library
libomp_get_ldflags(LIBOMP_CONFIGURED_LDFLAGS)
add_library(omp ${LIBOMP_LIBRARY_KIND} ${LIBOMP_SOURCE_FILES})
set_target_properties(omp PROPERTIES
PREFIX "" SUFFIX "" OUTPUT_NAME "${LIBOMP_LIB_FILE}"
LINK_FLAGS "${LIBOMP_CONFIGURED_LDFLAGS}"
LINKER_LANGUAGE ${LIBOMP_LINKER_LANGUAGE}
)
# Get the library's location within the build tree for the unit tester
if(NOT WIN32)
get_target_property(LIBOMP_LIBRARY_DIR omp LIBRARY_OUTPUT_DIRECTORY)
else()
get_target_property(LIBOMP_LIBRARY_DIR omp RUNTIME_OUTPUT_DIRECTORY)
endif()
if(NOT LIBOMP_LIBRARY_DIR)
set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(LIBOMP_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
else()
set(LIBOMP_LIBRARY_DIR ${LIBOMP_LIBRARY_DIR} PARENT_SCOPE)
endif()
# Add symbolic links to libomp
if(NOT WIN32)
add_custom_command(TARGET omp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_LIB_FILE}
libgomp${LIBOMP_LIBRARY_SUFFIX}
COMMAND ${CMAKE_COMMAND} -E create_symlink ${LIBOMP_LIB_FILE}
libiomp5${LIBOMP_LIBRARY_SUFFIX}
WORKING_DIRECTORY ${LIBOMP_LIBRARY_DIR}
)
endif()
# Linking command will include libraries in LIBOMP_CONFIGURED_LIBFLAGS
libomp_get_libflags(LIBOMP_CONFIGURED_LIBFLAGS)
target_link_libraries(omp ${LIBOMP_CONFIGURED_LIBFLAGS} ${CMAKE_DL_LIBS})
# Create *.inc before compiling any sources
# objects depend on : .inc files
add_custom_target(libomp-needed-headers DEPENDS kmp_i18n_id.inc kmp_i18n_default.inc)
add_dependencies(omp libomp-needed-headers)
# Windows specific build rules
if(WIN32)
configure_file(libomp.rc.var libomp.rc @ONLY)
# Create .def and .rc file before compiling any sources
add_custom_target(libomp-needed-windows-files DEPENDS ${LIBOMP_LIB_NAME}.def)
add_dependencies(omp libomp-needed-windows-files)
# z_Windows_NT-586_asm.asm requires definitions to be sent via command line
# It only needs the architecutre macro and OMPT_SUPPORT=0|1
libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_IA32" IF_TRUE IA32)
libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_AMD64" IF_TRUE INTEL64)
libomp_append(LIBOMP_MASM_DEFINITIONS "-DOMPT_SUPPORT" IF_TRUE_1_0 LIBOMP_OMPT_SUPPORT)
libomp_list_to_string("${LIBOMP_MASM_DEFINITIONS}" LIBOMP_MASM_DEFINITIONS)
set_property(SOURCE z_Windows_NT-586_asm.asm APPEND_STRING PROPERTY COMPILE_FLAGS " ${LIBOMP_MASM_DEFINITIONS}")
set_source_files_properties(thirdparty/ittnotify/ittnotify_static.c PROPERTIES COMPILE_DEFINITIONS "UNICODE")
# Create Windows import library
# the import library is "re-linked" to include kmp_import.cpp which prevents
# linking of both Visual Studio OpenMP and newly built OpenMP
set_source_files_properties(kmp_import.cpp PROPERTIES COMPILE_FLAGS "${LIBOMP_CONFIGURED_CFLAGS}")
set(LIBOMP_IMP_LIB_FILE ${LIBOMP_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
set(LIBOMP_GENERATED_IMP_LIB_FILENAME ${LIBOMP_LIB_FILE}${CMAKE_STATIC_LIBRARY_SUFFIX})
set_target_properties(omp PROPERTIES
VERSION ${LIBOMP_VERSION_MAJOR}.${LIBOMP_VERSION_MINOR} # uses /version flag
IMPORT_PREFIX "" IMPORT_SUFFIX "" # control generated import library name when building omp
ARCHIVE_OUTPUT_NAME ${LIBOMP_GENERATED_IMP_LIB_FILENAME}
)
# Get generated import library from creating omp
get_target_property(LIBOMP_IMPORT_LIB_DIRECTORY omp ARCHIVE_OUTPUT_DIRECTORY)
if(LIBOMP_IMPORT_LIB_DIRECTORY)
set(LIBOMP_GENERATED_IMP_LIB ${LIBOMP_IMPORT_LIB_DIRECTORY}/${LIBOMP_GENERATED_IMP_LIB_FILENAME})
else()
set(LIBOMP_GENERATED_IMP_LIB ${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_GENERATED_IMP_LIB_FILENAME})
endif()
set_source_files_properties(${LIBOMP_GENERATED_IMP_LIB} PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
# Create new import library that is just the previously created one + kmp_import.cpp
add_library(ompimp STATIC ${LIBOMP_GENERATED_IMP_LIB} kmp_import.cpp)
set_target_properties(ompimp PROPERTIES
PREFIX "" SUFFIX "" OUTPUT_NAME "${LIBOMP_IMP_LIB_FILE}"
LINKER_LANGUAGE C
)
add_dependencies(ompimp omp) # ensure generated import library is created first
# Create def file to designate exported functions
libomp_get_gdflags(LIBOMP_GDFLAGS) # generate-def.pl flags (Windows only)
libomp_string_to_list("${LIBOMP_GDFLAGS}" LIBOMP_GDFLAGS)
add_custom_command(
OUTPUT ${LIBOMP_LIB_NAME}.def
COMMAND ${PERL_EXECUTABLE} ${LIBOMP_TOOLS_DIR}/generate-def.pl ${LIBOMP_GDFLAGS}
-o ${LIBOMP_LIB_NAME}.def ${CMAKE_CURRENT_SOURCE_DIR}/dllexports
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dllexports ${LIBOMP_TOOLS_DIR}/generate-def.pl
)
endif()
# Building the Fortran module files
# One compilation step creates both omp_lib.mod and omp_lib_kinds.mod
if(${LIBOMP_FORTRAN_MODULES})
configure_file(${LIBOMP_INC_DIR}/omp_lib.h.var omp_lib.h @ONLY)
configure_file(${LIBOMP_INC_DIR}/omp_lib.f.var omp_lib.f @ONLY)
configure_file(${LIBOMP_INC_DIR}/omp_lib.f90.var omp_lib.f90 @ONLY)
add_custom_target(libomp-mod ALL DEPENDS omp_lib.mod omp_lib_kinds.mod)
libomp_get_fflags(LIBOMP_CONFIGURED_FFLAGS)
if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.f90)
else()
set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.f)
endif()
add_custom_command(
OUTPUT omp_lib.mod omp_lib_kinds.mod
COMMAND ${CMAKE_Fortran_COMPILER} -c ${LIBOMP_CONFIGURED_FFLAGS} ${LIBOMP_FORTRAN_SOURCE_FILE}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}
${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES omp_lib${CMAKE_C_OUTPUT_EXTENSION})
endif()
# Move files to exports/ directory if requested
if(${LIBOMP_COPY_EXPORTS})
include(LibompExports)
endif()
# Micro test rules for after library has been built (cmake/LibompMicroTests.cmake)
include(LibompMicroTests)
add_custom_target(libomp-micro-tests)
if(NOT ${MIC} AND NOT CMAKE_CROSSCOMPILING)
add_dependencies(libomp-micro-tests libomp-test-touch)
endif()
if(NOT WIN32 AND NOT APPLE)
add_dependencies(libomp-micro-tests libomp-test-relo)
endif()
if(NOT WIN32 AND NOT APPLE)
add_dependencies(libomp-micro-tests libomp-test-execstack)
endif()
if(${MIC})
add_dependencies(libomp-micro-tests libomp-test-instr)
endif()
add_dependencies(libomp-micro-tests libomp-test-deps)
# Install rules
# We want to install libomp in DESTDIR/CMAKE_INSTALL_PREFIX/lib
# We want to install headers in DESTDIR/CMAKE_INSTALL_PREFIX/include
if(${OPENMP_STANDALONE_BUILD})
set(LIBOMP_HEADERS_INSTALL_PATH include)
else()
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION ${PACKAGE_VERSION})
set(LIBOMP_HEADERS_INSTALL_PATH lib${OPENMP_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
endif()
if(WIN32)
install(TARGETS omp RUNTIME DESTINATION bin)
install(TARGETS ompimp ARCHIVE DESTINATION lib${OPENMP_LIBDIR_SUFFIX})
# Create aliases (regular copies) of the library for backwards compatibility
set(LIBOMP_ALIASES "libiomp5md")
foreach(alias IN LISTS LIBOMP_ALIASES)
install(CODE "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E copy \"${LIBOMP_LIB_FILE}\"
\"${alias}${LIBOMP_LIBRARY_SUFFIX}\" WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX}/bin)")
install(CODE "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E copy \"${LIBOMP_IMP_LIB_FILE}\"
\"${alias}${LIBOMP_LIBRARY_SUFFIX}\" WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX}/lib${OPENMP_LIBDIR_SUFFIX})")
endforeach()
else()
install(TARGETS omp ${LIBOMP_INSTALL_KIND} DESTINATION lib${OPENMP_LIBDIR_SUFFIX})
if(${LIBOMP_INSTALL_ALIASES})
# Create aliases (symlinks) of the library for backwards compatibility
set(LIBOMP_ALIASES "libgomp;libiomp5")
foreach(alias IN LISTS LIBOMP_ALIASES)
install(CODE "execute_process(COMMAND \"\${CMAKE_COMMAND}\" -E create_symlink \"${LIBOMP_LIB_FILE}\"
\"${alias}${LIBOMP_LIBRARY_SUFFIX}\" WORKING_DIRECTORY
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/lib${OPENMP_LIBDIR_SUFFIX})")
endforeach()
endif()
endif()
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/omp.h
DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH}
)
if(${LIBOMP_OMPT_SUPPORT})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/ompt.h DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH})
endif()
if(${LIBOMP_FORTRAN_MODULES})
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h
${CMAKE_CURRENT_BINARY_DIR}/omp_lib.mod
${CMAKE_CURRENT_BINARY_DIR}/omp_lib_kinds.mod
DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH}
)
endif()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,121 @@
# exports_so.txt #
#
#//===----------------------------------------------------------------------===//
#//
#// The LLVM Compiler Infrastructure
#//
#// This file is dual licensed under the MIT and the University of Illinois Open
#// Source Licenses. See LICENSE.txt for details.
#//
#//===----------------------------------------------------------------------===//
#
# This is version script for OMP RTL shared library (libomp*.so)
VERSION {
global: # Exported symbols.
#
# "Normal" symbols.
#
omp_*; # Standard OpenMP functions.
#
# OMPT API
#
ompt_start_tool; # OMPT start interface
# icc drops weak attribute at linking step without the following line:
Annotate*; # TSAN annotation
ompc_*; # omp.h renames some standard functions to ompc_*.
kmp_*; # Intel extensions.
kmpc_*; # Intel extensions.
__kmpc_*; # Functions called by compiler-generated code.
GOMP_*; # GNU C compatibility functions.
_You_must_link_with_*; # Mutual detection/MS compatibility symbols.
#
# Debugger support.
#
#if USE_DEBUGGER
__kmp_debugging;
__kmp_omp_debug_struct_info;
#endif /* USE_DEBUGGER */
#
# Internal functions exported for testing purposes.
#
__kmp_get_reduce_method;
___kmp_allocate;
___kmp_free;
__kmp_thread_pool;
__kmp_thread_pool_nth;
__kmp_reset_stats;
#if USE_ITT_BUILD
#
# ITT support.
#
# The following entry points are added so that the backtraces from
# the tools contain meaningful names for all the functions that might
# appear in a backtrace of a thread which is blocked in the RTL.
__kmp_acquire_drdpa_lock;
__kmp_acquire_nested_drdpa_lock;
__kmp_acquire_nested_queuing_lock;
__kmp_acquire_nested_tas_lock;
__kmp_acquire_nested_ticket_lock;
__kmp_acquire_queuing_lock;
__kmp_acquire_tas_lock;
__kmp_acquire_ticket_lock;
__kmp_fork_call;
__kmp_invoke_microtask;
#if KMP_USE_MONITOR
__kmp_launch_monitor;
__kmp_reap_monitor;
#endif
__kmp_launch_worker;
__kmp_reap_worker;
__kmp_release_64;
__kmp_wait_64;
__kmp_wait_yield_4;
# ittnotify symbols to be used by debugger
__kmp_itt_fini_ittlib;
__kmp_itt_init_ittlib;
#endif /* USE_ITT_BUILD */
local: # Non-exported symbols.
*; # All other symbols are not exported.
}; # VERSION
# sets up GCC OMP_ version dependency chain
OMP_1.0 {
};
OMP_2.0 {
} OMP_1.0;
OMP_3.0 {
} OMP_2.0;
OMP_3.1 {
} OMP_3.0;
OMP_4.0 {
} OMP_3.1;
# sets up GCC GOMP_ version dependency chain
GOMP_1.0 {
};
GOMP_2.0 {
} GOMP_1.0;
GOMP_3.0 {
} GOMP_2.0;
GOMP_4.0 {
} GOMP_3.0;
# end of file #

View File

@@ -0,0 +1,484 @@
/*
* extractExternal.cpp
*/
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include <fstream>
#include <iostream>
#include <map>
#include <set>
#include <stdlib.h>
#include <string>
#include <strstream>
/* Given a set of n object files h ('external' object files) and a set of m
object files o ('internal' object files),
1. Determines r, the subset of h that o depends on, directly or indirectly
2. Removes the files in h - r from the file system
3. For each external symbol defined in some file in r, rename it in r U o
by prefixing it with "__kmp_external_"
Usage:
hide.exe <n> <filenames for h> <filenames for o>
Thus, the prefixed symbols become hidden in the sense that they now have a
special prefix.
*/
using namespace std;
void stop(char *errorMsg) {
printf("%s\n", errorMsg);
exit(1);
}
// an entry in the symbol table of a .OBJ file
class Symbol {
public:
__int64 name;
unsigned value;
unsigned short sectionNum, type;
char storageClass, nAux;
};
class _rstream : public istrstream {
private:
const char *buf;
protected:
_rstream(pair<const char *, streamsize> p)
: istrstream(p.first, p.second), buf(p.first) {}
~_rstream() { delete[] buf; }
};
// A stream encapuslating the content of a file or the content of a string,
// overriding the >> operator to read various integer types in binary form,
// as well as a symbol table entry.
class rstream : public _rstream {
private:
template <class T> inline rstream &doRead(T &x) {
read((char *)&x, sizeof(T));
return *this;
}
static pair<const char *, streamsize> getBuf(const char *fileName) {
ifstream raw(fileName, ios::binary | ios::in);
if (!raw.is_open())
stop("rstream.getBuf: Error opening file");
raw.seekg(0, ios::end);
streampos fileSize = raw.tellg();
if (fileSize < 0)
stop("rstream.getBuf: Error reading file");
char *buf = new char[fileSize];
raw.seekg(0, ios::beg);
raw.read(buf, fileSize);
return pair<const char *, streamsize>(buf, fileSize);
}
public:
// construct from a string
rstream(const char *buf, streamsize size)
: _rstream(pair<const char *, streamsize>(buf, size)) {}
// construct from a file whole content is fully read once to initialize the
// content of this stream
rstream(const char *fileName) : _rstream(getBuf(fileName)) {}
rstream &operator>>(int &x) { return doRead(x); }
rstream &operator>>(unsigned &x) { return doRead(x); }
rstream &operator>>(short &x) { return doRead(x); }
rstream &operator>>(unsigned short &x) { return doRead(x); }
rstream &operator>>(Symbol &e) {
read((char *)&e, 18);
return *this;
}
};
// string table in a .OBJ file
class StringTable {
private:
map<string, unsigned> directory;
size_t length;
char *data;
// make <directory> from <length> bytes in <data>
void makeDirectory(void) {
unsigned i = 4;
while (i < length) {
string s = string(data + i);
directory.insert(make_pair(s, i));
i += s.size() + 1;
}
}
// initialize <length> and <data> with contents specified by the arguments
void init(const char *_data) {
unsigned _length = *(unsigned *)_data;
if (_length < sizeof(unsigned) || _length != *(unsigned *)_data)
stop("StringTable.init: Invalid symbol table");
if (_data[_length - 1]) {
// to prevent runaway strings, make sure the data ends with a zero
data = new char[length = _length + 1];
data[_length] = 0;
} else {
data = new char[length = _length];
}
*(unsigned *)data = length;
KMP_MEMCPY(data + sizeof(unsigned), _data + sizeof(unsigned),
length - sizeof(unsigned));
makeDirectory();
}
public:
StringTable(rstream &f) {
// Construct string table by reading from f.
streampos s;
unsigned strSize;
char *strData;
s = f.tellg();
f >> strSize;
if (strSize < sizeof(unsigned))
stop("StringTable: Invalid string table");
strData = new char[strSize];
*(unsigned *)strData = strSize;
// read the raw data into <strData>
f.read(strData + sizeof(unsigned), strSize - sizeof(unsigned));
s = f.tellg() - s;
if (s < strSize)
stop("StringTable: Unexpected EOF");
init(strData);
delete[] strData;
}
StringTable(const set<string> &strings) {
// Construct string table from given strings.
char *p;
set<string>::const_iterator it;
size_t s;
// count required size for data
for (length = sizeof(unsigned), it = strings.begin(); it != strings.end();
++it) {
size_t l = (*it).size();
if (l > (unsigned)0xFFFFFFFF)
stop("StringTable: String too long");
if (l > 8) {
length += l + 1;
if (length > (unsigned)0xFFFFFFFF)
stop("StringTable: Symbol table too long");
}
}
data = new char[length];
*(unsigned *)data = length;
// populate data and directory
for (p = data + sizeof(unsigned), it = strings.begin(); it != strings.end();
++it) {
const string &str = *it;
size_t l = str.size();
if (l > 8) {
directory.insert(make_pair(str, p - data));
KMP_MEMCPY(p, str.c_str(), l);
p[l] = 0;
p += l + 1;
}
}
}
~StringTable() { delete[] data; }
// Returns encoding for given string based on this string table. Error if
// string length is greater than 8 but string is not in the string table
// -- returns 0.
__int64 encode(const string &str) {
__int64 r;
if (str.size() <= 8) {
// encoded directly
((char *)&r)[7] = 0;
KMP_STRNCPY_S((char *)&r, sizeof(r), str.c_str(), 8);
return r;
} else {
// represented as index into table
map<string, unsigned>::const_iterator it = directory.find(str);
if (it == directory.end())
stop("StringTable::encode: String now found in string table");
((unsigned *)&r)[0] = 0;
((unsigned *)&r)[1] = (*it).second;
return r;
}
}
// Returns string represented by x based on this string table. Error if x
// references an invalid position in the table--returns the empty string.
string decode(__int64 x) const {
if (*(unsigned *)&x == 0) {
// represented as index into table
unsigned &p = ((unsigned *)&x)[1];
if (p >= length)
stop("StringTable::decode: Invalid string table lookup");
return string(data + p);
} else {
// encoded directly
char *p = (char *)&x;
int i;
for (i = 0; i < 8 && p[i]; ++i)
;
return string(p, i);
}
}
void write(ostream &os) { os.write(data, length); }
};
// for the named object file, determines the set of defined symbols and the set
// of undefined external symbols and writes them to <defined> and <undefined>
// respectively
void computeExternalSymbols(const char *fileName, set<string> *defined,
set<string> *undefined) {
streampos fileSize;
size_t strTabStart;
unsigned symTabStart, symNEntries;
rstream f(fileName);
f.seekg(0, ios::end);
fileSize = f.tellg();
f.seekg(8);
f >> symTabStart >> symNEntries;
// seek to the string table
f.seekg(strTabStart = symTabStart + 18 * (size_t)symNEntries);
if (f.eof()) {
printf("computeExternalSymbols: fileName='%s', fileSize = %lu, symTabStart "
"= %u, symNEntries = %u\n",
fileName, (unsigned long)fileSize, symTabStart, symNEntries);
stop("computeExternalSymbols: Unexpected EOF 1");
}
StringTable stringTable(f); // read the string table
if (f.tellg() != fileSize)
stop("computeExternalSymbols: Unexpected data after string table");
f.clear();
f.seekg(symTabStart); // seek to the symbol table
defined->clear();
undefined->clear();
for (int i = 0; i < symNEntries; ++i) {
// process each entry
Symbol e;
if (f.eof())
stop("computeExternalSymbols: Unexpected EOF 2");
f >> e;
if (f.fail())
stop("computeExternalSymbols: File read error");
if (e.nAux) { // auxiliary entry: skip
f.seekg(e.nAux * 18, ios::cur);
i += e.nAux;
}
// if symbol is extern and defined in the current file, insert it
if (e.storageClass == 2)
if (e.sectionNum)
defined->insert(stringTable.decode(e.name));
else
undefined->insert(stringTable.decode(e.name));
}
}
// For each occurrence of an external symbol in the object file named by
// by <fileName> that is a member of <hide>, renames it by prefixing
// with "__kmp_external_", writing back the file in-place
void hideSymbols(char *fileName, const set<string> &hide) {
static const string prefix("__kmp_external_");
set<string> strings; // set of all occurring symbols, appropriately prefixed
streampos fileSize;
size_t strTabStart;
unsigned symTabStart, symNEntries;
int i;
rstream in(fileName);
in.seekg(0, ios::end);
fileSize = in.tellg();
in.seekg(8);
in >> symTabStart >> symNEntries;
in.seekg(strTabStart = symTabStart + 18 * (size_t)symNEntries);
if (in.eof())
stop("hideSymbols: Unexpected EOF");
StringTable stringTableOld(in); // read original string table
if (in.tellg() != fileSize)
stop("hideSymbols: Unexpected data after string table");
// compute set of occurring strings with prefix added
for (i = 0; i < symNEntries; ++i) {
Symbol e;
in.seekg(symTabStart + i * 18);
if (in.eof())
stop("hideSymbols: Unexpected EOF");
in >> e;
if (in.fail())
stop("hideSymbols: File read error");
if (e.nAux)
i += e.nAux;
const string &s = stringTableOld.decode(e.name);
// if symbol is extern and found in <hide>, prefix and insert into strings,
// otherwise, just insert into strings without prefix
strings.insert(
(e.storageClass == 2 && hide.find(s) != hide.end()) ? prefix + s : s);
}
ofstream out(fileName, ios::trunc | ios::out | ios::binary);
if (!out.is_open())
stop("hideSymbols: Error opening output file");
// make new string table from string set
StringTable stringTableNew = StringTable(strings);
// copy input file to output file up to just before the symbol table
in.seekg(0);
char *buf = new char[symTabStart];
in.read(buf, symTabStart);
out.write(buf, symTabStart);
delete[] buf;
// copy input symbol table to output symbol table with name translation
for (i = 0; i < symNEntries; ++i) {
Symbol e;
in.seekg(symTabStart + i * 18);
if (in.eof())
stop("hideSymbols: Unexpected EOF");
in >> e;
if (in.fail())
stop("hideSymbols: File read error");
const string &s = stringTableOld.decode(e.name);
out.seekp(symTabStart + i * 18);
e.name = stringTableNew.encode(
(e.storageClass == 2 && hide.find(s) != hide.end()) ? prefix + s : s);
out.write((char *)&e, 18);
if (out.fail())
stop("hideSymbols: File write error");
if (e.nAux) {
// copy auxiliary symbol table entries
int nAux = e.nAux;
for (int j = 1; j <= nAux; ++j) {
in >> e;
out.seekp(symTabStart + (i + j) * 18);
out.write((char *)&e, 18);
}
i += nAux;
}
}
// output string table
stringTableNew.write(out);
}
// returns true iff <a> and <b> have no common element
template <class T> bool isDisjoint(const set<T> &a, const set<T> &b) {
set<T>::const_iterator ita, itb;
for (ita = a.begin(), itb = b.begin(); ita != a.end() && itb != b.end();) {
const T &ta = *ita, &tb = *itb;
if (ta < tb)
++ita;
else if (tb < ta)
++itb;
else
return false;
}
return true;
}
// PRE: <defined> and <undefined> are arrays with <nTotal> elements where
// <nTotal> >= <nExternal>. The first <nExternal> elements correspond to the
// external object files and the rest correspond to the internal object files.
// POST: file x is said to depend on file y if undefined[x] and defined[y] are
// not disjoint. Returns the transitive closure of the set of internal object
// files, as a set of file indexes, under the 'depends on' relation, minus the
// set of internal object files.
set<int> *findRequiredExternal(int nExternal, int nTotal, set<string> *defined,
set<string> *undefined) {
set<int> *required = new set<int>;
set<int> fresh[2];
int i, cur = 0;
bool changed;
for (i = nTotal - 1; i >= nExternal; --i)
fresh[cur].insert(i);
do {
changed = false;
for (set<int>::iterator it = fresh[cur].begin(); it != fresh[cur].end();
++it) {
set<string> &s = undefined[*it];
for (i = 0; i < nExternal; ++i) {
if (required->find(i) == required->end()) {
if (!isDisjoint(defined[i], s)) {
// found a new qualifying element
required->insert(i);
fresh[1 - cur].insert(i);
changed = true;
}
}
}
}
fresh[cur].clear();
cur = 1 - cur;
} while (changed);
return required;
}
int main(int argc, char **argv) {
int nExternal, nInternal, i;
set<string> *defined, *undefined;
set<int>::iterator it;
if (argc < 3)
stop("Please specify a positive integer followed by a list of object "
"filenames");
nExternal = atoi(argv[1]);
if (nExternal <= 0)
stop("Please specify a positive integer followed by a list of object "
"filenames");
if (nExternal + 2 > argc)
stop("Too few external objects");
nInternal = argc - nExternal - 2;
defined = new set<string>[argc - 2];
undefined = new set<string>[argc - 2];
// determine the set of defined and undefined external symbols
for (i = 2; i < argc; ++i)
computeExternalSymbols(argv[i], defined + i - 2, undefined + i - 2);
// determine the set of required external files
set<int> *requiredExternal =
findRequiredExternal(nExternal, argc - 2, defined, undefined);
set<string> hide;
// determine the set of symbols to hide--namely defined external symbols of
// the required external files
for (it = requiredExternal->begin(); it != requiredExternal->end(); ++it) {
int idx = *it;
set<string>::iterator it2;
// We have to insert one element at a time instead of inserting a range
// because the insert member function taking a range doesn't exist on
// Windows* OS, at least at the time of this writing.
for (it2 = defined[idx].begin(); it2 != defined[idx].end(); ++it2)
hide.insert(*it2);
}
// process the external files--removing those that are not required and hiding
// the appropriate symbols in the others
for (i = 0; i < nExternal; ++i)
if (requiredExternal->find(i) != requiredExternal->end())
hideSymbols(argv[2 + i], hide);
else
remove(argv[2 + i]);
// hide the appropriate symbols in the internal files
for (i = nExternal + 2; i < argc; ++i)
hideSymbols(argv[i], hide);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More