Skip to content

Commit

Permalink
Introduce unittests.
Browse files Browse the repository at this point in the history
Add the infrastructure for unittests to Polly and two simple tests for
conversion between isl_val and APInt. In addition, a build target
check-polly-unittests is added to run only the unittests but not the regression
tests.

Clang's unittest mechanism served as as a blueprint which then was adapted to
Polly.

Differential Revision: https://reviews.llvm.org/D23833

llvm-svn: 279734
  • Loading branch information
Meinersbur committed Aug 25, 2016
1 parent 0e63ab4 commit 05cf9c2
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 3 deletions.
31 changes: 29 additions & 2 deletions polly/CMakeLists.txt
Expand Up @@ -88,9 +88,33 @@ if (NOT DEFINED LLVM_MAIN_SRC_DIR)
endif()
endif()

# Sources available, too?
execute_process(COMMAND "${LLVM_INSTALL_ROOT}/bin/llvm-config" --src-root
OUTPUT_VARIABLE MAIN_SRC_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LLVM_SOURCE_ROOT ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")

# Enable unit tests if available.
set(UNITTEST_DIR ${LLVM_SOURCE_ROOT}/utils/unittest)
if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h)
add_library(gtest ${UNITTEST_DIR}/googletest/src/gtest-all.cc)
target_include_directories(gtest PUBLIC "${UNITTEST_DIR}/googletest/include" PRIVATE "${UNITTEST_DIR}/googletest")
if( NOT MSVC )
target_link_libraries(gtest pthread tinfo dl)
endif ()

add_library(gtest_main ${UNITTEST_DIR}/UnitTestMain/TestMain.cpp)
target_link_libraries(gtest_main gtest)

set(POLLY_GTEST_AVAIL 1)
endif()

# Make sure the isl c files are built as fPIC
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
endif(NOT DEFINED LLVM_MAIN_SRC_DIR)
else ()
set(LLVM_SOURCE_ROOT "${LLVM_MAIN_SRC_DIR}")
set(POLLY_GTEST_AVAIL 1)
endif ()

set(POLLY_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(POLLY_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
Expand Down Expand Up @@ -169,6 +193,9 @@ add_definitions( -D_GNU_SOURCE )
add_subdirectory(docs)
add_subdirectory(lib)
add_subdirectory(test)
if (POLLY_GTEST_AVAIL)
add_subdirectory(unittests)
endif ()
add_subdirectory(tools)
# TODO: docs.

Expand All @@ -177,7 +204,7 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/include/polly/Config/config.h.cmake
${POLLY_BINARY_DIR}/include/polly/Config/config.h )

# Add target to check formatting of polly files
file( GLOB_RECURSE files *.h lib/*.cpp lib/*.c tools/*.cpp tools/*.c tools/*.h)
file( GLOB_RECURSE files *.h lib/*.cpp lib/*.c tools/*.cpp tools/*.c tools/*.h unittests/*.cpp)
file( GLOB_RECURSE jsonfiles lib/JSON/*.h lib/JSON/*.cpp)
file( GLOB_RECURSE external lib/External/*.h lib/External/*.c)
list( REMOVE_ITEM files ${jsonfiles} ${external})
Expand Down
42 changes: 41 additions & 1 deletion polly/test/CMakeLists.txt
Expand Up @@ -18,6 +18,9 @@ if (NOT DEFINED LLVM_MAIN_SRC_DIR)
# FIXME: FileCheck is not available in llvm install directory at the moment.
set(LLVM_LIT ${LLVM_INSTALL_ROOT}/bin/llvm-lit)
set(POLLY_TEST_DEPS LLVMPolly)
if (POLLY_GTEST_AVAIL)
list(APPEND POLLY_TEST_DEPS PollyUnitTests)
endif ()

set(LLVM_BINARY_DIR "${LLVM_INSTALL_ROOT}")
set(LLVM_TOOLS_DIR "${LLVM_INSTALL_ROOT}/bin")
Expand Down Expand Up @@ -67,18 +70,38 @@ if (NOT DEFINED LLVM_MAIN_SRC_DIR)
add_custom_target(check-polly
COMMAND ${LLVM_LIT}
--param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
--param polly_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
--param build_config=${CMAKE_CFG_INTDIR}
-sv ${POLLY_TEST_EXTRA_ARGS}
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${POLLY_TEST_DEPS}
COMMENT "Running Polly regression tests")
COMMENT "Running Polly regression/unit tests")
set_target_properties(check-polly PROPERTIES FOLDER "Polly")

if (POLLY_GTEST_AVAIL)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg)

add_custom_target(check-polly-unittests
COMMAND ${LLVM_LIT}
--param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
--param build_config=${CMAKE_CFG_INTDIR}
-sv ${POLLY_TEST_EXTRA_ARGS}
${CMAKE_CURRENT_BINARY_DIR}/Unit
DEPENDS PollyUnitTests
COMMENT "Running Polly unit tests")
set_target_properties(check-polly-unittests PROPERTIES FOLDER "Polly")
endif ()
endif()

else (NOT DEFINED LLVM_MAIN_SRC_DIR)

set(LLVM_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit)
set(POLLY_TEST_DEPS llvm-config opt LLVMPolly FileCheck not)
if (POLLY_GTEST_AVAIL)
list(APPEND POLLY_TEST_DEPS PollyUnitTests)
endif ()

set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}")
set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}")
Expand All @@ -89,14 +112,31 @@ else (NOT DEFINED LLVM_MAIN_SRC_DIR)
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)

# Run regression and unit tests
add_lit_testsuite(check-polly "Running polly regression tests"
${CMAKE_CURRENT_BINARY_DIR}
PARAMS polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
polly_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
DEPENDS ${POLLY_TEST_DEPS}
)

set_target_properties(check-polly PROPERTIES FOLDER "Polly")

if (POLLY_GTEST_AVAIL)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
)

# Run only unit tests
add_lit_testsuite(check-polly-unittests "Running polly unit tests only"
${CMAKE_CURRENT_BINARY_DIR}/Unit
PARAMS polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
DEPENDS PollyUnitTests
)
set_target_properties(check-polly-unittests PROPERTIES FOLDER "Polly")
endif ()

# Run polly-check-format as part of polly-check only if we are compiling with
# clang, so clang-format is availbale.
# if (TARGET clang-format) would be preferable, but this target is only added
Expand Down
108 changes: 108 additions & 0 deletions polly/test/Unit/lit.cfg
@@ -0,0 +1,108 @@
# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import platform

import lit.formats
import lit.util

# name: The name of this test suite.
config.name = 'Polly-Unit'

# suffixes: A list of file extensions to treat as test files.
config.suffixes = []

# test_source_root: The root path where tests are located.
# test_exec_root: The root path where tests should be run.
polly_obj_root = getattr(config, 'polly_obj_root', None)
if polly_obj_root is not None:
config.test_exec_root = os.path.join(polly_obj_root, 'unittests')
config.test_source_root = config.test_exec_root

# testFormat: The test format to use to interpret tests.
llvm_build_mode = getattr(config, 'llvm_build_mode', "Debug")
config.test_format = lit.formats.GoogleTest(llvm_build_mode, 'Tests')

# Propagate the temp directory. Windows requires this because it uses \Windows\
# if none of these are present.
if 'TMP' in os.environ:
config.environment['TMP'] = os.environ['TMP']
if 'TEMP' in os.environ:
config.environment['TEMP'] = os.environ['TEMP']

# Propagate path to symbolizer for ASan/MSan.
for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
if symbolizer in os.environ:
config.environment[symbolizer] = os.environ[symbolizer]

###

# Check that the object root is known.
if config.test_exec_root is None:
# Otherwise, we haven't loaded the site specific configuration (the user is
# probably trying to run on a test file directly, and either the site
# configuration hasn't been created by the build system, or we are in an
# out-of-tree build situation).

# Check for 'polly_unit_site_config' user parameter, and use that if available.
site_cfg = lit_config.params.get('polly_unit_site_config', None)
if site_cfg and os.path.exists(site_cfg):
lit_config.load_config(config, site_cfg)
raise SystemExit

# Try to detect the situation where we are using an out-of-tree build by
# looking for 'llvm-config'.
#
# FIXME: I debated (i.e., wrote and threw away) adding logic to
# automagically generate the lit.site.cfg if we are in some kind of fresh
# build situation. This means knowing how to invoke the build system
# though, and I decided it was too much magic.

llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
if not llvm_config:
lit_config.fatal('No site specific configuration available!')

# Get the source and object roots.
llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
polly_src_root = os.path.join(llvm_src_root, "tools", "polly")
polly_obj_root = os.path.join(llvm_obj_root, "tools", "polly")

# Validate that we got a tree which points to here, using the standard
# tools/clang layout.
this_src_root = os.path.join(os.path.dirname(__file__),'..','..')
if os.path.realpath(polly_src_root) != os.path.realpath(this_src_root):
lit_config.fatal('No site specific configuration available!')

# Check that the site specific configuration exists.
site_cfg = os.path.join(polly_obj_root, 'test', 'Unit', 'lit.site.cfg')
if not os.path.exists(site_cfg):
lit_config.fatal('No site specific configuration available!')

# Okay, that worked. Notify the user of the automagic, and reconfigure.
lit_config.note('using out-of-tree build at %r' % polly_obj_root)
lit_config.load_config(config, site_cfg)
raise SystemExit

shlibpath_var = ''
if platform.system() == 'Linux':
shlibpath_var = 'LD_LIBRARY_PATH'
elif platform.system() == 'Darwin':
shlibpath_var = 'DYLD_LIBRARY_PATH'
elif platform.system() == 'Windows':
shlibpath_var = 'PATH'

# Point the dynamic loader at dynamic libraries in 'lib'.
llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
if not llvm_libs_dir:
lit_config.fatal('No LLVM libs dir set!')
shlibpath = os.path.pathsep.join((llvm_libs_dir,
config.environment.get(shlibpath_var,'')))

# Win32 seeks DLLs along %PATH%.
if sys.platform in ['win32', 'cygwin'] and os.path.isdir(config.shlibdir):
shlibpath = os.path.pathsep.join((config.shlibdir, shlibpath))

config.environment[shlibpath_var] = shlibpath
31 changes: 31 additions & 0 deletions polly/test/Unit/lit.site.cfg.in
@@ -0,0 +1,31 @@
@LIT_SITE_CFG_IN_HEADER@

import sys

config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
config.llvm_build_mode = "@LLVM_BUILD_MODE@"
config.polly_obj_root = "@POLLY_BINARY_DIR@"
config.polly_lib_dir = "@POLLY_LIB_DIR@"
config.enable_shared = @ENABLE_SHARED@
config.shlibdir = "@SHLIBDIR@"
config.target_triple = "@TARGET_TRIPLE@"
config.enable_gpgpu_codegen = "@GPU_CODEGEN@"
config.link_polly_into_tools = "@LINK_POLLY_INTO_TOOLS@"

# Support substitution of the tools_dir, libs_dirs, and build_mode with user
# parameters. This is used when we can't determine the tool dir at
# configuration time.
try:
config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
config.llvm_build_mode = config.llvm_build_mode % lit_config.params
except KeyError:
e = sys.exc_info()[1]
key, = e.args
lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))

# Let the main config do the real work.
lit_config.load_config(config, "@POLLY_SOURCE_DIR@/test/Unit/lit.cfg")
22 changes: 22 additions & 0 deletions polly/unittests/CMakeLists.txt
@@ -0,0 +1,22 @@
add_custom_target(PollyUnitTests)
set_target_properties(PollyUnitTests PROPERTIES FOLDER "Polly")

# add_polly_unittest(test_dirname file1.cpp file2.cpp)
#
# Will compile the list of files together and link against Polly and its dependences.
function(add_polly_unittest test_name)
if(COMMAND add_unittest)
add_unittest(PollyUnitTests ${test_name} ${ARGN})
else()
add_executable(${test_name} ${ARGN})
set_target_properties(${test_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

target_link_libraries(${test_name} gtest_main gtest)
add_dependencies(PollyUnitTests ${test_name})

set_property(TARGET ${test_name} PROPERTY FOLDER "Polly")
endif()
target_link_libraries(${test_name} Polly LLVMCore LLVMSupport)
endfunction()

add_subdirectory(Isl)
3 changes: 3 additions & 0 deletions polly/unittests/Isl/CMakeLists.txt
@@ -0,0 +1,3 @@
add_polly_unittest(IslTests
IslTest.cpp
)

0 comments on commit 05cf9c2

Please sign in to comment.