diff --git a/.githooks/Makefile b/.githooks/Makefile
deleted file mode 100644
index 05b369b..0000000
--- a/.githooks/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-GIT_ROOT=$(shell git rev-parse --git-common-dir)
-
-GIT_HOOKS_DIR=$(GIT_ROOT)/hooks
-
-HOOK_NAMES=pre-commit
-GIT_HOOKS=$(addprefix $(GIT_HOOKS_DIR)/, $(HOOK_NAMES))
-
-all: $(GIT_HOOKS)
-
-$(GIT_HOOKS_DIR)/%: $(CURDIR)/hooks/%
- ln -s $< $@
-
-clean:
- rm -f $(GIT_HOOKS)
-
-.PHONY: all clean
diff --git a/.githooks/hooks/pre-commit b/.githooks/pre-commit
similarity index 91%
rename from .githooks/hooks/pre-commit
rename to .githooks/pre-commit
index 4a9da70..73b52ea 100755
--- a/.githooks/hooks/pre-commit
+++ b/.githooks/pre-commit
@@ -2,8 +2,6 @@
#
# Pre-commit hook to run clang-format on all C/C++ files
# before they are commited.
-#
-# To enable this hook, rename this file to "pre-commit".
if git rev-parse --verify HEAD >/dev/null 2>&1
then
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..1b24036
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,155 @@
+cmake_minimum_required(VERSION 3.13)
+
+project(gino)
+
+include(FetchContent)
+
+include(config.default.cmake)
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.cmake)
+ include(config.cmake)
+endif()
+
+if(DEFINED GINO_INSTALL_DIR)
+ get_filename_component(GINO_INSTALL_DIR ${GINO_INSTALL_DIR} ABSOLUTE)
+ set(CMAKE_INSTALL_PREFIX ${GINO_INSTALL_DIR})
+else()
+ get_filename_component(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} ABSOLUTE)
+ set(GINO_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
+endif()
+
+if(NOT DEFINED GINO_BUILD_TYPE)
+ set(GINO_BUILD_TYPE "Debug")
+endif()
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(LLVM 14 REQUIRED CONFIG)
+
+string(ASCII 27 Esc)
+set(Purple "${Esc}[35m")
+set(Green "${Esc}[32m")
+set(Red "${Esc}[31m")
+set(ColorReset "${Esc}[m")
+
+function(gino_acquire_option OPT)
+ if(${OPT} MATCHES "ON|On|on|1")
+ set(${OPT} ON PARENT_SCOPE)
+ message(STATUS "${Purple}Option${ColorReset} ${OPT} ${Green}ON${ColorReset}")
+ elseif(${OPT} MATCHES "OFF|Off|off|0")
+ set(${OPT} OFF PARENT_SCOPE)
+ message(STATUS "${Purple}Option${ColorReset} ${OPT} ${Red}OFF${ColorReset}")
+ elseif(${OPT} MATCHES "OFF|Off|off|0")
+ else()
+ message(FATAL_ERROR "${OPT} must be either ON or OFF")
+ endif()
+endfunction()
+
+message(STATUS "${Purple}Install directory${ColorReset} is ${CMAKE_INSTALL_PREFIX}")
+
+gino_acquire_option(GINO_TOOLS)
+
+if(NOT DEFINED NOELLE_INSTALL_DIR OR (NOELLE_INSTALL_DIR STREQUAL ""))
+ message(STATUS "${Purple}NOELLE_INSTALL_DIR${ColorReset} is not defined. Noelle will be fetched from GitHub.")
+ include(FetchContent)
+ set(NOELLE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
+ FetchContent_Declare(
+ noelle
+ GIT_REPOSITORY "https://github.com/arcana-lab/noelle.git"
+ GIT_TAG master
+ )
+ FetchContent_MakeAvailable(noelle)
+ FetchContent_GetProperties(noelle)
+ file(
+ GLOB_RECURSE NOELLE_CORE_DIRS LIST_DIRECTORIES true
+ "${noelle_SOURCE_DIR}/src/core/*"
+ "${noelle_SOURCE_DIR}/src/tools/*"
+ )
+ foreach(dir ${NOELLE_CORE_DIRS})
+ if(IS_DIRECTORY ${dir} AND EXISTS "${dir}/include")
+ include_directories(${dir}/include)
+ endif()
+ endforeach()
+else()
+ message(STATUS "${Purple}NOELLE_INSTALL_DIR${ColorReset} is ${NOELLE_INSTALL_DIR}")
+ include_directories(${NOELLE_INSTALL_DIR}/include)
+endif()
+
+set(GINO_CMAKE_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
+set(CMAKE_BUILD_TYPE ${GINO_BUILD_TYPE})
+
+get_filename_component(CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} REALPATH)
+get_filename_component(GINO_CMAKE_ROOT ${GINO_CMAKE_ROOT} REALPATH)
+
+file(READ ${GINO_CMAKE_ROOT}/VERSION GINO_VERSION)
+string(STRIP ${GINO_VERSION} GINO_VERSION)
+
+configure_file(enable.in enable @ONLY)
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/enable
+ DESTINATION ${GINO_CMAKE_ROOT}
+)
+
+install(
+ PROGRAMS ${GINO_CMAKE_ROOT}/.githooks/pre-commit
+ DESTINATION ${GINO_CMAKE_ROOT}/.git/hooks
+)
+
+enable_language(C CXX)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+find_package(LLVM 14 REQUIRED CONFIG)
+include_directories(${LLVM_INCLUDE_DIRS})
+add_definitions(${LLVM_DEFINITIONS})
+link_directories(${LLVM_LIBRARY_DIRS})
+
+message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
+message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
+
+# prepare the pass to be included in the source tree
+list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
+include(AddLLVM)
+include(HandleLLVMOptions)
+
+include_directories(
+ ${LLVM_INCLUDE_DIRS}
+)
+
+set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/)
+set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/)
+
+add_compile_options(${GINO_CXX_FLAGS})
+
+add_definitions(
+ -D__STDC_LIMIT_MACROS
+ -D__STDC_CONSTANT_MACROS
+)
+
+add_custom_target(
+ GinoCompileCommands ALL
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ ${CMAKE_BINARY_DIR}/compile_commands.json
+ ${GINO_CMAKE_ROOT}/compile_commands.json
+)
+
+add_custom_target(gino_libraries)
+add_custom_target(gino_tool_libraries)
+set_target_properties(gino_libraries PROPERTIES NAMES "")
+set_target_properties(gino_tool_libraries PROPERTIES NAMES "")
+
+function(gino_component_declare name)
+ add_llvm_library(${name} MODULE)
+ get_target_property(names gino_libraries NAMES)
+ list(APPEND names ${name})
+ set_target_properties(gino_libraries PROPERTIES NAMES "${names}")
+endfunction()
+
+function(gino_tool_declare name)
+ add_llvm_library(${name} MODULE)
+ get_target_property(names gino_tool_libraries NAMES)
+ list(APPEND names ${name})
+ set_target_properties(gino_tool_libraries PROPERTIES NAMES "${names}")
+endfunction()
+
+add_subdirectory(src)
+add_subdirectory(bin)
diff --git a/Kconfig b/Kconfig
new file mode 100644
index 0000000..79dce10
--- /dev/null
+++ b/Kconfig
@@ -0,0 +1,15 @@
+config GINO_INSTALL_DIR
+ string "Installation directory for Gino"
+ default "./install"
+
+config NOELLE_INSTALL_DIR
+ string "Pre-existing installation of Noelle. If empty, Noelle will be installed anew"
+ default ""
+
+config GINO_TOOLS
+ bool "Install all the tools build on top of Gino"
+ default y
+
+config GINO_BUILD_TYPE
+ string "Set build type for Gino"
+ default "Debug"
diff --git a/Makefile b/Makefile
index 2df589c..fd1fb9d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,27 +1,42 @@
-all: hooks src
+BUILD_DIR ?= build
+export GENERATOR ?= Unix Makefiles
+export JOBS ?= 16
+export MAKEFLAGS += --no-print-directory
+export KCONFIG_CONFIG = .config
+export MENUCONFIG_STYLE = aquatic
-src:
- cd src ; make ;
+all: install
-tests: src
- cd tests ; make ;
+install: compile
+ cmake --install $(BUILD_DIR)
-hooks:
- make -C .githooks
+compile: $(BUILD_DIR)
+ cmake --build $(BUILD_DIR) -j$(JOBS)
+
+build:
+ cmake -S . -B $(BUILD_DIR) -G "$(GENERATOR)" \
+ -DCMAKE_INSTALL_MESSAGE=LAZY \
+ -DCMAKE_INSTALL_PREFIX=install
+
+tests: install
+ $(MAKE) -C tests
format:
- cd src ; ./scripts/format_source_code.sh
+ find ./src -regex '.*\.[c|h]pp' | xargs clang-format -i
+
+menuconfig:
+ @python3 bin/menuconfig.py
-clean:
- cd src ; make $@ ;
- cd tests ; make $@ ;
- find ./ -name .clangd -exec rm -rv {} +
- find ./ -name .cache -exec rm -rv {} +
+clean: uninstall
+ rm -rf $(BUILD_DIR)
+ rm -rf .config
+ $(MAKE) -C tests clean > /dev/null
+ rm -f compile_commands.json
+ rm -f config.cmake
-uninstall: clean
- cd src ; make $@ ;
- rm -f enable ;
- rm -rf install ;
- if test -d .githooks ; then cd .githooks ; make clean ; fi;
+uninstall:
+ -cat $(BUILD_DIR)/install_manifest.txt | xargs rm -f
+ rm -f enable
+ rm -f .git/hooks/pre-commit
-.PHONY: src tests hooks format clean uninstall
+.PHONY: all build install compile tests format clean uninstall
diff --git a/README.md b/README.md
index 323d656..fa39b05 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,33 @@
-# Gino
+# Gino: An (automatic) parallelizing compiler
[](https://gist.github.com/cheerfulstoic/d107229326a01ff0f333a1d3476e068d)

- [Description](#description)
+- [Mascot](#mascot)
- [Version](#version)
- [Status](#status)
- [Prerequisites](#prerequisites)
-- [Building Gino](#building-gino)
-- [Testing Gino](#testing-gino)
+- [Building and Installing](#building-and-installing)
+- [Testing](#testing)
+- [Uninstalling](#uninstalling)
- [Repository structure](#repository-structure)
- [Projects built upon Gino](#Projects-built-upon-Gino)
-- [Contributions](#contributions)
+- [Contributing](#contributing)
- [License](#license)
-- [Logo](#logo)
-
## Description
-Gino is a parallelizing compiler for LLVM IR.
-Gino is built upon [NOELLE](https://github.com/arcana-lab/noelle), [VIRGIL](https://github.com/arcana-lab/virgil), and [LLVM](http://llvm.org).
+GINO is an automatic parallelizing compiler that works at the LLVM IR level.
+It relies on the abstractions provided by [NOELLE](https://github.com/arcana-lab/noelle) (e.g. PDG, SCCDAG, ecc), [VIRGIL](https://github.com/arcana-lab/virgil), and [LLVM](http://llvm.org).
+GINO supports DOALL and provides an implementation of [DSWP](https://liberty.princeton.edu/Publications/micro05_dswp.pdf) and [HELIX](https://users.cs.northwestern.edu/~simonec/files/Research/papers/HELIX_CGO_2012.pdf).
+
+The following material composes the **documentation** available at the moment:
+- An introductory [video](https://www.youtube.com/watch?v=whORNUUWIjI)
+- The [CGO 2022 Paper](http://www.cs.northwestern.edu/~simonec/files/Research/papers/HELIX_CGO_2022.pdf)
+- The slides used during [Advanced Topics in Compilers](http://www.cs.northwestern.edu/~simonec/ATC.html) at Northwestern
-We release Gino's source code in the hope of benefiting others.
+[We](https://users.cs.northwestern.edu/~simonec/Team.html) released GINO's source code in the hope of enriching the resources available to the research community and compiler developers.
You are kindly asked to acknowledge usage of the tool by citing the following paper:
```
@inproceedings{NOELLE,
@@ -32,24 +38,27 @@ You are kindly asked to acknowledge usage of the tool by citing the following pa
}
```
-The only documentation available for Gino is:
-- a [video](https://www.youtube.com/watch?v=whORNUUWIjI&t=7s) introducing NOELLE and Gino
-- the [paper](http://www.cs.northwestern.edu/~simonec/files/Research/papers/HELIX_CGO_2022.pdf)
-- the comments within the code
-- the slides we use in the class [Advanced Topics in Compilers](http://www.cs.northwestern.edu/~simonec/ATC.html)
+## Mascot
+Gino is the name of the cat Simone and his wife adopted from [Tree House Cat Shelter](https://treehouseanimals.org) when they moved to Chicago.
+It was surprisingly hard to find a picture of Gino by himself.
+He's always playing and cuddling with his brother Gigi.
+
+

+

+
+
+A future project may or may not be called Gigi...
## Version
The latest stable version is 14.1.0 (tag = `v14.1.0`).
-
### Version Numbering Scheme
The version number is in the form of \[v _Major.Minor.Revision_ \]
- **Major**: Each major version matches a specific LLVM version (e.g., version 9 matches LLVM 9, version 11 matches LLVM 11)
- **Minor**: Starts from 0, each minor version represents either one or more API replacements/removals that might impact the users OR a forced update every six months (the minimum minor update frequency)
- **Revision**: Starts from 0; each revision version may include bug fixes or incremental improvements
-
#### Update Frequency
- **Major**: Matches the LLVM releases on a best-effort basis
- **Minor**: At least once per six months, at most once per month (1/month ~ 2/year)
@@ -68,79 +77,77 @@ Next is the status of Gino for different LLVM versions.
- LLVM 14.0.6
- NOELLE 14.1.0
-### Northwestern
-Next is the information for those that have access to the [Zythos](https://users.cs.northwestern.edu/~simonec/files/Research/manuals/Zythos_guide.pdf) cluster at Northwestern.
-
-To enable the correct LLVM, run the following command from any node of the [Zythos](https://users.cs.northwestern.edu/~simonec/files/Research/manuals/Zythos_guide.pdf) cluster:
+### Northwestern users
+Those who have access to the Zythos cluster at Northwestern can source LLVM 14.0.6 from any node of the cluster with:
```
source /project/extra/llvm/14.0.6/enable
```
-
-To enable the correct NOELLE, run the following command from any node of the [Zythos](https://users.cs.northwestern.edu/~simonec/files/Research/manuals/Zythos_guide.pdf) cluster:
+and Noelle with:
```
-source /project/extra/noelle/14.1.0/enable
+source /project/extra/noelle/9.14.1/enable
```
+Check out the Zythos cluster guide [here](http://www.cs.northwestern.edu/~simonec/files/Research/manuals/Zythos_guide.pdf) for more.
+## Building and Installing
-## Building Gino
-To build and install Gino: run `make` from the repository root directory.
-
-Run `make clean` from the root directory to clean the repository.
-
-Run `make uninstall` from the root directory to uninstall the Gino installation.
-
+To build and install GINO you need to configure it first, unless the [default configuration](config.default.cmake) is satisfactory.
+From the root directory:
+```
+source /path/to/noelle/enable # make NOELLE available
+make menuconfig # to customize the installation
+make # set the number of jobs with JOBS=8 (default is 16)
+```
-## Testing Gino
-To run all tests in parallel using Condor, invoke the following commands:
+## Testing
+To run all tests in parallel using [Condor](https://htcondor.org/), invoke the following commands:
```
-make clean ;
-cd tests ;
-make condor ;
+cd tests
+make clean
+make condor
```
-To monitor how tests are doing: `cd tests ; make condor_watch`
+To monitor test progress use `cd tests ; make condor_watch`.
-To find out if all tests passed: `cd tests ; make condor_check`
+To monitor test failures use `cd tests ; make condor_check`.
+
+`make condor` creates a `regression_X` sub-directory per configuration (e.g., `regression_42`).
+Each single test within a given `regression_X` sub-directory will contain a `run_me.sh` script, which is automatically generated by `make condor`
+and can be used to re-produce the compilation for that specific configuration.
-To test Gino using condor to run all tests in parallel, go to "tests" and run "make condor".
-This creates one `regression_X` sub-directory per configuration where `X` is going to be a number (e.g., `regression_42`).
-Each single test within a given `regression_X` sub-directory will contain a `run_me.sh` script, which is automatically generated by `make condor`.
-To re-produce the compilation for a specific test for a specific configuration (e.g., the one associated with the current `regression_X` sub-directory), then do the following:
```
-cd tests/regression_42 ;
-cd THE_TEST_YOU_ARE_INTERESTED ;
-./run_me.sh ;
+cd tests/regression_42
+cd test_of_your_interest
+./run_me.sh
```
-where `regression_42` is the sub-directory of the configuration you are interested and `THE_TEST_YOU_ARE_INTERESTED` is the test you care.
To run only the autotuned performance tests using Condor, invoke the following commands:
```
-make clean ;
-cd tests ;
-make condor_autotuner ;
+cd tests
+make clean
+make condor_autotuner
```
-The speedup results will be collected in the tests/performance/speedups_autotuner.txt file.
+The speedup results will be collected in `tests/performance/speedups_autotuner.txt`.
-## Repository structure
-The directory `src` includes sources of the Gino parallelizer.
-Within this directory, `src/core` includes the analyses and transformations needed by Gino to parallelize the code.
-Also, `src/tools` includes tools that can be used to diagnose Gino (e.g., to understand the decisions Gino made to parallelize the code).
+## Uninstalling
-The directory `tests` includes integration tests, and performance tests.
-Furthermore, this directory includes the scripts to run all these tests in parallel via condor.
+In this order:
-Finally, the directory `doc` includes the documentation of Gino.
+Run `make uninstall` to uninstall without cleaning the build files.
+Run `make clean` to reset the repository to its initial state.
+For generality, the install directory is not removed.
-### Contributing to Gino
-Gino uses `clang-format` to ensure uniform styling across the project's source code.
-`clang-format` is run automatically as a pre-commit git hook, meaning that when you commit a file `clang-format` is automatically run on the file in-place.
+## Repository structure
-Since git doesn't allow for git hooks to be installed when you clone the repository we manage this with our top-level Makefile.
-To install the Gino git hooks, run `make hooks` at the root of the directory.
-This make rule is run at the start of the `make all` rule as well for ease of use.
+- `bin` contains the scripts through which the user will run all analyses and transformations
+- `doc` contains the documentation
+- `src` contains the C++ source of the framework
+- `src/core` contains all the main abstractions
+- `src/tools` contains a set of tools built on top of the core. All tools are independent from one another
+- `tests` contains regression and performance tests
## Projects built upon Gino
+
Several projects have already been built successfully upon Gino.
These projects are (in no particular order):
- [HBC](https://github.com/arcana-lab/heartbeatcompiler)
@@ -148,24 +155,22 @@ These projects are (in no particular order):
- [CCK](https://github.com/arcana-lab/cck)
-## Contributions
+## Contributing
We welcome contributions from the community to improve this framework and evolve it to cater for more users.
-If you have any trouble using this framework feel free to reach out to us for help (contact simone.campanoni@northwestern.edu).
-
-
-## License
-Gino is licensed under the [MIT License](./LICENSE.md).
+GINO uses `clang-format` to ensure uniform styling across the project's source code.
+To format all `.cpp` and `.hpp` files in the repository run `make format` from the root.
+`clang-format` is run automatically as a pre-commit git hook, meaning that when you commit a file `clang-format` is automatically run on the file in-place.
-## Logo
-
+Since git doesn't allow for git hooks to be installed when you clone the repository,
+cmake will install the pre-commit git hook upon installation.
-Gino is the name of our cat we have taken home from the [Tree house cat shelter](https://treehouseanimals.org) when we moved to Chicago.
-It was surprisingly hard to find a picture of Gino by himself.
-He is always playing and cuddling with his brother Gigi like here:
-
+## Contributions
+We welcome contributions from the community to improve this framework and evolve it to cater for more users.
+If you have any trouble using this framework feel free to reach out to us for help (contact simone.campanoni@northwestern.edu).
-A future project may or may not be called Gigi.
+## License
+Gino is licensed under the [MIT License](./LICENSE.md).
diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt
new file mode 100644
index 0000000..9dee9b9
--- /dev/null
+++ b/bin/CMakeLists.txt
@@ -0,0 +1,62 @@
+if(EXISTS ${GINO_CMAKE_ROOT}/.git/HEAD)
+ execute_process(
+ COMMAND git remote get-url --all origin
+ WORKING_DIRECTORY ${GINO_CMAKE_ROOT}
+ OUTPUT_VARIABLE gino_config_GIT_ORIGIN
+ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
+ )
+ execute_process(
+ COMMAND git log -1 --format=%H
+ WORKING_DIRECTORY ${GINO_CMAKE_ROOT}
+ OUTPUT_VARIABLE gino_config_GIT_COMMIT
+ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
+ )
+else()
+ set(gino_config_GIT_ORIGIN "")
+ set(gino_config_GIT_COMMIT "")
+endif()
+
+string(REPLACE ";" " " gino_config_CXX_FLAGS "${GINO_CXX_FLAGS}")
+
+get_target_property(GINO_LIBRARIES gino_libraries NAMES)
+set(gino_config_CORE_LIBS "")
+foreach(lib IN LISTS GINO_LIBRARIES)
+ list(APPEND gino_config_CORE_LIBS
+ "-load ${CMAKE_INSTALL_PREFIX}/lib/${lib}.so"
+ )
+endforeach()
+string(REPLACE ";" " " gino_config_CORE_LIBS "${gino_config_CORE_LIBS}")
+
+set(gino_config_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/include")
+set(gino_config_CXXFLAGS "-I ${CMAKE_INSTALL_PREFIX}/include")
+set(gino_config_RUNTIME_DECL "${CMAKE_INSTALL_PREFIX}/runtime/gino_runtime_decl.c")
+set(gino_config_RUNTIME_DEF "${CMAKE_INSTALL_PREFIX}/runtime/gino_runtime_def.cpp")
+
+if(NOT "${NOELLE_INSTALL_DIR}" STREQUAL "${GINO_INSTALL_DIR}")
+ list(APPEND gino_config_INCLUDE_DIRS
+ "${NOELLE_INSTALL_DIR}/include"
+ )
+ list(APPEND gino_config_CXXFLAGS
+ "-I ${NOELLE_INSTALL_DIR}/include"
+ )
+endif()
+
+get_target_property(GINO_TOOL_LIBRARIES gino_tool_libraries NAMES)
+set(gino_config_TOOL_LIBS "")
+foreach(lib IN LISTS GINO_TOOL_LIBRARIES)
+ list(APPEND gino_config_TOOL_LIBS
+ "-load ${CMAKE_INSTALL_PREFIX}/lib/${lib}.so"
+ )
+endforeach()
+string(REPLACE ";" " " gino_config_TOOL_LIBS "${gino_config_TOOL_LIBS}")
+string(REPLACE ";" "\n" gino_config_INCLUDE_DIRS "${gino_config_INCLUDE_DIRS}")
+string(REPLACE ";" " " gino_config_CXXFLAGS "${gino_config_CXXFLAGS}")
+
+configure_file(gino-config.in gino-config @ONLY)
+install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/gino-config DESTINATION bin)
+
+add_subdirectory(core)
+
+if(GINO_TOOLS STREQUAL ON)
+ add_subdirectory(tools)
+endif()
diff --git a/bin/core/CMakeLists.txt b/bin/core/CMakeLists.txt
new file mode 100644
index 0000000..d4727cf
--- /dev/null
+++ b/bin/core/CMakeLists.txt
@@ -0,0 +1,14 @@
+install(
+ PROGRAMS
+ gino
+ gino-autotuner
+ gino-enable
+ gino-inline
+ gino-io
+ gino-load
+ gino-loops
+ gino-planner
+ gino-pre
+ DESTINATION
+ bin
+)
diff --git a/bin/core/gino b/bin/core/gino
new file mode 100644
index 0000000..a2d8349
--- /dev/null
+++ b/bin/core/gino
@@ -0,0 +1,38 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+if test $# -lt 3 ; then
+ echo "USAGE: `basename $0` INPUT_BITCODE -o OUTPUT_BITCODE"
+ exit 1
+fi
+
+inputIR=$1
+afterLoopMetadata="afterLoopMetadata.bc"
+intermediateResult="baseline_with_parallel_plan.bc"
+intermediateResult_unoptimized="parallelized_unoptimized.bc"
+outputIR=$3
+
+# step 0: add loop id to all loops
+noelle-meta-loop-embed ${inputIR} -o ${afterLoopMetadata}
+
+# step 1: run parallelization planner
+gino-planner ${afterLoopMetadata} -o ${intermediateResult} ${@:4}
+
+# step 2: include function prototypes needed by parallelization techniques
+clang -c -emit-llvm gino_runtime_decl.c
+llvm-link gino_runtime_decl.bc ${intermediateResult} -o code_with_prototypes.bc
+noelle-rm-function -function-name=SIMONE_CAMPANONI_IS_GOING_TO_REMOVE_THIS_FUNCTION code_with_prototypes.bc -o code_to_parallelize.bc
+
+# step 3: run loop parallelization on bitcode with parallel plan
+gino-loops code_to_parallelize.bc -o ${intermediateResult_unoptimized} ${@:4}
+
+# step 4: cleaning the metadata that are now disaligned with the code
+noelle-meta-clean ${intermediateResult_unoptimized} -o ${intermediateResult_unoptimized}
+clang -O3 -c -emit-llvm ${intermediateResult_unoptimized} -o ${outputIR}
+
+# step 6: link with the runtime
+llvm-link ${outputIR} gino_runtime_def.bc -o ${outputIR}
+
+# step 7: conventional optimizations
+clang -O3 -c -emit-llvm ${outputIR} -o ${outputIR}
diff --git a/src/core/scripts/gino-autotuner b/bin/core/gino-autotuner
similarity index 59%
rename from src/core/scripts/gino-autotuner
rename to bin/core/gino-autotuner
index 0f73094..95d9d2d 100644
--- a/src/core/scripts/gino-autotuner
+++ b/bin/core/gino-autotuner
@@ -1,15 +1,8 @@
#!/bin/bash -e
-# Fetch the installation directories
-SOURCE=${BASH_SOURCE[0]}
-while [ -L "${SOURCE}" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR=$( cd -P "$( dirname "${SOURCE}" )" >/dev/null 2>&1 && pwd )
- SOURCE=$(readlink "${SOURCE}")
- # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
- [[ ${SOURCE} != /* ]] && SOURCE=$DIR/$SOURCE
-done
-installDir=$(realpath $( cd -P "$( dirname "${SOURCE}" )" >/dev/null 2>&1 && pwd )/..)
-noelleInstallDir="`noelle-config --prefix`" ;
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+noelleInstallDir=$(noelle-config --prefix)
# Parse arguments
for arg in "$@"; do
@@ -39,15 +32,15 @@ for arg in "$@"; do
shift # past argument=value
;;
--nosearchspace)
- generateSearchSpace="0" ;
+ generateSearchSpace="0"
shift # past argument with no value
;;
--noDOALLfiltering)
- filterDOALLSearchSpace="0" ;
+ filterDOALLSearchSpace="0"
shift # past argument with no value
;;
--noDOALLtimefiltering)
- filterDOALLtimeSearchSpace="0" ;
+ filterDOALLtimeSearchSpace="0"
shift # past argument with no value
;;
-*|--*)
@@ -61,77 +54,77 @@ done
# Get additional arguments
if [ "${inputToRun}" == "" ] ; then
- echo "ERROR: --input cannot be empty. Abort." ;
- exit 1 ;
+ echo "ERROR: --input cannot be empty. Abort."
+ exit 1
fi
if [ "${parallelizerArgs}" == "" ] ; then
- echo "ERROR: --parallelizer-args cannot be empty. Abort." ;
- exit 1 ;
+ echo "ERROR: --parallelizer-args cannot be empty. Abort."
+ exit 1
fi
-IFS=' ' read -ra parallelizerArgsArray <<< "${parallelizerArgs}" ;
-inputbc="${parallelizerArgsArray[0]}" ;
-outputbc="${parallelizerArgsArray[2]}" ;
+IFS=' ' read -ra parallelizerArgsArray <<< "${parallelizerArgs}"
+inputbc="${parallelizerArgsArray[0]}"
+outputbc="${parallelizerArgsArray[2]}"
-autotunerConf="autotuner_conf.info" ;
-autotunerSpace="autotuner_space.info" ;
+autotunerConf="autotuner_conf.info"
+autotunerSpace="autotuner_space.info"
# Needed for the creation and filtering of the autotuner search space
-export autotunerSPACE_FILE="${autotunerSpace}" ;
+export autotunerSPACE_FILE="${autotunerSpace}"
# Add loop ID to all loops
# NOTE: the outputbc file must be the same as the input because of --parallelizer-args
cmd="noelle-meta-loop-embed ${inputbc} -o ${inputbc}"
-echo $cmd ;
-eval $cmd ;
+echo $cmd
+eval $cmd
if [ "${generateSearchSpace}" != "0" ] ; then
# Generate autotuner_space.info
- cmd="noelle-load -load ${installDir}/lib/AutotunerSearchSpace.so -autotunersearchspace ${inputbc} -disable-output" ;
- echo ${cmd} ;
- eval ${cmd} ;
+ cmd="noelle-load -load ${ginoInstallDir}/lib/AutotunerSearchSpace.so -AutotunerSearchSpace ${inputbc} -disable-output"
+ echo ${cmd}
+ eval ${cmd}
fi
# Sanity check for existance of autotuner_space.info file
if ! test -f ${autotunerSpace} ; then
- echo "ERROR: no ${autotunerSpace} found. Abort." ;
- exit 1 ;
+ echo "ERROR: no ${autotunerSpace} found. Abort."
+ exit 1
fi
if [ "${filterDOALLSearchSpace}" != "0" ] ; then
# Adjust search space with DOALL only loops
- cmd="gino-load -load ${installDir}/lib/AutotunerDoallFilter.so -autotunerdoallfilter ${inputbc} -disable-output" ;
- echo ${cmd} ;
- eval ${cmd} ;
+ cmd="gino-load -load ${ginoInstallDir}/lib/AutotunerDoallFilter.so -AutotunerDoallFilter ${inputbc} -disable-output"
+ echo ${cmd}
+ eval ${cmd}
fi
# Export the remaining environment variables for the autotuner
-export autotunerPARALLELIZED_BINARY="binaryToRun" ;
-export autotunerEXECUTION_TIME="executionTime.txt" ;
-export autotunerBASELINE_TIME="baselineTime.txt" ;
-export autotunerINSTALL_DIR="${installDir}" ;
-export autotunerARGS="${parallelizerArgs}" ;
-export autotunerINPUT="${inputToRun}" ;
-export autotunerOUTPUTBC="${outputbc}" ;
-export autotunerLIBS="${libs}" ;
+export autotunerPARALLELIZED_BINARY="binaryToRun"
+export autotunerEXECUTION_TIME="executionTime.txt"
+export autotunerBASELINE_TIME="baselineTime.txt"
+export autotunerINSTALL_DIR="${ginoInstallDir}"
+export autotunerARGS="${parallelizerArgs}"
+export autotunerINPUT="${inputToRun}"
+export autotunerOUTPUTBC="${outputbc}"
+export autotunerLIBS="${libs}"
# We need to export this env var to force loop parallelization in GINO
-export INDEX_FILE="${autotunerConf}" ;
+export INDEX_FILE="${autotunerConf}"
# Setup python virtualEnv
-source ${noelleInstallDir}/autotuner/source-me-to-setup-python-virtual-environment ;
+source ${noelleInstallDir}/autotuner/source-me-to-setup-python-virtual-environment
# Compile and run baseline
-cmd="python ${noelleInstallDir}/autotuner/utils/compileAndRunBaseline.py" ;
-echo ${cmd} ;
-eval ${cmd} ;
+cmd="python ${noelleInstallDir}/autotuner/utils/compileAndRunBaseline.py"
+echo ${cmd}
+eval ${cmd}
if [ "${filterDOALLtimeSearchSpace}" != "0" ] && [ "${filterDOALLSearchSpace}" != "0" ] ; then
# Filter search space by trying to parallelize DOALL loops one by one
# if they don't speedup compared to the baseline, then disable them
# (note: modifies autotuner_space.info)
- cmd="python ${noelleInstallDir}/autotuner/scripts/filter.py" ;
- echo ${cmd} ;
- eval ${cmd} ;
+ cmd="python ${noelleInstallDir}/autotuner/scripts/filter.py"
+ echo ${cmd}
+ eval ${cmd}
fi
# Execute autotuner only if space file is not empty.
@@ -139,46 +132,46 @@ fi
# 1) the IR of the program has no loops
# 2) the filtering of loops removed all of them
if [ -s ${autotunerSpace} ] ; then
- echo "AUTOTUNER: space file ${autotunerSpace} contains:" ;
- echo `cat ${autotunerSpace}` ;
+ echo "AUTOTUNER: space file ${autotunerSpace} contains:"
+ echo `cat ${autotunerSpace}`
# Set the command to execute
- cmd="python ${noelleInstallDir}/autotuner/src/autotuner.py --no-dups --parallelism=1" ;
+ cmd="python ${noelleInstallDir}/autotuner/src/autotuner.py --no-dups --parallelism=1"
# Get autotuner time limit
if [ "${autotunerTime}" != "" ] ; then
- cmd="${cmd} --stop-after=${autotunerTime}" ;
+ cmd="${cmd} --stop-after=${autotunerTime}"
fi
# Get autotuner number of configurations to explore limit
if [ "${autotunerNumConf}" != "" ] ; then
- cmd="${cmd} --test-limit=${autotunerNumConf}" ;
+ cmd="${cmd} --test-limit=${autotunerNumConf}"
fi
# Get autotuner seed conf
if [ "${autotunerSeedConf}" != "" ] ; then
# Safety check: check if seed conf file and space file have at least the same number of lines
# (we really should check if the number of configuration parameters match, but good enough for now.)
- seedConfNumLines="`wc -l < ${autotunerSeedConf}`" ;
- spaceNumLines="`wc -l < ${autotunerSpace}`" ;
+ seedConfNumLines="`wc -l < ${autotunerSeedConf}`"
+ spaceNumLines="`wc -l < ${autotunerSpace}`"
if [ "${seedConfNumLines}" != "${spaceNumLines}" ] ; then
- echo "ERROR: #lines mismatch! autotuner seed conf file ${autotunerSeedConf} has ${seedConfNumLines} lines, while autotuner space file ${autotunerSpace} has ${spaceNumLines}. Abort." ;
- exit 1 ;
+ echo "ERROR: #lines mismatch! autotuner seed conf file ${autotunerSeedConf} has ${seedConfNumLines} lines, while autotuner space file ${autotunerSpace} has ${spaceNumLines}. Abort."
+ exit 1
fi
autotunerPathToSeedConf="`python ${noelleInstallDir}/autotuner/utils/genSeedConf.py ${autotunerSeedConf}`" ;
- cmd="${cmd} --seed-configuration=${autotunerPathToSeedConf}" ;
+ cmd="${cmd} --seed-configuration=${autotunerPathToSeedConf}"
fi
# Print command we are about to execute
- echo ${cmd} ;
+ echo ${cmd}
# Execute
- eval ${cmd} ;
+ eval ${cmd}
else
- echo "AUTOTUNER: space file ${autotunerSpace} is empty. We will not run the autotuner. Bye." ;
+ echo "AUTOTUNER: space file ${autotunerSpace} is empty. We will not run the autotuner. Bye."
fi
# Deactivate python virtualEnv
-deactivate ;
+deactivate
diff --git a/bin/core/gino-enable b/bin/core/gino-enable
new file mode 100644
index 0000000..0c1b176
--- /dev/null
+++ b/bin/core/gino-enable
@@ -0,0 +1,7 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+echo "GINO: Enablers: Start"
+noelle-fixedpoint $1 $2 "gino-load" -Enablers ${@:3}
+echo "GINO: Enablers: Exit"
diff --git a/bin/core/gino-inline b/bin/core/gino-inline
new file mode 100644
index 0000000..d86731a
--- /dev/null
+++ b/bin/core/gino-inline
@@ -0,0 +1,8 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+# delete dead functions until a fixed point is reached
+echo "GINO: Inliner: Start"
+noelle-fixedpoint $1 $1 "gino-load" -Inliner ${@:2}
+echo "GINO: Inliner: Exit"
diff --git a/bin/core/gino-io b/bin/core/gino-io
new file mode 100644
index 0000000..8862138
--- /dev/null
+++ b/bin/core/gino-io
@@ -0,0 +1,6 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+# set the command to execute
+gino-load -InputOutput $1 -o $1
diff --git a/bin/core/gino-load b/bin/core/gino-load
new file mode 100644
index 0000000..8af4065
--- /dev/null
+++ b/bin/core/gino-load
@@ -0,0 +1,8 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+noelle-load \
+ $(noelle-config --tool-libs) \
+ $(gino-config --core-libs) \
+ $@
diff --git a/bin/core/gino-loops b/bin/core/gino-loops
new file mode 100644
index 0000000..59c8028
--- /dev/null
+++ b/bin/core/gino-loops
@@ -0,0 +1,5 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+gino-load -Parallelizer $@
diff --git a/bin/core/gino-planner b/bin/core/gino-planner
new file mode 100644
index 0000000..6ca80c6
--- /dev/null
+++ b/bin/core/gino-planner
@@ -0,0 +1,5 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+gino-load -Planner $@
diff --git a/bin/core/gino-pre b/bin/core/gino-pre
new file mode 100644
index 0000000..d3cc152
--- /dev/null
+++ b/bin/core/gino-pre
@@ -0,0 +1,85 @@
+#!/bin/bash -e
+
+trap 'echo "error: $(basename $0): line $LINENO"; exit 1' ERR
+
+# configurations
+enablePrivatizer="1"
+enableEnablers="1"
+enableDead="1"
+
+# partition the arguments between options and not
+options=""
+notOptions=""
+for var in "$@" ; do
+ if [[ $var == -* ]] ; then
+
+ # handle custom options
+ if [[ $var == "-gino-disable-privatizer" ]] ; then
+ enablePrivatizer="0"
+ continue
+ fi
+
+ if [[ $var == "-gino-disable-enablers" ]] ; then
+ enableEnablers="0"
+ continue
+ fi
+
+ if [[ $var == "-gino-disable-dead" ]] ; then
+ enableDead="0"
+ continue
+ fi
+
+ if [[ $var == -gino-* ]] ; then
+ # skip all parallelizer-specific options
+ continue
+ fi
+ # general options
+ options="$options $var"
+ else
+ notOptions="$notOptions $var"
+ fi
+done
+
+# strip debugging symbols
+opt --strip-debug --strip-debug-declare $notOptions -o $notOptions
+
+# delete dead functions
+if test "$enableDead" == "1" ; then
+ noelle-deadcode $notOptions $notOptions
+fi
+
+# normalize the code
+noelle-simplification $notOptions -o $notOptions
+
+# make file accesses more amenable for parallelization
+gino-io $notOptions
+
+# inline functions
+gino-inline $notOptions "-gino-inliner-verbose=1 $options"
+
+# normalize the code
+noelle-simplification $notOptions -o $notOptions
+
+# delete dead functions
+if test "$enableDead" == "1" ; then
+ noelle-deadcode $notOptions $notOptions
+fi
+
+# normalize the code
+noelle-simplification $notOptions -o $notOptions
+
+# run the privatizer
+if test "$enablePrivatizer" == "1" ; then
+ noelle-privatizer $notOptions $options
+fi
+
+# run the enablers
+if test "$enableEnablers" == "1" ; then
+ gino-enable $notOptions $notOptions $options
+fi
+
+# normalize the code
+noelle-simplification $notOptions -o $notOptions
+
+# clean up the metadata that is no longer valid
+noelle-meta-clean $notOptions -o $notOptions
diff --git a/bin/gino-config.in b/bin/gino-config.in
new file mode 100755
index 0000000..f1d979a
--- /dev/null
+++ b/bin/gino-config.in
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+function show_help() {
+ echo "usage: $(basename $0) ..."
+ echo
+ echo "Options"
+ echo " --help Print this help message"
+ echo " --version Print the library version"
+ echo " --flags Print special options used during compilation"
+ echo " --prefix Print the installation directory path"
+ echo " --runtime-decl Print the runtime declaration source file"
+ echo " --runtime-def Print the runtime definition source file"
+ echo " --include-dirs Print the include directories one per line"
+ echo " --cxxflags Print necessary C++ flags for using Gino headers"
+ echo " --core-libs Print the shared libraries used by the Gino core"
+ echo " --tool-libs Print the shared libraries of the Gino tools"
+ echo " --git-commit Print the git commit hash used at compilation time"
+ echo " --git-origin Print the git origin used during compilation"
+ echo " --build-type Print the build type used for Gino. E.g. Debug"
+ echo " --llvm-build Print the build type of the specific LLVM used by Gino"
+ echo " --llvm-prefix Print the installation prefix of the specific LLVM used by Gino"
+ echo " --llvm-version Print the version of the specific LLVM used by Gino"
+ echo " --noelle-prefix Print the installation directory path for Noelle"
+}
+
+if [[ $# < 1 ]]; then
+ show_help
+ exit 0
+fi
+
+for arg in "$@"; do
+ case $arg in
+ -h | --help )
+ show_help
+ break
+ ;;
+ --flags)
+ echo "@gino_config_CXX_FLAGS@"
+ ;;
+ --prefix)
+ echo "@CMAKE_INSTALL_PREFIX@"
+ ;;
+ --runtime-decl)
+ echo "@gino_config_RUNTIME_DECL@"
+ ;;
+ --runtime-def)
+ echo "@gino_config_RUNTIME_DEF@"
+ ;;
+ --version)
+ echo "@GINO_VERSION@"
+ ;;
+ --include-dirs)
+ echo "@gino_config_INCLUDE_DIRS@"
+ ;;
+ --cxxflags)
+ echo "@gino_config_CXXFLAGS@"
+ ;;
+ --core-libs)
+ echo "@gino_config_CORE_LIBS@"
+ ;;
+ --tool-libs)
+ echo "@gino_config_TOOL_LIBS@"
+ ;;
+ --git-commit)
+ echo "@gino_config_GIT_COMMIT@"
+ ;;
+ --git-origin)
+ echo "@gino_config_GIT_ORIGIN@"
+ ;;
+ --build-type)
+ echo "@GINO_BUILD_TYPE@"
+ ;;
+ --llvm-build)
+ echo "@LLVM_BUILD_TYPE@"
+ ;;
+ --llvm-prefix)
+ echo "@LLVM_INSTALL_PREFIX@"
+ ;;
+ --llvm-version)
+ echo "@LLVM_PACKAGE_VERSION@"
+ ;;
+ --noelle-prefix)
+ echo "@NOELLE_INSTALL_DIR@"
+ ;;
+ *)
+ echo "Unknown argument: $arg"
+ show_help
+ exit 1
+ ;;
+ esac
+done
diff --git a/bin/menuconfig.py b/bin/menuconfig.py
new file mode 100755
index 0000000..b4933a2
--- /dev/null
+++ b/bin/menuconfig.py
@@ -0,0 +1,10488 @@
+#!/usr/bin/env python3
+
+# Copyright (c) 2018-2019, Nordic Semiconductor ASA and Ulf Magnusson
+# SPDX-License-Identifier: ISC
+
+"""
+Overview
+========
+
+A curses-based Python 2/3 menuconfig implementation. The interface should feel
+familiar to people used to mconf ('make menuconfig').
+
+Supports the same keys as mconf, and also supports a set of keybindings
+inspired by Vi:
+
+ J/K : Down/Up
+ L : Enter menu/Toggle item
+ H : Leave menu
+ Ctrl-D/U: Page Down/Page Up
+ G/End : Jump to end of list
+ g/Home : Jump to beginning of list
+
+[Space] toggles values if possible, and enters menus otherwise. [Enter] works
+the other way around.
+
+The mconf feature where pressing a key jumps to a menu entry with that
+character in it in the current menu isn't supported. A jump-to feature for
+jumping directly to any symbol (including invisible symbols), choice, menu or
+comment (as in a Kconfig 'comment "Foo"') is available instead.
+
+A few different modes are available:
+
+ F: Toggle show-help mode, which shows the help text of the currently selected
+ item in the window at the bottom of the menu display. This is handy when
+ browsing through options.
+
+ C: Toggle show-name mode, which shows the symbol name before each symbol menu
+ entry
+
+ A: Toggle show-all mode, which shows all items, including currently invisible
+ items and items that lack a prompt. Invisible items are drawn in a different
+ style to make them stand out.
+
+
+Running
+=======
+
+menuconfig.py can be run either as a standalone executable or by calling the
+menuconfig() function with an existing Kconfig instance. The second option is a
+bit inflexible in that it will still load and save .config, etc.
+
+When run in standalone mode, the top-level Kconfig file to load can be passed
+as a command-line argument. With no argument, it defaults to "Kconfig".
+
+The KCONFIG_CONFIG environment variable specifies the .config file to load (if
+it exists) and save. If KCONFIG_CONFIG is unset, ".config" is used.
+
+When overwriting a configuration file, the old version is saved to
+.old (e.g. .config.old).
+
+$srctree is supported through Kconfiglib.
+
+
+Color schemes
+=============
+
+It is possible to customize the color scheme by setting the MENUCONFIG_STYLE
+environment variable. For example, setting it to 'aquatic' will enable an
+alternative, less yellow, more 'make menuconfig'-like color scheme, contributed
+by Mitja Horvat (pinkfluid).
+
+This is the current list of built-in styles:
+ - default classic Kconfiglib theme with a yellow accent
+ - monochrome colorless theme (uses only bold and standout) attributes,
+ this style is used if the terminal doesn't support colors
+ - aquatic blue-tinted style loosely resembling the lxdialog theme
+
+It is possible to customize the current style by changing colors of UI
+elements on the screen. This is the list of elements that can be stylized:
+
+ - path Top row in the main display, with the menu path
+ - separator Separator lines between windows. Also used for the top line
+ in the symbol information display.
+ - list List of items, e.g. the main display
+ - selection Style for the selected item
+ - inv-list Like list, but for invisible items. Used in show-all mode.
+ - inv-selection Like selection, but for invisible items. Used in show-all
+ mode.
+ - help Help text windows at the bottom of various fullscreen
+ dialogs
+ - show-help Window showing the help text in show-help mode
+ - frame Frame around dialog boxes
+ - body Body of dialog boxes
+ - edit Edit box in pop-up dialogs
+ - jump-edit Edit box in jump-to dialog
+ - text Symbol information text
+
+The color definition is a comma separated list of attributes:
+
+ - fg:COLOR Set the foreground/background colors. COLOR can be one of
+ * or * the basic 16 colors (black, red, green, yellow, blue,
+ - bg:COLOR magenta, cyan, white and brighter versions, for example,
+ brightred). On terminals that support more than 8 colors,
+ you can also directly put in a color number, e.g. fg:123
+ (hexadecimal and octal constants are accepted as well).
+ Colors outside the range -1..curses.COLORS-1 (which is
+ terminal-dependent) are ignored (with a warning). The COLOR
+ can be also specified using a RGB value in the HTML
+ notation, for example #RRGGBB. If the terminal supports
+ color changing, the color is rendered accurately.
+ Otherwise, the visually nearest color is used.
+
+ If the background or foreground color of an element is not
+ specified, it defaults to -1, representing the default
+ terminal foreground or background color.
+
+ Note: On some terminals a bright version of the color
+ implies bold.
+ - bold Use bold text
+ - underline Use underline text
+ - standout Standout text attribute (reverse color)
+
+More often than not, some UI elements share the same color definition. In such
+cases the right value may specify an UI element from which the color definition
+will be copied. For example, "separator=help" will apply the current color
+definition for "help" to "separator".
+
+A keyword without the '=' is assumed to be a style template. The template name
+is looked up in the built-in styles list and the style definition is expanded
+in-place. With this, built-in styles can be used as basis for new styles.
+
+For example, take the aquatic theme and give it a red selection bar:
+
+MENUCONFIG_STYLE="aquatic selection=fg:white,bg:red"
+
+If there's an error in the style definition or if a missing style is assigned
+to, the assignment will be ignored, along with a warning being printed on
+stderr.
+
+The 'default' theme is always implicitly parsed first, so the following two
+settings have the same effect:
+
+ MENUCONFIG_STYLE="selection=fg:white,bg:red"
+ MENUCONFIG_STYLE="default selection=fg:white,bg:red"
+
+If the terminal doesn't support colors, the 'monochrome' theme is used, and
+MENUCONFIG_STYLE is ignored. The assumption is that the environment is broken
+somehow, and that the important thing is to get something usable.
+
+
+Other features
+==============
+
+ - Seamless terminal resizing
+
+ - No dependencies on *nix, as the 'curses' module is in the Python standard
+ library
+
+ - Unicode text entry
+
+ - Improved information screen compared to mconf:
+
+ * Expressions are split up by their top-level &&/|| operands to improve
+ readability
+
+ * Undefined symbols in expressions are pointed out
+
+ * Menus and comments have information displays
+
+ * Kconfig definitions are printed
+
+ * The include path is shown, listing the locations of the 'source'
+ statements that included the Kconfig file of the symbol (or other
+ item)
+
+
+Limitations
+===========
+
+Doesn't work out of the box on Windows, but can be made to work with
+
+ pip install windows-curses
+
+See the https://github.com/zephyrproject-rtos/windows-curses repository.
+"""
+from __future__ import print_function
+
+import os
+import sys
+
+_IS_WINDOWS = os.name == "nt" # Are we running on Windows?
+
+try:
+ import curses
+except ImportError as e:
+ if not _IS_WINDOWS:
+ raise
+ sys.exit("""\
+menuconfig failed to import the standard Python 'curses' library. Try
+installing a package like windows-curses
+(https://github.com/zephyrproject-rtos/windows-curses) by running this command
+in cmd.exe:
+
+ pip install windows-curses
+
+Starting with Kconfiglib 13.0.0, windows-curses is no longer automatically
+installed when installing Kconfiglib via pip on Windows (because it breaks
+installation on MSYS2).
+
+Exception:
+{}: {}""".format(type(e).__name__, e))
+
+import errno
+import locale
+import re
+import textwrap
+
+
+# Copyright (c) 2011-2019, Ulf Magnusson
+# SPDX-License-Identifier: ISC
+
+"""
+Overview
+========
+
+Kconfiglib is a Python 2/3 library for scripting and extracting information
+from Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt)
+configuration systems.
+
+See the homepage at https://github.com/ulfalizer/Kconfiglib for a longer
+overview.
+
+Since Kconfiglib 12.0.0, the library version is available in
+kconfiglib.VERSION, which is a (, , ) tuple, e.g.
+(12, 0, 0).
+
+
+Using Kconfiglib on the Linux kernel with the Makefile targets
+==============================================================
+
+For the Linux kernel, a handy interface is provided by the
+scripts/kconfig/Makefile patch, which can be applied with either 'git am' or
+the 'patch' utility:
+
+ $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | git am
+ $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1
+
+Warning: Not passing -p1 to patch will cause the wrong file to be patched.
+
+Please tell me if the patch does not apply. It should be trivial to apply
+manually, as it's just a block of text that needs to be inserted near the other
+*conf: targets in scripts/kconfig/Makefile.
+
+Look further down for a motivation for the Makefile patch and for instructions
+on how you can use Kconfiglib without it.
+
+If you do not wish to install Kconfiglib via pip, the Makefile patch is set up
+so that you can also just clone Kconfiglib into the kernel root:
+
+ $ git clone git://github.com/ulfalizer/Kconfiglib.git
+ $ git am Kconfiglib/makefile.patch (or 'patch -p1 < Kconfiglib/makefile.patch')
+
+Warning: The directory name Kconfiglib/ is significant in this case, because
+it's added to PYTHONPATH by the new targets in makefile.patch.
+
+The targets added by the Makefile patch are described in the following
+sections.
+
+
+make kmenuconfig
+----------------
+
+This target runs the curses menuconfig interface with Python 3. As of
+Kconfiglib 12.2.0, both Python 2 and Python 3 are supported (previously, only
+Python 3 was supported, so this was a backport).
+
+
+make guiconfig
+--------------
+
+This target runs the Tkinter menuconfig interface. Both Python 2 and Python 3
+are supported. To change the Python interpreter used, pass
+PYTHONCMD= to 'make'. The default is 'python'.
+
+
+make [ARCH=] iscriptconfig
+--------------------------------
+
+This target gives an interactive Python prompt where a Kconfig instance has
+been preloaded and is available in 'kconf'. To change the Python interpreter
+used, pass PYTHONCMD= to 'make'. The default is 'python'.
+
+To get a feel for the API, try evaluating and printing the symbols in
+kconf.defined_syms, and explore the MenuNode menu tree starting at
+kconf.top_node by following 'next' and 'list' pointers.
+
+The item contained in a menu node is found in MenuNode.item (note that this can
+be one of the constants kconfiglib.MENU and kconfiglib.COMMENT), and all
+symbols and choices have a 'nodes' attribute containing their menu nodes
+(usually only one). Printing a menu node will print its item, in Kconfig
+format.
+
+If you want to look up a symbol by name, use the kconf.syms dictionary.
+
+
+make scriptconfig SCRIPT=