Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -434,6 +434,8 @@ option(LLVM_USE_SPLIT_DWARF "Use -gsplit-dwarf when compiling llvm." OFF) +option(LLVM_INCLUDE_ISL "Include the integer set library to the build" OFF) + option(LLVM_POLLY_LINK_INTO_TOOLS "Statically link Polly into tools (if available)" ON) option(LLVM_POLLY_BUILD "Build LLVM with Polly" ON) @@ -969,6 +971,22 @@ PATTERN ".svn" EXCLUDE ) + if (LLVM_INCLUDE_ISL) + install(DIRECTORY contrib/isl/include/isl + DESTINATION include/llvm/ISL + COMPONENT llvm-headers + FILES_MATCHING + PATTERN "*.h" + ) + + install(DIRECTORY ${LLVM_BINARY_DIR}/lib/ISL/isl/include/isl + DESTINATION include/llvm/ISL + COMPONENT llvm-headers + FILES_MATCHING + PATTERN "*.h" + ) + endif () + # Installing the headers needs to depend on generating any public # tablegen'd headers. add_custom_target(llvm-headers DEPENDS intrinsics_gen) Index: contrib/isl-merge.py =================================================================== --- /dev/null +++ contrib/isl-merge.py @@ -0,0 +1,64 @@ +#! /usr/bin/env python3 +# -*- coding: UTF-8 -*- + +import os +import subprocess + +def main(): + # TODO: Does not yet update imath + print("Updating to latest isl version...") + + # Get the version we already merged in + idfile = os.path.join('isl', 'GIT_HEAD_ID') + with open(idfile, 'rt') as f: + ca = f.readline().rstrip() + if not ca or ca.isspace(): + raise Exception("Error reading GIT_HEAD_ID") + + # Remember the LLVM trunk revision for later + llvmhead = subprocess.check_output( + ['git', 'rev-parse', 'HEAD'], universal_newlines=True).rstrip() + + # Fetch the latest isl from the official repository + subprocess.check_call( + ['git', 'fetch', 'http://repo.or.cz/isl.git', 'master']) + isldesc = subprocess.check_output( + ['git', 'describe', 'FETCH_HEAD'], universal_newlines=True).rstrip() + if isldesc == ca: + print("Already at latest version, abort") + return + + # Update GIT_HEAD_ID + with open(idfile, 'wt') as f: + f.write(isldesc) + subprocess.check_call(['git', 'add', idfile]) + subprocess.check_call(['git', 'commit', '-m', + ("Update GIT_HEAD_ID\n" + "\n" + "This commit is only temporary to have an updated GIT_HEAD_ID\n" + "in the repository even if a merge conflict occurs")]) + + # Do the actual merge + # Cannot use 'git merge' because it expects the existence of a common + # ancestor commit. The linear history of LLVM does not allow subtree + # merge commits to find such an ancestor, hence we use 'git rebase --onto' + # which acts like a cherry-pick. + try: + subprocess.check_call( + ['git', 'rebase', '-Xsubtree=contrib/isl', + ca, 'FETCH_HEAD', '--onto', 'HEAD']) + except: + print("A merge conflict occurred, manual commit necessary") + return + + print("Rebase succeeded, squash and commit...") + subprocess.check_call(['git', 'reset', '--soft', llvmhead]) + subprocess.check_call( + ['git', 'commit', '-m', "Update isl to {desc}".format(desc=isldesc)]) + + print() + print("Done. Push using 'git svn dcommit'" + "(maybe verify using 'git svn dcommit -n' first)") + +if __name__ == '__main__': + main() Index: contrib/isl/.gitmodules =================================================================== --- contrib/isl/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "imath"] - path = imath - url = https://github.com/creachadair/imath.git Index: contrib/isl/GIT_HEAD_ID =================================================================== --- /dev/null +++ contrib/isl/GIT_HEAD_ID @@ -0,0 +1 @@ +isl-0.18-979-g130e0d9 \ No newline at end of file Index: lib/CMakeLists.txt =================================================================== --- lib/CMakeLists.txt +++ lib/CMakeLists.txt @@ -26,3 +26,6 @@ add_subdirectory(XRay) add_subdirectory(Testing) add_subdirectory(WindowsManifest) +if (LLVM_INCLUDE_ISL) + add_subdirectory(ISL) +endif () \ No newline at end of file Index: lib/ISL/CMakeLists.txt =================================================================== --- /dev/null +++ lib/ISL/CMakeLists.txt @@ -0,0 +1,297 @@ +set(ISL_SOURCE_DIR "${LLVM_MAIN_SRC_DIR}/contrib/isl") +set(ISL_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/isl") + +# Determine version of isl +if (EXISTS "${ISL_SOURCE_DIR}/GIT_HEAD_ID") + # The source comes from a 'make dist' archive + file(READ "${ISL_SOURCE_DIR}/GIT_HEAD_ID" ISL_GIT_HEAD_ID) + string(STRIP "${ISL_GIT_HEAD_ID}" ISL_GIT_HEAD_ID) +elseif (EXISTS "${ISL_SOURCE_DIR}/gitversion.h") + # The source directory is preconfigured + file(READ "${ISL_SOURCE_DIR}/gitversion.h" GITVERSION_H) + string(REGEX REPLACE ".*\\\"([^\\\"]*)\\\".*" "\\1" ISL_GIT_HEAD_ID "${GITVERSION_H}") +elseif () + # Unknown revision + set(ISL_GIT_HEAD_ID "UNKNOWN") +endif () + +message(STATUS "isl version: ${ISL_GIT_HEAD_ID}") + +# Enable small integer optimization and imath. We currently do not allow +# configuring them. +set(USE_GMP_FOR_MP OFF) +set(USE_IMATH_FOR_MP ON) +set(USE_SMALL_INT_OPT ON) + +# Determine compiler characteristics +include(CheckCSourceCompiles) + +# Like check_c_source_compiles, but sets the result to either +# 0 (error while compiling) or 1 (compiled successfully) +# Required for compatibility with autotool's AC_CHECK_DECLS +function (check_c_source_compiles_numeric _prog _var) + check_c_source_compiles("${_prog}" "${_var}") + if ("${${_var}}") + set("${_var}" 1 PARENT_SCOPE) + else () + set("${_var}" 0 PARENT_SCOPE) + endif () +endfunction () + +# Check for the existance of a type +function (check_c_type_exists _type _files _variable) + set(_includes "") + foreach (file_name ${_files}) + set(_includes "${_includes}#include<${file_name}>\n") + endforeach() + check_c_source_compiles(" + ${_includes} + ${_type} typeVar; + int main() { + return 0; + } + " ${_variable}) +endfunction () + +check_c_source_compiles(" +int func(void) __attribute__((__warn_unused_result__)); +int main() { return 0; } +" HAS_ATTRIBUTE_WARN_UNUSED_RESULT) +set(GCC_WARN_UNUSED_RESULT) +if (HAS_ATTRIBUTE_WARN_UNUSED_RESULT) + set(GCC_WARN_UNUSED_RESULT "__attribute__((__warn_unused_result__))") +endif () + +check_c_source_compiles(" +__attribute__ ((unused)) static void foo(void); +int main() { return 0; } +" HAVE___ATTRIBUTE__) + +check_c_source_compiles_numeric(" +#include +int main() { (void)ffs(0); return 0; } +" HAVE_DECL_FFS) + +check_c_source_compiles_numeric(" +int main() { (void)__builtin_ffs(0); return 0; } +" HAVE_DECL___BUILTIN_FFS) + +check_c_source_compiles_numeric(" +#include +int main() { (void)_BitScanForward(NULL, 0); return 0; } +" HAVE_DECL__BITSCANFORWARD) + +if (NOT HAVE_DECL_FFS AND + NOT HAVE_DECL___BUILTIN_FFS AND + NOT HAVE_DECL__BITSCANFORWARD) + message(FATAL_ERROR "No ffs implementation found") +endif () + +check_c_source_compiles_numeric(" +#include +int main() { (void)strcasecmp(\"\", \"\"); return 0; } +" HAVE_DECL_STRCASECMP) + +check_c_source_compiles_numeric(" +#include +int main() { (void)_stricmp(\"\", \"\"); return 0; } +" HAVE_DECL__STRICMP) + +if (NOT HAVE_DECL_STRCASECMP AND NOT HAVE_DECL__STRICMP) + message(FATAL_ERROR "No strcasecmp implementation found") +endif () + +check_c_source_compiles_numeric(" +#include +int main() { (void)strncasecmp(\"\", \"\", 0); return 0; } +" HAVE_DECL_STRNCASECMP) + +check_c_source_compiles_numeric(" +#include +int main() { (void)_strnicmp(\"\", \"\", 0); return 0; } +" HAVE_DECL__STRNICMP) + +if (NOT HAVE_DECL_STRNCASECMP AND NOT HAVE_DECL__STRNICMP) + message(FATAL_ERROR "No strncasecmp implementation found") +endif () + +check_c_source_compiles_numeric(" +#include +int main() { snprintf((void*)0, 0, \" \"); return 0; } +" HAVE_DECL_SNPRINTF) + +check_c_source_compiles_numeric(" +#include +int main() { _snprintf((void*)0, 0, \" \"); return 0; } +" HAVE_DECL__SNPRINTF) + +if (NOT HAVE_DECL_SNPRINTF AND NOT HAVE_DECL__SNPRINTF) + message(FATAL_ERROR "No snprintf implementation found") +endif () + +check_c_type_exists(uint8_t "" HAVE_UINT8T) +check_c_type_exists(uint8_t "stdint.h" HAVE_STDINT_H) +check_c_type_exists(uint8_t "inttypes.h" HAVE_INTTYPES_H) +check_c_type_exists(uint8_t "sys/types.h" HAVE_SYS_INTTYPES_H) +if (HAVE_UINT8T) + set(INCLUDE_STDINT_H "") +elseif (HAVE_STDINT_H) + set(INCLUDE_STDINT_H "stdint.h") +elseif (HAVE_INTTYPES_H) + set(INCLUDE_STDINT_H "inttypes.h") +elseif (HAVE_SYS_INTTYPES_H) + set(INCLUDE_STDINT_H "sys/inttypes.h") +else () + message(FATAL_ERROR "No stdint.h or compatible found") +endif () + +# Write probing result. +configure_file("stdint.h.cmake" "${ISL_BINARY_DIR}/include/isl/stdint.h") +configure_file("gitversion.h.cmake" "${ISL_BINARY_DIR}/gitversion.h") +configure_file("isl_config.h.cmake" "${ISL_BINARY_DIR}/isl_config.h") +configure_file("isl_srcdir.c.cmake" "${ISL_BINARY_DIR}/isl_srcdir.c") + +# isl files to compile. +set (ISL_FILES + basis_reduction_tab.c + isl_aff.c + isl_affine_hull.c + isl_arg.c + isl_ast_build.c + isl_ast_build_expr.c + isl_ast.c + isl_ast_codegen.c + isl_ast_graft.c + isl_bernstein.c + isl_blk.c + isl_bound.c + isl_coalesce.c + isl_constraint.c + isl_convex_hull.c + isl_ctx.c + isl_deprecated.c + isl_dim_map.c + isl_equalities.c + isl_factorization.c + isl_farkas.c + isl_ffs.c + isl_flow.c + isl_fold.c + isl_hash.c + isl_id.c + isl_id_to_ast_expr.c + isl_id_to_id.c + isl_id_to_pw_aff.c + isl_ilp.c + isl_imath.c + isl_input.c + isl_int_sioimath.c + isl_local.c + isl_local_space.c + isl_lp.c + isl_map.c + isl_map_list.c + isl_map_simplify.c + isl_map_subtract.c + isl_map_to_basic_set.c + isl_mat.c + isl_morph.c + isl_obj.c + isl_options.c + isl_output.c + isl_point.c + isl_polynomial.c + isl_printer.c + isl_range.c + isl_reordering.c + isl_sample.c + isl_scan.c + isl_schedule.c + isl_schedule_band.c + isl_schedule_constraints.c + isl_schedule_node.c + isl_schedule_read.c + isl_schedule_tree.c + isl_scheduler.c + isl_seq.c + isl_set_list.c + isl_sort.c + isl_space.c + isl_stream.c + isl_tab.c + isl_tab_pip.c + isl_tarjan.c + isl_transitive_closure.c + isl_union_map.c + isl_val.c + isl_val_sioimath.c + isl_vec.c + isl_version.c + isl_vertices.c + print.c + imath/gmp_compat.c + imath/imath.c + imath/imrat.c + ) + +set(ISL_FILES_PATHS) +foreach (srcfile IN LISTS ISL_FILES) + list(APPEND ISL_FILES_PATHS "${ISL_SOURCE_DIR}/${srcfile}") +endforeach () + +add_llvm_library(LLVMISL + ${ISL_FILES_PATHS} + ADDITIONAL_HEADER_DIRS + "${LLVM_MAIN_SRC_DIR}/contrib/isl/include" + "${ISL_BINARY_DIR}" + ) + +# isl requires at least C99 to compile. gcc < 5.0 uses -std=gnu89 as default. +set_target_properties(LLVMISL PROPERTIES C_STANDARD 99) + +target_include_directories(LLVMISL + PRIVATE + "${ISL_BINARY_DIR}" + "${ISL_BINARY_DIR}/include" + "${ISL_SOURCE_DIR}" + "${ISL_SOURCE_DIR}/imath" + PUBLIC + $ + $ + $ + ) + +# Disable warnings for upstream project. +set(ISL_DISABLE_WARNINGS_FLAGS) +if (MSVC) + set(ISL_DISABLE_WARNINGS_FLAGS + -wd4018 # 'expression' : signed/unsigned mismatch + -wd4090 # 'operation' : different 'modifier' qualifiers + -wd4200 # nonstandard extension used: zero-sized array in struct/union + -wd4201 # nonstandard extension used: nameless struct/union + -wd4334 # 'operator': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) + -wd4221 # nonstandard extension used : 'identifier' : cannot be initialized using address of automatic variable + ) +elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_CXX_COMPILER MATCHES ".*clang") + set(ISL_DISABLE_WARNINGS_FLAGS -w) +endif () +target_compile_options(LLVMISL PRIVATE ${ISL_DISABLE_WARNINGS_FLAGS}) + +if (LLVM_INCLUDE_TESTS) + set(LLVM_LINK_COMPONENTS ISL) + add_llvm_executable(isl-test + IGNORE_EXTERNALIZE_DEBUGINFO NO_INSTALL_RPATH + "${ISL_SOURCE_DIR}/isl_test.c" + ) + + # isl-test needs access to private headers. + target_include_directories(isl-test + PRIVATE + "${ISL_BINARY_DIR}" + "${ISL_BINARY_DIR}/include" + "${ISL_SOURCE_DIR}" + "${ISL_SOURCE_DIR}/imath" + ) + + target_compile_options(isl-test PRIVATE ${ISL_DISABLE_WARNINGS_FLAGS}) +endif () Index: lib/ISL/LLVMBuild.txt =================================================================== --- lib/ISL/LLVMBuild.txt +++ lib/ISL/LLVMBuild.txt @@ -1,4 +1,4 @@ -;===- ./lib/LLVMBuild.txt --------------------------------------*- Conf -*--===; +;===- ./lib/isl/LLVMBuild.txt ----------------------------------*- Conf -*--===; ; ; The LLVM Compiler Infrastructure ; @@ -15,37 +15,8 @@ ; ;===------------------------------------------------------------------------===; -[common] -subdirectories = - Analysis - AsmParser - Bitcode - CodeGen - DebugInfo - Demangle - ExecutionEngine - FuzzMutate - LineEditor - Linker - IR - IRReader - LTO - MC - Object - BinaryFormat - ObjectYAML - Option - Passes - ProfileData - Support - TableGen - Target - Testing - ToolDrivers - Transforms - WindowsManifest - [component_0] -type = Group -name = Libraries -parent = $ROOT +type = Library +name = ISL +parent = Libraries +required_libraries = Index: lib/ISL/gitversion.h.cmake =================================================================== --- /dev/null +++ lib/ISL/gitversion.h.cmake @@ -0,0 +1 @@ +#define GIT_HEAD_ID "@ISL_GIT_HEAD_ID@" Index: lib/ISL/isl_config.h.cmake =================================================================== --- /dev/null +++ lib/ISL/isl_config.h.cmake @@ -0,0 +1,51 @@ +/* define if your compiler has __attribute__ */ +#cmakedefine HAVE___ATTRIBUTE__ /**/ + +/* most gcc compilers know a function __attribute__((__warn_unused_result__)) */ +#define GCC_WARN_UNUSED_RESULT @GCC_WARN_UNUSED_RESULT@ + +/* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */ +#define HAVE_DECL_FFS @HAVE_DECL_FFS@ + +/* Define to 1 if you have the declaration of `__builtin_ffs', and to 0 if you + don't. */ +#define HAVE_DECL___BUILTIN_FFS @HAVE_DECL___BUILTIN_FFS@ + +/* Define to 1 if you have the declaration of `_BitScanForward', and to 0 if + you don't. */ +#define HAVE_DECL__BITSCANFORWARD @HAVE_DECL__BITSCANFORWARD@ + +/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you + don't. */ +#define HAVE_DECL_STRCASECMP @HAVE_DECL_STRCASECMP@ + +/* Define to 1 if you have the declaration of `_stricmp', and to 0 if you + don't. */ +#define HAVE_DECL__STRICMP @HAVE_DECL__STRICMP@ + +/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you + don't. */ +#define HAVE_DECL_STRNCASECMP @HAVE_DECL_STRNCASECMP@ + +/* Define to 1 if you have the declaration of `_strnicmp', and to 0 if you + don't. */ +#define HAVE_DECL__STRNICMP @HAVE_DECL__STRNICMP@ + +/* Define to 1 if you have the declaration of `snprintf', and to 0 if you + don't. */ +#define HAVE_DECL_SNPRINTF @HAVE_DECL_SNPRINTF@ + +/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you + don't. */ +#define HAVE_DECL__SNPRINTF @HAVE_DECL__SNPRINTF@ + +/* use gmp to implement isl_int */ +#cmakedefine USE_GMP_FOR_MP + +/* use imath to implement isl_int */ +#cmakedefine USE_IMATH_FOR_MP + +/* Use small integer optimization */ +#cmakedefine USE_SMALL_INT_OPT + +#include Index: lib/ISL/isl_srcdir.c.cmake =================================================================== --- /dev/null +++ lib/ISL/isl_srcdir.c.cmake @@ -0,0 +1 @@ +static const char *srcdir = "@ISL_SOURCE_DIR@"; Index: lib/ISL/stdint.h.cmake =================================================================== --- /dev/null +++ lib/ISL/stdint.h.cmake @@ -0,0 +1 @@ +#include <@INCLUDE_STDINT_H@> Index: lib/LLVMBuild.txt =================================================================== --- lib/LLVMBuild.txt +++ lib/LLVMBuild.txt @@ -44,6 +44,7 @@ ToolDrivers Transforms WindowsManifest + ISL [component_0] type = Group Index: test/CMakeLists.txt =================================================================== --- test/CMakeLists.txt +++ test/CMakeLists.txt @@ -117,6 +117,10 @@ set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} LTO) endif() +if (TARGET ISL) + set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} isl-test) +endif() + if(LLVM_BUILD_EXAMPLES) list(APPEND LLVM_TEST_DEPENDS Kaleidoscope-Ch3 Index: test/UnitISL/isl-test.test =================================================================== --- /dev/null +++ test/UnitISL/isl-test.test @@ -0,0 +1 @@ +; RUN: isl-test Index: tools/llvm-config/BuildVariables.inc.in =================================================================== --- tools/llvm-config/BuildVariables.inc.in +++ tools/llvm-config/BuildVariables.inc.in @@ -35,3 +35,4 @@ #define LLVM_DYLIB_VERSION "@LLVM_DYLIB_VERSION@" #define LLVM_HAS_GLOBAL_ISEL @LLVM_HAS_GLOBAL_ISEL@ #define LLVM_TOOLS_INSTALL_DIR "@LLVM_TOOLS_INSTALL_DIR@" +#define LLVM_INCLUDE_ISL @LLVM_INCLUDE_ISL@ Index: tools/llvm-config/CMakeLists.txt =================================================================== --- tools/llvm-config/CMakeLists.txt +++ tools/llvm-config/CMakeLists.txt @@ -49,7 +49,8 @@ LLVM_LINK_LLVM_DYLIB LLVM_HAS_RTTI LLVM_HAS_GLOBAL_ISEL - BUILD_SHARED_LIBS) + BUILD_SHARED_LIBS + LLVM_INCLUDE_ISL) configure_file(${BUILDVARIABLES_SRCPATH} ${BUILDVARIABLES_OBJPATH} @ONLY) # Set build-time environment(s). Index: tools/llvm-config/llvm-config.cpp =================================================================== --- tools/llvm-config/llvm-config.cpp +++ tools/llvm-config/llvm-config.cpp @@ -330,6 +330,11 @@ // We need to include files from both the source and object trees. ActiveIncludeOption = ("-I" + ActiveIncludeDir + " " + "-I" + ActiveObjRoot + "/include"); +#if LLVM_INCLUDE_ISL + ActiveIncludeOption += + (" -I" + std::string(LLVM_SRC_ROOT) + "/contrib/isl/include" + " -I" + + ActiveLibDir + "/ISL/isl/include"); +#endif } else { ActivePrefix = CurrentExecPrefix; ActiveIncludeDir = ActivePrefix + "/include"; @@ -338,7 +343,10 @@ ActiveBinDir = path.str(); ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX; ActiveCMakeDir = ActiveLibDir + "/cmake/llvm"; - ActiveIncludeOption = "-I" + ActiveIncludeDir; + ActiveIncludeOption = ActiveIncludeOption = "-I" + ActiveIncludeDir; +#if LLVM_INCLUDE_ISL + ActiveIncludeOption += " -I" + ActiveIncludeDir + "/llvm/ISL"; +#endif } /// We only use `shared library` mode in cases where the static library form