├── docs ├── source │ ├── _static │ │ └── EMPTY │ ├── release-notes.rst │ ├── user-guide │ │ ├── index.rst │ │ ├── examples │ │ │ ├── test.ll │ │ │ ├── floatrep.py │ │ │ ├── ir_fpadd.py │ │ │ ├── parseasm.py │ │ │ ├── llvmir.py │ │ │ ├── ll_fpadd.py │ │ │ └── sum.py │ │ ├── binding │ │ │ ├── examples.rst │ │ │ ├── context.rst │ │ │ ├── dynamic-libraries.rst │ │ │ ├── index.rst │ │ │ ├── type-references.rst │ │ │ ├── analysis-utilities.rst │ │ │ ├── initialization-finalization.rst │ │ │ ├── object-file.rst │ │ │ ├── value-references.rst │ │ │ ├── execution-engine.rst │ │ │ ├── modules.rst │ │ │ └── optimization-passes.rst │ │ └── ir │ │ │ ├── examples.rst │ │ │ ├── index.rst │ │ │ ├── modules.rst │ │ │ └── types.rst │ ├── index.rst │ ├── glossary.rst │ └── contributing.rst └── gh-pages.py ├── llvmlite ├── llvmpy │ ├── __init__.py │ ├── passes.py │ └── core.py ├── tests │ ├── __main__.py │ ├── test_llvmpy.py │ ├── __init__.py │ └── test_valuerepr.py ├── ir │ ├── __init__.py │ ├── context.py │ ├── transforms.py │ └── _utils.py ├── __init__.py ├── binding │ ├── __init__.py │ ├── options.py │ ├── linker.py │ ├── context.py │ ├── common.py │ ├── dylib.py │ ├── initfini.py │ ├── analysis.py │ ├── object_file.py │ ├── transforms.py │ └── value.py └── utils.py ├── .gitattributes ├── requirements.txt ├── ffi ├── dummy │ └── CMakeLists.txt ├── Makefile.freebsd ├── Makefile.osx ├── dylib.cpp ├── core.h ├── Makefile.linux ├── assembly.cpp ├── bitcode.cpp ├── core.cpp ├── CMakeLists.txt ├── initfini.cpp ├── linker.cpp ├── object_file.cpp ├── passmanagers.cpp ├── transforms.cpp ├── value.cpp └── build.py ├── runtests.py ├── conda-recipes ├── llvmdev │ ├── test_cfg_dot.py │ ├── bld.bat │ ├── cfg_test.ll │ ├── build.sh │ ├── numba-3016.ll │ └── meta.yaml ├── llvmlite │ ├── run_test.py │ ├── bld.bat │ ├── build.sh │ └── meta.yaml ├── llvm-lto-static.patch ├── twine_cfg_undefined_behavior.patch ├── 0001-RuntimeDyld-Fix-a-bug-in-RuntimeDyld-loadObjectImpl-.patch ├── partial-testing.patch ├── llvmdev_manylinux1 │ ├── meta.yaml │ └── build.sh ├── appveyor │ └── run_with_env.cmd └── 0001-RuntimeDyld-Add-test-case-that-was-accidentally-left.patch ├── .gitignore ├── AUTHORS ├── MANIFEST.in ├── examples ├── test.ll ├── floatrep.py ├── ir_fpadd.py ├── parseasm.py ├── llvmir.py ├── ll_fpadd.py └── sum.py ├── .coveragerc ├── .codeclimate.yml ├── .landscape.yml ├── codecov.yml ├── .scrutinizer.yml ├── run_coverage.py ├── .travis.yml ├── appveyor.yml ├── azure-pipelines.yml ├── LICENSE ├── bench.py ├── README.rst └── setup.py /docs/source/_static/EMPTY: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /llvmlite/llvmpy/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | llvmlite/_version.py export-subst 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | enum34; python_version < '3.4' 2 | -------------------------------------------------------------------------------- /llvmlite/tests/__main__.py: -------------------------------------------------------------------------------- 1 | from . import main 2 | 3 | main() 4 | -------------------------------------------------------------------------------- /ffi/dummy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # A dummy project to exercise CMake settings 2 | 3 | project(llvmlite_dummy) 4 | -------------------------------------------------------------------------------- /docs/source/release-notes.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | Release Notes 3 | ============= 4 | 5 | .. include:: ../../CHANGE_LOG 6 | -------------------------------------------------------------------------------- /runtests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | from llvmlite.tests import main 6 | 7 | 8 | if __name__ == "__main__": 9 | main() 10 | -------------------------------------------------------------------------------- /docs/source/user-guide/index.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | User guide 3 | ========== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | ir/index 9 | binding/index 10 | -------------------------------------------------------------------------------- /conda-recipes/llvmdev/test_cfg_dot.py: -------------------------------------------------------------------------------- 1 | with open("cfg.testme.dot") as fin: 2 | got = fin.read() 3 | 4 | assert '[label="W:1"]' in got 5 | assert '[label="W:9"]' in got 6 | -------------------------------------------------------------------------------- /conda-recipes/llvmlite/run_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from llvmlite.tests import main 3 | 4 | # Enable tests for distribution only 5 | os.environ['LLVMLITE_DIST_TEST'] = '1' 6 | main() 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.pyd 3 | *.so 4 | *.dylib 5 | *.dll 6 | build/ 7 | dist/ 8 | *.egg-info 9 | ffi/build/ 10 | htmlcov/ 11 | .coverage 12 | coverage.xml 13 | MANIFEST 14 | docs/_build/ 15 | docs/gh-pages/ 16 | 17 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | This is the list of people who contributed to this repository: 2 | 3 | Antoine Pitrou 4 | Eli Bendersky 5 | Graham Markall, Embecosm 6 | Leonard Truong 7 | Rex.Ge 8 | Siu Kwan Lam 9 | Stan Seibert 10 | Yaniv Ben-Ami 11 | 12 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.rst setup.py runtests.py run_coverage.py LICENSE 2 | include versioneer.py 3 | include llvmlite/_version.py 4 | recursive-include examples *.py *.ll 5 | recursive-include ffi *.txt *.h *.cpp Makefile.* *.py 6 | global-exclude CMakeCache.txt 7 | -------------------------------------------------------------------------------- /llvmlite/ir/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This subpackage implements the LLVM IR classes in pure python 3 | """ 4 | 5 | from .types import * 6 | from .values import * 7 | from .module import * 8 | from .builder import * 9 | from .instructions import * 10 | from .transforms import * 11 | from .context import Context, global_context 12 | -------------------------------------------------------------------------------- /examples/test.ll: -------------------------------------------------------------------------------- 1 | define i32 @foo(i32 %.0, i32 %.1) noreturn 2 | { 3 | .2: 4 | %.3 = alloca i32 5 | store i32 123, i32* %.3 6 | %.5 = load i32* %.3 7 | %.6 = add i32 %.0, %.1 8 | %.7 = mul i32 %.6, 123 9 | %.8 = icmp slt i32 %.6, %.7 10 | ret i32 %.7 11 | .10: 12 | %.12 = trunc i32 %.6 to i1 13 | br i1 %.12, label %.10, label %.11 14 | .11: 15 | ret i32 %.5 16 | } 17 | 18 | -------------------------------------------------------------------------------- /llvmlite/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | try: 4 | import enum 5 | except ImportError: 6 | raise ImportError("could not find the 'enum' module; please install " 7 | "it using e.g. 'pip install enum34'") 8 | 9 | from ._version import get_versions 10 | __version__ = get_versions()['version'] 11 | del get_versions 12 | -------------------------------------------------------------------------------- /examples/floatrep.py: -------------------------------------------------------------------------------- 1 | from llvmlite.ir import Constant, FloatType, DoubleType 2 | import math 3 | 4 | print(Constant(FloatType(), math.pi)) 5 | print(Constant(DoubleType(), math.pi)) 6 | print(Constant(FloatType(), float('+inf'))) 7 | print(Constant(DoubleType(), float('+inf'))) 8 | print(Constant(FloatType(), float('-inf'))) 9 | print(Constant(DoubleType(), float('-inf'))) 10 | -------------------------------------------------------------------------------- /conda-recipes/llvmlite/bld.bat: -------------------------------------------------------------------------------- 1 | 2 | @rem Let CMake know about the LLVM install path, for find_package() 3 | set CMAKE_PREFIX_PATH=%LIBRARY_PREFIX% 4 | 5 | @rem Ensure there are no build leftovers (CMake can complain) 6 | if exist ffi\build rmdir /S /Q ffi\build 7 | 8 | %PYTHON% -S setup.py install 9 | if errorlevel 1 exit 1 10 | 11 | %PYTHON% runtests.py 12 | if errorlevel 1 exit 1 13 | -------------------------------------------------------------------------------- /docs/source/user-guide/examples/test.ll: -------------------------------------------------------------------------------- 1 | define i32 @foo(i32 %.0, i32 %.1) noreturn 2 | { 3 | .2: 4 | %.3 = alloca i32 5 | store i32 123, i32* %.3 6 | %.5 = load i32* %.3 7 | %.6 = add i32 %.0, %.1 8 | %.7 = mul i32 %.6, 123 9 | %.8 = icmp slt i32 %.6, %.7 10 | ret i32 %.7 11 | .10: 12 | %.12 = trunc i32 %.6 to i1 13 | br i1 %.12, label %.10, label %.11 14 | .11: 15 | ret i32 %.5 16 | } 17 | 18 | -------------------------------------------------------------------------------- /docs/source/user-guide/examples/floatrep.py: -------------------------------------------------------------------------------- 1 | from llvmlite.ir import Constant, FloatType, DoubleType 2 | import math 3 | 4 | print(Constant(FloatType(), math.pi)) 5 | print(Constant(DoubleType(), math.pi)) 6 | print(Constant(FloatType(), float('+inf'))) 7 | print(Constant(DoubleType(), float('+inf'))) 8 | print(Constant(FloatType(), float('-inf'))) 9 | print(Constant(DoubleType(), float('-inf'))) 10 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | # configuration file used by run_coverage.py 2 | [run] 3 | branch = True 4 | source = llvmlite 5 | 6 | [report] 7 | 8 | exclude_lines = 9 | pragma: no cover 10 | if __name__ == .__main__.: 11 | 12 | # General support infrastructure (third-party libs, testing machinery) 13 | # that we don't bother covering. 14 | omit = 15 | */__main__.py 16 | llvmlite/enum.py 17 | llvmlite/six.py 18 | llvmlite/_version.py 19 | llvmlite/tests/customize.py 20 | 21 | [html] 22 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | # Configuration for codeclimate.com 2 | 3 | engines: 4 | duplication: 5 | enabled: true 6 | config: 7 | languages: 8 | python: 9 | mass_threshold: 50 10 | fixme: 11 | enabled: true 12 | pep8: 13 | enabled: true 14 | radon: 15 | enabled: true 16 | 17 | ratings: 18 | paths: 19 | - "llvmlite/**.py" 20 | 21 | exclude_paths: 22 | - "**/six.py" 23 | - "**/_version.py" 24 | -------------------------------------------------------------------------------- /llvmlite/binding/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Things that relies on LLVM library 3 | """ 4 | from __future__ import print_function, absolute_import 5 | 6 | from .dylib import * 7 | from .executionengine import * 8 | from .initfini import * 9 | from .linker import * 10 | from .module import * 11 | from .options import * 12 | from .passmanagers import * 13 | from .targets import * 14 | from .transforms import * 15 | from .value import * 16 | from .analysis import * 17 | from .object_file import * 18 | from .context import * -------------------------------------------------------------------------------- /.landscape.yml: -------------------------------------------------------------------------------- 1 | # Configuration for landscape.io 2 | # See http://docs.landscape.io/configuration.html 3 | # and also http://prospector.landscape.io/en/master/profiles.html 4 | 5 | doc-warnings: false 6 | 7 | test-warnings: false 8 | 9 | strictness: medium 10 | 11 | max-line-length: 85 12 | 13 | autodetect: yes 14 | 15 | ignore-paths: 16 | - docs/ 17 | - setup.py 18 | - llvmlite/six.py 19 | - llvmlite/_version.py 20 | - versioneer.py 21 | 22 | python-targets: 23 | - 2 24 | - 3 25 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/examples.rst: -------------------------------------------------------------------------------- 1 | ===================================== 2 | Example---compiling a simple function 3 | ===================================== 4 | 5 | .. currentmodule:: llvmlite.binding 6 | 7 | 8 | Compile and execute the function defined in ``ir-fpadd.py``. 9 | For more information on ``ir-fpadd.py``, see 10 | :doc:`Example---Defining a simple function <../ir/examples>`. 11 | The function is compiled with no specific optimizations. 12 | 13 | .. literalinclude:: ../examples/ll_fpadd.py 14 | -------------------------------------------------------------------------------- /ffi/Makefile.freebsd: -------------------------------------------------------------------------------- 1 | 2 | CXX = clang++ -std=c++11 -stdlib=libc++ 3 | CXXFLAGS = $(LLVM_CXXFLAGS) 4 | LDFLAGS = $(LLVM_LDFLAGS) 5 | LIBS = $(LLVM_LIBS) 6 | INCLUDE = core.h 7 | SRC = assembly.cpp bitcode.cpp core.cpp initfini.cpp module.cpp value.cpp \ 8 | executionengine.cpp transforms.cpp passmanagers.cpp targets.cpp dylib.cpp \ 9 | linker.cpp object_file.cpp 10 | OUTPUT = libllvmlite.so 11 | 12 | all: $(OUTPUT) 13 | 14 | $(OUTPUT): $(SRC) $(INCLUDE) 15 | $(CXX) -shared $(CXXFLAGS) $(SRC) -o $(OUTPUT) $(LDFLAGS) $(LIBS) 16 | 17 | clean: 18 | rm -rf test 19 | -------------------------------------------------------------------------------- /llvmlite/tests/test_llvmpy.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for legacy llvmpy-compatibility APIs. 3 | """ 4 | 5 | from __future__ import print_function, absolute_import 6 | 7 | from . import TestCase 8 | 9 | 10 | class TestMisc(TestCase): 11 | 12 | def test_imports(self): 13 | """ 14 | Sanity-check llvmpy APIs import correctly. 15 | """ 16 | from llvmlite.llvmpy.core import Constant, Type, Builder 17 | from llvmlite.llvmpy.passes import create_pass_manager_builder 18 | 19 | 20 | if __name__ == '__main__': 21 | unittest.main() 22 | -------------------------------------------------------------------------------- /llvmlite/binding/options.py: -------------------------------------------------------------------------------- 1 | from . import ffi 2 | from .common import _encode_string 3 | from ctypes import c_char_p 4 | 5 | 6 | def set_option(name, option): 7 | """ 8 | Set the given LLVM "command-line" option. 9 | 10 | For example set_option("test", "-debug-pass=Structure") would display 11 | all optimization passes when generating code. 12 | """ 13 | ffi.lib.LLVMPY_SetCommandLine(_encode_string(name), 14 | _encode_string(option)) 15 | 16 | 17 | ffi.lib.LLVMPY_SetCommandLine.argtypes = [c_char_p, c_char_p] 18 | -------------------------------------------------------------------------------- /ffi/Makefile.osx: -------------------------------------------------------------------------------- 1 | 2 | CXX = clang++ -std=c++11 -stdlib=libc++ 3 | CXXFLAGS = $(LLVM_CXXFLAGS) 4 | LDFLAGS := $(LDFLAGS) $(LLVM_LDFLAGS) 5 | LIBS = $(LLVM_LIBS) 6 | INCLUDE = core.h 7 | SRC = assembly.cpp bitcode.cpp core.cpp initfini.cpp module.cpp value.cpp \ 8 | executionengine.cpp transforms.cpp passmanagers.cpp targets.cpp dylib.cpp \ 9 | linker.cpp object_file.cpp 10 | OUTPUT = libllvmlite.dylib 11 | MACOSX_DEPLOYMENT_TARGET ?= 10.9 12 | 13 | all: $(SRC) $(INCLUDE) 14 | MACOSX_DEPLOYMENT_TARGET=$(MACOSX_DEPLOYMENT_TARGET) $(CXX) -dynamiclib $(CXXFLAGS) $(SRC) -o $(OUTPUT) $(LDFLAGS) $(LIBS) 15 | 16 | clean: 17 | rm -rf test 18 | -------------------------------------------------------------------------------- /llvmlite/binding/linker.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function, absolute_import 2 | from ctypes import c_int, c_char_p, POINTER 3 | from . import ffi 4 | 5 | 6 | def link_modules(dst, src): 7 | with ffi.OutputString() as outerr: 8 | err = ffi.lib.LLVMPY_LinkModules(dst, src, outerr) 9 | # The underlying module was destroyed 10 | src.detach() 11 | if err: 12 | raise RuntimeError(str(outerr)) 13 | 14 | 15 | ffi.lib.LLVMPY_LinkModules.argtypes = [ 16 | ffi.LLVMModuleRef, 17 | ffi.LLVMModuleRef, 18 | POINTER(c_char_p), 19 | ] 20 | 21 | ffi.lib.LLVMPY_LinkModules.restype = c_int 22 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/context.rst: -------------------------------------------------------------------------------- 1 | Context 2 | ============ 3 | 4 | LLVMContext is an opaque context reference used to group modules into logical groups. 5 | For example, the type names are unique within a context, the name collisions 6 | are resolved by LLVM automatically. 7 | 8 | LLVMContextRef 9 | -------------- 10 | 11 | A wrapper around LLVMContext. Should not be instantiated directly, use the 12 | following methods: 13 | 14 | .. class:: LLVMContextRef 15 | 16 | * .. function:: create_context(): 17 | 18 | Create a new LLVMContext instance. 19 | 20 | * .. function:: get_global_context(): 21 | 22 | Get the reference to the global context. -------------------------------------------------------------------------------- /llvmlite/ir/context.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function, absolute_import 2 | from . import _utils 3 | from . import types 4 | 5 | 6 | class Context(object): 7 | def __init__(self): 8 | self.scope = _utils.NameScope() 9 | self.identified_types = {} 10 | 11 | def get_identified_type(self, name): 12 | if name not in self.identified_types: 13 | self.scope.register(name) 14 | ty = types.IdentifiedStructType(self, name) 15 | self.identified_types[name] = ty 16 | else: 17 | ty = self.identified_types[name] 18 | return ty 19 | 20 | 21 | global_context = Context() 22 | -------------------------------------------------------------------------------- /examples/ir_fpadd.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates a trivial function "fpadd" returning the sum of 3 | two floating-point numbers. 4 | """ 5 | 6 | from llvmlite import ir 7 | 8 | # Create some useful types 9 | double = ir.DoubleType() 10 | fnty = ir.FunctionType(double, (double, double)) 11 | 12 | # Create an empty module... 13 | module = ir.Module(name=__file__) 14 | # and declare a function named "fpadd" inside it 15 | func = ir.Function(module, fnty, name="fpadd") 16 | 17 | # Now implement the function 18 | block = func.append_basic_block(name="entry") 19 | builder = ir.IRBuilder(block) 20 | a, b = func.args 21 | result = builder.fadd(a, b, name="res") 22 | builder.ret(result) 23 | 24 | # Print the module IR 25 | print(module) 26 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | # Configuration for codecov.io 2 | # When editing this file, please validate its contents using: 3 | # curl -X POST --data-binary @- https://codecov.io/validate < codecov.yml 4 | 5 | comment: 6 | layout: "header, diff, changes, uncovered" 7 | 8 | coverage: 9 | ignore: 10 | - "numba/cuda/.*" 11 | - "numba/hsa/.*" 12 | 13 | status: 14 | # This check can mark a build failed if too much new code 15 | # is not covered (which happens often with JITted functions). 16 | patch: false 17 | project: 18 | default: 19 | # The build fails if total project coverage drops by more than 3% 20 | target: auto 21 | threshold: "3%" 22 | -------------------------------------------------------------------------------- /conda-recipes/llvm-lto-static.patch: -------------------------------------------------------------------------------- 1 | LTO is the only shared library built by LLVM. It breaks llvmlite 2 | builds under Windows with the following message: 3 | 4 | LINK : fatal error LNK1181: cannot open input file 'LTO-NOTFOUND.obj' 5 | 6 | diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt 7 | index 6e91351..66bea35 100644 8 | --- a/tools/lto/CMakeLists.txt 9 | +++ b/tools/lto/CMakeLists.txt 10 | @@ -16,7 +16,7 @@ set(SOURCES 11 | 12 | set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/lto.exports) 13 | 14 | -add_llvm_library(LTO SHARED ${SOURCES} DEPENDS intrinsics_gen) 15 | +add_llvm_library(LTO ${SOURCES} DEPENDS intrinsics_gen) 16 | 17 | install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h 18 | DESTINATION include/llvm-c 19 | -------------------------------------------------------------------------------- /docs/source/user-guide/examples/ir_fpadd.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates a trivial function "fpadd" returning the sum of 3 | two floating-point numbers. 4 | """ 5 | 6 | from llvmlite import ir 7 | 8 | # Create some useful types 9 | double = ir.DoubleType() 10 | fnty = ir.FunctionType(double, (double, double)) 11 | 12 | # Create an empty module... 13 | module = ir.Module(name=__file__) 14 | # and declare a function named "fpadd" inside it 15 | func = ir.Function(module, fnty, name="fpadd") 16 | 17 | # Now implement the function 18 | block = func.append_basic_block(name="entry") 19 | builder = ir.IRBuilder(block) 20 | a, b = func.args 21 | result = builder.fadd(a, b, name="res") 22 | builder.ret(result) 23 | 24 | # Print the module IR 25 | print(module) 26 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/dynamic-libraries.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Dynamic libraries and symbols 3 | ============================= 4 | 5 | .. currentmodule:: llvmlite.binding 6 | 7 | These functions tell LLVM how to resolve external symbols 8 | referred from compiled LLVM code. 9 | 10 | 11 | * .. function:: add_symbol(name, address) 12 | 13 | Register the *address* of global symbol *name*, for use from 14 | LLVM-compiled functions. 15 | 16 | 17 | * .. function:: address_of_symbol(name) 18 | 19 | Get the in-process address of symbol *name*. An integer is 20 | returned, or ``None`` if the symbol is not found. 21 | 22 | 23 | * .. function:: load_library_permanently(filename) 24 | 25 | Load an external shared library. *filename* is the path to the 26 | shared library file. 27 | 28 | -------------------------------------------------------------------------------- /llvmlite/utils.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import sys 4 | 5 | 6 | # This module must be importable without loading the binding, to avoid 7 | # bootstrapping issues in setup.py. 8 | 9 | def get_library_name(): 10 | """ 11 | Return the name of the llvmlite shared library file. 12 | """ 13 | if os.name == 'posix': 14 | if sys.platform == 'darwin': 15 | return 'libllvmlite.dylib' 16 | else: 17 | return 'libllvmlite.so' 18 | else: 19 | assert os.name == 'nt' 20 | return 'llvmlite.dll' 21 | 22 | 23 | def get_library_files(): 24 | """ 25 | Return the names of shared library files needed for this platform. 26 | """ 27 | files = [get_library_name()] 28 | if os.name == 'nt': 29 | files.extend(['msvcr120.dll', 'msvcp120.dll']) 30 | return files 31 | -------------------------------------------------------------------------------- /ffi/dylib.cpp: -------------------------------------------------------------------------------- 1 | #include "core.h" 2 | #include "llvm/Support/DynamicLibrary.h" 3 | #include "llvm/ADT/StringRef.h" 4 | 5 | extern "C" { 6 | 7 | API_EXPORT(void *) 8 | LLVMPY_SearchAddressOfSymbol(const char *name) 9 | { 10 | return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(name); 11 | } 12 | 13 | 14 | API_EXPORT(void) 15 | LLVMPY_AddSymbol(const char *name, 16 | void *addr) 17 | { 18 | llvm::sys::DynamicLibrary::AddSymbol(name, addr); 19 | } 20 | 21 | API_EXPORT(bool) 22 | LLVMPY_LoadLibraryPermanently(const char *filename, char **OutError) 23 | { 24 | std::string error; 25 | bool failed = llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename, &error); 26 | if (failed) { 27 | *OutError = strdup(error.c_str()); 28 | } 29 | return failed; 30 | } 31 | 32 | 33 | } // end extern "C" 34 | -------------------------------------------------------------------------------- /llvmlite/binding/context.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function, absolute_import 2 | 3 | from . import ffi 4 | 5 | 6 | def create_context(): 7 | return ContextRef(ffi.lib.LLVMPY_ContextCreate()) 8 | 9 | 10 | def get_global_context(): 11 | return GlobalContextRef(ffi.lib.LLVMPY_GetGlobalContext()) 12 | 13 | 14 | class ContextRef(ffi.ObjectRef): 15 | def __init__(self, context_ptr): 16 | super(ContextRef, self).__init__(context_ptr) 17 | 18 | def _dispose(self): 19 | ffi.lib.LLVMPY_ContextDispose(self) 20 | 21 | class GlobalContextRef(ContextRef): 22 | def _dispose(self): 23 | pass 24 | 25 | 26 | ffi.lib.LLVMPY_GetGlobalContext.restype = ffi.LLVMContextRef 27 | 28 | ffi.lib.LLVMPY_ContextCreate.restype = ffi.LLVMContextRef 29 | 30 | ffi.lib.LLVMPY_ContextDispose.argtypes = [ffi.LLVMContextRef] -------------------------------------------------------------------------------- /ffi/core.h: -------------------------------------------------------------------------------- 1 | #ifndef LLVMPY_CORE_H_ 2 | #define LLVMPY_CORE_H_ 3 | 4 | #include "llvm-c/Core.h" 5 | #include 6 | #include 7 | 8 | 9 | #if defined(_MSC_VER) 10 | #define HAVE_DECLSPEC_DLL 11 | #endif 12 | 13 | #if defined(HAVE_DECLSPEC_DLL) 14 | #define API_EXPORT(RTYPE) __declspec(dllexport) RTYPE 15 | #else 16 | #define API_EXPORT(RTYPE) RTYPE 17 | #endif 18 | 19 | extern "C" { 20 | 21 | API_EXPORT(const char *) 22 | LLVMPY_CreateString(const char *msg); 23 | 24 | API_EXPORT(const char *) 25 | LLVMPY_CreateByteString(const char *buf, size_t len); 26 | 27 | API_EXPORT(void) 28 | LLVMPY_DisposeString(const char *msg); 29 | 30 | API_EXPORT(LLVMContextRef) 31 | LLVMPY_GetGlobalContext(); 32 | 33 | API_EXPORT(LLVMContextRef) 34 | LLVMPY_ContextCreate(); 35 | 36 | } /* end extern "C" */ 37 | 38 | 39 | #endif /* LLVMPY_CORE_H_ */ 40 | -------------------------------------------------------------------------------- /docs/source/user-guide/ir/examples.rst: -------------------------------------------------------------------------------- 1 | ==================================== 2 | Example---defining a simple function 3 | ==================================== 4 | 5 | .. _ir-fpadd: 6 | 7 | This example defines a function that adds 2 double-precision, 8 | floating-point numbers. 9 | 10 | .. literalinclude:: ../examples/ir_fpadd.py 11 | 12 | The generated LLVM 13 | :ref:`intermediate representation ` 14 | is printed at the end: 15 | 16 | .. code-block:: llvm 17 | 18 | ; ModuleID = "examples/ir_fpadd.py" 19 | target triple = "unknown-unknown-unknown" 20 | target datalayout = "" 21 | 22 | define double @"fpadd"(double %".1", double %".2") 23 | { 24 | entry: 25 | %"res" = fadd double %".1", %".2" 26 | ret double %"res" 27 | } 28 | 29 | To learn how to compile and execute this function, see 30 | :doc:`../binding/index`. -------------------------------------------------------------------------------- /ffi/Makefile.linux: -------------------------------------------------------------------------------- 1 | # Using g++ is recommended for linking 2 | CXX ?= g++ 3 | 4 | # -flto and --exclude-libs allow us to remove those parts of LLVM we don't use 5 | CXX_FLTO_FLAGS ?= -flto 6 | LD_FLTO_FLAGS ?= -flto -Wl,--exclude-libs=ALL 7 | 8 | CXXFLAGS = $(LLVM_CXXFLAGS) $(CXX_FLTO_FLAGS) 9 | LDFLAGS := $(LDFLAGS) $(LLVM_LDFLAGS) $(LD_FLTO_FLAGS) 10 | LIBS = $(LLVM_LIBS) 11 | INCLUDE = core.h 12 | SRC = assembly.cpp bitcode.cpp core.cpp initfini.cpp module.cpp value.cpp \ 13 | executionengine.cpp transforms.cpp passmanagers.cpp targets.cpp dylib.cpp \ 14 | linker.cpp object_file.cpp 15 | OUTPUT = libllvmlite.so 16 | 17 | all: $(OUTPUT) 18 | 19 | $(OUTPUT): $(SRC) $(INCLUDE) 20 | # static-libstdc++ avoids runtime dependencies on a 21 | # particular libstdc++ version. 22 | $(CXX) $(CXX_STATIC_LINK) -shared $(CXXFLAGS) $(SRC) -o $(OUTPUT) $(LDFLAGS) $(LIBS) 23 | 24 | clean: 25 | rm -rf test $(OUTPUT) 26 | -------------------------------------------------------------------------------- /docs/source/user-guide/ir/index.rst: -------------------------------------------------------------------------------- 1 | .. _ir-layer: 2 | 3 | ====================== 4 | IR layer---llvmlite.ir 5 | ====================== 6 | 7 | .. module:: llvmlite.ir 8 | :synopsis: Classes for building the LLVM intermediate representation of functions. 9 | 10 | The :mod:`llvmlite.ir` module contains classes and utilities to 11 | build the LLVM 12 | :ref:`intermediate representation ` 13 | (IR) of native functions. 14 | 15 | The provided APIs may sometimes look like LLVM's C++ APIs, but 16 | they never call into LLVM, unless otherwise noted. Instead, they 17 | construct a pure Python representation of the IR. 18 | 19 | To use this module, you should be familiar with the concepts 20 | in the `LLVM Language Reference 21 | `_. 22 | 23 | .. toctree:: 24 | :maxdepth: 1 25 | 26 | types 27 | values 28 | modules 29 | ir-builder 30 | examples 31 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/index.rst: -------------------------------------------------------------------------------- 1 | .. _binding-layer: 2 | 3 | ===================================== 4 | LLVM binding layer---llvmlite.binding 5 | ===================================== 6 | 7 | .. module:: llvmlite.binding 8 | :synopsis: Interacting with the LLVM library. 9 | 10 | The :mod:`llvmlite.binding` module provides classes to interact 11 | with functionalities of the LLVM library. Generally, they closely 12 | mirror concepts of the C++ API. Only a small subset of the LLVM 13 | API is mirrored: those parts that have proven useful to 14 | implement Numba_'s JIT compiler. 15 | 16 | .. _Numba: http://numba.pydata.org/ 17 | 18 | 19 | .. toctree:: 20 | :maxdepth: 1 21 | 22 | initialization-finalization 23 | dynamic-libraries 24 | target-information 25 | context 26 | modules 27 | value-references 28 | type-references 29 | execution-engine 30 | object-file 31 | optimization-passes 32 | analysis-utilities 33 | examples 34 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/type-references.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Type references 3 | ================= 4 | 5 | .. currentmodule:: llvmlite.binding 6 | 7 | A type reference wraps an LLVM type. It allows accessing type's name and 8 | IR representation. It is also accepted by methods like 9 | :meth:`TargetData.get_abi_size`. 10 | 11 | The TypeRef class 12 | ------------------ 13 | 14 | .. class:: TypeRef 15 | 16 | A wrapper around an LLVM type. The attributes available are: 17 | 18 | * .. attribute:: name 19 | 20 | This type's name, as a string. 21 | 22 | * .. attribute:: is_pointer 23 | 24 | * ``True``---The type is a pointer type 25 | * ``False``---The type is not a pointer type 26 | 27 | * .. attribute:: element_type 28 | 29 | If the type is a pointer, return the pointed-to type. Raises a 30 | ValueError if the type is not a pointer type. 31 | 32 | * .. method:: __str__(self) 33 | 34 | Get the string IR representation of the type. 35 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | checks: 2 | python: 3 | code_rating: true 4 | duplicate_code: true 5 | variables_used_before_assignment: true 6 | variables_unused_variable: true 7 | variables_undefined_variable: true 8 | variables_undefined_all_variable: true 9 | variables_no_name_in_module: true 10 | variables_invalid_all_object: true 11 | variables_global_variable_undefined: true 12 | string_too_many_format_args: true 13 | string_too_few_format_args: true 14 | imports_relative_import: true 15 | imports_cyclic_import: true 16 | format_unnecessary_semicolon: true 17 | format_bad_whitespace: true 18 | basic_unreachable: true 19 | basic_empty_docstring: true 20 | basic_duplicate_key: true 21 | 22 | filter: 23 | excluded_paths: 24 | - 'llvmlite/tests/*' 25 | - 'llvmlite/six.py' 26 | - 'llvmlite/_version.py' 27 | - 'llvmlite/versioneer.py' 28 | -------------------------------------------------------------------------------- /ffi/assembly.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm/IR/LLVMContext.h" 2 | #include "llvm/IR/Module.h" 3 | #include "llvm/AsmParser/Parser.h" 4 | #include "llvm/Support/SourceMgr.h" 5 | #include "llvm/Support/raw_ostream.h" 6 | 7 | #include "llvm-c/Core.h" 8 | #include "core.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | extern "C" { 15 | 16 | API_EXPORT(LLVMModuleRef) 17 | LLVMPY_ParseAssembly(LLVMContextRef context, 18 | const char *ir, 19 | const char **outmsg) 20 | { 21 | using namespace llvm; 22 | 23 | SMDiagnostic error; 24 | 25 | Module *m = parseAssemblyString(ir, error, *unwrap(context)).release(); 26 | if (!m) { 27 | // Error occurred 28 | std::string osbuf; 29 | raw_string_ostream os(osbuf); 30 | error.print("", os); 31 | os.flush(); 32 | *outmsg = LLVMPY_CreateString(os.str().c_str()); 33 | return NULL; 34 | } 35 | return wrap(m); 36 | } 37 | 38 | } // end extern "C" 39 | -------------------------------------------------------------------------------- /examples/parseasm.py: -------------------------------------------------------------------------------- 1 | from llvmlite import binding as llvm 2 | from llvmlite import ir as lc 3 | 4 | llvm.initialize() 5 | llvm.initialize_native_target() 6 | llvm.initialize_native_asmprinter() 7 | 8 | mod = lc.Module() 9 | mod.triple = llvm.get_default_triple() 10 | func = lc.Function(mod, lc.FunctionType(lc.VoidType(), [lc.IntType(32)]), 11 | name='foo') 12 | builder = lc.IRBuilder(func.append_basic_block()) 13 | builder.ret_void() 14 | 15 | print(mod) 16 | 17 | mod = llvm.parse_assembly(str(mod)) 18 | 19 | mod.verify() 20 | print(repr(mod)) 21 | print(mod) 22 | 23 | with llvm.create_module_pass_manager() as pm: 24 | with llvm.create_pass_manager_builder() as pmb: 25 | pmb.populate(pm) 26 | pm.run(mod) 27 | 28 | print(mod) 29 | 30 | tm = llvm.Target.from_default_triple().create_target_machine() 31 | ee = llvm.create_mcjit_compiler(mod, tm) 32 | func = mod.get_function("foo") 33 | print(func, ee.get_function_address("foo")) 34 | ee.close() 35 | 36 | llvm.shutdown() 37 | 38 | -------------------------------------------------------------------------------- /examples/llvmir.py: -------------------------------------------------------------------------------- 1 | import llvmlite.ir as ll 2 | 3 | fntype = ll.FunctionType(ll.IntType(32), [ll.IntType(32), ll.IntType(32)]) 4 | 5 | module = ll.Module() 6 | 7 | func = ll.Function(module, fntype, name='foo') 8 | bb_entry = func.append_basic_block() 9 | 10 | builder = ll.IRBuilder() 11 | builder.position_at_end(bb_entry) 12 | 13 | stackint = builder.alloca(ll.IntType(32)) 14 | builder.store(ll.Constant(stackint.type.pointee, 123), stackint) 15 | myint = builder.load(stackint) 16 | 17 | addinstr = builder.add(func.args[0], func.args[1]) 18 | mulinstr = builder.mul(addinstr, ll.Constant(ll.IntType(32), 123)) 19 | pred = builder.icmp_signed('<', addinstr, mulinstr) 20 | builder.ret(mulinstr) 21 | 22 | bb_block = func.append_basic_block() 23 | builder.position_at_end(bb_block) 24 | 25 | bb_exit = func.append_basic_block() 26 | 27 | pred = builder.trunc(addinstr, ll.IntType(1)) 28 | builder.cbranch(pred, bb_block, bb_exit) 29 | 30 | builder.position_at_end(bb_exit) 31 | builder.ret(myint) 32 | 33 | print(module) 34 | -------------------------------------------------------------------------------- /docs/source/user-guide/examples/parseasm.py: -------------------------------------------------------------------------------- 1 | from llvmlite import binding as llvm 2 | from llvmlite import ir as lc 3 | 4 | llvm.initialize() 5 | llvm.initialize_native_target() 6 | llvm.initialize_native_asmprinter() 7 | 8 | mod = lc.Module() 9 | mod.triple = llvm.get_default_triple() 10 | func = lc.Function(mod, lc.FunctionType(lc.VoidType(), [lc.IntType(32)]), 11 | name='foo') 12 | builder = lc.IRBuilder(func.append_basic_block()) 13 | builder.ret_void() 14 | 15 | print(mod) 16 | 17 | mod = llvm.parse_assembly(str(mod)) 18 | 19 | mod.verify() 20 | print(repr(mod)) 21 | print(mod) 22 | 23 | with llvm.create_module_pass_manager() as pm: 24 | with llvm.create_pass_manager_builder() as pmb: 25 | pmb.populate(pm) 26 | pm.run(mod) 27 | 28 | print(mod) 29 | 30 | tm = llvm.Target.from_default_triple().create_target_machine() 31 | ee = llvm.create_mcjit_compiler(mod, tm) 32 | func = mod.get_function("foo") 33 | print(func, ee.get_function_address("foo")) 34 | ee.close() 35 | 36 | llvm.shutdown() 37 | 38 | -------------------------------------------------------------------------------- /docs/source/user-guide/examples/llvmir.py: -------------------------------------------------------------------------------- 1 | import llvmlite.ir as ll 2 | 3 | fntype = ll.FunctionType(ll.IntType(32), [ll.IntType(32), ll.IntType(32)]) 4 | 5 | module = ll.Module() 6 | 7 | func = ll.Function(module, fntype, name='foo') 8 | bb_entry = func.append_basic_block() 9 | 10 | builder = ll.IRBuilder() 11 | builder.position_at_end(bb_entry) 12 | 13 | stackint = builder.alloca(ll.IntType(32)) 14 | builder.store(ll.Constant(stackint.type.pointee, 123), stackint) 15 | myint = builder.load(stackint) 16 | 17 | addinstr = builder.add(func.args[0], func.args[1]) 18 | mulinstr = builder.mul(addinstr, ll.Constant(ll.IntType(32), 123)) 19 | pred = builder.icmp_signed('<', addinstr, mulinstr) 20 | builder.ret(mulinstr) 21 | 22 | bb_block = func.append_basic_block() 23 | builder.position_at_end(bb_block) 24 | 25 | bb_exit = func.append_basic_block() 26 | 27 | pred = builder.trunc(addinstr, ll.IntType(1)) 28 | builder.cbranch(pred, bb_block, bb_exit) 29 | 30 | builder.position_at_end(bb_exit) 31 | builder.ret(myint) 32 | 33 | print(module) 34 | -------------------------------------------------------------------------------- /conda-recipes/twine_cfg_undefined_behavior.patch: -------------------------------------------------------------------------------- 1 | From b42222e01abc1a799c4e421fa26d72d49afe4b99 Mon Sep 17 00:00:00 2001 2 | From: Siu Kwan Lam 3 | Date: Fri, 23 Mar 2018 11:46:45 -0500 4 | Subject: [PATCH] Patch to fix undefined behavior in cfgprinter 5 | 6 | --- 7 | include/llvm/Analysis/CFGPrinter.h | 3 +-- 8 | 1 file changed, 1 insertion(+), 2 deletions(-) 9 | 10 | diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h 11 | index 5786769..a4b642b 100644 12 | --- a/include/llvm/Analysis/CFGPrinter.h 13 | +++ b/include/llvm/Analysis/CFGPrinter.h 14 | @@ -172,8 +172,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { 15 | 16 | // Prepend a 'W' to indicate that this is a weight rather than the actual 17 | // profile count (due to scaling). 18 | - Twine Attrs = "label=\"W:" + Twine(Weight->getZExtValue()) + "\""; 19 | - return Attrs.str(); 20 | + return ("label=\"W:" + Twine(Weight->getZExtValue()) + "\"").str(); 21 | } 22 | }; 23 | } // End llvm namespace 24 | -- 25 | 2.10.1 26 | 27 | -------------------------------------------------------------------------------- /ffi/bitcode.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm-c/BitReader.h" 2 | #include "llvm-c/BitWriter.h" 3 | 4 | #include "core.h" 5 | 6 | 7 | extern "C" { 8 | 9 | API_EXPORT(void) 10 | LLVMPY_WriteBitcodeToString(LLVMModuleRef M, 11 | const char **outbuf, size_t *outlen) 12 | { 13 | LLVMMemoryBufferRef MB = LLVMWriteBitcodeToMemoryBuffer(M); 14 | *outlen = LLVMGetBufferSize(MB); 15 | *outbuf = LLVMPY_CreateByteString(LLVMGetBufferStart(MB), *outlen); 16 | LLVMDisposeMemoryBuffer(MB); 17 | } 18 | 19 | API_EXPORT(LLVMModuleRef) 20 | LLVMPY_ParseBitcode(LLVMContextRef context, 21 | const char *bitcode, size_t bitcodelen, 22 | char **outmsg) 23 | { 24 | LLVMModuleRef ref; 25 | LLVMMemoryBufferRef mem = LLVMCreateMemoryBufferWithMemoryRange( 26 | bitcode, bitcodelen, 27 | "" /* BufferName*/, 28 | 0 /* RequiresNullTerminator*/ 29 | ); 30 | 31 | LLVMParseBitcodeInContext(context, mem, &ref, outmsg); 32 | LLVMDisposeMemoryBuffer(mem); 33 | return ref; 34 | } 35 | 36 | } // end extern "C" 37 | -------------------------------------------------------------------------------- /run_coverage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Run code coverage sampling over the test suite, and produce 4 | an HTML report in "htmlcov". 5 | """ 6 | 7 | import os 8 | import shutil 9 | import sys 10 | 11 | try: 12 | import coverage 13 | except ImportError: 14 | raise ImportError("Please install the coverage module " 15 | "(https://pypi.python.org/pypi/coverage/)") 16 | 17 | 18 | if __name__ == "__main__": 19 | # We must start coverage before importing the package under test, 20 | # otherwise some lines will be missed. 21 | config_file = os.path.join( 22 | os.path.dirname(os.path.dirname(__file__)), 23 | '.coveragerc') 24 | os.environ['COVERAGE_PROCESS_START'] = config_file 25 | cov = coverage.coverage(config_file=config_file) 26 | cov.start() 27 | 28 | from llvmlite.tests import run_tests 29 | 30 | html_dir = 'htmlcov' 31 | try: 32 | run_tests() 33 | finally: 34 | cov.stop() 35 | cov.save() 36 | cov.combine() 37 | if os.path.exists(html_dir): 38 | shutil.rmtree(html_dir) 39 | cov.html_report(directory=html_dir) 40 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/analysis-utilities.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Analysis utilities 3 | ================== 4 | 5 | .. currentmodule:: llvmlite.binding 6 | 7 | .. function:: get_function_cfg(func, show_inst=True) 8 | 9 | Return a string of the control-flow graph of the function, 10 | in DOT format. 11 | 12 | * If `func` is not a materialized function, the module 13 | containing the function is parsed to create an actual 14 | LLVM module. 15 | * The `show_inst` flag controls whether the instructions of each block 16 | are ``printed.functions``. 17 | 18 | .. function:: view_dot_graph(graph, filename=None, view=False) 19 | 20 | View the given DOT source. This function requires the 21 | graphviz package. 22 | 23 | * If view is ``True``, the image is rendered and displayed in 24 | the default application in the system. The file path of the 25 | output is returned. 26 | * If view is ``False``, a ``graphviz.Source`` object is 27 | returned. 28 | * If view is ``False`` and the environment is in an IPython 29 | session, an IPython image object is returned and can be 30 | displayed inline in the notebook. 31 | -------------------------------------------------------------------------------- /ffi/core.cpp: -------------------------------------------------------------------------------- 1 | #include "core.h" 2 | 3 | #include "llvm-c/Support.h" 4 | 5 | extern "C" { 6 | 7 | API_EXPORT(const char *) 8 | LLVMPY_CreateString(const char *msg) { 9 | return strdup(msg); 10 | } 11 | 12 | API_EXPORT(const char *) 13 | LLVMPY_CreateByteString(const char *buf, size_t len) { 14 | char *dest = (char *) malloc(len + 1); 15 | if (dest != NULL) { 16 | memcpy(dest, buf, len); 17 | dest[len] = '\0'; 18 | } 19 | return dest; 20 | } 21 | 22 | API_EXPORT(void) 23 | LLVMPY_DisposeString(const char *msg) { 24 | free(const_cast(msg)); 25 | } 26 | 27 | API_EXPORT(LLVMContextRef) 28 | LLVMPY_GetGlobalContext() { 29 | return LLVMGetGlobalContext(); 30 | } 31 | 32 | API_EXPORT(LLVMContextRef) 33 | LLVMPY_ContextCreate() { 34 | return LLVMContextCreate(); 35 | } 36 | 37 | API_EXPORT(void) 38 | LLVMPY_ContextDispose(LLVMContextRef context) { 39 | return LLVMContextDispose(context); 40 | } 41 | 42 | API_EXPORT(void) 43 | LLVMPY_SetCommandLine(const char *name, const char *option) 44 | { 45 | const char *argv[] = {name, option}; 46 | LLVMParseCommandLineOptions(2, argv, NULL); 47 | } 48 | 49 | } // end extern "C" 50 | -------------------------------------------------------------------------------- /llvmlite/binding/common.py: -------------------------------------------------------------------------------- 1 | 2 | import atexit 3 | import sys 4 | 5 | 6 | if sys.version_info < (3, 0): 7 | def _encode_string(s): 8 | if isinstance(s, bytes): 9 | return s 10 | else: 11 | return s.encode('latin1') 12 | 13 | def _decode_string(b): 14 | return b 15 | else: 16 | def _encode_string(s): 17 | encoded = s.encode('latin1') 18 | return encoded 19 | 20 | def _decode_string(b): 21 | return b.decode('latin1') 22 | 23 | _encode_string.__doc__ = """Encode a string for use by LLVM.""" 24 | _decode_string.__doc__ = """Decode a LLVM character (byte)string.""" 25 | 26 | 27 | _shutting_down = [False] 28 | 29 | def _at_shutdown(): 30 | _shutting_down[0] = True 31 | 32 | atexit.register(_at_shutdown) 33 | 34 | def _is_shutting_down(_shutting_down=_shutting_down): 35 | """ 36 | Whether the interpreter is currently shutting down. 37 | For use in finalizers, __del__ methods, and similar; it is advised 38 | to early bind this function rather than look it up when calling it, 39 | since at shutdown module globals may be cleared. 40 | """ 41 | return _shutting_down[0] 42 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # TravisCI is testing manylinux1 wheels only. 2 | # Azure is used to test the Anaconda compiler toolchina. 3 | # 4 | # Reference: 5 | # - https://github.com/pypa/python-manylinux-demo 6 | 7 | sudo: required 8 | services: 9 | - docker 10 | 11 | matrix: 12 | include: 13 | - env: PYVER=cp27-cp27mu ARCH=x64 14 | - env: PYVER=cp35-cp35m ARCH=x64 15 | - env: PYVER=cp36-cp36m ARCH=x64 16 | - env: PYVER=cp37-cp37m ARCH=x64 17 | - env: PYVER=cp27-cp27mu ARCH=x32 18 | - env: PYVER=cp35-cp35m ARCH=x32 19 | - env: PYVER=cp36-cp36m ARCH=x32 20 | - env: PYVER=cp37-cp37m ARCH=x32 21 | 22 | 23 | install: 24 | - if [ "$ARCH" == "x64" ]; then DOCKER_IMAGE=quay.io/pypa/manylinux1_x86_64; else DOCKER_IMAGE=quay.io/pypa/manylinux1_i686; fi 25 | - docker pull $DOCKER_IMAGE 26 | 27 | script: 28 | - ./buildscripts/manylinux1/docker_run_$ARCH.sh build_llvmlite.sh $PYVER 29 | 30 | notifications: 31 | email: false 32 | on_success: "change" 33 | on_failure: "always" # "change" 34 | slack: 35 | secure: "FKl89SqORRj0CQCeZZ6vLzSyX8644b+c3VMO2lfTMDj5asnSYmq4J8cmytzLuTO4vCDXXNzqbO+8jCsPtnt+2gvXC+NccZOvlPsHXOy9Iu4SAfPKmN2rsxlu27Tn86HN5zgGJsm53aQFG2BXnsc848/HtSzzxdUx8oml6w3SdwI=" 36 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # Environment based on https://github.com/rmcgibbo/python-appveyor-conda-example 2 | 3 | environment: 4 | # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the 5 | # /E:ON and /V:ON options are not enabled in the batch script intepreter 6 | # See: http://stackoverflow.com/a/13751649/163740 7 | CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\conda-recipes\\appveyor\\run_with_env.cmd" 8 | 9 | matrix: 10 | # Since appveyor is quite slow, we only use a single configuration 11 | - PYTHON: "3.5" 12 | ARCH: "64" 13 | CONDA_ENV: testenv 14 | 15 | init: 16 | # Use AppVeyor's provided Miniconda: https://www.appveyor.com/docs/installed-software#python 17 | - if "%ARCH%" == "64" set MINICONDA=C:\Miniconda35-x64 18 | - if "%ARCH%" == "32" set MINICONDA=C:\Miniconda35 19 | - set PATH=%MINICONDA%;%MINICONDA%/Scripts;%MINICONDA%/Library/bin;%PATH% 20 | 21 | install: 22 | # Update to a known good conda 23 | # (to workaround http://help.appveyor.com/discussions/problems/4910) 24 | - conda install -q -y conda=4.1.4 25 | - buildscripts\\incremental\\setup_conda_environment.cmd 26 | # Build the package 27 | - buildscripts\\incremental\\build.cmd 28 | 29 | build: false 30 | 31 | test_script: 32 | - buildscripts\\incremental\\test.cmd 33 | -------------------------------------------------------------------------------- /conda-recipes/llvmlite/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | if [[ $(uname) == Darwin ]]; then 6 | ${SYS_PREFIX}/bin/conda create -y -p ${SRC_DIR}/bootstrap clangxx_osx-64 7 | export PATH=${SRC_DIR}/bootstrap/bin:${PATH} 8 | CONDA_PREFIX=${SRC_DIR}/bootstrap \ 9 | . ${SRC_DIR}/bootstrap/etc/conda/activate.d/* 10 | export CONDA_BUILD_SYSROOT=${CONDA_BUILD_SYSROOT:-/opt/MacOSX${MACOSX_DEPLOYMENT_TARGET}.sdk} 11 | export CXXFLAGS=${CFLAGS}" -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}" 12 | export CFLAGS=${CFLAGS}" -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}" 13 | SYSROOT_DIR=${CONDA_BUILD_SYSROOT} 14 | CFLAG_SYSROOT="--sysroot ${SYSROOT_DIR}" 15 | # export LLVM_CONFIG explicitly as the one installed from llvmdev 16 | # in the build root env, the one in the bootstrap location needs to be ignored. 17 | export LLVM_CONFIG="${PREFIX}/bin/llvm-config" 18 | ${LLVM_CONFIG} --version 19 | fi 20 | 21 | if [ -n "$MACOSX_DEPLOYMENT_TARGET" ]; then 22 | # OSX needs 10.7 or above with libc++ enabled 23 | export MACOSX_DEPLOYMENT_TARGET=10.10 24 | fi 25 | 26 | DARWIN_TARGET=x86_64-apple-darwin13.4.0 27 | 28 | 29 | export PYTHONNOUSERSITE=1 30 | # Enables static linking of stdlibc++ 31 | export LLVMLITE_CXX_STATIC_LINK=1 32 | 33 | $PYTHON setup.py build --force 34 | $PYTHON setup.py install 35 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | # Mac and Linux use the same template with different matrixes 3 | - template: buildscripts/azure/azure-linux-macos.yml 4 | parameters: 5 | name: macOS 6 | vmImage: xcode9-macos10.13 7 | matrix: 8 | py27: 9 | PYTHON: '2.7' 10 | CONDA_ENV: travisci 11 | py36: 12 | PYTHON: '3.6' 13 | CONDA_ENV: travisci 14 | 15 | - template: buildscripts/azure/azure-linux-macos.yml 16 | parameters: 17 | name: Linux 18 | vmImage: ubuntu-16.04 19 | matrix: 20 | py27: 21 | PYTHON: '2.7' 22 | CONDA_ENV: travisci 23 | py35: 24 | PYTHON: '3.5' 25 | CONDA_ENV: travisci 26 | py36: 27 | PYTHON: '3.6' 28 | CONDA_ENV: travisci 29 | py37: 30 | PYTHON: '3.7' 31 | CONDA_ENV: travisci 32 | pypy: 33 | PYTHON: pypy 34 | CONDA_ENV: travisci 35 | py27_wheel: 36 | PYTHON: '2.7' 37 | CONDA_ENV: travisci 38 | WHEEL: 'yes' 39 | py36_wheel: 40 | PYTHON: '3.6' 41 | CONDA_ENV: travisci 42 | WHEEL: 'yes' 43 | py37_wheel: 44 | PYTHON: '3.7' 45 | CONDA_ENV: travisci 46 | WHEEL: 'yes' 47 | 48 | - template: buildscripts/azure/azure-windows.yml 49 | parameters: 50 | name: Windows 51 | vmImage: vs2015-win2012r2 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-, Continuum Analytics, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /conda-recipes/0001-RuntimeDyld-Fix-a-bug-in-RuntimeDyld-loadObjectImpl-.patch: -------------------------------------------------------------------------------- 1 | From 88048c200486d7bf7fc81196798dbeefde6b80eb Mon Sep 17 00:00:00 2001 2 | From: Lang Hames 3 | Date: Sat, 18 Aug 2018 18:38:37 +0000 4 | Subject: [PATCH] [RuntimeDyld] Fix a bug in RuntimeDyld::loadObjectImpl that 5 | was over-allocating space for common symbols. 6 | 7 | Patch by Dmitry Sidorov. Thanks Dmitry! 8 | 9 | Differential revision: https://reviews.llvm.org/D50240 10 | 11 | git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340125 91177308-0d34-0410-b5e6-96231b3b80d8 12 | --- 13 | lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp | 2 +- 14 | 1 file changed, 1 insertion(+), 1 deletion(-) 15 | 16 | diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp 17 | index af5427e..df4bd572 100644 18 | --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp 19 | +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp 20 | @@ -277,7 +277,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { 21 | uint64_t Size = I->getCommonSize(); 22 | if (!CommonAlign) 23 | CommonAlign = Align; 24 | - CommonSize += alignTo(CommonSize, Align) + Size; 25 | + CommonSize = alignTo(CommonSize, Align) + Size; 26 | CommonSymbolsToAllocate.push_back(*I); 27 | } 28 | } else 29 | -- 30 | 1.8.3.1 31 | 32 | -------------------------------------------------------------------------------- /conda-recipes/partial-testing.patch: -------------------------------------------------------------------------------- 1 | Patch from: 2 | https://github.com/conda-forge/llvmdev-feedstock/pull/53 3 | 4 | LLVM build system does not allow to use llvm-lit without building 5 | unittests. However, unittests take a lot of time and the build fails 6 | in public CI. Thus, enabling only necessary cmake configs here, 7 | partially copying code from test/CMakeLists.txt 8 | 9 | diff --git a/CMakeLists.txt b/CMakeLists.txt 10 | index 31df6408..4538f912 100644 11 | --- a/CMakeLists.txt 12 | +++ b/CMakeLists.txt 13 | @@ -951,6 +951,28 @@ if( LLVM_INCLUDE_TESTS ) 14 | add_custom_target(test-depends 15 | DEPENDS ${LLVM_LIT_DEPENDS} ${LLVM_ADDITIONAL_TEST_DEPENDS}) 16 | set_target_properties(test-depends PROPERTIES FOLDER "Tests") 17 | +else() 18 | + # enable partial testing support 19 | + add_subdirectory(utils/lit) 20 | + llvm_canonicalize_cmake_booleans( 21 | + LLVM_TOOL_LTO_BUILD 22 | + HAVE_OCAMLOPT 23 | + HAVE_OCAML_OUNIT 24 | + LLVM_INCLUDE_GO_TESTS 25 | + LLVM_USE_INTEL_JITEVENTS 26 | + HAVE_LIBZ 27 | + HAVE_LIBXAR 28 | + LLVM_ENABLE_DIA_SDK 29 | + LLVM_ENABLE_FFI 30 | + BUILD_SHARED_LIBS 31 | + LLVM_LINK_LLVM_DYLIB 32 | + ) 33 | + configure_lit_site_cfg( 34 | + ${CMAKE_CURRENT_SOURCE_DIR}/test/lit.site.cfg.py.in 35 | + ${CMAKE_CURRENT_SOURCE_DIR}/test/lit.site.cfg.py 36 | + MAIN_CONFIG 37 | + ${CMAKE_CURRENT_SOURCE_DIR}/test/lit.cfg.py 38 | + ) 39 | endif() 40 | 41 | if (LLVM_INCLUDE_DOCS) 42 | -------------------------------------------------------------------------------- /ffi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 2.8.8) 3 | 4 | # This will define the name of the solution file in the build directory 5 | project(llvmlite_ffi) 6 | 7 | include(CheckIncludeFiles) 8 | 9 | find_package(LLVM REQUIRED CONFIG) 10 | 11 | message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 12 | message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") 13 | 14 | # Set your project compile flags. 15 | # E.g. if using the C++ header files 16 | # you will need to enable C++11 support 17 | # for your compiler. 18 | 19 | include_directories(${LLVM_INCLUDE_DIRS}) 20 | add_definitions(${LLVM_DEFINITIONS}) 21 | 22 | # Look for SVML 23 | set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIRS}) 24 | 25 | CHECK_INCLUDE_FILES("llvm/IR/SVML.inc" HAVE_SVML) 26 | if(HAVE_SVML) 27 | message(STATUS "SVML found") 28 | add_definitions(-DHAVE_SVML) 29 | else() 30 | message(STATUS "SVML not found") 31 | endif() 32 | 33 | 34 | # Define our shared library 35 | add_library(llvmlite SHARED assembly.cpp bitcode.cpp core.cpp initfini.cpp 36 | module.cpp value.cpp executionengine.cpp transforms.cpp 37 | passmanagers.cpp targets.cpp dylib.cpp linker.cpp object_file.cpp) 38 | 39 | # Find the libraries that correspond to the LLVM components 40 | # that we wish to use 41 | # llvm_map_components_to_libnames(llvm_libs support core irreader) 42 | llvm_map_components_to_libnames(llvm_libs all) 43 | 44 | # Link against LLVM libraries 45 | target_link_libraries(llvmlite ${llvm_libs}) 46 | -------------------------------------------------------------------------------- /llvmlite/binding/dylib.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, print_function 2 | from ctypes import c_void_p, c_char_p, c_bool, POINTER 3 | 4 | from . import ffi 5 | from .common import _encode_string 6 | 7 | 8 | def address_of_symbol(name): 9 | """ 10 | Get the in-process address of symbol named *name*. 11 | An integer is returned, or None if the symbol isn't found. 12 | """ 13 | return ffi.lib.LLVMPY_SearchAddressOfSymbol(_encode_string(name)) 14 | 15 | 16 | def add_symbol(name, address): 17 | """ 18 | Register the *address* of global symbol *name*. This will make 19 | it usable (e.g. callable) from LLVM-compiled functions. 20 | """ 21 | ffi.lib.LLVMPY_AddSymbol(_encode_string(name), c_void_p(address)) 22 | 23 | def load_library_permanently(filename): 24 | """ 25 | Load an external library 26 | """ 27 | with ffi.OutputString() as outerr: 28 | if ffi.lib.LLVMPY_LoadLibraryPermanently( 29 | _encode_string(filename), outerr): 30 | raise RuntimeError(str(outerr)) 31 | 32 | # ============================================================================ 33 | # FFI 34 | 35 | ffi.lib.LLVMPY_AddSymbol.argtypes = [ 36 | c_char_p, 37 | c_void_p, 38 | ] 39 | 40 | ffi.lib.LLVMPY_SearchAddressOfSymbol.argtypes = [c_char_p] 41 | ffi.lib.LLVMPY_SearchAddressOfSymbol.restype = c_void_p 42 | 43 | ffi.lib.LLVMPY_LoadLibraryPermanently.argtypes = [c_char_p, POINTER(c_char_p)] 44 | ffi.lib.LLVMPY_LoadLibraryPermanently.restype = c_bool 45 | -------------------------------------------------------------------------------- /ffi/initfini.cpp: -------------------------------------------------------------------------------- 1 | #include "llvm-c/Core.h" 2 | #include "llvm-c/Initialization.h" 3 | #include "llvm-c/Target.h" 4 | 5 | #include "core.h" 6 | #include "llvm/Config/llvm-config.h" 7 | 8 | extern "C" { 9 | 10 | 11 | #define INIT(F) \ 12 | API_EXPORT(void) LLVMPY_Initialize ## F() { \ 13 | LLVMInitialize ## F (LLVMGetGlobalPassRegistry()); } 14 | 15 | INIT(Core) 16 | INIT(TransformUtils) 17 | INIT(ScalarOpts) 18 | INIT(ObjCARCOpts) 19 | INIT(Vectorization) 20 | INIT(InstCombine) 21 | INIT(IPO) 22 | // INIT(Instrumentation) 23 | INIT(Analysis) 24 | INIT(IPA) 25 | INIT(CodeGen) 26 | INIT(Target) 27 | 28 | #undef INIT 29 | 30 | API_EXPORT(void) 31 | LLVMPY_Shutdown(){ 32 | LLVMShutdown(); 33 | } 34 | 35 | // Target Initialization 36 | #define INIT(F) API_EXPORT(void) LLVMPY_Initialize ## F() { LLVMInitialize ## F (); } 37 | 38 | // NOTE: it is important that we don't export functions which we don't use, 39 | // especially those which may pull in large amounts of additional code or data. 40 | 41 | INIT(AllTargetInfos) 42 | INIT(AllTargets) 43 | INIT(AllTargetMCs) 44 | INIT(AllAsmPrinters) 45 | INIT(NativeTarget) 46 | INIT(NativeAsmParser) 47 | INIT(NativeAsmPrinter) 48 | // INIT(NativeDisassembler) 49 | 50 | #undef INIT 51 | 52 | API_EXPORT(unsigned int) 53 | LLVMPY_GetVersionInfo() 54 | { 55 | unsigned int verinfo = 0; 56 | verinfo += LLVM_VERSION_MAJOR << 16; 57 | verinfo += LLVM_VERSION_MINOR << 8; 58 | #ifdef LLVM_VERSION_PATCH 59 | /* Not available under Windows... */ 60 | verinfo += LLVM_VERSION_PATCH << 0; 61 | #endif 62 | return verinfo; 63 | } 64 | 65 | } // end extern "C" 66 | -------------------------------------------------------------------------------- /conda-recipes/llvmdev/bld.bat: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build 3 | 4 | set BUILD_CONFIG=Release 5 | 6 | REM Configure step 7 | if "%ARCH%"=="32" ( 8 | set CMAKE_GENERATOR=Visual Studio 14 2015 9 | ) else ( 10 | set CMAKE_GENERATOR=Visual Studio 14 2015 Win64 11 | ) 12 | set CMAKE_GENERATOR_TOOLSET=v140_xp 13 | 14 | REM Reduce build times and package size by removing unused stuff 15 | set CMAKE_CUSTOM=-DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_INCLUDE_TESTS=OFF ^ 16 | -DLLVM_INCLUDE_UTILS=ON -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF ^ 17 | -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_USE_INTEL_JITEVENTS=ON 18 | 19 | cmake -G "%CMAKE_GENERATOR%" -T "%CMAKE_GENERATOR_TOOLSET%" ^ 20 | -DCMAKE_BUILD_TYPE="%BUILD_CONFIG%" -DCMAKE_PREFIX_PATH=%LIBRARY_PREFIX% ^ 21 | -DCMAKE_INSTALL_PREFIX:PATH=%LIBRARY_PREFIX% %CMAKE_CUSTOM% %SRC_DIR% 22 | if errorlevel 1 exit 1 23 | 24 | REM Build step 25 | cmake --build . --config "%BUILD_CONFIG%" 26 | if errorlevel 1 exit 1 27 | 28 | REM Install step 29 | cmake --build . --config "%BUILD_CONFIG%" --target install 30 | if errorlevel 1 exit 1 31 | 32 | REM From: https://github.com/conda-forge/llvmdev-feedstock/pull/53 33 | %BUILD_CONFIG%\bin\opt -S -vector-library=SVML -mcpu=haswell -O3 %RECIPE_DIR%\numba-3016.ll | %BUILD_CONFIG%\bin\FileCheck %RECIPE_DIR%\numba-3016.ll 34 | if errorlevel 1 exit 1 35 | 36 | REM This is technically how to run the suite, but it will only run in an 37 | REM enhanced unix-like shell which has functions like `grep` available. 38 | REM cd ..\test 39 | REM %PYTHON% ..\build\%BUILD_CONFIG%\bin\llvm-lit.py -vv Transforms ExecutionEngine Analysis CodeGen/X86 40 | REM if errorlevel 1 exit 1 41 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/initialization-finalization.rst: -------------------------------------------------------------------------------- 1 | =============================== 2 | Initialization and finalization 3 | =============================== 4 | 5 | .. currentmodule:: llvmlite.binding 6 | 7 | You only need to call these functions once per process invocation. 8 | 9 | * .. function:: initialize() 10 | 11 | Initialize the LLVM core. 12 | 13 | * .. function:: initialize_all_targets() 14 | 15 | Initialize all targets. Must be called before targets can 16 | be looked up via the :class:`Target` class. 17 | 18 | * .. function:: initialize_all_asmprinters() 19 | 20 | Initialize all code generators. Must be called before 21 | generating any assembly or machine code via the 22 | :meth:`TargetMachine.emit_object` and 23 | :meth:`TargetMachine.emit_assembly` methods. 24 | 25 | * .. function:: initialize_native_target() 26 | 27 | Initialize the native---host---target. Must be called once 28 | before doing any code generation. 29 | 30 | 31 | * .. function:: initialize_native_asmprinter() 32 | 33 | Initialize the native assembly printer. 34 | 35 | 36 | * .. function:: initialize_native_asmparser() 37 | 38 | Initialize the native assembly parser. Must be called for 39 | inline assembly to work. 40 | 41 | * .. function:: shutdown() 42 | 43 | Shut down the LLVM core. 44 | 45 | 46 | * .. data:: llvm_version_info 47 | 48 | A 3-integer tuple representing the LLVM version number. 49 | 50 | EXAMPLE: ``(3, 7, 1)`` 51 | 52 | Since LLVM is statically linked into the ``llvmlite`` DLL, 53 | this is guaranteed to represent the true LLVM version in use. 54 | 55 | -------------------------------------------------------------------------------- /llvmlite/tests/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | 4 | import unittest 5 | from unittest import TestCase 6 | 7 | try: 8 | import faulthandler 9 | except ImportError: 10 | pass 11 | else: 12 | try: 13 | # May fail in IPython Notebook with UnsupportedOperation 14 | faulthandler.enable() 15 | except BaseException as e: 16 | msg = "Failed to enable faulthandler due to:\n{err}" 17 | warnings.warn(msg.format(err=e)) 18 | 19 | 20 | # Try to inject Numba's unittest customizations. 21 | from . import customize 22 | 23 | 24 | def discover_tests(startdir): 25 | """Discover test under a directory 26 | """ 27 | # Avoid importing unittest 28 | loader = unittest.TestLoader() 29 | suite = loader.discover(startdir) 30 | return suite 31 | 32 | 33 | def run_tests(suite=None, xmloutput=None, verbosity=1): 34 | """ 35 | args 36 | ---- 37 | - suite [TestSuite] 38 | A suite of all tests to run 39 | - xmloutput [str or None] 40 | Path of XML output directory (optional) 41 | - verbosity [int] 42 | Verbosity level of tests output 43 | 44 | Returns the TestResult object after running the test *suite*. 45 | """ 46 | if suite is None: 47 | suite = discover_tests("llvmlite.tests") 48 | if xmloutput is not None: 49 | import xmlrunner 50 | runner = xmlrunner.XMLTestRunner(output=xmloutput) 51 | else: 52 | runner = None 53 | prog = unittest.main(suite=suite, testRunner=runner, exit=False, 54 | verbosity=verbosity) 55 | return prog.result 56 | 57 | 58 | def main(): 59 | res = run_tests() 60 | sys.exit(0 if res.wasSuccessful() else 1) 61 | 62 | -------------------------------------------------------------------------------- /conda-recipes/llvmlite/meta.yaml: -------------------------------------------------------------------------------- 1 | {% set VERSION_SUFFIX = "" %} # debug version suffix, appended to the version 2 | 3 | package: 4 | name: llvmlite 5 | # GIT_DESCRIBE_TAG may not be set 6 | version: {{ "%s%s" % (environ.get('GIT_DESCRIBE_TAG', '').lstrip('v'), VERSION_SUFFIX) }} 7 | 8 | source: 9 | # Using the local source tree helps test building without pushing changes 10 | path: ../.. 11 | 12 | build: 13 | number: {{ environ.get('GIT_DESCRIBE_NUMBER', 0) }} 14 | script_env: 15 | - PY_VCRUNTIME_REDIST 16 | 17 | requirements: 18 | build: 19 | # We cannot do this on macOS as the llvm-config from the 20 | # toolchain conflicts with the same from llvmdev, the 21 | # build.sh deals with it! 22 | - {{ compiler('c') }} # [not (osx or armv6l or armv7l or aarch64)] 23 | - {{ compiler('cxx') }} # [not (osx or armv6l or armv7l or aarch64)] 24 | # The DLL build uses cmake on Windows 25 | - cmake # [win] 26 | - make # [unix and not (armv6l or armv7l or aarch64)] 27 | host: 28 | - python 29 | # On channel https://anaconda.org/numba/ 30 | - llvmdev 7.0* 31 | - vs2015_runtime # [win] 32 | - enum34 # [py27] 33 | # llvmdev is built with libz compression support 34 | - zlib # [unix and not (armv6l or armv7l or aarch64)] 35 | run: 36 | - python 37 | - enum34 # [py27] 38 | - vs2015_runtime # [win] 39 | # osx has dynamically linked libstdc++ 40 | - libcxx >=4.0.1 # [osx] 41 | 42 | test: 43 | imports: 44 | - llvmlite 45 | - llvmlite.binding 46 | commands: 47 | - python -m llvmlite.tests 48 | 49 | about: 50 | home: https://github.com/numba/llvmlite 51 | license: New BSD License 52 | summary: A lightweight LLVM python binding for writing JIT compilers 53 | -------------------------------------------------------------------------------- /llvmlite/tests/test_valuerepr.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function, absolute_import 2 | 3 | import math 4 | import unittest 5 | 6 | from llvmlite.ir import ( 7 | Constant, FloatType, DoubleType, LiteralStructType, IntType, 8 | ArrayType) 9 | from . import TestCase 10 | 11 | 12 | int8 = IntType(8) 13 | int16 = IntType(16) 14 | 15 | 16 | class TestValueRepr(TestCase): 17 | 18 | def test_double_repr(self): 19 | def check_repr(val, expected): 20 | c = Constant(DoubleType(), val) 21 | self.assertEqual(str(c), expected) 22 | check_repr(math.pi, "double 0x400921fb54442d18") 23 | check_repr(float('inf'), "double 0x7ff0000000000000") 24 | check_repr(float('-inf'), "double 0xfff0000000000000") 25 | 26 | def test_float_repr(self): 27 | def check_repr(val, expected): 28 | c = Constant(FloatType(), val) 29 | self.assertEqual(str(c), expected) 30 | check_repr(math.pi, "float 0x400921fb60000000") 31 | check_repr(float('inf'), "float 0x7ff0000000000000") 32 | check_repr(float('-inf'), "float 0xfff0000000000000") 33 | 34 | def test_struct_repr(self): 35 | tp = LiteralStructType([int8, int16]) 36 | c = Constant(tp, (Constant(int8, 100), Constant(int16, 1000))) 37 | self.assertEqual(str(c), "{i8, i16} {i8 100, i16 1000}") 38 | 39 | def test_array_repr(self): 40 | tp = ArrayType(int8, 3) 41 | values = [Constant(int8, x) for x in (5, 10, -15)] 42 | c = Constant(tp, values) 43 | self.assertEqual(str(c), "[3 x i8] [i8 5, i8 10, i8 -15]") 44 | c = Constant(tp, bytearray(b"\x01\x02\x03")) 45 | self.assertEqual(str(c), '[3 x i8] c"\\01\\02\\03"') 46 | 47 | 48 | if __name__ == "__main__": 49 | unittest.main() 50 | -------------------------------------------------------------------------------- /llvmlite/ir/transforms.py: -------------------------------------------------------------------------------- 1 | from . import CallInstr 2 | 3 | 4 | class Visitor(object): 5 | def visit(self, module): 6 | self._module = module 7 | for func in module.functions: 8 | self.visit_Function(func) 9 | 10 | def visit_Function(self, func): 11 | self._function = func 12 | for bb in func.blocks: 13 | self.visit_BasicBlock(bb) 14 | 15 | def visit_BasicBlock(self, bb): 16 | self._basic_block = bb 17 | for instr in bb.instructions: 18 | self.visit_Instruction(instr) 19 | 20 | def visit_Instruction(self, instr): 21 | raise NotImplementedError 22 | 23 | @property 24 | def module(self): 25 | return self._module 26 | 27 | @property 28 | def function(self): 29 | return self._function 30 | 31 | @property 32 | def basic_block(self): 33 | return self._basic_block 34 | 35 | 36 | class CallVisitor(Visitor): 37 | def visit_Instruction(self, instr): 38 | if isinstance(instr, CallInstr): 39 | self.visit_Call(instr) 40 | 41 | def visit_Call(self, instr): 42 | raise NotImplementedError 43 | 44 | 45 | class ReplaceCalls(CallVisitor): 46 | def __init__(self, orig, repl): 47 | super(ReplaceCalls, self).__init__() 48 | self.orig = orig 49 | self.repl = repl 50 | self.calls = [] 51 | 52 | def visit_Call(self, instr): 53 | if instr.callee == self.orig: 54 | instr.replace_callee(self.repl) 55 | self.calls.append(instr) 56 | 57 | 58 | def replace_all_calls(mod, orig, repl): 59 | """Replace all calls to `orig` to `repl` in module `mod`. 60 | Returns the references to the returned calls 61 | """ 62 | rc = ReplaceCalls(orig, repl) 63 | rc.visit(mod) 64 | return rc.calls 65 | -------------------------------------------------------------------------------- /llvmlite/binding/initfini.py: -------------------------------------------------------------------------------- 1 | from ctypes import c_uint 2 | 3 | from . import ffi 4 | 5 | 6 | def initialize(): 7 | """ 8 | Initialize the LLVM core. 9 | """ 10 | ffi.lib.LLVMPY_InitializeCore() 11 | 12 | 13 | def initialize_all_targets(): 14 | """ 15 | Initialize all targets. Necessary before targets can be looked up 16 | via the :class:`Target` class. 17 | """ 18 | ffi.lib.LLVMPY_InitializeAllTargetInfos() 19 | ffi.lib.LLVMPY_InitializeAllTargets() 20 | ffi.lib.LLVMPY_InitializeAllTargetMCs() 21 | 22 | def initialize_all_asmprinters(): 23 | """ 24 | Initialize all code generators. Necessary before generating 25 | any assembly or machine code via the :meth:`TargetMachine.emit_object` 26 | and :meth:`TargetMachine.emit_assembly` methods. 27 | """ 28 | ffi.lib.LLVMPY_InitializeAllAsmPrinters() 29 | 30 | 31 | def initialize_native_target(): 32 | """ 33 | Initialize the native (host) target. Necessary before doing any 34 | code generation. 35 | """ 36 | ffi.lib.LLVMPY_InitializeNativeTarget() 37 | 38 | 39 | def initialize_native_asmprinter(): 40 | """ 41 | Initialize the native ASM printer. 42 | """ 43 | ffi.lib.LLVMPY_InitializeNativeAsmPrinter() 44 | 45 | 46 | def initialize_native_asmparser(): 47 | """ 48 | Initialize the native ASM parser. 49 | """ 50 | ffi.lib.LLVMPY_InitializeNativeAsmParser() 51 | 52 | 53 | def shutdown(): 54 | ffi.lib.LLVMPY_Shutdown() 55 | 56 | 57 | # ============================================================================= 58 | # Set function FFI 59 | 60 | ffi.lib.LLVMPY_GetVersionInfo.restype = c_uint 61 | 62 | 63 | def _version_info(): 64 | v = [] 65 | x = ffi.lib.LLVMPY_GetVersionInfo() 66 | while x: 67 | v.append(x & 0xff) 68 | x >>= 8 69 | return tuple(reversed(v)) 70 | 71 | llvm_version_info = _version_info() 72 | -------------------------------------------------------------------------------- /ffi/linker.cpp: -------------------------------------------------------------------------------- 1 | #include "core.h" 2 | 3 | #include "llvm/IR/Module.h" 4 | #include "llvm/IR/DiagnosticInfo.h" 5 | #include "llvm/IR/DiagnosticPrinter.h" 6 | #include "llvm/Support/raw_ostream.h" 7 | 8 | #include "llvm-c/Linker.h" 9 | 10 | extern "C" { 11 | 12 | API_EXPORT(int) 13 | LLVMPY_LinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, const char **Err) 14 | { 15 | using namespace llvm; 16 | std::string errorstring; 17 | llvm::raw_string_ostream errstream(errorstring); 18 | Module *D = unwrap(Dest); 19 | LLVMContext &Ctx = D->getContext(); 20 | 21 | // This exists at the change to LLVM 6.x 22 | // Link error diagnostics end up with a call to abort() 23 | // install this handler to instead extract the reason for failure 24 | // and report it. 25 | class ReportNotAbortDiagnosticHandler: public DiagnosticHandler { 26 | public: 27 | ReportNotAbortDiagnosticHandler(llvm::raw_string_ostream &s): 28 | raw_stream(s) {} 29 | 30 | bool handleDiagnostics(const DiagnosticInfo &DI) override 31 | { 32 | llvm::DiagnosticPrinterRawOStream DP(raw_stream); 33 | DI.print(DP); 34 | return true; 35 | } 36 | 37 | private: 38 | llvm::raw_string_ostream& raw_stream; 39 | }; 40 | 41 | // save current handler as "old" 42 | auto OldDiagnosticHandler = Ctx.getDiagnosticHandler(); 43 | 44 | // set the handler to a new one 45 | Ctx.setDiagnosticHandler(llvm::make_unique(errstream)); 46 | 47 | // link 48 | bool failed = LLVMLinkModules2(Dest, Src); 49 | 50 | // put old handler back 51 | Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); 52 | 53 | // if linking failed extract the reason for the failure 54 | if (failed) { 55 | errstream.flush(); 56 | *Err = LLVMPY_CreateString(errorstring.c_str()); 57 | } 58 | 59 | return failed; 60 | } 61 | 62 | } // end extern "C" 63 | -------------------------------------------------------------------------------- /examples/ll_fpadd.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from ctypes import CFUNCTYPE, c_double 4 | 5 | import llvmlite.binding as llvm 6 | 7 | 8 | # All these initializations are required for code generation! 9 | llvm.initialize() 10 | llvm.initialize_native_target() 11 | llvm.initialize_native_asmprinter() # yes, even this one 12 | 13 | llvm_ir = """ 14 | ; ModuleID = "examples/ir_fpadd.py" 15 | target triple = "unknown-unknown-unknown" 16 | target datalayout = "" 17 | 18 | define double @"fpadd"(double %".1", double %".2") 19 | { 20 | entry: 21 | %"res" = fadd double %".1", %".2" 22 | ret double %"res" 23 | } 24 | """ 25 | 26 | def create_execution_engine(): 27 | """ 28 | Create an ExecutionEngine suitable for JIT code generation on 29 | the host CPU. The engine is reusable for an arbitrary number of 30 | modules. 31 | """ 32 | # Create a target machine representing the host 33 | target = llvm.Target.from_default_triple() 34 | target_machine = target.create_target_machine() 35 | # And an execution engine with an empty backing module 36 | backing_mod = llvm.parse_assembly("") 37 | engine = llvm.create_mcjit_compiler(backing_mod, target_machine) 38 | return engine 39 | 40 | 41 | def compile_ir(engine, llvm_ir): 42 | """ 43 | Compile the LLVM IR string with the given engine. 44 | The compiled module object is returned. 45 | """ 46 | # Create a LLVM module object from the IR 47 | mod = llvm.parse_assembly(llvm_ir) 48 | mod.verify() 49 | # Now add the module and make sure it is ready for execution 50 | engine.add_module(mod) 51 | engine.finalize_object() 52 | return mod 53 | 54 | 55 | engine = create_execution_engine() 56 | mod = compile_ir(engine, llvm_ir) 57 | 58 | # Look up the function pointer (a Python int) 59 | func_ptr = engine.get_function_address("fpadd") 60 | 61 | # Run the function via ctypes 62 | cfunc = CFUNCTYPE(c_double, c_double, c_double)(func_ptr) 63 | res = cfunc(1.0, 3.5) 64 | print("fpadd(...) =", res) 65 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/object-file.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Object file 3 | =========== 4 | 5 | .. currentmodule:: llvmlite.binding 6 | 7 | The object file is an abstraction of LLVM representation of 8 | the static object code files. This class provides methods to examine 9 | the contents of the object files. It also can be passed as parameter to 10 | :meth:`ExecutionEngine.add_object_file` to make the symbols available 11 | to the JIT. 12 | 13 | The ObjectFileRef class 14 | ------------------------ 15 | 16 | .. class:: ObjectFileRef 17 | 18 | A wrapper around LLVM object file. The following methods and properties 19 | are available: 20 | 21 | * .. classmethod:: from_data(data): 22 | 23 | Create an instance of ObjectFileRef from the provided binary data. 24 | 25 | * .. classmethod:: from_path(path): 26 | 27 | Create an instance of ObjectFileRef from the supplied filesystem 28 | path. Raises IOError if the path does not exist. 29 | 30 | * .. method:: sections: 31 | 32 | Return an iterator to the sections objects consisting of the 33 | instance of :class:`SectionIteratorRef` 34 | 35 | The SectionIteratorRef class 36 | ---------------------------- 37 | 38 | .. class:: SectionIteratorRef 39 | A wrapper around the section class which provides information like 40 | section name, type and size, etc. 41 | 42 | * .. method:: name(): 43 | 44 | Get section name. 45 | 46 | * .. method:: is_text(): 47 | 48 | Returns true when section is of type text. 49 | 50 | * .. method:: size(): 51 | 52 | Get section size. 53 | 54 | * .. method:: address(): 55 | 56 | Get section address. 57 | 58 | * .. method:: data(): 59 | 60 | Get section contents. 61 | 62 | * .. method:: is_end(object_file): 63 | 64 | Return true if the section iterator is the last element of the 65 | object_file. 66 | 67 | * object_file: an instance of :class:`ObjectFileRef` 68 | 69 | * .. method:: next(): 70 | 71 | Get the next section instance. 72 | 73 | -------------------------------------------------------------------------------- /docs/source/user-guide/examples/ll_fpadd.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from ctypes import CFUNCTYPE, c_double 4 | 5 | import llvmlite.binding as llvm 6 | 7 | 8 | # All these initializations are required for code generation! 9 | llvm.initialize() 10 | llvm.initialize_native_target() 11 | llvm.initialize_native_asmprinter() # yes, even this one 12 | 13 | llvm_ir = """ 14 | ; ModuleID = "examples/ir_fpadd.py" 15 | target triple = "unknown-unknown-unknown" 16 | target datalayout = "" 17 | 18 | define double @"fpadd"(double %".1", double %".2") 19 | { 20 | entry: 21 | %"res" = fadd double %".1", %".2" 22 | ret double %"res" 23 | } 24 | """ 25 | 26 | def create_execution_engine(): 27 | """ 28 | Create an ExecutionEngine suitable for JIT code generation on 29 | the host CPU. The engine is reusable for an arbitrary number of 30 | modules. 31 | """ 32 | # Create a target machine representing the host 33 | target = llvm.Target.from_default_triple() 34 | target_machine = target.create_target_machine() 35 | # And an execution engine with an empty backing module 36 | backing_mod = llvm.parse_assembly("") 37 | engine = llvm.create_mcjit_compiler(backing_mod, target_machine) 38 | return engine 39 | 40 | 41 | def compile_ir(engine, llvm_ir): 42 | """ 43 | Compile the LLVM IR string with the given engine. 44 | The compiled module object is returned. 45 | """ 46 | # Create a LLVM module object from the IR 47 | mod = llvm.parse_assembly(llvm_ir) 48 | mod.verify() 49 | # Now add the module and make sure it is ready for execution 50 | engine.add_module(mod) 51 | engine.finalize_object() 52 | engine.run_static_constructors() 53 | return mod 54 | 55 | 56 | engine = create_execution_engine() 57 | mod = compile_ir(engine, llvm_ir) 58 | 59 | # Look up the function pointer (a Python int) 60 | func_ptr = engine.get_function_address("fpadd") 61 | 62 | # Run the function via ctypes 63 | cfunc = CFUNCTYPE(c_double, c_double, c_double)(func_ptr) 64 | res = cfunc(1.0, 3.5) 65 | print("fpadd(...) =", res) 66 | -------------------------------------------------------------------------------- /ffi/object_file.cpp: -------------------------------------------------------------------------------- 1 | #include "core.h" 2 | 3 | #include "llvm-c/ExecutionEngine.h" 4 | #include "llvm-c/Object.h" 5 | 6 | #include "llvm/Object/ObjectFile.h" 7 | 8 | #include 9 | 10 | // From lib/Object/Object.cpp 11 | namespace llvm { 12 | inline object::section_iterator *unwrap(LLVMSectionIteratorRef SI) { 13 | return reinterpret_cast(SI); 14 | } 15 | 16 | inline LLVMSectionIteratorRef 17 | wrap(const object::section_iterator *SI) { 18 | return reinterpret_cast 19 | (const_cast(SI)); 20 | } 21 | } // llvm 22 | 23 | extern "C" { 24 | 25 | API_EXPORT(LLVMObjectFileRef) 26 | LLVMPY_CreateObjectFile(const char* buf, const size_t n) 27 | { 28 | return LLVMCreateObjectFile(LLVMCreateMemoryBufferWithMemoryRangeCopy(buf, n, "")); 29 | } 30 | 31 | API_EXPORT(void) 32 | LLVMPY_DisposeObjectFile(LLVMObjectFileRef O) 33 | { 34 | return LLVMDisposeObjectFile(O); 35 | } 36 | 37 | API_EXPORT(LLVMSectionIteratorRef) 38 | LLVMPY_GetSections(LLVMObjectFileRef O) 39 | { 40 | return LLVMGetSections(O); 41 | } 42 | 43 | API_EXPORT(void) 44 | LLVMPY_DisposeSectionIterator(LLVMSectionIteratorRef SI) 45 | { 46 | LLVMDisposeSectionIterator(SI); 47 | } 48 | 49 | API_EXPORT(void) 50 | LLVMPY_MoveToNextSection(LLVMSectionIteratorRef SI) 51 | { 52 | LLVMMoveToNextSection(SI); 53 | } 54 | 55 | API_EXPORT(bool) 56 | LLVMPY_IsSectionIteratorAtEnd(LLVMObjectFileRef O, LLVMSectionIteratorRef SI) 57 | { 58 | return LLVMIsSectionIteratorAtEnd(O, SI); 59 | } 60 | 61 | API_EXPORT(const char*) 62 | LLVMPY_GetSectionName(LLVMSectionIteratorRef SI) 63 | { 64 | return LLVMGetSectionName(SI); 65 | } 66 | 67 | API_EXPORT(uint64_t) 68 | LLVMPY_GetSectionAddress(LLVMSectionIteratorRef SI) 69 | { 70 | return LLVMGetSectionAddress(SI); 71 | } 72 | 73 | API_EXPORT(const char*) 74 | LLVMPY_GetSectionContents(LLVMSectionIteratorRef SI) 75 | { 76 | return LLVMGetSectionContents(SI); 77 | } 78 | 79 | API_EXPORT(uint64_t) 80 | LLVMPY_GetSectionSize(LLVMSectionIteratorRef SI) 81 | { 82 | return LLVMGetSectionSize(SI); 83 | } 84 | 85 | API_EXPORT(bool) 86 | LLVMPY_IsSectionText(LLVMSectionIteratorRef SI) 87 | { 88 | return (*llvm::unwrap(SI))->isText(); 89 | } 90 | 91 | } // end extern C 92 | -------------------------------------------------------------------------------- /conda-recipes/llvmdev/cfg_test.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'foo' 2 | source_filename = "" 3 | target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 4 | target triple = "x86_64-apple-darwin17.4.0" 5 | 6 | @.const.foo = internal constant [4 x i8] c"foo\00" 7 | @".const.Fatal error: missing _dynfunc.Closure" = internal constant [38 x i8] c"Fatal error: missing _dynfunc.Closure\00" 8 | @PyExc_RuntimeError = external global i8 9 | @".const.missing Environment" = internal constant [20 x i8] c"missing Environment\00" 10 | 11 | ; Function Attrs: norecurse nounwind 12 | declare i32 @"_ZN8__main__7foo$241Ex"(i64* noalias nocapture %retptr, { i8*, i32 }** noalias nocapture readnone %excinfo, i8* noalias nocapture readnone %env, i64 %arg.x) local_unnamed_addr #0 13 | 14 | 15 | define i8* @"testme"(i8* %py_closure, i8* %py_args, i8* nocapture readnone %py_kws) local_unnamed_addr { 16 | entry: 17 | %.5 = alloca i8*, align 8 18 | %.6 = call i32 (i8*, i8*, i64, i64, ...) @PyArg_UnpackTuple(i8* %py_args, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.const.foo, i64 0, i64 0), i64 1, i64 1, i8** nonnull %.5) 19 | %.7 = icmp eq i32 %.6, 0 20 | br i1 %.7, label %entry_if, label %entry_endif, !prof !0 21 | 22 | entry_if: ; preds = %entry.endif.1.1.endif, %entry 23 | ret i8* null 24 | 25 | entry_endif: ; preds = %entry 26 | %.11 = icmp eq i8* %py_closure, null 27 | ret i8* null 28 | 29 | } 30 | 31 | declare i32 @PyArg_UnpackTuple(i8*, i8*, i64, i64, ...) local_unnamed_addr 32 | 33 | ; Function Attrs: nounwind 34 | declare i32 @puts(i8* nocapture readonly) local_unnamed_addr #1 35 | 36 | declare void @PyErr_SetString(i8*, i8*) local_unnamed_addr 37 | 38 | declare i8* @PyNumber_Long(i8*) local_unnamed_addr 39 | 40 | declare i64 @PyLong_AsLongLong(i8*) local_unnamed_addr 41 | 42 | declare void @Py_DecRef(i8*) local_unnamed_addr 43 | 44 | declare i8* @PyErr_Occurred() local_unnamed_addr 45 | 46 | declare i8* @PyLong_FromLongLong(i64) local_unnamed_addr 47 | 48 | ; Function Attrs: nounwind 49 | declare void @llvm.stackprotector(i8*, i8**) #1 50 | 51 | attributes #0 = { norecurse nounwind } 52 | attributes #1 = { nounwind } 53 | 54 | !0 = !{!"branch_weights", i32 1, i32 9} 55 | !1 = !{!"branch_weights", i32 9, i32 1} 56 | 57 | -------------------------------------------------------------------------------- /llvmlite/ir/_utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function, absolute_import 2 | 3 | from collections import defaultdict 4 | 5 | 6 | class DuplicatedNameError(NameError): 7 | pass 8 | 9 | 10 | class NameScope(object): 11 | def __init__(self): 12 | self._useset = set(['']) 13 | self._basenamemap = defaultdict(int) 14 | 15 | def is_used(self, name): 16 | return name in self._useset 17 | 18 | def register(self, name, deduplicate=False): 19 | if deduplicate: 20 | name = self.deduplicate(name) 21 | elif self.is_used(name): 22 | raise DuplicatedNameError(name) 23 | self._useset.add(name) 24 | return name 25 | 26 | def deduplicate(self, name): 27 | basename = name 28 | while self.is_used(name): 29 | ident = self._basenamemap[basename] + 1 30 | self._basenamemap[basename] = ident 31 | name = "{0}.{1}".format(basename, ident) 32 | return name 33 | 34 | def get_child(self): 35 | return type(self)(parent=self) 36 | 37 | 38 | class _StrCaching(object): 39 | 40 | def _clear_string_cache(self): 41 | try: 42 | del self.__cached_str 43 | except AttributeError: 44 | pass 45 | 46 | def __str__(self): 47 | try: 48 | return self.__cached_str 49 | except AttributeError: 50 | s = self.__cached_str = self._to_string() 51 | return s 52 | 53 | 54 | class _StringReferenceCaching(object): 55 | 56 | def get_reference(self): 57 | try: 58 | return self.__cached_refstr 59 | except AttributeError: 60 | s = self.__cached_refstr = self._get_reference() 61 | return s 62 | 63 | 64 | class _HasMetadata(object): 65 | 66 | def set_metadata(self, name, node): 67 | """ 68 | Attach unnamed metadata *node* to the metadata slot *name* of this value. 69 | """ 70 | self.metadata[name] = node 71 | 72 | def _stringify_metadata(self, leading_comma=False): 73 | if self.metadata: 74 | buf = [] 75 | if leading_comma: 76 | buf.append("") 77 | buf += ["!{0} {1}".format(k, v.get_reference()) 78 | for k, v in self.metadata.items()] 79 | return ', '.join(buf) 80 | else: 81 | return '' 82 | -------------------------------------------------------------------------------- /llvmlite/binding/analysis.py: -------------------------------------------------------------------------------- 1 | """ 2 | A collection of analysis utils 3 | """ 4 | 5 | from __future__ import absolute_import, print_function 6 | 7 | from ctypes import POINTER, c_char_p, c_int 8 | 9 | from llvmlite import ir 10 | from . import ffi 11 | from .module import parse_assembly 12 | 13 | 14 | def get_function_cfg(func, show_inst=True): 15 | """Return a string of the control-flow graph of the function in DOT 16 | format. If the input `func` is not a materialized function, the module 17 | containing the function is parsed to create an actual LLVM module. 18 | The `show_inst` flag controls whether the instructions of each block 19 | are printed. 20 | """ 21 | assert func is not None 22 | if isinstance(func, ir.Function): 23 | mod = parse_assembly(str(func.module)) 24 | func = mod.get_function(func.name) 25 | 26 | # Assume func is a materialized function 27 | with ffi.OutputString() as dotstr: 28 | ffi.lib.LLVMPY_WriteCFG(func, dotstr, show_inst) 29 | return str(dotstr) 30 | 31 | 32 | def view_dot_graph(graph, filename=None, view=False): 33 | """ 34 | View the given DOT source. If view is True, the image is rendered 35 | and viewed by the default application in the system. The file path of 36 | the output is returned. If view is False, a graphviz.Source object is 37 | returned. If view is False and the environment is in a IPython session, 38 | an IPython image object is returned and can be displayed inline in the 39 | notebook. 40 | 41 | This function requires the graphviz package. 42 | 43 | Args 44 | ---- 45 | - graph [str]: a DOT source code 46 | - filename [str]: optional. if given and view is True, this specifies 47 | the file path for the rendered output to write to. 48 | - view [bool]: if True, opens the rendered output file. 49 | 50 | """ 51 | # Optionally depends on graphviz package 52 | import graphviz as gv 53 | 54 | src = gv.Source(graph) 55 | if view: 56 | # Returns the output file path 57 | return src.render(filename, view=view) 58 | else: 59 | # Attempts to show the graph in IPython notebook 60 | try: 61 | __IPYTHON__ 62 | except NameError: 63 | return src 64 | else: 65 | import IPython.display as display 66 | format = 'svg' 67 | return display.SVG(data=src.pipe(format)) 68 | 69 | 70 | # Ctypes binding 71 | ffi.lib.LLVMPY_WriteCFG.argtypes = [ffi.LLVMValueRef, POINTER(c_char_p), c_int] 72 | -------------------------------------------------------------------------------- /docs/source/user-guide/binding/value-references.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Value references 3 | ================ 4 | 5 | .. currentmodule:: llvmlite.binding 6 | 7 | A value reference is a wrapper around an LLVM value for you to 8 | inspect. You cannot create a value reference yourself. You get 9 | them from methods of the :class:`ModuleRef` class. 10 | 11 | Enumerations 12 | ------------ 13 | 14 | .. class:: Linkage 15 | 16 | The linkage types allowed for global values are: 17 | 18 | * .. data:: external 19 | * .. data:: available_externally 20 | * .. data:: linkonce_any 21 | * .. data:: linkonce_odr 22 | * .. data:: linkonce_odr_autohide 23 | * .. data:: weak_any 24 | * .. data:: weak_odr 25 | * .. data:: appending 26 | * .. data:: internal 27 | * .. data:: private 28 | * .. data:: dllimport 29 | * .. data:: dllexport 30 | * .. data:: external_weak 31 | * .. data:: ghost 32 | * .. data:: common 33 | * .. data:: linker_private 34 | * .. data:: linker_private_weak 35 | 36 | 37 | .. class:: Visibility 38 | 39 | The visibility styles allowed for global values are: 40 | 41 | * .. data:: default 42 | * .. data:: hidden 43 | * .. data:: protected 44 | 45 | 46 | .. class:: StorageClass 47 | 48 | The storage classes allowed for global values are: 49 | 50 | * .. data:: default 51 | * .. data:: dllimport 52 | * .. data:: dllexport 53 | 54 | 55 | The ValueRef class 56 | ------------------ 57 | 58 | .. class:: ValueRef 59 | 60 | A wrapper around an LLVM value. The attributes available are: 61 | 62 | * .. attribute:: is_declaration 63 | 64 | * ``True``---The global value is a mere declaration. 65 | * ``False``---The global value is defined in the given 66 | module. 67 | 68 | * .. attribute:: linkage 69 | 70 | The linkage type---a :class:`Linkage` instance---for 71 | this value. This attribute can be set. 72 | 73 | * .. attribute:: module 74 | 75 | The module---a :class:`ModuleRef` instance---that this 76 | value is defined in. 77 | 78 | * .. attribute:: name 79 | 80 | This value's name, as a string. This attribute can be set. 81 | 82 | * .. attribute:: type 83 | 84 | This value's LLVM type as :class:`TypeRef` object. 85 | 86 | * .. attribute:: storage_class 87 | 88 | The storage 89 | class---a :class:`StorageClass` instance---for 90 | this value. This attribute can be set. 91 | 92 | * .. attribute:: visibility 93 | 94 | The visibility 95 | style---a :class:`Visibility` instance---for 96 | this value. This attribute can be set. 97 | -------------------------------------------------------------------------------- /llvmlite/llvmpy/passes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Useful options to debug LLVM passes 3 | 4 | llvm.set_option("test", "-debug-pass=Details") 5 | llvm.set_option("test", "-debug-pass=Executions") 6 | llvm.set_option("test", "-debug-pass=Arguments") 7 | llvm.set_option("test", "-debug-pass=Structure") 8 | llvm.set_option("test", "-debug-only=loop-vectorize") 9 | llvm.set_option("test", "-help-hidden") 10 | 11 | """ 12 | 13 | from llvmlite import binding as llvm 14 | from collections import namedtuple 15 | 16 | 17 | def _inlining_threshold(optlevel, sizelevel=0): 18 | # Refer http://llvm.org/docs/doxygen/html/InlineSimple_8cpp_source.html 19 | if optlevel > 2: 20 | return 275 21 | 22 | # -Os 23 | if sizelevel == 1: 24 | return 75 25 | 26 | # -Oz 27 | if sizelevel == 2: 28 | return 25 29 | 30 | return 225 31 | 32 | 33 | def create_pass_manager_builder(opt=2, loop_vectorize=False, 34 | slp_vectorize=False): 35 | pmb = llvm.create_pass_manager_builder() 36 | pmb.opt_level = opt 37 | pmb.loop_vectorize = loop_vectorize 38 | pmb.slp_vectorize = slp_vectorize 39 | pmb.inlining_threshold = _inlining_threshold(opt) 40 | return pmb 41 | 42 | 43 | def build_pass_managers(**kws): 44 | mod = kws.get('mod') 45 | if not mod: 46 | raise NameError("module must be provided") 47 | 48 | pm = llvm.create_module_pass_manager() 49 | 50 | if kws.get('fpm', True): 51 | assert isinstance(mod, llvm.ModuleRef) 52 | fpm = llvm.create_function_pass_manager(mod) 53 | else: 54 | fpm = None 55 | 56 | with llvm.create_pass_manager_builder() as pmb: 57 | pmb.opt_level = opt = kws.get('opt', 2) 58 | pmb.loop_vectorize = kws.get('loop_vectorize', False) 59 | pmb.slp_vectorize = kws.get('slp_vectorize', False) 60 | pmb.inlining_threshold = _inlining_threshold(optlevel=opt) 61 | 62 | if mod: 63 | tli = llvm.create_target_library_info(mod.triple) 64 | if kws.get('nobuiltins', False): 65 | # Disable all builtins (-fno-builtins) 66 | tli.disable_all() 67 | else: 68 | # Disable a list of builtins given 69 | for k in kws.get('disable_builtins', ()): 70 | libf = tli.get_libfunc(k) 71 | tli.set_unavailable(libf) 72 | 73 | tli.add_pass(pm) 74 | if fpm is not None: 75 | tli.add_pass(fpm) 76 | 77 | tm = kws.get('tm') 78 | if tm: 79 | tm.add_analysis_passes(pm) 80 | if fpm is not None: 81 | tm.add_analysis_passes(fpm) 82 | 83 | pmb.populate(pm) 84 | if fpm is not None: 85 | pmb.populate(fpm) 86 | 87 | return namedtuple("pms", ['pm', 'fpm'])(pm=pm, fpm=fpm) 88 | 89 | -------------------------------------------------------------------------------- /conda-recipes/llvmdev_manylinux1/meta.yaml: -------------------------------------------------------------------------------- 1 | {% set shortversion = "7.0" %} 2 | {% set version = "7.0.0" %} 3 | {% set sha256_llvm = "8bc1f844e6cbde1b652c19c1edebc1864456fd9c78b8c1bea038e51b363fe222" %} 4 | {% set sha256_lld = "fbcf47c5e543f4cdac6bb9bbbc6327ff24217cd7eafc5571549ad6d237287f9c" %} 5 | {% set build_number = "1" %} 6 | 7 | 8 | package: 9 | name: llvmdev 10 | version: {{ version }} 11 | 12 | source: 13 | - url: http://llvm.org/releases/{{ version }}/llvm-{{ version }}.src.tar.xz 14 | fn: llvm-{{ version }}.src.tar.xz 15 | sha256: {{ sha256_llvm }} 16 | patches: 17 | # http://lists.llvm.org/pipermail/llvm-dev/2016-January/094520.html 18 | - ../llvm-lto-static.patch # [win] 19 | - ../partial-testing.patch 20 | # Intel SVML optimizations 21 | # The second part of this patch was published as: 22 | # https://reviews.llvm.org/D53035 23 | # (the first, as mentioned in the patch itself, was: 24 | # https://reviews.llvm.org/D47188) 25 | - ../D47188-svml-VF.patch 26 | # undefined behavior bug due to Twine usage 27 | - ../twine_cfg_undefined_behavior.patch 28 | # Patches for X86 common symbols over-allocation and testing thereof, see 29 | # https://reviews.llvm.org/D50240 and https://reviews.llvm.org/rL340788 30 | # for details: 31 | - ../0001-RuntimeDyld-Fix-a-bug-in-RuntimeDyld-loadObjectImpl-.patch 32 | - ../0001-RuntimeDyld-Add-test-case-that-was-accidentally-left.patch 33 | 34 | - url: http://releases.llvm.org/{{ version }}/lld-{{ version }}.src.tar.xz 35 | fn: lld-{{ version }}.src.tar.xz 36 | sha256: {{ sha256_lld }} 37 | folder: tools/lld 38 | 39 | build: 40 | number: {{ build_number }} 41 | string: "manylinux1h{{ PKG_HASH }}" 42 | script_env: 43 | - CFLAGS 44 | - CXXFLAGS 45 | - PY_VCRUNTIME_REDIST 46 | ignore_run_exports: 47 | # Is static-linked 48 | - xar 49 | 50 | requirements: 51 | build: 52 | - cmake 53 | # - make # Unavailable in old miniconda 54 | # Needed to unpack the source tarball 55 | - m2w64-xz # [py27 and win] 56 | # Needed to build LLVM 57 | - python >=3 58 | test: 59 | commands: 60 | - $PREFIX/bin/llvm-config --libs # [not win] 61 | - $PREFIX/bin/llc -version # [not win] 62 | 63 | - if not exist %LIBRARY_INC%\\llvm\\Pass.h exit 1 # [win] 64 | - if not exist %LIBRARY_LIB%\\LLVMSupport.lib exit 1 # [win] 65 | 66 | - test -f $PREFIX/include/llvm/Pass.h # [unix] 67 | - test -f $PREFIX/lib/libLLVMSupport.a # [unix] 68 | 69 | - test -f $PREFIX/lib/libLLVMCore.a # [not win] 70 | 71 | about: 72 | home: http://llvm.org/ 73 | dev_url: https://github.com/llvm-mirror/llvm 74 | license: NCSA 75 | license_file: LICENSE.TXT 76 | summary: Development headers and libraries for LLVM 77 | -------------------------------------------------------------------------------- /llvmlite/binding/object_file.py: -------------------------------------------------------------------------------- 1 | from . import ffi 2 | from ctypes import c_bool, c_char_p, c_size_t, c_ulonglong, string_at, c_uint64 3 | 4 | class SectionIteratorRef(ffi.ObjectRef): 5 | def name(self): 6 | return ffi.lib.LLVMPY_GetSectionName(self) 7 | def is_text(self): 8 | return ffi.lib.LLVMPY_IsSectionText(self) 9 | def size(self): 10 | return ffi.lib.LLVMPY_GetSectionSize(self) 11 | def address(self): 12 | return ffi.lib.LLVMPY_GetSectionAddress(self) 13 | def data(self): 14 | return string_at(ffi.lib.LLVMPY_GetSectionContents(self), self.size()) 15 | def is_end(self, object_file): 16 | return ffi.lib.LLVMPY_IsSectionIteratorAtEnd(object_file, self) 17 | def next(self): 18 | ffi.lib.LLVMPY_MoveToNextSection(self) 19 | def _dispose(self): 20 | ffi.lib.LLVMPY_DisposeSectionIterator(self) 21 | 22 | class ObjectFileRef(ffi.ObjectRef): 23 | @classmethod 24 | def from_data(cls, data): 25 | return cls(ffi.lib.LLVMPY_CreateObjectFile(data, len(data))) 26 | 27 | @classmethod 28 | def from_path(cls, path): 29 | with open(path, 'rb') as f: 30 | data = f.read() 31 | return cls(ffi.lib.LLVMPY_CreateObjectFile(data, len(data))) 32 | 33 | def sections(self): 34 | it = SectionIteratorRef(ffi.lib.LLVMPY_GetSections(self)) 35 | while not it.is_end(self): 36 | yield it 37 | it.next() 38 | 39 | def _dispose(self): 40 | ffi.lib.LLVMPY_DisposeObjectFile(self) 41 | 42 | ffi.lib.LLVMPY_CreateObjectFile.argtypes = [c_char_p, c_size_t] 43 | ffi.lib.LLVMPY_CreateObjectFile.restype = ffi.LLVMObjectFileRef 44 | 45 | ffi.lib.LLVMPY_DisposeObjectFile.argtypes = [ffi.LLVMObjectFileRef] 46 | 47 | ffi.lib.LLVMPY_GetSections.argtypes = [ffi.LLVMObjectFileRef] 48 | ffi.lib.LLVMPY_GetSections.restype = ffi.LLVMSectionIteratorRef 49 | 50 | ffi.lib.LLVMPY_DisposeSectionIterator.argtypes = [ffi.LLVMSectionIteratorRef] 51 | 52 | ffi.lib.LLVMPY_MoveToNextSection.argtypes = [ffi.LLVMSectionIteratorRef] 53 | 54 | ffi.lib.LLVMPY_IsSectionIteratorAtEnd.argtypes = [ffi.LLVMObjectFileRef, ffi.LLVMSectionIteratorRef] 55 | ffi.lib.LLVMPY_IsSectionIteratorAtEnd.restype = c_bool 56 | 57 | ffi.lib.LLVMPY_GetSectionName.argtypes = [ffi.LLVMSectionIteratorRef] 58 | ffi.lib.LLVMPY_GetSectionName.restype = c_char_p 59 | 60 | ffi.lib.LLVMPY_GetSectionSize.argtypes = [ffi.LLVMSectionIteratorRef] 61 | ffi.lib.LLVMPY_GetSectionSize.restype = c_uint64 62 | 63 | ffi.lib.LLVMPY_GetSectionAddress.argtypes = [ffi.LLVMSectionIteratorRef] 64 | ffi.lib.LLVMPY_GetSectionAddress.restype = c_uint64 65 | 66 | ffi.lib.LLVMPY_GetSectionContents.argtypes = [ffi.LLVMSectionIteratorRef] 67 | ffi.lib.LLVMPY_GetSectionContents.restype = c_char_p 68 | 69 | ffi.lib.LLVMPY_IsSectionText.argtypes = [ffi.LLVMSectionIteratorRef] 70 | ffi.lib.LLVMPY_IsSectionText.restype = c_bool 71 | -------------------------------------------------------------------------------- /examples/sum.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from ctypes import CFUNCTYPE, c_int, POINTER 4 | import sys 5 | try: 6 | from time import perf_counter as time 7 | except ImportError: 8 | from time import time 9 | 10 | import numpy as np 11 | 12 | try: 13 | import faulthandler; faulthandler.enable() 14 | except ImportError: 15 | pass 16 | 17 | import llvmlite.ir as ll 18 | import llvmlite.binding as llvm 19 | 20 | 21 | llvm.initialize() 22 | llvm.initialize_native_target() 23 | llvm.initialize_native_asmprinter() 24 | 25 | 26 | t1 = time() 27 | 28 | fnty = ll.FunctionType(ll.IntType(32), [ll.IntType(32).as_pointer(), 29 | ll.IntType(32)]) 30 | module = ll.Module() 31 | 32 | func = ll.Function(module, fnty, name="sum") 33 | 34 | bb_entry = func.append_basic_block() 35 | bb_loop = func.append_basic_block() 36 | bb_exit = func.append_basic_block() 37 | 38 | builder = ll.IRBuilder() 39 | builder.position_at_end(bb_entry) 40 | 41 | builder.branch(bb_loop) 42 | builder.position_at_end(bb_loop) 43 | 44 | index = builder.phi(ll.IntType(32)) 45 | index.add_incoming(ll.Constant(index.type, 0), bb_entry) 46 | accum = builder.phi(ll.IntType(32)) 47 | accum.add_incoming(ll.Constant(accum.type, 0), bb_entry) 48 | 49 | ptr = builder.gep(func.args[0], [index]) 50 | value = builder.load(ptr) 51 | 52 | added = builder.add(accum, value) 53 | accum.add_incoming(added, bb_loop) 54 | 55 | indexp1 = builder.add(index, ll.Constant(index.type, 1)) 56 | index.add_incoming(indexp1, bb_loop) 57 | 58 | cond = builder.icmp_unsigned('<', indexp1, func.args[1]) 59 | builder.cbranch(cond, bb_loop, bb_exit) 60 | 61 | builder.position_at_end(bb_exit) 62 | builder.ret(added) 63 | 64 | strmod = str(module) 65 | 66 | t2 = time() 67 | 68 | print("-- generate IR:", t2-t1) 69 | 70 | t3 = time() 71 | 72 | llmod = llvm.parse_assembly(strmod) 73 | 74 | t4 = time() 75 | 76 | print("-- parse assembly:", t4-t3) 77 | 78 | print(llmod) 79 | 80 | pmb = llvm.create_pass_manager_builder() 81 | pmb.opt_level = 2 82 | pm = llvm.create_module_pass_manager() 83 | pmb.populate(pm) 84 | 85 | t5 = time() 86 | 87 | pm.run(llmod) 88 | 89 | t6 = time() 90 | 91 | print("-- optimize:", t6-t5) 92 | 93 | t7 = time() 94 | 95 | target_machine = llvm.Target.from_default_triple().create_target_machine() 96 | 97 | with llvm.create_mcjit_compiler(llmod, target_machine) as ee: 98 | ee.finalize_object() 99 | cfptr = ee.get_function_address("sum") 100 | 101 | t8 = time() 102 | print("-- JIT compile:", t8 - t7) 103 | 104 | print(target_machine.emit_assembly(llmod)) 105 | 106 | cfunc = CFUNCTYPE(c_int, POINTER(c_int), c_int)(cfptr) 107 | A = np.arange(10, dtype=np.int32) 108 | res = cfunc(A.ctypes.data_as(POINTER(c_int)), A.size) 109 | 110 | print(res, A.sum()) 111 | 112 | -------------------------------------------------------------------------------- /docs/source/user-guide/examples/sum.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from ctypes import CFUNCTYPE, c_int, POINTER 4 | import sys 5 | try: 6 | from time import perf_counter as time 7 | except ImportError: 8 | from time import time 9 | 10 | import numpy as np 11 | 12 | try: 13 | import faulthandler; faulthandler.enable() 14 | except ImportError: 15 | pass 16 | 17 | import llvmlite.ir as ll 18 | import llvmlite.binding as llvm 19 | 20 | 21 | llvm.initialize() 22 | llvm.initialize_native_target() 23 | llvm.initialize_native_asmprinter() 24 | 25 | 26 | t1 = time() 27 | 28 | fnty = ll.FunctionType(ll.IntType(32), [ll.IntType(32).as_pointer(), 29 | ll.IntType(32)]) 30 | module = ll.Module() 31 | 32 | func = ll.Function(module, fnty, name="sum") 33 | 34 | bb_entry = func.append_basic_block() 35 | bb_loop = func.append_basic_block() 36 | bb_exit = func.append_basic_block() 37 | 38 | builder = ll.IRBuilder() 39 | builder.position_at_end(bb_entry) 40 | 41 | builder.branch(bb_loop) 42 | builder.position_at_end(bb_loop) 43 | 44 | index = builder.phi(ll.IntType(32)) 45 | index.add_incoming(ll.Constant(index.type, 0), bb_entry) 46 | accum = builder.phi(ll.IntType(32)) 47 | accum.add_incoming(ll.Constant(accum.type, 0), bb_entry) 48 | 49 | ptr = builder.gep(func.args[0], [index]) 50 | value = builder.load(ptr) 51 | 52 | added = builder.add(accum, value) 53 | accum.add_incoming(added, bb_loop) 54 | 55 | indexp1 = builder.add(index, ll.Constant(index.type, 1)) 56 | index.add_incoming(indexp1, bb_loop) 57 | 58 | cond = builder.icmp_unsigned('<', indexp1, func.args[1]) 59 | builder.cbranch(cond, bb_loop, bb_exit) 60 | 61 | builder.position_at_end(bb_exit) 62 | builder.ret(added) 63 | 64 | strmod = str(module) 65 | 66 | t2 = time() 67 | 68 | print("-- generate IR:", t2-t1) 69 | 70 | t3 = time() 71 | 72 | llmod = llvm.parse_assembly(strmod) 73 | 74 | t4 = time() 75 | 76 | print("-- parse assembly:", t4-t3) 77 | 78 | print(llmod) 79 | 80 | pmb = llvm.create_pass_manager_builder() 81 | pmb.opt_level = 2 82 | pm = llvm.create_module_pass_manager() 83 | pmb.populate(pm) 84 | 85 | t5 = time() 86 | 87 | pm.run(llmod) 88 | 89 | t6 = time() 90 | 91 | print("-- optimize:", t6-t5) 92 | 93 | t7 = time() 94 | 95 | target_machine = llvm.Target.from_default_triple().create_target_machine() 96 | 97 | with llvm.create_mcjit_compiler(llmod, target_machine) as ee: 98 | ee.finalize_object() 99 | cfptr = ee.get_function_address("sum") 100 | 101 | t8 = time() 102 | print("-- JIT compile:", t8 - t7) 103 | 104 | print(target_machine.emit_assembly(llmod)) 105 | 106 | cfunc = CFUNCTYPE(c_int, POINTER(c_int), c_int)(cfptr) 107 | A = np.arange(10, dtype=np.int32) 108 | res = cfunc(A.ctypes.data_as(POINTER(c_int)), A.size) 109 | 110 | print(res, A.sum()) 111 | 112 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | llvmlite 3 | ======== 4 | 5 | :emphasis:`A lightweight LLVM-Python binding for writing JIT compilers` 6 | 7 | llvmlite provides a Python binding to LLVM for use in Numba_. Numba 8 | previously relied on llvmpy_. 9 | 10 | Llvmpy became hard to maintain because: 11 | 12 | * It has a cumbersome architecture. 13 | * The C++11 requirement of recent LLVM versions does not go well 14 | with the compiler and runtime ABI requirements of some Python 15 | versions, especially under Windows. 16 | 17 | Llvmpy also proved to be responsible for a sizable part of 18 | Numba's compilation times, because of its inefficient layering 19 | and object encapsulation. Fixing this issue inside the llvmpy 20 | codebase seemed a time-consuming and uncertain task. 21 | 22 | The Numba developers decided to start a new binding from scratch, 23 | with an entirely different architecture, centered around the 24 | specific requirements of a JIT compiler. 25 | 26 | .. _Numba: http://numba.pydata.org/ 27 | .. _llvmpy: http://www.llvmpy.org/ 28 | 29 | Philosophy 30 | ========== 31 | 32 | While llvmpy_ exposed large parts of the LLVM C++ API for direct 33 | calls into the LLVM library, llvmlite takes an entirely different 34 | approach. Llvmlite starts from the needs of a JIT compiler and 35 | splits them into two decoupled tasks: 36 | 37 | * Construction of a :ref:`module`, function by function, 38 | :ref:`instruction` by instruction. 39 | 40 | * Compilation and optimization of the module into machine code. 41 | 42 | The construction of an LLVM module does not call the LLVM C++ API. 43 | Rather, it constructs the 44 | LLVM :ref:`intermediate representation ` 45 | (IR) in pure Python. This is the role of the 46 | :ref:`IR layer `. 47 | 48 | The compilation of an LLVM module takes the IR in textual form 49 | and feeds it into LLVM's parsing API. It then returns a thin 50 | wrapper around LLVM's C++ module object. This is the role of the 51 | :ref:`binding layer `. 52 | 53 | Once parsed, the module's source code cannot be modified, which 54 | loses the flexibility of the direct mapping of C++ APIs into 55 | Python that was provided by llvmpy but saves a great deal of 56 | maintenance. 57 | 58 | LLVM compatibility 59 | ================== 60 | 61 | Despite minimizing the API surface with LLVM, llvmlite is 62 | impacted by changes to LLVM's C++ API, which can occur at every 63 | feature release. Therefore, each llvmlite version is targeted to 64 | a specific LLVM feature version and works across all given bugfix 65 | releases of that version. 66 | 67 | EXAMPLE: Llvmlite 0.12.0 works with LLVM 3.8.0 and 3.8.1, but 68 | it does not work with LLVM 3.7.0 or 3.9.0. 69 | 70 | Numba's requirements determine which LLVM version is supported. 71 | 72 | API stability 73 | ============= 74 | 75 | At this time, we reserve the possibility of slightly breaking 76 | the llvmlite API at each release, for the following reasons: 77 | 78 | * Changes in LLVM behaviour, such as differences in the IR across 79 | versions. 80 | 81 | * As a young library, llvmlite has room for improvement or fixes 82 | to the existing APIs. 83 | 84 | 85 | .. toctree:: 86 | :maxdepth: 1 87 | :hidden: 88 | 89 | admin-guide/install 90 | user-guide/index 91 | contributing 92 | release-notes 93 | glossary 94 | 95 | .. |reg| unicode:: U+000AE .. REGISTERED SIGN 96 | -------------------------------------------------------------------------------- /docs/source/glossary.rst: -------------------------------------------------------------------------------- 1 | 2 | ======== 3 | Glossary 4 | ======== 5 | 6 | .. contents:: 7 | :local: 8 | :depth: 1 9 | 10 | 11 | .. _basic block: 12 | 13 | Basic block 14 | =========== 15 | 16 | A sequence of instructions inside a function. A basic block 17 | always starts with a :ref:`label` and ends with a 18 | :ref:`terminator `. No other instruction inside the 19 | basic block can transfer control out of the block. 20 | 21 | .. _function declaration: 22 | 23 | Function declaration 24 | ==================== 25 | 26 | The specification of a function's prototype without an 27 | associated implementation. A declaration includes the argument 28 | types, return types and other information such as the calling 29 | convention. This is like an ``extern`` function declaration in C. 30 | 31 | .. _function definition: 32 | 33 | Function definition 34 | =================== 35 | 36 | A function's prototype, as in a :ref:`function declaration`, 37 | plus a body implementing the function. 38 | 39 | .. _getelementptr: 40 | 41 | getelementptr 42 | ============= 43 | 44 | An LLVM :ref:`instruction` that lets you get the address of a 45 | subelement of an aggregate data structure. 46 | 47 | See :llvm:ref:`i_getelementptr` in the official LLVM 48 | documentation. 49 | 50 | 51 | .. _global value: 52 | 53 | Global value 54 | ============ 55 | 56 | A named value accessible to all members of a module. 57 | 58 | .. _global variable: 59 | 60 | Global variable 61 | =============== 62 | 63 | A variable whose value is accessible to all members of a module. 64 | It is a constant pointer to a module-allocated slot of the given 65 | type. 66 | 67 | All global variables are global values. However, the opposite is 68 | not true---function declarations and function definitions are not 69 | global variables, they are only :ref:`global values `. 70 | 71 | .. _instruction: 72 | 73 | Instruction 74 | =========== 75 | 76 | The fundamental element used in implementing an LLVM function. 77 | LLVM instructions define a procedural, assembly-like language. 78 | 79 | .. _IR: 80 | 81 | .. _intermediate representation: 82 | 83 | Intermediate representation (IR) 84 | ================================ 85 | 86 | High-level assembly-language code describing to LLVM the 87 | program to be compiled to native code. 88 | 89 | .. _label: 90 | 91 | Label 92 | ===== 93 | 94 | A branch target inside a function. A label always denotes the 95 | start of a :ref:`basic block`. 96 | 97 | .. _metadata: 98 | 99 | Metadata 100 | ======== 101 | 102 | Optional information associated with LLVM instructions, 103 | functions and other code. Metadata provides information that is 104 | not critical to the compiling of an 105 | LLVM :ref:`intermediate representation `, such as the 106 | likelihood of a condition branch or the source code location 107 | corresponding to a given instruction. 108 | 109 | .. _module: 110 | 111 | Module 112 | ====== 113 | 114 | A compilation unit for LLVM :ref:`intermediate representation `. 115 | A module can contain any number of function declarations and 116 | definitions, global variables and metadata. 117 | 118 | .. _terminator: 119 | 120 | .. _terminator instruction: 121 | 122 | Terminator, terminator instruction 123 | ================================== 124 | 125 | A kind of :ref:`instruction` that explicitly transfers control 126 | to another part of the program instead of going to the next 127 | instruction after it is executed. Examples are branches and 128 | function returns. 129 | -------------------------------------------------------------------------------- /docs/source/contributing.rst: -------------------------------------------------------------------------------- 1 | 2 | ======================== 3 | Contributing to llvmlite 4 | ======================== 5 | 6 | llvmlite originated to fulfill the needs of the Numba_ project. 7 | It is maintained mostly by the Numba team. We tend to prioritize 8 | the needs and constraints of Numba over other conflicting desires. 9 | 10 | We do welcome any contributions in the form of 11 | :ref:`bug reports ` or :ref:`pull requests `. 12 | 13 | .. _Numba: http://numba.pydata.org/ 14 | 15 | .. contents:: 16 | :local: 17 | :depth: 1 18 | 19 | Communication methods 20 | ===================== 21 | 22 | Mailing list 23 | ------------ 24 | 25 | Send email to the Numba users public mailing list at 26 | numba-users@anaconda.com. You are welcome to send any questions 27 | about contributing to llvmlite to this mailing list. 28 | 29 | You can subscribe and read the archives on 30 | `Google Groups `_. 31 | The `Gmane mirror `_ 32 | allows NNTP access. 33 | 34 | .. _report-bugs: 35 | 36 | Bug reports 37 | ----------- 38 | 39 | We use the 40 | `Github issue tracker `_ 41 | to track both bug reports and feature requests. If you report an 42 | issue, please include: 43 | 44 | * What you are trying to do. 45 | 46 | * Your operating system. 47 | 48 | * What version of llvmlite you are running. 49 | 50 | * A description of the problem---for example, the full error 51 | traceback or the unexpected results you are getting. 52 | 53 | * As far as possible, a code snippet that allows full 54 | reproduction of your problem. 55 | 56 | .. _pull-requests: 57 | 58 | Pull requests 59 | ------------- 60 | 61 | To contribute code: 62 | 63 | #. Fork our `Github repository `_. 64 | 65 | #. Create a branch representing your work. 66 | 67 | #. When your work is ready, submit it as a pull request from the 68 | Github interface. 69 | 70 | 71 | Development rules 72 | ================= 73 | 74 | Coding conventions 75 | ------------------ 76 | 77 | * All Python code should follow `PEP 8 `_. 78 | * Our C++ code does not have a well-defined coding style. 79 | * Code and documentation should generally fit within 80 columns, 80 | for maximum readability with all existing tools, such as code 81 | review user interfaces. 82 | 83 | 84 | Platform support 85 | ---------------- 86 | 87 | Llvmlite will be kept compatible with Python 2.7, 3.4 and later 88 | under at least Windows, macOS and Linux. It needs to be 89 | compatible only with the currently supported LLVM version---the 90 | 3.8 series. 91 | 92 | We do not expect contributors to test their code on all platforms. 93 | Pull requests are automatically built and tested using 94 | `Travis-CI `_, which 95 | addresses Linux compatibility. Other operating systems are tested 96 | on an internal continuous integration platform at 97 | Anaconda\ |reg|. 98 | 99 | 100 | Documentation 101 | ============= 102 | 103 | This llvmlite documentation is built using Sphinx and maintained 104 | in the ``docs`` directory inside the 105 | `llvmlite repository `_. 106 | 107 | #. Edit the source files under ``docs/source/``. 108 | 109 | #. Build the documentation:: 110 | 111 | make html 112 | 113 | #. Check the documentation:: 114 | 115 | open _build/html/index.html 116 | 117 | .. |reg| unicode:: U+000AE .. REGISTERED SIGN 118 | -------------------------------------------------------------------------------- /bench.py: -------------------------------------------------------------------------------- 1 | """ 2 | Crude benchmark to compare llvmlite and llvmpy performance. 3 | """ 4 | 5 | from __future__ import print_function 6 | 7 | from ctypes import CFUNCTYPE, c_int, POINTER 8 | import sys 9 | try: 10 | from time import perf_counter as time 11 | except ImportError: 12 | from time import time 13 | 14 | import numpy as np 15 | 16 | try: 17 | import faulthandler; faulthandler.enable() 18 | except ImportError: 19 | pass 20 | 21 | 22 | def run_bench(verbose): 23 | t = time() 24 | 25 | int32 = lc.Type.int(32) 26 | fnty = lc.Type.function(int32, [lc.Type.pointer(int32), int32]) 27 | module = lc.Module.new('foo') 28 | 29 | func = lc.Function.new(module, fnty, name="sum") 30 | 31 | bb_entry = func.append_basic_block('entry') 32 | bb_loop = func.append_basic_block('loop') 33 | bb_exit = func.append_basic_block('exit') 34 | 35 | builder = lc.Builder.new(bb_entry) 36 | builder.position_at_end(bb_entry) 37 | 38 | builder.branch(bb_loop) 39 | builder.position_at_end(bb_loop) 40 | 41 | index = builder.phi(int32) 42 | index.add_incoming(lc.Constant.int(index.type, 0), bb_entry) 43 | accum = builder.phi(int32) 44 | accum.add_incoming(lc.Constant.int(accum.type, 0), bb_entry) 45 | 46 | ptr = builder.gep(func.args[0], [index]) 47 | value = builder.load(ptr) 48 | 49 | added = builder.add(accum, value) 50 | accum.add_incoming(added, bb_loop) 51 | 52 | indexp1 = builder.add(index, lc.Constant.int(index.type, 1)) 53 | index.add_incoming(indexp1, bb_loop) 54 | 55 | cond = builder.icmp(lc.ICMP_ULT, indexp1, func.args[1]) 56 | builder.cbranch(cond, bb_loop, bb_exit) 57 | 58 | builder.position_at_end(bb_exit) 59 | builder.ret(added) 60 | 61 | #strmod = str(module) 62 | 63 | dt = time() - t 64 | if verbose: 65 | print("generate IR: %s" % (dt,)) 66 | 67 | t = time() 68 | 69 | eb = ee.EngineBuilder.new(module) #.opt(3) 70 | tm = ee.TargetMachine.new(opt=2) 71 | engine = eb.create(tm) 72 | 73 | dt = time() - t 74 | if verbose: 75 | print("create EngineBuilder: %s" % (dt,)) 76 | 77 | t = time() 78 | 79 | if hasattr(eb, "module"): 80 | # llvmlite 81 | llmod = eb.module 82 | llfunc = llmod.get_function("sum") 83 | else: 84 | llmod = module 85 | llfunc = llmod.get_function_named("sum") 86 | 87 | cfptr = engine.get_pointer_to_function(llfunc) 88 | 89 | dt = time() - t 90 | if verbose: 91 | print("JIT compile: %s" % (dt,)) 92 | 93 | # Check function calling 94 | cfunc = CFUNCTYPE(c_int, POINTER(c_int), c_int)(cfptr) 95 | A = np.arange(10, dtype=np.int32) 96 | res = cfunc(A.ctypes.data_as(POINTER(c_int)), A.size) 97 | 98 | assert res == A.sum(), (res, A.sum()) 99 | 100 | 101 | if __name__ == "__main__": 102 | if len(sys.argv) != 2: 103 | print("Usage: %s (llvmlite|llvmpy)" 104 | % (sys.executable,), file=sys.stderr) 105 | sys.exit(1) 106 | impl = sys.argv[1] 107 | 108 | if impl == 'llvmlite': 109 | import llvmlite.binding as llvm 110 | import llvmlite.llvmpy.core as lc 111 | from llvmlite.llvmpy import ee 112 | 113 | llvm.initialize() 114 | llvm.initialize_native_target() 115 | llvm.initialize_native_asmprinter() 116 | 117 | del llvm 118 | 119 | elif impl == 'llvmpy': 120 | import llvm.core as lc 121 | from llvm import ee 122 | 123 | else: 124 | raise RuntimeError("Wrong implementation %r" % (impl,)) 125 | 126 | for i in range(3): 127 | run_bench(True) 128 | print() 129 | -------------------------------------------------------------------------------- /conda-recipes/llvmdev_manylinux1/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # based on https://github.com/AnacondaRecipes/llvmdev-feedstock/blob/master/recipe/build.sh 4 | 5 | set -x 6 | 7 | # This is the clang compiler prefix 8 | DARWIN_TARGET=x86_64-apple-darwin13.4.0 9 | 10 | 11 | declare -a _cmake_config 12 | _cmake_config+=(-DCMAKE_INSTALL_PREFIX:PATH=${PREFIX}) 13 | _cmake_config+=(-DCMAKE_BUILD_TYPE:STRING=Release) 14 | # The bootstrap clang I use was built with a static libLLVMObject.a and I trying to get the same here 15 | # _cmake_config+=(-DBUILD_SHARED_LIBS:BOOL=ON) 16 | _cmake_config+=(-DLLVM_ENABLE_ASSERTIONS:BOOL=ON) 17 | _cmake_config+=(-DLINK_POLLY_INTO_TOOLS:BOOL=ON) 18 | # Don't really require libxml2. Turn it off explicitly to avoid accidentally linking to system libs 19 | _cmake_config+=(-DLLVM_ENABLE_LIBXML2:BOOL=OFF) 20 | # Urgh, llvm *really* wants to link to ncurses / terminfo and we *really* do not want it to. 21 | _cmake_config+=(-DHAVE_TERMINFO_CURSES=OFF) 22 | # Sometimes these are reported as unused. Whatever. 23 | _cmake_config+=(-DHAVE_TERMINFO_NCURSES=OFF) 24 | _cmake_config+=(-DHAVE_TERMINFO_NCURSESW=OFF) 25 | _cmake_config+=(-DHAVE_TERMINFO_TERMINFO=OFF) 26 | _cmake_config+=(-DHAVE_TERMINFO_TINFO=OFF) 27 | _cmake_config+=(-DHAVE_TERMIOS_H=OFF) 28 | _cmake_config+=(-DCLANG_ENABLE_LIBXML=OFF) 29 | _cmake_config+=(-DLIBOMP_INSTALL_ALIASES=OFF) 30 | _cmake_config+=(-DLLVM_ENABLE_RTTI=OFF) 31 | _cmake_config+=(-DLLVM_TARGETS_TO_BUILD=host) 32 | _cmake_config+=(-DLLVM_INCLUDE_UTILS=ON) # for llvm-lit 33 | # TODO :: It would be nice if we had a cross-ecosystem 'BUILD_TIME_LIMITED' env var we could use to 34 | # disable these unnecessary but useful things. 35 | if [[ ${CONDA_FORGE} == yes ]]; then 36 | _cmake_config+=(-DLLVM_INCLUDE_TESTS=OFF) 37 | _cmake_config+=(-DLLVM_INCLUDE_DOCS=OFF) 38 | _cmake_config+=(-DLLVM_INCLUDE_EXAMPLES=OFF) 39 | fi 40 | # Only valid when using the Ninja Generator AFAICT 41 | # _cmake_config+=(-DLLVM_PARALLEL_LINK_JOBS:STRING=1) 42 | # What about cross-compiling targetting Darwin here? Are any of these needed? 43 | if [[ $(uname) == Darwin ]]; then 44 | _cmake_config+=(-DCMAKE_OSX_SYSROOT=${SYSROOT_DIR}) 45 | _cmake_config+=(-DDARWIN_macosx_CACHED_SYSROOT=${SYSROOT_DIR}) 46 | _cmake_config+=(-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}) 47 | _cmake_config+=(-DCMAKE_LIBTOOL=$(which ${DARWIN_TARGET}-libtool)) 48 | _cmake_config+=(-DLD64_EXECUTABLE=$(which ${DARWIN_TARGET}-ld)) 49 | _cmake_config+=(-DCMAKE_INSTALL_NAME_TOOL=$(which ${DARWIN_TARGET}-install_name_tool)) 50 | # Once we are using our libc++ (not until llvm_build_final), it will be single-arch only and not setting 51 | # this causes link failures building the santizers since they respect DARWIN_osx_ARCHS. We may as well 52 | # save some compilation time by setting this for all of our llvm builds. 53 | _cmake_config+=(-DDARWIN_osx_ARCHS=x86_64) 54 | elif [[ $(uname) == Linux ]]; then 55 | _cmake_config+=(-DLLVM_USE_INTEL_JITEVENTS=ON) 56 | # _cmake_config+=(-DLLVM_BINUTILS_INCDIR=${PREFIX}/lib/gcc/${cpu_arch}-${vendor}-linux-gnu/${compiler_ver}/plugin/include) 57 | fi 58 | 59 | # For when the going gets tough: 60 | # _cmake_config+=(-Wdev) 61 | # _cmake_config+=(--debug-output) 62 | # _cmake_config+=(--trace-expand) 63 | # CPU_COUNT=1 64 | 65 | mkdir build 66 | cd build 67 | 68 | cmake -G'Unix Makefiles' \ 69 | "${_cmake_config[@]}" \ 70 | .. 71 | 72 | ARCH=`uname -m` 73 | if [ $ARCH == 'armv7l' ]; then # RPi need thread count throttling 74 | make -j2 VERBOSE=1 75 | else 76 | make -j${CPU_COUNT} VERBOSE=1 77 | fi 78 | 79 | # From: https://github.com/conda-forge/llvmdev-feedstock/pull/53 80 | make install || exit $? 81 | 82 | cd ../test 83 | ../build/bin/llvm-lit -vv Transforms ExecutionEngine Analysis CodeGen/X86 84 | -------------------------------------------------------------------------------- /conda-recipes/appveyor/run_with_env.cmd: -------------------------------------------------------------------------------- 1 | :: From https://github.com/ogrisel/python-appveyor-demo 2 | :: 3 | :: To build extensions for 64 bit Python 3, we need to configure environment 4 | :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: 5 | :: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) 6 | :: 7 | :: To build extensions for 64 bit Python 2, we need to configure environment 8 | :: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: 9 | :: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) 10 | :: 11 | :: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific 12 | :: environment configurations. 13 | :: 14 | :: Note: this script needs to be run with the /E:ON and /V:ON flags for the 15 | :: cmd interpreter, at least for (SDK v7.0) 16 | :: 17 | :: More details at: 18 | :: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows 19 | :: http://stackoverflow.com/a/13751649/163740 20 | :: 21 | :: Author: Olivier Grisel 22 | :: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ 23 | :: 24 | :: Notes about batch files for Python people: 25 | :: 26 | :: Quotes in values are literally part of the values: 27 | :: SET FOO="bar" 28 | :: FOO is now five characters long: " b a r " 29 | :: If you don't want quotes, don't include them on the right-hand side. 30 | :: 31 | :: The CALL lines at the end of this file look redundant, but if you move them 32 | :: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y 33 | :: case, I don't know why. 34 | @ECHO OFF 35 | 36 | SET COMMAND_TO_RUN=%* 37 | SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows 38 | SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf 39 | 40 | :: Extract the major and minor versions, and allow for the minor version to be 41 | :: more than 9. This requires the version number to have two dots in it. 42 | SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% 43 | IF "%PYTHON_VERSION:~3,1%" == "." ( 44 | SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% 45 | ) ELSE ( 46 | SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% 47 | ) 48 | 49 | :: Based on the Python version, determine what SDK version to use, and whether 50 | :: to set the SDK for 64-bit. 51 | IF %MAJOR_PYTHON_VERSION% == 2 ( 52 | SET WINDOWS_SDK_VERSION="v7.0" 53 | SET SET_SDK_64=Y 54 | ) ELSE ( 55 | IF %MAJOR_PYTHON_VERSION% == 3 ( 56 | SET WINDOWS_SDK_VERSION="v7.1" 57 | IF %MINOR_PYTHON_VERSION% LEQ 4 ( 58 | SET SET_SDK_64=Y 59 | ) ELSE ( 60 | SET SET_SDK_64=N 61 | IF EXIST "%WIN_WDK%" ( 62 | :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/ 63 | REN "%WIN_WDK%" 0wdf 64 | ) 65 | ) 66 | ) ELSE ( 67 | ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" 68 | EXIT 1 69 | ) 70 | ) 71 | 72 | IF %PYTHON_ARCH% == 64 ( 73 | IF %SET_SDK_64% == Y ( 74 | ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture 75 | SET DISTUTILS_USE_SDK=1 76 | SET MSSdk=1 77 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% 78 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release 79 | ECHO Executing: %COMMAND_TO_RUN% 80 | call %COMMAND_TO_RUN% || EXIT 1 81 | ) ELSE ( 82 | ECHO Using default MSVC build environment for 64 bit architecture 83 | ECHO Executing: %COMMAND_TO_RUN% 84 | call %COMMAND_TO_RUN% || EXIT 1 85 | ) 86 | ) ELSE ( 87 | ECHO Using default MSVC build environment for 32 bit architecture 88 | ECHO Executing: %COMMAND_TO_RUN% 89 | call %COMMAND_TO_RUN% || EXIT 1 90 | ) 91 | -------------------------------------------------------------------------------- /docs/source/user-guide/ir/modules.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Modules 3 | ======= 4 | 5 | .. currentmodule:: llvmlite.ir 6 | 7 | A module is a compilation unit. It defines a set of related 8 | functions, global variables and metadata. In the IR layer, a 9 | module is represented by the :class:`Module` class. 10 | 11 | 12 | .. class:: Module(name='') 13 | 14 | Create a module. For informational purposes, you can specify 15 | the optional *name*, a Python string. 16 | 17 | Modules have the following methods and attributes: 18 | 19 | * .. method:: add_debug_info(kind, operands, is_distinct=False) 20 | 21 | Add debug information metadata to the module with the 22 | given *operands*---a mapping of string keys to values---or 23 | return a previous equivalent metadata. *kind* is the name 24 | of the debug information kind. 25 | 26 | EXAMPLE: ``'DICompileUnit'`` 27 | 28 | A :class:`DIValue` instance is returned. You can then 29 | associate it to, for example, an instruction. 30 | 31 | EXAMPLE:: 32 | 33 | di_file = module.add_debug_info("DIFile", { 34 | "filename": "factorial.py", 35 | "directory": "bar", 36 | }) 37 | di_compile_unit = module.add_debug_info("DICompileUnit", { 38 | "language": ir.DIToken("DW_LANG_Python"), 39 | "file": di_file, 40 | "producer": "llvmlite x.y", 41 | "runtimeVersion": 2, 42 | "isOptimized": False, 43 | }, is_distinct=True) 44 | 45 | * .. method:: add_global(globalvalue) 46 | 47 | Add the given *globalvalue*---a :class:`GlobalValue`---to 48 | this module. It should have a unique name in the whole 49 | module. 50 | 51 | * .. method:: add_metadata(operands) 52 | 53 | Add an unnamed :ref:`metadata` node to the module with 54 | the given *operands*---a list of metadata-compatible 55 | values. If another metadata node with equal operands 56 | already exists in the module, it is reused instead. 57 | Returns an :class:`MDValue`. 58 | 59 | * .. method:: add_named_metadata(name, element=None) 60 | 61 | Return the metadata node with the given *name*. If it does 62 | not already exist, the named metadata node is created 63 | first. If *element* is not ``None``, it can be a metadata 64 | value or a sequence of values to append to the metadata 65 | node's elements. Returns a :class:`NamedMetaData`. 66 | 67 | EXAMPLE:: 68 | 69 | module.add_named_metadata("llvm.ident", ["llvmlite/1.0"]) 70 | 71 | * .. method:: get_global(name) 72 | 73 | Get the 74 | :ref:`global value`---a :class:`GlobalValue`---with the 75 | given name. :exc:`KeyError` is raised if the name does 76 | not exist. 77 | 78 | * .. method:: get_named_metadata(name) 79 | 80 | Return the metadata node with the given *name*. 81 | :exc:`KeyError` is raised if the name does not exist. 82 | 83 | * .. method:: get_unique_name(name) 84 | 85 | Return a unique name across the whole module. *name* is 86 | the desired name, but a variation can be returned if it 87 | is already in use. 88 | 89 | * .. attribute:: data_layout 90 | 91 | A string representing the data layout in LLVM format. 92 | 93 | * .. attribute:: functions 94 | 95 | The list of functions, as :class:`Function` instances, 96 | declared or defined in the module. 97 | 98 | * .. attribute:: global_values 99 | 100 | An iterable of global values in this module. 101 | 102 | * .. attribute:: triple 103 | 104 | A string representing the target architecture in LLVM 105 | "triple" form. 106 | -------------------------------------------------------------------------------- /conda-recipes/llvmdev/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # based on https://github.com/AnacondaRecipes/llvmdev-feedstock/blob/master/recipe/build.sh 4 | 5 | set -x 6 | 7 | # This is the clang compiler prefix 8 | DARWIN_TARGET=x86_64-apple-darwin13.4.0 9 | 10 | 11 | declare -a _cmake_config 12 | _cmake_config+=(-DCMAKE_INSTALL_PREFIX:PATH=${PREFIX}) 13 | _cmake_config+=(-DCMAKE_BUILD_TYPE:STRING=Release) 14 | # The bootstrap clang I use was built with a static libLLVMObject.a and I trying to get the same here 15 | # _cmake_config+=(-DBUILD_SHARED_LIBS:BOOL=ON) 16 | _cmake_config+=(-DLLVM_ENABLE_ASSERTIONS:BOOL=ON) 17 | _cmake_config+=(-DLINK_POLLY_INTO_TOOLS:BOOL=ON) 18 | # Don't really require libxml2. Turn it off explicitly to avoid accidentally linking to system libs 19 | _cmake_config+=(-DLLVM_ENABLE_LIBXML2:BOOL=OFF) 20 | # Urgh, llvm *really* wants to link to ncurses / terminfo and we *really* do not want it to. 21 | _cmake_config+=(-DHAVE_TERMINFO_CURSES=OFF) 22 | # Sometimes these are reported as unused. Whatever. 23 | _cmake_config+=(-DHAVE_TERMINFO_NCURSES=OFF) 24 | _cmake_config+=(-DHAVE_TERMINFO_NCURSESW=OFF) 25 | _cmake_config+=(-DHAVE_TERMINFO_TERMINFO=OFF) 26 | _cmake_config+=(-DHAVE_TERMINFO_TINFO=OFF) 27 | _cmake_config+=(-DHAVE_TERMIOS_H=OFF) 28 | _cmake_config+=(-DCLANG_ENABLE_LIBXML=OFF) 29 | _cmake_config+=(-DLIBOMP_INSTALL_ALIASES=OFF) 30 | _cmake_config+=(-DLLVM_ENABLE_RTTI=OFF) 31 | _cmake_config+=(-DLLVM_TARGETS_TO_BUILD=host) 32 | _cmake_config+=(-DLLVM_INCLUDE_UTILS=ON) # for llvm-lit 33 | # TODO :: It would be nice if we had a cross-ecosystem 'BUILD_TIME_LIMITED' env var we could use to 34 | # disable these unnecessary but useful things. 35 | if [[ ${CONDA_FORGE} == yes ]]; then 36 | _cmake_config+=(-DLLVM_INCLUDE_TESTS=OFF) 37 | _cmake_config+=(-DLLVM_INCLUDE_DOCS=OFF) 38 | _cmake_config+=(-DLLVM_INCLUDE_EXAMPLES=OFF) 39 | fi 40 | # Only valid when using the Ninja Generator AFAICT 41 | # _cmake_config+=(-DLLVM_PARALLEL_LINK_JOBS:STRING=1) 42 | # What about cross-compiling targetting Darwin here? Are any of these needed? 43 | if [[ $(uname) == Darwin ]]; then 44 | _cmake_config+=(-DCMAKE_OSX_SYSROOT=${SYSROOT_DIR}) 45 | _cmake_config+=(-DDARWIN_macosx_CACHED_SYSROOT=${SYSROOT_DIR}) 46 | _cmake_config+=(-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}) 47 | _cmake_config+=(-DCMAKE_LIBTOOL=$(which ${DARWIN_TARGET}-libtool)) 48 | _cmake_config+=(-DLD64_EXECUTABLE=$(which ${DARWIN_TARGET}-ld)) 49 | _cmake_config+=(-DCMAKE_INSTALL_NAME_TOOL=$(which ${DARWIN_TARGET}-install_name_tool)) 50 | # Once we are using our libc++ (not until llvm_build_final), it will be single-arch only and not setting 51 | # this causes link failures building the santizers since they respect DARWIN_osx_ARCHS. We may as well 52 | # save some compilation time by setting this for all of our llvm builds. 53 | _cmake_config+=(-DDARWIN_osx_ARCHS=x86_64) 54 | elif [[ $(uname) == Linux ]]; then 55 | _cmake_config+=(-DLLVM_USE_INTEL_JITEVENTS=ON) 56 | # _cmake_config+=(-DLLVM_BINUTILS_INCDIR=${PREFIX}/lib/gcc/${cpu_arch}-${vendor}-linux-gnu/${compiler_ver}/plugin/include) 57 | fi 58 | 59 | # For when the going gets tough: 60 | # _cmake_config+=(-Wdev) 61 | # _cmake_config+=(--debug-output) 62 | # _cmake_config+=(--trace-expand) 63 | # CPU_COUNT=1 64 | 65 | mkdir build 66 | cd build 67 | 68 | cmake -G'Unix Makefiles' \ 69 | "${_cmake_config[@]}" \ 70 | .. 71 | 72 | ARCH=`uname -m` 73 | if [ $ARCH == 'armv7l' ]; then # RPi need thread count throttling 74 | make -j2 VERBOSE=1 75 | else 76 | make -j${CPU_COUNT} VERBOSE=1 77 | fi 78 | 79 | # From: https://github.com/conda-forge/llvmdev-feedstock/pull/53 80 | make install || exit $? 81 | 82 | # SVML tests on x86_64 arch only 83 | if [[ $ARCH == 'x86_64' ]]; then 84 | bin/opt -S -vector-library=SVML -mcpu=haswell -O3 $RECIPE_DIR/numba-3016.ll | bin/FileCheck $RECIPE_DIR/numba-3016.ll || exit $? 85 | fi 86 | cd ../test 87 | ../build/bin/llvm-lit -vv Transforms ExecutionEngine Analysis CodeGen/X86 88 | -------------------------------------------------------------------------------- /conda-recipes/llvmdev/numba-3016.ll: -------------------------------------------------------------------------------- 1 | ; Regression test for llvmdev-feedstock#52 and numba#3016 2 | 3 | ; Generated from C code: int a[1<<10],b[1<<10]; void foo() { int i=0; for(i=0; i<1<<10; i++) { b[i]=sin(a[i]); }} 4 | ; compiled: -fvectorize -fveclib=SVML -O -S -mavx -mllvm -disable-llvm-optzns -emit-llvm 5 | 6 | ; RUN: opt -vector-library=SVML -mcpu=haswell -O3 -S < %s | FileCheck %s 7 | ; CHECK: __svml_sin4_ha 8 | ; CHECK-NOT: __svml_sin4( 9 | ; CHECK-NOT: __svml_sin8 10 | 11 | source_filename = "svml-3016.c" 12 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 13 | target triple = "x86_64-pc-linux-gnu" 14 | 15 | @a = common dso_local global [1024 x i32] zeroinitializer, align 16 16 | @b = common dso_local global [1024 x i32] zeroinitializer, align 16 17 | 18 | ; Function Attrs: nounwind uwtable 19 | define dso_local void @foo() #0 { 20 | %1 = alloca i32, align 4 21 | %2 = bitcast i32* %1 to i8* 22 | call void @llvm.lifetime.start.p0i8(i64 4, i8* %2) #3 23 | store i32 0, i32* %1, align 4, !tbaa !2 24 | store i32 0, i32* %1, align 4, !tbaa !2 25 | br label %3 26 | 27 | ;