IteratorRecognition - A pass for LLVM opt
Introduction
This is a pass using LLVM
opt
.
Features
- Out-of-source builds thanks to cmake.
- In-tree
LLVM
builds.
Requirements
- cmake 3.2.0 or later
- C++ compilers:
- LLVM
tested with:
- 7.0.0
- GCC
tested with:
- ?.?.?
- googletest
tested with:
- 1.9.x
- LLVM
tested with:
External dependencies
- Boost:
- 1.68.0
Mandatory
- Pedigree pass is a requirement for building and executing this pass.
- cmake-utils
Used for supporting the
cmake
-based build system. Usinggit clone --recursive
should take care of everything. - sanitizers-cmake Used to provide support for sanitizers. Although the subproject is required for successful configuration, its use is optional.
Optional
None.
Other
Currently, for this pass to work via opt
and dynamic loading, the LLVM distribution used is required to have been
built with -DBUILD_SHARED_LIBS=On
.
How to build
git clone --recursive
this repo.- Create a directory for an out-of-source build and
cd
into it. - Run
cmake
andcmake --build .
with that appropriate options. For examples on the various options have a look at the build scripts (provided for convenience) located in theutils/scripts/build
subdirectory.
- compiler selection is catered by the
exports_local_*
scripts using theCC
andCXX
variables for my current machine, so adjust appropriately for your setup. - export one of the
exports_deps_*
scripts, depending on the kind of setup you are interested in.
- Optionally, you can install the pass by
cmake -DCMAKE_INSTALL_PREFIX=[path-to-install] -P cmake_install.cmake
Omitting CMAKE_INSTALL_PREFIX
will use the ../install/
directory relative to the build directory.
lit
-based tests can be run withcmake --build . --target check
- googletest-based unit tests can be run with
./run_unit_tests.sh
(see the script for details).
How to execute
The basic barebones way to use this plugin are listed below, but for more intricate and up-to-date incantations you
should have a look and use the scripts under utils/scripts/run/
which end up under the bin
subdirectory at the
installation root.
-
Using opt
opt -load [path to plugin]/libLLVMIteratorRecognitionPass.so -itr-recognize foo.bc -o foo.out.bc
-
Using clang
clang -Xclang -load -Xclang [path to plugin]/libLLVMIteratorRecognitionPass.so foo.c -o foo
Notes
Customizing
A first step towards customization is to search for the pattern [Ss]keleton]
and replace as with the desired name. A
general good approach is to prefix everything with the name of the pass, especially in languages that do not offer some
sort of namespace capability like cmake
.
Another customization that needs to be take care of in the case of creating a new project based on this template is the use of cmake-utils. There are 3 options:
- Just copy the files and include them in the new repository.
- Use it as a submodule using the initial URL address.
- Use it as a submodule using a fork of the initial URL address. This allows you to keep the repo separately and have full control on updates and other desired enhancements.
Clarifications on building
The shared object containing the pass is dynamically loaded by opt
. This poses a restriction on its build dependency
upon opt
and its transient dependency to the C++
library it is linked against. So, it is recommended to perform
readelf -d $(which opt)
and note which implementation of the C++
library it uses
(libc++
or libstdc++
). Then, you can influence which C++
library your pass uses with the
CMAKE_CXX_FLAGS
and the -stdlib
flag for LLVM
.
The main problem stems from the binary incompatibility (ABI) between the two implementations, although they are API
compatible since they adhere to the ISO standard. For this reason, libc++
uses the inlined namespace std::__1
, which
will show up in the errors when you have your pass built against libstdc++
and try to load it using an opt
built
against libc++
.
When LLVM
is build with BUILD_SHARED_LIBS=OFF
, opt
cannot load dynamically any pass built as a shared object,
complaining about multiply defined symbols, since it contains everything in its executable. The only workaround is to
build your pass in the LLVM
tree (resulting in a static archive, also included in the opt
executable).
Miscellaneous
When the build script uses LLVM
cmake
utility functions the lib
shared library prefix is omitted.
TODO
- Add
travis-ci
support.