Introduce a CMakefile scaffolding to build and test an executable.

This also updates the README to include some building information.

Lots of caveats:
 - This is all experimental
 - The actual tool isn't interesting yet.
 - The naming is arbitrary and will likely change.
 - Much of the cmake files were cargo culted from other places
   because I don't know what I'm doing.
This commit is contained in:
Chris Lattner 2020-03-05 15:16:55 -08:00
parent 2d02904135
commit 64cec97240
11 changed files with 449 additions and 2 deletions

63
CMakeLists.txt Normal file
View File

@ -0,0 +1,63 @@
# SPT project.
set(SPT_MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include ) # --src-root
set(SPT_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) # --includedir
set(SPT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SPT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
include(AddSPT)
# Installing the headers and docs needs to depend on generating any public
# tablegen'd targets.
add_custom_target(spt-headers)
set_target_properties(spt-headers PROPERTIES FOLDER "Misc")
add_custom_target(spt-doc)
include_directories( "include")
include_directories( ${SPT_INCLUDE_DIR})
#add_subdirectory(include/spt)
#add_subdirectory(lib)
add_subdirectory(tools)
#add_subdirectory(unittests)
add_subdirectory(test)
#option(SPT_INCLUDE_DOCS "Generate build targets for the SPT docs."
# ${LLVM_INCLUDE_DOCS} ${MLIR_INCLUDE_DOCS})
#if (SPT_INCLUDE_DOCS)
# add_subdirectory(docs)
#endif()
install(DIRECTORY include/spt
DESTINATION include
COMPONENT spt-headers
FILES_MATCHING
PATTERN "*.def"
PATTERN "*.h"
PATTERN "*.inc"
PATTERN "*.td"
PATTERN "LICENSE.TXT"
)
install(DIRECTORY ${SPT_INCLUDE_DIR}/spt
DESTINATION include
COMPONENT spt-headers
FILES_MATCHING
PATTERN "*.def"
PATTERN "*.h"
PATTERN "*.gen"
PATTERN "*.inc"
PATTERN "*.td"
PATTERN "CMakeFiles" EXCLUDE
PATTERN "config.h" EXCLUDE
)
if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-spt-headers
DEPENDS spt-headers
COMPONENT spt-headers)
endif()
add_subdirectory(cmake/modules)

View File

@ -1,2 +1,51 @@
# clattner-test
Chris Lattner's psychic pancake
# clattner-test / spt
This is a test repository, experimenting with an approach of building a modular set of tools
for verilog and other SiFive related projects.
SPT is just a placeholder, "SiFive Platform Tools", better suggestion welcome :-)
## Setting this up
These are the commands Chris used to set this up on a Mac:
1) Install Dependences of LLVM/MLIR according to [the
instructions](https://mlir.llvm.org/getting_started/), including cmake and ninja.
2) Check out LLVM and SPT repo's:
```
$ cd ~/Projects
$ git clone git@github.com:llvm/llvm-project.git
$ git clone git@github.com:sifive/clattner-experimental.git spt
```
3) HACK: Add symlink because I can't figure out how to get LLVM_EXTERNAL_SPT_SOURCE_DIR to work with cmake:
```
$ cd ~/Projects/llvm-project
$ ln -s ../spt spt
```
4) Configure the build to build MLIR and SPT (MLIR is probably not necessary, but it builds
reasonably fast and is good to provide a sanity check that things are working):
```
$ cd ~/Projects/llvm-project
$ mkdir build
$ cd build
$ cmake -G Ninja ../llvm -DLLVM_EXTERNAL_PROJECTS="spt" -DLLVM_EXTERNAL_SPT_SOURCE_DIR=/Users/chrisl/Projects/spt -DLLVM_ENABLE_PROJECTS="mlir;spt" -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON
```
5) Build MLIR and run MLIR tests as a smoketest:
```
$ ninja check-mlir
```
6) Build SPT and run SPT tests:
```
$ ninja check-spt
```

View File

@ -0,0 +1,62 @@
#function(spt_tablegen ofn)
# tablegen(SPT ${ARGV} "-I${SPT_MAIN_SRC_DIR}" "-I${SPT_INCLUDE_DIR}")
# set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
# PARENT_SCOPE)
#endfunction()
# TODO: This is to handle the current static registration, but should be
# factored out a bit.
#function(whole_archive_link target)
# add_dependencies(${target} ${ARGN})
# if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
# set(link_flags "-L${CMAKE_BINARY_DIR}/lib ")
# FOREACH(LIB ${ARGN})
# string(CONCAT link_flags ${link_flags} "-Wl,-force_load ${CMAKE_BINARY_DIR}/lib/lib${LIB}.a ")
# ENDFOREACH(LIB)
# elseif(MSVC)
# FOREACH(LIB ${ARGN})
# string(CONCAT link_flags ${link_flags} "/WHOLEARCHIVE:${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib/${LIB}.lib ")
# ENDFOREACH(LIB)
# else()
# set(link_flags "-L${CMAKE_BINARY_DIR}/lib -Wl,--whole-archive,")
# FOREACH(LIB ${ARGN})
# string(CONCAT link_flags ${link_flags} "-l${LIB},")
# ENDFOREACH(LIB)
# string(CONCAT link_flags ${link_flags} "--no-whole-archive")
# endif()
# set_target_properties(${target} PROPERTIES LINK_FLAGS ${link_flags})
#endfunction(whole_archive_link)
# Declare a dialect in the include directory
#function(add_mlir_dialect dialect dialect_doc_filename)
# set(LLVM_TARGET_DEFINITIONS ${dialect}.td)
# mlir_tablegen(${dialect}.h.inc -gen-op-decls)
# mlir_tablegen(${dialect}.cpp.inc -gen-op-defs)
# add_public_tablegen_target(MLIR${dialect}IncGen)
# add_dependencies(mlir-headers MLIR${dialect}IncGen)
# # Generate Dialect Documentation
# set(LLVM_TARGET_DEFINITIONS ${dialect_doc_filename}.td)
# tablegen(MLIR ${dialect_doc_filename}.md -gen-op-doc "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}")
# set(GEN_DOC_FILE ${MLIR_BINARY_DIR}/docs/Dialects/${dialect_doc_filename}.md)
# add_custom_command(
# OUTPUT ${GEN_DOC_FILE}
# COMMAND ${CMAKE_COMMAND} -E copy
# ${CMAKE_CURRENT_BINARY_DIR}/${dialect_doc_filename}.md
# ${GEN_DOC_FILE}
# DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${dialect_doc_filename}.md)
# add_custom_target(${dialect_doc_filename}DocGen DEPENDS ${GEN_DOC_FILE})
# add_dependencies(mlir-doc ${dialect_doc_filename}DocGen)
#endfunction()
# Declare the library associated with a dialect.
#function(add_mlir_dialect_library name)
# set_property(GLOBAL APPEND PROPERTY MLIR_DIALECT_LIBS ${name})
# add_llvm_library(${ARGV})
#endfunction(add_mlir_dialect_library)
# Declare the library associated with a conversion.
#function(add_mlir_conversion_library name)
# set_property(GLOBAL APPEND PROPERTY MLIR_CONVERSION_LIBS ${name})
# add_llvm_library(${ARGV})
#endfunction(add_mlir_conversion_library)

View File

@ -0,0 +1,67 @@
# Generate a list of CMake library targets so that other CMake projects can
# link against them. LLVM calls its version of this file LLVMExports.cmake, but
# the usual CMake convention seems to be ${Project}Targets.cmake.
set(SPT_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm)
set(spt_cmake_builddir "${CMAKE_BINARY_DIR}/${SPT_INSTALL_PACKAGE_DIR}")
# Keep this in sync with llvm/cmake/CMakeLists.txt!
set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm)
set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}")
get_property(SPT_EXPORTS GLOBAL PROPERTY SPT_EXPORTS)
export(TARGETS ${SPT_EXPORTS} FILE ${spt_cmake_builddir}/SptTargets.cmake)
# Generate SptConfig.cmake for the build tree.
set(SPT_CONFIG_CMAKE_DIR "${spt_cmake_builddir}")
set(SPT_CONFIG_LLVM_CMAKE_DIR "${llvm_cmake_builddir}")
set(SPT_CONFIG_EXPORTS_FILE "${spt_cmake_builddir}/SptTargets.cmake")
set(SPT_CONFIG_INCLUDE_DIRS
"${SPT_SOURCE_DIR}/include"
"${SPT_BINARY_DIR}/include"
)
set(SPT_CONFIG_CMAKE_DIR)
set(SPT_CONFIG_LLVM_CMAKE_DIR)
set(SPT_CONFIG_EXPORTS_FILE)
# Generate SptConfig.cmake for the install tree.
set(SPT_CONFIG_CODE "
# Compute the installation prefix from this LLVMConfig.cmake file location.
get_filename_component(SPT_INSTALL_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)")
# Construct the proper number of get_filename_component(... PATH)
# calls to compute the installation prefix.
string(REGEX REPLACE "/" ";" _count "${SPT_INSTALL_PACKAGE_DIR}")
foreach(p ${_count})
set(SPT_CONFIG_CODE "${SPT_CONFIG_CODE}
get_filename_component(SPT_INSTALL_PREFIX \"\${SPT_INSTALL_PREFIX}\" PATH)")
endforeach(p)
set(SPT_CONFIG_CMAKE_DIR "\${SPT_INSTALL_PREFIX}/${SPT_INSTALL_PACKAGE_DIR}")
set(SPT_CONFIG_LLVM_CMAKE_DIR "\${SPT_INSTALL_PREFIX}/${LLVM_INSTALL_PACKAGE_DIR}")
set(SPT_CONFIG_EXPORTS_FILE "\${SPT_CMAKE_DIR}/SptTargets.cmake")
set(SPT_CONFIG_INCLUDE_DIRS
"\${SPT_INSTALL_PREFIX}/include"
)
set(SPT_CONFIG_CODE)
set(SPT_CONFIG_CMAKE_DIR)
set(SPT_CONFIG_EXPORTS_FILE)
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
# Not TOOLCHAIN ONLY, so install the SPT parts as well
# Include the cmake files so other tools can use spt-tblgen, etc.
get_property(spt_has_exports GLOBAL PROPERTY SPT_HAS_EXPORTS)
if(spt_has_exports)
install(EXPORT SptTargets DESTINATION ${SPT_INSTALL_PACKAGE_DIR}
COMPONENT spt-cmake-exports)
endif()
install(FILES #${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/SptConfig.cmake
${CMAKE_CURRENT_SOURCE_DIR}/AddSPT.cmake
DESTINATION ${SPT_INSTALL_PACKAGE_DIR}
COMPONENT spt-cmake-exports)
if(NOT LLVM_ENABLE_IDE)
# Add a dummy target so this can be used with LLVM_DISTRIBUTION_COMPONENTS
add_custom_target(spt-cmake-exports)
add_llvm_install_targets(install-spt-cmake-exports
COMPONENT spt-cmake-exports)
endif()
endif()

21
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,21 @@
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
MAIN_CONFIG
${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
)
set(SPT_TEST_DEPENDS
FileCheck count not
spt-opt
)
add_lit_testsuite(check-spt "Running the SPT regression tests"
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${SPT_TEST_DEPENDS}
)
set_target_properties(check-spt PROPERTIES FOLDER "Tests")
add_lit_testsuites(SPT ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${SPT_TEST_DEPS}
)

59
test/lit.cfg.py Normal file
View File

@ -0,0 +1,59 @@
# -*- Python -*-
import os
import platform
import re
import subprocess
import tempfile
import lit.formats
import lit.util
from lit.llvm import llvm_config
from lit.llvm.subst import ToolSubst
from lit.llvm.subst import FindTool
# Configuration file for the 'lit' test runner.
# name: The name of this test suite.
config.name = 'SPT'
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.td', '.mlir', '.ll']
# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
# test_exec_root: The root path where tests should be run.
config.test_exec_root = os.path.join(config.spt_obj_root, 'test')
config.substitutions.append(('%PATH%', config.environment['PATH']))
config.substitutions.append(('%shlibext', config.llvm_shlib_ext))
llvm_config.with_system_environment(
['HOME', 'INCLUDE', 'LIB', 'TMP', 'TEMP'])
llvm_config.use_default_substitutions()
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']
# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)
# test_exec_root: The root path where tests should be run.
config.test_exec_root = os.path.join(config.spt_obj_root, 'test')
# Tweak the PATH to include the tools dir.
llvm_config.with_environment('PATH', config.llvm_tools_dir, append_path=True)
tool_dirs = [config.spt_tools_dir, config.mlir_tools_dir, config.llvm_tools_dir]
tools = [
'spt-opt',
]
llvm_config.add_tool_substitutions(tools, tool_dirs)

52
test/lit.site.cfg.py.in Normal file
View File

@ -0,0 +1,52 @@
@LIT_SITE_CFG_IN_HEADER@
import sys
config.host_triple = "@LLVM_HOST_TRIPLE@"
config.target_triple = "@TARGET_TRIPLE@"
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@"
config.llvm_shlib_dir = "@SHLIBDIR@"
config.llvm_shlib_ext = "@SHLIBEXT@"
config.llvm_exe_ext = "@EXEEXT@"
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.python_executable = "@PYTHON_EXECUTABLE@"
config.gold_executable = "@GOLD_EXECUTABLE@"
config.ld64_executable = "@LD64_EXECUTABLE@"
config.enable_shared = @ENABLE_SHARED@
config.enable_assertions = @ENABLE_ASSERTIONS@
config.targets_to_build = "@TARGETS_TO_BUILD@"
config.native_target = "@LLVM_NATIVE_ARCH@"
config.llvm_bindings = "@LLVM_BINDINGS@".split(' ')
config.host_os = "@HOST_OS@"
config.host_cc = "@HOST_CC@"
config.host_cxx = "@HOST_CXX@"
# Note: ldflags can contain double-quoted paths, so must use single quotes here.
config.host_ldflags = '@HOST_LDFLAGS@'
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
config.llvm_host_triple = '@LLVM_HOST_TRIPLE@'
config.host_arch = "@HOST_ARCH@"
config.mlir_src_root = "@MLIR_SOURCE_DIR@"
config.mlir_obj_root = "@MLIR_BINARY_DIR@"
config.mlir_tools_dir = "@MLIR_TOOLS_DIR@"
config.spt_src_root = "@SPT_SOURCE_DIR@"
config.spt_obj_root = "@SPT_BINARY_DIR@"
config.spt_tools_dir = "@SPT_TOOLS_DIR@"
# Support substitution of the tools_dir 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_shlib_dir = config.llvm_shlib_dir % 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))
import lit.llvm
lit.llvm.initialize(lit_config, config)
# Let the main config do the real work.
lit_config.load_config(config, "@SPT_SOURCE_DIR@/test/lit.cfg.py")

View File

@ -0,0 +1,3 @@
// RUN: spt-opt --help | FileCheck %s
//
// CHECK: OVERVIEW: spt modular optimizer driver

2
tools/CMakeLists.txt Normal file
View File

@ -0,0 +1,2 @@
add_subdirectory(spt-opt)

View File

@ -0,0 +1,52 @@
set(LIB_LIBS
MLIRAnalysis
MLIRLLVMIR
MLIROptLib
MLIRParser
MLIRPass
MLIRTransforms
MLIRSupport
)
add_llvm_library(SPTSptOptMain
spt-opt.cpp
)
target_link_libraries(SPTSptOptMain
${LIB_LIBS}
)
#get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
#get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS)
set(LIBS
# ${dialect_libs}
# ${conversion_libs}
MLIRDialect
MLIRParser
MLIRPass
MLIRTransforms
MLIRTransformUtils
MLIRSupport
MLIRIR
MLIROptLib
LLVMSupport
LLVMCore
LLVMAsmParser
)
add_llvm_tool(spt-opt
spt-opt.cpp
)
# Manually expand the target library, since our SPT libraries
# aren't plugged into the LLVM dependency tracking. If we don't
# do this then we can't insert the CodeGen library after ourselves
llvm_expand_pseudo_components(TARGET_LIBS AllTargetsCodeGens)
# Prepend LLVM in front of every target, this is how the library
# are named with CMake
SET(targets_to_link)
FOREACH(t ${TARGET_LIBS})
LIST(APPEND targets_to_link "LLVM${t}")
ENDFOREACH(t)
llvm_update_compile_flags(spt-opt)
target_link_libraries(spt-opt PRIVATE ${LIBS} ${targets_to_link})

17
tools/spt-opt/spt-opt.cpp Normal file
View File

@ -0,0 +1,17 @@
//===- spt-opt.cpp - The spt-opt driver -----------------------------------===//
//
// This file implements the 'spt-opt' tool, which is the spt analog of mlir-opt,
// used to drive compiler passes, e.g. for testing.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/CommandLine.h"
using namespace llvm;
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, "spt modular optimizer driver\n");
// TODO: Implement stuff! :-)
return 0;
}