diff --git a/doc/make/split-stack.md b/doc/make/split-stack.md new file mode 100644 index 000000000..2e9a05ae5 --- /dev/null +++ b/doc/make/split-stack.md @@ -0,0 +1,120 @@ +Compiling Lean with Split Stacks +================================ + +[Split stacks](http://gcc.gnu.org/wiki/SplitStacks) is a relatively +new feature in gcc. It allows the stack to grown automatically as +needed. There is a small performance penalty since the program stack +is stored in the heap. However, we multiple threads, each starting +with a small stack, and have the stack grow and shrink as required by +the program. + +In principle, it is possible to build a program that uses split-stacks +with libraries that do not. However, it did not work in our experiments. +To be able to compile Lean with split-stacks, we also have to compile +GMP, MPFR and Lua using split-stacks. + +We also had to use the [gold linker](http://en.wikipedia.org/wiki/Gold_(linker)). + +Gold linker +----------- + +The gold linker is called `ld.gold` (in our test system). On Ubuntu, you +can install it by executing + + sudo apt-get install binutils-gold + +Before we compiled GMP, MPFR, Lua, and Lean, we created an alias + + alias ld=ld.gold + +If everything is working correctly, when we execute `ld --version`, we should +get an output like the following one: + + GNU gold (GNU Binutils for Ubuntu 2.22) 1.11 + Copyright 2011 Free Software Foundation, Inc. + ... + +Compiling GMP using split-stacks +-------------------------------- + +- Download GMP from [https://gmplib.org](https://gmplib.org/) +- Uncompress the gmp tar-ball at `$HOME/tools` +- Configure it using + + ./configure CFLAGS=-fsplit-stack --prefix=$HOME/tools/split-stack --enable-static + +- Build + + make + +- Install + + make install + +We should have the file `libgmp.a` at `$HOME/tools/split-stack/lib`. + +Compiling MPFR using split-stacks +---------------------------------- + +- Download MPFR from [http://www.mpfr.org/](http://www.mpfr.org/) +- Uncompress the mpfr tar-ball at `$HOME/tools` +- Configure it using + + ./configure CFLAGS=-fsplit-stack --prefix=$HOME/tools/split-stack --with-gmp-include=$HOME/tools/split-stack/include --with-gmp-lib=$HOME/tools/split-stack/lib --enable-static + +Make sure MPFR does not produce any warning/error message + +- Build + + make + +- Install + + make install + +We should have the file `libmpfr.a` at `$HOME/tools/split-stack/lib`. + +Compiling Lua using split-stacks +-------------------------------- + +- Download Lua from [http://www.lua.org/](http://www.lua.org/) +- Uncompress the Lua tar-ball at `$HOME/tools` +- Modify the following line in the file `src/Makefile` in the Lua directory + + CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) + + We should include the option `-fsplit-stack` + + CFLAGS= -O2 -fsplit-stack -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) + +- Build + + make linux + +- Install + + make linux install INSTALL_TOP=$HOME/tools/split-stack + +We should have the file `liblua.a` at `$HOME/tools/split-stack/lib`. + +Compiling Lean using split-stacks +-------------------------------- + +- Go to the Lean directory +- Create the folder `build/release` + + mkdir build/release + +- Configure it using + + cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_COMPILER=g++ -D TCMALLOC=OFF -D LUA_LIBRARIES=$HOME/tools/split-stack/lib/liblua.a -D LUA_INCLUDE_DIR=$HOME/tool/split-stack/include -D GMP_INCLUDE_DIR=$HOME/tools/split-stack/include -D GMP_LIBRARIES=$HOME/tools/split-stack/lib/libgmp.a -D MPFR_LIBRARIES=$HOME/tools/split-stack/lib/libmpfr.a ../../src + +Remark: if you have ninja build tool installed in your system, you can also provide `-G Ninja` + +- Build + + make + +- Test it + + yes "C" | ctest diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 293776a75..c6728f043 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ option(TRACK_MEMORY_USAGE "TRACK_MEMORY_USAGE" ON) option(MULTI_THREAD "MULTI_THREAD" ON) option(BOOST "BOOST" OFF) option(STATIC "STATIC" OFF) +option(SPLIT_STACK "SPLIT_STACK" OFF) # Added for CTest INCLUDE(CTest) @@ -49,6 +50,16 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") +# SPLIT_STACK +if ("${SPLIT_STACK}" MATCHES "ON") + if ((${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsplit-stack -D LEAN_USE_SPLIT_STACK") + message(STATUS "Using split-stacks") + else() + message(FATAL_ERROR "Split-stacks are only supported on Linux with g++") + endif() +endif() + # Test coverage if("${TESTCOV}" MATCHES "ON") include(CodeCoverage) diff --git a/src/util/stackinfo.cpp b/src/util/stackinfo.cpp index 84bcebb8d..abf92aebe 100644 --- a/src/util/stackinfo.cpp +++ b/src/util/stackinfo.cpp @@ -10,6 +10,8 @@ Author: Leonardo de Moura #include "util/thread.h" #include "util/exception.h" +#if !defined(LEAN_USE_SPLIT_STACK) + #if defined(LEAN_WINDOWS) // no extra included needed so far #elif defined(__APPLE__) @@ -116,3 +118,4 @@ void check_stack(char const * component_name) { throw stack_space_exception(component_name); } } +#endif diff --git a/src/util/stackinfo.h b/src/util/stackinfo.h index 72b59024b..8469406bc 100644 --- a/src/util/stackinfo.h +++ b/src/util/stackinfo.h @@ -8,6 +8,14 @@ Author: Leonardo de Moura #include namespace lean { +#if defined(LEAN_USE_SPLIT_STACK) +// If we are using split stacks, we don't need to check anything +inline void check_stack(char const * ) { } +inline size_t get_stack_size(bool ) { return 8192*1024; } +inline void save_stack_info(bool = true) {} +inline size_t get_used_stack_size() { return 0; } +inline size_t get_available_stack_size() { return 8192*1024; } +#else size_t get_stack_size(bool main); void save_stack_info(bool main = true); size_t get_used_stack_size(); @@ -19,4 +27,5 @@ size_t get_available_stack_size(); user which module is the potential offender. */ void check_stack(char const * component_name); +#endif } diff --git a/tests/lean/slow/tactic2.lean b/tests/lean/stackoverflow/tactic2.lean similarity index 100% rename from tests/lean/slow/tactic2.lean rename to tests/lean/stackoverflow/tactic2.lean diff --git a/tests/lean/slow/tactic2.lean.expected.out b/tests/lean/stackoverflow/tactic2.lean.expected.out similarity index 100% rename from tests/lean/slow/tactic2.lean.expected.out rename to tests/lean/stackoverflow/tactic2.lean.expected.out