├── .clang-format ├── .gitignore ├── .vimrc ├── LICENSE ├── Makefile ├── README.rst ├── TODO ├── build_vs_released_binary.sh ├── inputs ├── README.rst ├── assert.cc ├── basic-kernel-call.cu ├── bigfunc.c ├── c_if_and_for.c ├── cfunc_with_if.c ├── cstr-for-replacement.cpp ├── ctor-initializer-list.cpp ├── cuda_support_header.h ├── diamond-cfg.ll ├── div0.c ├── fact.c ├── fact.ll ├── fptr.c ├── funcallsample.cpp ├── funcwithattr.c ├── globals.c ├── globals.ll ├── iflhsptr.c ├── kernel-signatures.c ├── loopy-cfg.ll ├── namesp.cpp ├── nestedloops.c ├── nullptr.cpp ├── pass-nullptr.c ├── ptrtoptrparam.c ├── simpleswitch.c ├── simpleswitch.ll ├── structinit.c ├── template-insts.cpp ├── threadidx.c ├── threadidx.ll ├── twodoublefoo.c ├── twodoublefoo.ll ├── types.c ├── types.ll ├── typeuse.cpp ├── union.c ├── using_builtins.c ├── vectortype.ll ├── with-headers1 │ ├── header.h │ ├── header_nested.h │ └── source.cpp └── xcudacxx11-repro.cpp ├── reformat.sh ├── src_clang ├── ClangCheck.cpp ├── experimental │ ├── RemoveCStrCalls.cpp │ ├── apply_replacements_with_rewriter.cpp │ ├── callexpr.py │ ├── kernel-sigs.py │ ├── show-mangle.py │ ├── showattrs.py │ ├── toplevel_decls.cpp │ └── try_matcher.cpp ├── matchers_rewriter.cpp ├── plugin_print_funcnames.cpp ├── rewritersample.cpp └── tooling_sample.cpp ├── src_llvm ├── access_debug_metadata.cpp ├── analyze_geps.cpp ├── bb_toposort_sccs.cpp ├── experimental │ ├── build_llvm_ir.cpp │ └── loop_info.cpp ├── hello_pass.cpp ├── replace_threadidx_with_call.cpp ├── simple_bb_pass.cpp └── simple_module_pass.cpp ├── stop.jpg ├── test ├── all_tests.py ├── test_bb_toposort_sccs.py ├── test_clang_check.py ├── test_hello_pass_plugin.py ├── test_rewriter_sample.py ├── test_simple_bb_pass.py ├── test_simple_module_pass.py ├── test_tooling_sample.py └── tools.py ├── tools ├── gen_c_straightline.py ├── htmlize-ast-dump.py ├── sample-ast-dump.txt ├── sample-js.js ├── show-cfg.py └── template.html └── using_clang_toolchain ├── Makefile ├── README.rst ├── cxx11-range-sample.cpp ├── exceptions1.cpp ├── memcaller.c ├── memmain.c ├── simple.cpp └── warn_in_macro.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.pyc 3 | *.dot 4 | 5 | -------------------------------------------------------------------------------- /.vimrc: -------------------------------------------------------------------------------- 1 | " Force indentation styles for this directory 2 | autocmd FileType python set shiftwidth=4 3 | autocmd FileType python set tabstop=4 4 | autocmd FileType python set softtabstop=4 5 | 6 | autocmd FileType c set shiftwidth=2 7 | autocmd FileType c set tabstop=2 8 | autocmd FileType c set softtabstop=2 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Sample makefile for building the code samples. Read inline comments for 3 | # documentation. 4 | # 5 | # Eli Bendersky (eliben@gmail.com) 6 | # This code is in the public domain 7 | #------------------------------------------------------------------------------- 8 | 9 | # The following variables will likely need to be customized, depending on where 10 | # and how you built LLVM & Clang. They can be overridden by setting them on the 11 | # make command line: "make VARNAME=VALUE", etc. 12 | 13 | # LLVM_SRC_PATH is the path to the root of the checked out source code. This 14 | # directory should contain the configure script, the include/ and lib/ 15 | # directories of LLVM, Clang in tools/clang/, etc. 16 | # 17 | # The most recent build from source of LLVM I did used the following cmake 18 | # invocation: 19 | # 20 | # $ cmake -DCMAKE_BUILD_TYPE=Release \ 21 | # -DLLVM_ENABLE_ASSERTIONS=ON \ 22 | # -DCMAKE_C_FLAGS=-DLLVM_ENABLE_DUMP \ 23 | # -DCMAKE_CXX_FLAGS=-DLLVM_ENABLE_DUMP \ 24 | # -DLLVM_TARGETS_TO_BUILD="X86" \ 25 | # -G Ninja 26 | # 27 | # Note that this is a release build with assertions enabled, and with 28 | # LLVM_ENABLE_DUMP explicitly passed. This is required to get the LLVM IR-level 29 | # 'dump' methods to work. With debug builds, assertions should be enabled by 30 | # default. Also note that a fairly recent version of cmake is required; the 31 | # latest I've been using is 3.5.2 32 | # 33 | # It is recommended to use a recent Clang to build LLVM itself. For example if 34 | # you have a Clang binary release in $CLANGDIR, cmake should be run with: 35 | # 36 | # $ CC=$CLANGDIR/bin/clang CXX=$CLANGDIR/bin/clang++ cmake .... 37 | # 38 | # Alternatively, if you're building vs. a binary distribution of LLVM 39 | # (downloaded from llvm.org), then LLVM_SRC_PATH can point to the main untarred 40 | # directory of the binary download (the directory that has bin/, lib/, include/ 41 | # and other directories inside). 42 | # See the build_vs_released_binary.sh script for an example. 43 | # 44 | # Changes for building against the Homebrew install of llvm on OSX platforms 45 | # (provided by b.van straalen Lawrence Berkeley National Lab) 46 | # 1. >brew install llvm --with-toolchain 47 | # 2. LLVM_SRC_PATH := /usr/local/opt/llvm 48 | # 3. LLVM_BUILD_PATH := $(LLVM_SRC_PATH) 49 | # 4. CXX:=$(LLVM_BUILD_PATH)/bin/clang++ 50 | # 5. PLUGIN_LDFLAGS := -shared -undefined dynamic_lookup 51 | # 6. -Wl,--start-group \ changed to -Wl, \ 52 | # 7 -Wl,--end-group changed to -Wl, 53 | 54 | LLVM_SRC_PATH := $$HOME/llvm/llvm_svn_rw 55 | 56 | # LLVM_BUILD_PATH is the directory in which you built LLVM - where you ran 57 | # configure or cmake. 58 | # For linking vs. a binary build of LLVM, point to the main untarred directory. 59 | # LLVM_BIN_PATH is the directory where binaries are placed by the LLVM build 60 | # process. It should contain the tools like opt, llc and clang. The default 61 | # reflects a release build with CMake and Ninja. binary build of LLVM, point it 62 | # to the bin/ directory. 63 | LLVM_BUILD_PATH := $$HOME/llvm/build/svn-ninja-release 64 | LLVM_BIN_PATH := $(LLVM_BUILD_PATH)/bin 65 | 66 | $(info -----------------------------------------------) 67 | $(info Using LLVM_SRC_PATH = $(LLVM_SRC_PATH)) 68 | $(info Using LLVM_BUILD_PATH = $(LLVM_BUILD_PATH)) 69 | $(info Using LLVM_BIN_PATH = $(LLVM_BIN_PATH)) 70 | $(info -----------------------------------------------) 71 | 72 | CXX := g++ 73 | CXXFLAGS := -fno-rtti -O0 -g 74 | PLUGIN_CXXFLAGS := -fpic 75 | 76 | LLVM_CXXFLAGS := `$(LLVM_BIN_PATH)/llvm-config --cxxflags` 77 | LLVM_LDFLAGS := `$(LLVM_BIN_PATH)/llvm-config --ldflags --libs --system-libs` 78 | 79 | # Plugins shouldn't link LLVM and Clang libs statically, because they are 80 | # already linked into the main executable (opt or clang). LLVM doesn't like its 81 | # libs to be linked more than once because it uses globals for configuration 82 | # and plugin registration, and these trample over each other. 83 | LLVM_LDFLAGS_NOLIBS := `$(LLVM_BIN_PATH)/llvm-config --ldflags` 84 | PLUGIN_LDFLAGS := -shared 85 | 86 | # These are required when compiling vs. a source distribution of Clang. For 87 | # binary distributions llvm-config --cxxflags gives the right path. 88 | CLANG_INCLUDES := \ 89 | -I$(LLVM_SRC_PATH)/tools/clang/include \ 90 | -I$(LLVM_BUILD_PATH)/tools/clang/include 91 | 92 | # List of Clang libraries to link. The proper -L will be provided by the 93 | # call to llvm-config 94 | # Note that I'm using -Wl,--{start|end}-group around the Clang libs; this is 95 | # because there are circular dependencies that make the correct order difficult 96 | # to specify and maintain. The linker group options make the linking somewhat 97 | # slower, but IMHO they're still perfectly fine for tools that link with Clang. 98 | CLANG_LIBS := \ 99 | -Wl,--start-group \ 100 | -lclangAST \ 101 | -lclangASTMatchers \ 102 | -lclangAnalysis \ 103 | -lclangBasic \ 104 | -lclangDriver \ 105 | -lclangEdit \ 106 | -lclangFrontend \ 107 | -lclangFrontendTool \ 108 | -lclangLex \ 109 | -lclangParse \ 110 | -lclangSema \ 111 | -lclangEdit \ 112 | -lclangRewrite \ 113 | -lclangRewriteFrontend \ 114 | -lclangStaticAnalyzerFrontend \ 115 | -lclangStaticAnalyzerCheckers \ 116 | -lclangStaticAnalyzerCore \ 117 | -lclangCrossTU \ 118 | -lclangIndex \ 119 | -lclangSerialization \ 120 | -lclangToolingCore \ 121 | -lclangTooling \ 122 | -lclangFormat \ 123 | -Wl,--end-group 124 | 125 | # Internal paths in this project: where to find sources, and where to put 126 | # build artifacts. 127 | SRC_LLVM_DIR := src_llvm 128 | SRC_CLANG_DIR := src_clang 129 | BUILDDIR := build 130 | 131 | .PHONY: all 132 | all: make_builddir \ 133 | emit_build_config \ 134 | $(BUILDDIR)/bb_toposort_sccs \ 135 | $(BUILDDIR)/simple_module_pass \ 136 | $(BUILDDIR)/simple_bb_pass \ 137 | $(BUILDDIR)/analyze_geps \ 138 | $(BUILDDIR)/hello_pass.so \ 139 | $(BUILDDIR)/replace_threadidx_with_call \ 140 | $(BUILDDIR)/access_debug_metadata \ 141 | $(BUILDDIR)/clang-check \ 142 | $(BUILDDIR)/rewritersample \ 143 | $(BUILDDIR)/matchers_rewriter \ 144 | $(BUILDDIR)/tooling_sample \ 145 | $(BUILDDIR)/plugin_print_funcnames.so 146 | 147 | .PHONY: test 148 | test: emit_build_config 149 | python3 test/all_tests.py 150 | 151 | .PHONY: emit_build_config 152 | emit_build_config: make_builddir 153 | @echo $(LLVM_BIN_PATH) > $(BUILDDIR)/_build_config 154 | 155 | .PHONY: make_builddir 156 | make_builddir: 157 | @test -d $(BUILDDIR) || mkdir $(BUILDDIR) 158 | 159 | $(BUILDDIR)/simple_bb_pass: $(SRC_LLVM_DIR)/simple_bb_pass.cpp 160 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ $(LLVM_LDFLAGS) -o $@ 161 | 162 | $(BUILDDIR)/analyze_geps: $(SRC_LLVM_DIR)/analyze_geps.cpp 163 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ $(LLVM_LDFLAGS) -o $@ 164 | 165 | $(BUILDDIR)/replace_threadidx_with_call: $(SRC_LLVM_DIR)/replace_threadidx_with_call.cpp 166 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ $(LLVM_LDFLAGS) -o $@ 167 | 168 | $(BUILDDIR)/simple_module_pass: $(SRC_LLVM_DIR)/simple_module_pass.cpp 169 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ $(LLVM_LDFLAGS) -o $@ 170 | 171 | $(BUILDDIR)/access_debug_metadata: $(SRC_LLVM_DIR)/access_debug_metadata.cpp 172 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ $(LLVM_LDFLAGS) -o $@ 173 | 174 | $(BUILDDIR)/bb_toposort_sccs: $(SRC_LLVM_DIR)/bb_toposort_sccs.cpp 175 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ $(LLVM_LDFLAGS) -o $@ 176 | 177 | $(BUILDDIR)/hello_pass.so: $(SRC_LLVM_DIR)/hello_pass.cpp 178 | $(CXX) $(PLUGIN_CXXFLAGS) $(CXXFLAGS) $(LLVM_CXXFLAGS) \ 179 | $^ $(PLUGIN_LDFLAGS) $(LLVM_LDFLAGS_NOLIBS) -o $@ 180 | 181 | $(BUILDDIR)/clang-check: $(SRC_CLANG_DIR)/ClangCheck.cpp 182 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 183 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 184 | 185 | $(BUILDDIR)/rewritersample: $(SRC_CLANG_DIR)/rewritersample.cpp 186 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 187 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 188 | 189 | $(BUILDDIR)/tooling_sample: $(SRC_CLANG_DIR)/tooling_sample.cpp 190 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 191 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 192 | 193 | $(BUILDDIR)/matchers_rewriter: $(SRC_CLANG_DIR)/matchers_rewriter.cpp 194 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 195 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 196 | 197 | $(BUILDDIR)/plugin_print_funcnames.so: $(SRC_CLANG_DIR)/plugin_print_funcnames.cpp 198 | $(CXX) $(PLUGIN_CXXFLAGS) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 199 | $(PLUGIN_LDFLAGS) $(LLVM_LDFLAGS_NOLIBS) -o $@ 200 | 201 | # Experimental tools - use at your own peril. 202 | # 203 | .PHONY: experimental_tools 204 | experimental_tools: make_builddir \ 205 | emit_build_config \ 206 | $(BUILDDIR)/loop_info \ 207 | $(BUILDDIR)/build_llvm_ir \ 208 | $(BUILDDIR)/remove-cstr-calls \ 209 | $(BUILDDIR)/toplevel_decls \ 210 | $(BUILDDIR)/try_matcher 211 | 212 | $(BUILDDIR)/loop_info: $(SRC_LLVM_DIR)/experimental/loop_info.cpp 213 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ $(LLVM_LDFLAGS) -o $@ 214 | 215 | # build_llvm_ir needs -rdynamic so that it can dlsym symbols from its own 216 | # binary in the JIT. 217 | $(BUILDDIR)/build_llvm_ir: $(SRC_LLVM_DIR)/experimental/build_llvm_ir.cpp 218 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $^ -rdynamic $(LLVM_LDFLAGS) -o $@ 219 | 220 | $(BUILDDIR)/remove-cstr-calls: $(SRC_CLANG_DIR)/experimental/RemoveCStrCalls.cpp 221 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 222 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 223 | 224 | $(BUILDDIR)/toplevel_decls: $(SRC_CLANG_DIR)/experimental/toplevel_decls.cpp 225 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 226 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 227 | 228 | $(BUILDDIR)/try_matcher: $(SRC_CLANG_DIR)/experimental/try_matcher.cpp 229 | $(CXX) $(CXXFLAGS) $(LLVM_CXXFLAGS) $(CLANG_INCLUDES) $^ \ 230 | $(CLANG_LIBS) $(LLVM_LDFLAGS) -o $@ 231 | 232 | .PHONY: clean format 233 | 234 | clean: 235 | rm -rf $(BUILDDIR)/* *.dot test/*.pyc test/__pycache__ 236 | 237 | format: 238 | find . -name "*.cpp" | xargs clang-format -style=file -i 239 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | **Note (Sep-18-2018)**: this repository is now unmaintained. Keeping 2 | out-of-source samples working with LLVM & Clang is tricky because of the 3 | continuously changing build requirements. I have been working on other stuff 4 | recently and haven't had the time and stamina to keep up-to-date. 5 | 6 | I may take maintainership up again in the future. 7 | 8 | .. image:: https://raw.github.com/eliben/llvm-clang-samples/master/stop.jpg 9 | :align: center 10 | 11 | LLVM & Clang library usage samples 12 | ================================== 13 | 14 | A collection of samples for using LLVM and Clang as libraries. 15 | 16 | Branches 17 | -------- 18 | 19 | LLVM & Clang evolve rapidly and the C++ API is not stable. This means that code 20 | that links against LLVM & Clang as libraries in version X may very well not 21 | compile or work in version X+1. 22 | 23 | Therefore, this repository has branches that track LLVM versions. For example, 24 | in branch ``llvm4.0`` the code should compile and work when linked against the 25 | released LLVM 4.0; The code in the ``master`` branch attempts to track the 26 | upstream trunk, but may sometimes lag behind. Also, note that as more samples 27 | are added I'll usually add them to ``master`` and will not backport them to 28 | older branches. 29 | 30 | In any case, if anything doesn't compile as you'd expect it to, please open 31 | an issue. 32 | 33 | Last known LLVM build revision for the master branch 34 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 35 | 36 | The last upstream LLVM revision I've successfully built the ``master`` branch 37 | against is r332892 (21-May-2018). It may build with newer revisions, or it may 38 | not. If you know it builds successfully with a newer one, please let me know and 39 | I'll update this note. 40 | 41 | What is where 42 | ------------- 43 | 44 | src_llvm/ 45 | Source code for LLVM-based samples. These typically only require LLVM 46 | to compile and link. 47 | 48 | src_clang/ 49 | Source code for Clang-based samples. These require both LLVM and Clang. 50 | 51 | using_clang_toolchain/ 52 | Some samples of using Clang as a compilation toolchain for C and C++. 53 | 54 | inputs/ 55 | Some input files for the samples and tests. 56 | 57 | test/ 58 | Tests for the samples. 59 | 60 | Building the samples 61 | -------------------- 62 | 63 | A complete ``Makefile`` for Linux is included in the repository. Read the 64 | documentation at its top; it explains how to configure the build to find your 65 | local LLVM & Clang installation/build. A helper shell script named 66 | ``build_vs_released_binary.sh`` can make the build easier if you just point it 67 | to a directory when you've untarred a binary rlease. 68 | 69 | Note that LLVM & Clang use modern C++11 constructs and require a fairly 70 | up-to-date compiler and standard C++ library to build. 71 | `This blog post `_ 72 | may be useful if you don't have a modern C++ compiler on your machine. 73 | 74 | Running tests and tools 75 | ----------------------- 76 | 77 | Note: This is not really necessary to study the examples. The tests allow me to 78 | make sure the examples keep working as LLVM advances. 79 | 80 | For running the tests and auxiliary tools (and any other Python scripts in this 81 | repo), Python 3 is required (I tested with 3.3+). Once the samples are built 82 | with 'make', just run:: 83 | 84 | make test 85 | 86 | Note that it expects to find binaries from the LLVM directory with which the 87 | samples were built and linked. Look at the ``emit_build_config`` rule in the 88 | Makefile for more information. 89 | 90 | License 91 | ------- 92 | 93 | Unless stated otherwise, all the code in this repository is in the public 94 | domain. See the ``LICENSE`` file for more details. Some source files were taken 95 | almost verbatim from LLVM/Clang; for these, the LLVM license header comment is 96 | retained and LLVM's license applies (please see ``LICENSE.txt`` in the LLVM 97 | source tree). 98 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /build_vs_released_binary.sh: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Shows how to build the samples vs. a released binary download of LLVM & Clang. 3 | # 4 | # Assumes the binary release was downloaded from http://llvm.org/releases/ 5 | # and untarred in some directory. The actual script code here uses a location 6 | # I use on my machine, but that can be replaced by anything you fancy in the 7 | # BINARY_DIR_PATH variable. 8 | # 9 | # Eli Bendersky (eliben@gmail.com) 10 | # This code is in the public domain 11 | #------------------------------------------------------------------------------- 12 | 13 | #!/bin/bash 14 | 15 | set -eu 16 | set -x 17 | 18 | BINARY_DIR_PATH=${BINARY_DIR_PATH:-$HOME/llvm/llvm6.0-binaries} 19 | 20 | make -j8 \ 21 | CXX=$BINARY_DIR_PATH/bin/clang++ \ 22 | LLVM_SRC_PATH=$BINARY_DIR_PATH \ 23 | LLVM_BUILD_PATH=$BINARY_DIR_PATH/bin \ 24 | LLVM_BIN_PATH=$BINARY_DIR_PATH/bin 25 | 26 | make LLVM_BIN_PATH=$BINARY_DIR_PATH/bin test 27 | -------------------------------------------------------------------------------- /inputs/README.rst: -------------------------------------------------------------------------------- 1 | LLVM IR is in .ll files; if an .ll file has a corresponding .c file, then the 2 | .ll file can be generated by calling clang:: 3 | 4 | clang -cc1 -emit-llvm 5 | 6 | For an optimized version, the following can be used:: 7 | 8 | clang -O3 -c -emit-llvm z.c -S -o - 9 | 10 | -------------------------------------------------------------------------------- /inputs/assert.cc: -------------------------------------------------------------------------------- 1 | extern "C" void __assertfail( 2 | const void *message, 3 | const void *file, 4 | unsigned int line, 5 | const void *function, 6 | unsigned long charsize); 7 | 8 | void __assert_fail( 9 | const char *__assertion, 10 | const char *__file, 11 | unsigned int __line, 12 | const char *__function) 13 | { 14 | __assertfail( 15 | (const void *)__assertion, 16 | (const void *)__file, 17 | __line, 18 | (const void *)__function, 19 | sizeof(char)); 20 | } 21 | -------------------------------------------------------------------------------- /inputs/basic-kernel-call.cu: -------------------------------------------------------------------------------- 1 | __attribute__((global)) void kernel(int* in, int* out) {} 2 | 3 | 4 | void host_func_foobar(int* inbuf, int* outbuf) { 5 | kernel<<<1, 32>>>(inbuf, outbuf); 6 | } 7 | -------------------------------------------------------------------------------- /inputs/bigfunc.c: -------------------------------------------------------------------------------- 1 | #define N_WAVE 1024 2 | #define LOG2_N_WAVE 10 3 | 4 | typedef short fixed; 5 | 6 | fixed fix_mpy(fixed a, fixed b) { 7 | return ((long)(a) * (long)(b))>>15; 8 | } 9 | 10 | fixed foo2(fixed a) { 11 | return fix_mpy(a, a * 2) + fix_mpy(a, a * 3); 12 | } 13 | 14 | void foo3(fixed* q, fixed* w, int m) { 15 | int i; 16 | for (i = 0; i < m; ++i) { 17 | for (int j = 0; j < i; ++j) { 18 | for (int k = 0; k < j; ++k) { 19 | q[i] = m * w[j] + q[i-2]; 20 | q[k + 1] = w[j]; 21 | } 22 | } 23 | } 24 | } 25 | 26 | int fix_fft(fixed fr[], fixed fi[], fixed* Sinewave, int m, int inverse) 27 | { 28 | int mr,nn,i,j,l,k,istep, n, scale, shift; 29 | fixed qr,qi,tr,ti,wr,wi,t; 30 | 31 | n = 1< N_WAVE) 34 | return -1; 35 | 36 | mr = 0; 37 | nn = n - 1; 38 | scale = 0; 39 | 40 | foo3(fr, fi, m); 41 | 42 | for(m=1; m<=nn; ++m) { 43 | l = n; 44 | do { 45 | l >>= 1; 46 | } while(mr+l > nn); 47 | mr = foo2((mr & (l-1)) + l); 48 | 49 | if(mr <= m) continue; 50 | tr = fr[m]; 51 | fr[m] = fr[mr]; 52 | fr[mr] = tr; 53 | ti = fi[m]; 54 | fi[m] = fi[mr]; 55 | fi[mr] = ti; 56 | } 57 | 58 | foo3(fr, fi, m); 59 | foo3(fr, Sinewave, m); 60 | foo3(fr, fi, m); 61 | foo3(fr, Sinewave, m); 62 | foo3(fr, fi, m); 63 | foo3(fr, Sinewave, m); 64 | foo3(fr, fi, m); 65 | foo3(fr, Sinewave, m); 66 | foo3(fr, fi, m); 67 | foo3(fr, Sinewave, m); 68 | foo3(fr, fi, m); 69 | foo3(fr, Sinewave, m); 70 | foo3(fr, fi, m); 71 | foo3(fr, fi, m); 72 | foo3(fr, fi, m); 73 | foo3(fr, fi, m); 74 | foo3(fr, fi, m); 75 | foo3(fr, fi, m); 76 | foo3(fr, fi, m); 77 | foo3(fr, Sinewave, m); 78 | foo3(fr, fi, m); 79 | foo3(fr, Sinewave, m); 80 | foo3(fr, fi, m); 81 | foo3(fr, Sinewave, m); 82 | foo3(fr, fi, m); 83 | foo3(fr, Sinewave, m); 84 | foo3(fr, fi, m); 85 | foo3(fr, Sinewave, m); 86 | foo3(fr, fi, m); 87 | foo3(fr, Sinewave, m); 88 | foo3(fr, Sinewave, m); 89 | foo3(fr, fi, m); 90 | foo3(fr, Sinewave, m); 91 | foo3(fr, fi, m); 92 | foo3(fr, Sinewave, m); 93 | foo3(fr, fi, m); 94 | foo3(fr, Sinewave, m); 95 | foo3(fr, fi, m); 96 | foo3(fr, Sinewave, m); 97 | foo3(fr, fi, m); 98 | foo3(fr, Sinewave, m); 99 | foo3(fr, Sinewave, m); 100 | foo3(fr, fi, m); 101 | foo3(fr, Sinewave, m); 102 | foo3(fr, fi, m); 103 | foo3(fr, Sinewave, m); 104 | foo3(fr, fi, m); 105 | foo3(fr, Sinewave, m); 106 | foo3(fr, fi, m); 107 | foo3(fr, Sinewave, m); 108 | foo3(fr, fi, m); 109 | foo3(fr, Sinewave, m); 110 | foo3(fr, Sinewave, m); 111 | foo3(fr, fi, m); 112 | foo3(fr, Sinewave, m); 113 | foo3(fr, fi, m); 114 | foo3(fr, Sinewave, m); 115 | foo3(fr, fi, m); 116 | foo3(fr, Sinewave, m); 117 | foo3(fr, fi, m); 118 | foo3(fr, Sinewave, m); 119 | foo3(fr, fi, m); 120 | foo3(fr, Sinewave, m); 121 | foo3(fr, Sinewave, m); 122 | foo3(fr, fi, m); 123 | foo3(fr, Sinewave, m); 124 | foo3(fr, fi, m); 125 | foo3(fr, Sinewave, m); 126 | foo3(fr, fi, m); 127 | foo3(fr, Sinewave, m); 128 | foo3(fr, fi, m); 129 | foo3(fr, Sinewave, m); 130 | foo3(fr, fi, m); 131 | foo3(fr, Sinewave, m); 132 | foo3(fr, Sinewave, m); 133 | foo3(fr, fi, m); 134 | foo3(fr, Sinewave, m); 135 | foo3(fr, fi, m); 136 | foo3(fr, Sinewave, m); 137 | foo3(fr, fi, m); 138 | foo3(fr, Sinewave, m); 139 | foo3(fr, fi, m); 140 | foo3(fr, Sinewave, m); 141 | foo3(fr, fi, m); 142 | foo3(fr, Sinewave, m); 143 | foo3(fr, Sinewave, m); 144 | foo3(fr, fi, m); 145 | foo3(fr, Sinewave, m); 146 | foo3(fr, fi, m); 147 | foo3(fr, Sinewave, m); 148 | foo3(fr, fi, m); 149 | foo3(fr, Sinewave, m); 150 | foo3(fr, fi, m); 151 | foo3(fr, Sinewave, m); 152 | foo3(fr, fi, m); 153 | foo3(fr, Sinewave, m); 154 | l = 1; 155 | k = LOG2_N_WAVE-1; 156 | while(l < n) { 157 | if(inverse) { 158 | 159 | shift = 0; 160 | for(i=0; i 16383 || m > 16383) { 170 | shift = 1; 171 | break; 172 | } 173 | } 174 | if(shift) 175 | ++scale; 176 | } else { 177 | 178 | shift = 1; 179 | } 180 | istep = l << 1; 181 | for(m=0; m>= 1; 192 | wi >>= 1; 193 | } 194 | for(i=m; i>= 1; 234 | qi >>= 1; 235 | } 236 | fr[j] = qr - tr; 237 | fi[j] = qi - ti; 238 | fr[i] = qr + tr; 239 | fi[i] = qi + ti; 240 | } 241 | } 242 | --k; 243 | l = istep; 244 | } 245 | 246 | return scale; 247 | } 248 | -------------------------------------------------------------------------------- /inputs/c_if_and_for.c: -------------------------------------------------------------------------------- 1 | void foo(int* a, int *b) { 2 | if (a[0] > 1) { 3 | b[0] = 2; 4 | } 5 | } 6 | 7 | void bar(float x, float y); // just a declaration 8 | 9 | void bang(int* a, int v) { 10 | for (int i = 0; i < v; ++i) { 11 | a[i] -= i; 12 | } 13 | } -------------------------------------------------------------------------------- /inputs/cfunc_with_if.c: -------------------------------------------------------------------------------- 1 | void foo(int* a, int *b) { 2 | if (a[0] > 1) { 3 | b[0] = 2; 4 | } 5 | } 6 | 7 | void bar(float x, float y); // just a declaration 8 | -------------------------------------------------------------------------------- /inputs/cstr-for-replacement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(std::string s); 4 | 5 | int bar(std::string joe) { 6 | // This c_str() call should be replaced by remov-cstr-calls 7 | return foo(joe.c_str()); 8 | } 9 | -------------------------------------------------------------------------------- /inputs/ctor-initializer-list.cpp: -------------------------------------------------------------------------------- 1 | namespace detail { 2 | 3 | struct Base {}; 4 | 5 | constexpr int foo2(int i) { return 2 * i; } 6 | } 7 | 8 | namespace ns { 9 | 10 | // constexpr int foo2(int i) { 11 | // return 2*i; 12 | //} 13 | 14 | using detail::foo2; 15 | 16 | constexpr float foo2(float f) { return 2.2 + f; } 17 | 18 | float joe = foo2(45.4f); 19 | 20 | namespace Sambusak { 21 | 22 | constexpr double foo2(double d) { return d * 2.2; } 23 | } 24 | } 25 | 26 | int iii = ns::foo2(10); 27 | float fla = ns::foo2(4.4f); 28 | double dla = ns::Sambusak::foo2(4.4); 29 | 30 | void bbbb() { 31 | auto func = ns::Sambusak::foo2; 32 | int k = func(10); 33 | } 34 | 35 | template class Foo : public detail::Base { 36 | public: 37 | typedef typename T::zoo_type arg_type; 38 | 39 | Foo(char c) : iguana(c) { f = 0.9; } 40 | 41 | Foo(arg_type i_, float f_) : kak(i_), iguana(ns::foo2(i_)), f(f_) {} 42 | Foo(arg_type i_, float f_, int tt) { 43 | using ns::foo2; 44 | iguana = foo2(i_, i_); 45 | } 46 | 47 | Foo() : detail::Base(), iguana(1) {} 48 | 49 | private: 50 | int kak; 51 | int iguana; 52 | float f; 53 | 54 | struct Faborz { 55 | } faborz; 56 | }; 57 | -------------------------------------------------------------------------------- /inputs/cuda_support_header.h: -------------------------------------------------------------------------------- 1 | /* Minimal declarations for CUDA support. Testing purposes only. */ 2 | 3 | #define __constant__ __attribute__((constant)) 4 | #define __device__ __attribute__((device)) 5 | #define __global__ __attribute__((global)) 6 | #define __host__ __attribute__((host)) 7 | #define __shared__ __attribute__((shared)) 8 | #define __launch_bounds__(...) __attribute__((launch_bounds(__VA_ARGS__))) 9 | 10 | struct dim3 { 11 | unsigned x, y, z; 12 | __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1) : x(x), y(y), z(z) {} 13 | }; 14 | 15 | typedef struct cudaStream *cudaStream_t; 16 | 17 | int cudaConfigureCall(dim3 gridSize, dim3 blockSize, unsigned sharedSize = 0, 18 | cudaStream_t stream = 0); 19 | -------------------------------------------------------------------------------- /inputs/diamond-cfg.ll: -------------------------------------------------------------------------------- 1 | ; Crafted to have a diamond-like CFG for testing the CFG analysis 2 | ; samples. 3 | 4 | define i32 @func(i32 %a, i32 %b) #0 { 5 | AA: 6 | %cmp1 = icmp eq i32 %a, %b 7 | br i1 %cmp1, label %BB, label %CC 8 | 9 | BB: 10 | %cmp2 = icmp ult i32 %a, %b 11 | br i1 %cmp2, label %CC, label %DD 12 | 13 | CC: 14 | br label %DD 15 | 16 | DD: 17 | ret i32 %a 18 | } 19 | 20 | -------------------------------------------------------------------------------- /inputs/div0.c: -------------------------------------------------------------------------------- 1 | #define DODIV(a, b) ((a) / (b)) 2 | 3 | int test(int z) { 4 | if (z == 0) { 5 | #ifdef FOO 6 | return DODIV(1, z); 7 | #else 8 | return 1 - z; 9 | #endif 10 | } 11 | return 1 + z; 12 | } 13 | -------------------------------------------------------------------------------- /inputs/fact.c: -------------------------------------------------------------------------------- 1 | unsigned mult(unsigned a, unsigned b) { 2 | unsigned s = 0; 3 | for (int i = 0; i < a; ++i) { 4 | s += b; 5 | } 6 | return s; 7 | } 8 | 9 | unsigned fact(unsigned a) { 10 | if (a <= 1) { 11 | return 1; 12 | } else { 13 | return a * fact(a - 1); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /inputs/fact.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'fact.c' 2 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3 | target triple = "x86_64-unknown-linux-gnu" 4 | 5 | ; Function Attrs: nounwind 6 | define i32 @mult(i32 %a, i32 %b) #0 { 7 | %1 = alloca i32, align 4 8 | %2 = alloca i32, align 4 9 | %i = alloca i32, align 4 10 | %s = alloca i32, align 4 11 | store i32 %a, i32* %1, align 4 12 | store i32 %b, i32* %2, align 4 13 | store i32 0, i32* %s, align 4 14 | store i32 0, i32* %i, align 4 15 | br label %3 16 | 17 | ;