diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 3a05aa8..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -llvm/_version.py export-subst diff --git a/.gitignore b/.gitignore index 6d6296f..6d0cc2b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,4 @@ build _build *.pyc -*.so /llvm/_intrinsic_ids.py -llvm_ -newbinding/api/* \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f4474f7..0000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: python - -python: - - "2.6" - - "2.7" - - "3.2" - - "3.3" - -branches: - only: - - master - -install: - - wget "http://repo.continuum.io/pkgs/free/linux-64/llvm-3.2-0.tar.bz2" - - tar -xjf llvm-3.2-0.tar.bz2 - - PATH+=":`pwd`/bin" - - export LD_LIBRARY_PATH="`pwd`/lib" - - export LLVM_CONFIG_PATH="`pwd`/bin/llvm-config" - - $LLVM_CONFIG_PATH --cflags # test llvm-config - - export LLVMPY_DYNLINK=1 - - python setup.py install -q - -script: cd ~; python -c "import sys;import llvm;sys.exit(0 if llvm.test() == 0 else 1)" - diff --git a/CHANGELOG b/CHANGELOG index 45d6a5f..815ecf7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,70 +1,5 @@ -2014-04-28 0.12.5: ---------------------- - * Fixes memory leaks (#92) - * Fixes tarball (#99) -2014-03-20 0.12.4: ---------------------- - * Add dylib_import_library and friends - * Fix BasicBlock downcast - * Module hashing - * Fix test script - -2014-02-18 0.12.3: ---------------------- - * Fix deprecation message for py2.6 - * Fix llvm_cbuilder for using deprecated_alloca - * Merged PR #88 by cantora - * Merged PR #94 by cgohlke - -2014-02-04 0.12.2: ---------------------- - * enhance wrapper efficiency by moving some capsule code into C++ - * fix unclosed file handler in avx_support - * multiple-dimension insert_value, extract_value - * various minor fixes - -2013-11-11 0.12.1: ---------------------- - * various bug fixes - -2013-08-28 0.12.0: ---------------------- - * update to LLVM 3.3 and maintain compatibility with LLVM 3.2 - * add LLRT for minimal support for 64-bit divmod on 32-bit platform - * start to adopt MCJIT (not quite usable on win32) - * various bug fixes - -2013-03-05 0.11.1: --------------------- - * fix test when cc is not available - * fix Python 3 division (Hernan Grecco) (Issue #59) - * add relocation enums and add reloc argument for TargetMachine - - -2013-03-01 0.11.0: --------------------- - * fix Python 3 support on Windows - * New llvm binding - - -2013-02-01 0.10.2: --------------------- - * change default to link dynamically to LLVM use: - $ export LLVMPY_DYNLINK=0 # link statically - $ export LLVMPY_DYNLINK=1 # link dynamically - $ unset LLVMPY_DYNLINK # tries to link dynamically if LLVM shared - # objects are found and statically otherwise - * fix llpython for Python 2.6 support - - -2013-01-25 0.10.1: --------------------- - * fix support for Python 2.6 - - -2013-01-18 0.10.0: --------------------- +0.10, 18-Jan-2013: * Add LLVM 3.2 support. * New TargetData class. * Fixed windows issue (Issue #42). @@ -73,16 +8,16 @@ * Added llvm.passes.build_pass_managers as a simpler way to build PassManagers. -in progress, 0.7: ------------------ +0.7, in progress: + * Add llvm.core.Argument.alignment property. * Migrate to LLVM 2.8. * Fix ffi link issue on darwin (Albert Mietus) (Issue #29). * LLVM tutorial ported (Max Shawabkeh) (Issue #33). -2010-08-31 0.6: ------------------ +0.6, 31-Aug-2010: + * Add and remove function attributes (Krzysztof Goj) (Issue #21). * Wrap fadd,fsub,fmul (Aaron S Lav) (Issue #31). * Migrate to LLVM 2.7. @@ -101,16 +36,16 @@ in progress, 0.7: * Migrate to LLVM 2.5. -2008-11-22 0.5: ------------------ +0.5, 22-Nov-2008: + * Added vicmp, vfcmp instructions and constant expressions. * Builds on FreeBSD. * Updated documentation. * Migrate to LLVM 2.4. -2008-11-21 0.4: ------------------ +0.4, 21-Nov-2008: + * Code cleanup, added license headers. * Added llvm.core.load_library_permanently() (Issue #12). * Fix comparison using != (Issue #11). @@ -119,8 +54,8 @@ in progress, 0.7: * Added viewCFG methods to Function (Paulo Silva). -2008-09-08 0.3: ------------------ +0.3, 8-Sep-2008: + * Passes added. * Assembly support: create modules from .ll files. * Various bug fixes. @@ -132,13 +67,13 @@ in progress, 0.7: * Updated documentation. -2008-06-28 0.2.1: -------------------- +0.2.1, 18-Jun-2008: + * Build cleanly with LLVM 2.3 and 2.3svn. -2008-06-15 0.2: ------------------ +0.2, 15-Jun-2008: + * Independent package, need not be unpacked into llvm/bindings. * Fixed ownership issues with Module/ModuleProvider. * Modules, values and types can be stringified, to get their LLVM @@ -153,6 +88,7 @@ in progress, 0.7: * Lots of cleanup. -2008-05-10 0.1: ------------------ - * Initial release +0.1, 10-May-2008: + + * Initial release. + diff --git a/MANIFEST.in b/MANIFEST.in index 25a211d..295794c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,5 @@ -include CHANGELOG LICENSE README.rst setup.py MANIFEST.in versioneer.py +include CHANGELOG LICENSE README setup.py MANIFEST.in recursive-include llvm * -recursive-include llvmpy * recursive-include www * recursive-include test * recursive-include tools * diff --git a/README.rst b/README.rst index a1abf84..973dfdb 100644 --- a/README.rst +++ b/README.rst @@ -10,54 +10,32 @@ http://www.llvmpy.org Versions -------- -This package has been tested with LLVM 3.2, Python 2.6, 2.7 and 3.3. -Other Python versions may work. +This package has been tested with LLVM 3.1 and 3.2, Python 2.7 and Python 3.2. +Other Python versions should work. Quickstart ---------- -1. Get and extract LLVM 3.2 source tarball from - `llvm.org `_. Then, ``cd`` into - the extracted directory. +1. Get 3.1 or 3.2 version of LLVM, build it. Make sure ``--enable-pic`` is + passed to LLVM's ``configure``. + + For LLVM 3.2, make sure that environment variable ``REQUIRES_RTTI=1`` is + defined when running ``make``. Otherwise, you may see "undefined symbol: + _ZTIN4llvm24PassRegistrationListenerE". Please refer to + http://llvm.org/docs/Packaging.html#c-features for details. -2. Run ``./configure --enable-optimized --prefix=LLVM_INSTALL_PATH``. - - **Note**: Without the ``--enable-optimized`` flag, debug build will be - selected. Unless you are developing LLVM or llvmpy, it is recommended - that the flag is used to reduce build time and binary size. - - **Note**: Use prefix to select the installation path. It is recommended - to separate your custom build from the default system package. Please - replace ``LLVM_INSTALL_PATH`` with your own path. - -3. Run ``REQUIRES_RTTI=1 make install`` to build and install. - - **Note**: With LLVM 3.2, the default build configuration has C++ RTTI - disabled. However, llvmpy requires RTTI. - - **Note**: Use ``make -j2 install`` to enable concurrent build. - Replace ``2`` with the actual number of processor you have. - -4. Get llvm-py and install it:: +2. Get llvm-py and install it:: $ git clone git@github.com:llvmpy/llvmpy.git $ cd llvmpy - $ LLVM_CONFIG_PATH=LLVM_INSTALL_PATH/bin/llvm-config python setup.py install + $ python setup.py install Run the tests:: $ python -c "import llvm; llvm.test()" -5. See documentation at 'http://www.llvmpy.org' and examples +3. See documentation at 'http://www.llvmpy.org' and examples under 'test'. - -Common Build Problems ---------------------- - -1. If llvmpy cannot be imported due to "undefined symbol: - _ZTIN4llvm24PassRegistrationListenerE", it is because RTTI is not enabled - when building LLVM. "_ZTIN4llvm24PassRegistrationListenerE" is the typeinfo - of PassRegistrationListener class. LICENSE ------- diff --git a/buildscripts/condarecipe/bld.bat b/buildscripts/condarecipe/bld.bat deleted file mode 100644 index e9177c5..0000000 --- a/buildscripts/condarecipe/bld.bat +++ /dev/null @@ -1,6 +0,0 @@ -set LLVMPY_DYNLINK=0 -set INCLUDE=%LIBRARY_INC% -set LIBPATH=%LIBRARY_LIB% -set LIB=%LIBRARY_LIB% -%PYTHON% setup.py install -if errorlevel 1 exit 1 diff --git a/buildscripts/condarecipe/build.sh b/buildscripts/condarecipe/build.sh deleted file mode 100644 index 5c98fde..0000000 --- a/buildscripts/condarecipe/build.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -if [[ (`uname` == Linux) && (`uname -m` != armv6l) ]] -then - export CC=gcc - #gcc44 - export CXX=g++ - #g++44 -fi - -export LLVMPY_DYNLINK=$DISTRO_BUILD - -$PYTHON setup.py install diff --git a/buildscripts/condarecipe/meta.yaml b/buildscripts/condarecipe/meta.yaml deleted file mode 100644 index 4612840..0000000 --- a/buildscripts/condarecipe/meta.yaml +++ /dev/null @@ -1,28 +0,0 @@ -package: - name: llvmpy - version: 99.9.9 - -source: - git_url: git@github.com:llvmpy/llvmpy.git -# git_tag: 0.12.0 - -requirements: - build: - - llvm - - python - #- chrpath [linux] - run: - - llvm [unix] - - python - -test: - imports: - - llvm - - llvmpy - - llvmpy._api - - llvmpy._capsule - - llpython - - llvm_array - - llvm_cbuilder - - diff --git a/buildscripts/condarecipe/run_test.py b/buildscripts/condarecipe/run_test.py deleted file mode 100644 index 682b8d4..0000000 --- a/buildscripts/condarecipe/run_test.py +++ /dev/null @@ -1,22 +0,0 @@ -import sys -import platform -import llvm - -from llvm.core import Module -from llvm.ee import EngineBuilder -from llvm.utils import check_intrinsics - -m = Module.new('fjoidajfa') -eb = EngineBuilder.new(m) -target = eb.select_target() - -print('target.triple=%r' % target.triple) -if sys.platform == 'darwin': - s = {'64bit': 'x86_64', '32bit': 'x86'}[platform.architecture()[0]] - assert target.triple.startswith(s + '-apple-darwin') - -assert llvm.test(verbosity=2, run_isolated=False) == 0 -#check_intrinsics.main() - -print('llvm.__version__: %s' % llvm.__version__) -#assert llvm.__version__ == '0.12.0' diff --git a/docs/gh-pages.py b/docs/gh-pages.py index 3ee5d20..d9c8614 100755 --- a/docs/gh-pages.py +++ b/docs/gh-pages.py @@ -30,7 +30,7 @@ from subprocess import Popen, PIPE, CalledProcessError, check_call pages_dir = 'gh-pages' html_dir = '_build/html' pdf_dir = '_build/latex' -pages_repo = 'https://github.com/llvmpy/llvmpy-doc.git' +pages_repo = 'git@github.com:llvmpy/llvmpy-doc.git' #----------------------------------------------------------------------------- # Functions @@ -86,7 +86,7 @@ if __name__ == '__main__': tag = sh2('git describe --exact-match') except CalledProcessError: tag = "dev" # Fallback - + startdir = os.getcwdu() if not os.path.exists(pages_dir): # init the repo diff --git a/docs/source/conf.py b/docs/source/conf.py index 701ef80..5c5c38d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -11,23 +11,12 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os, glob +import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('../..')) - -# Support sphinx.ext.autodoc to extract docstrings from modules without installing -# complete package. -# The python modules depend on _core, so we must build entire package first though. -built_lib = glob.glob('../../build/lib.*-%d.%d/' % sys.version_info[:2]) -if not built_lib: - sys.stderr.write("WARNING: To build complete documentation you must build " - "package first\n") -else: - # lib dir has platform suffix - sys.path.insert(0, os.path.abspath(built_lib[0])) +#sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- @@ -52,22 +41,16 @@ master_doc = 'index' # General information about the project. project = u'llvmpy' -copyright = u'2013, Mahadevan R (2008-2010), Continuum Analytics (2012-2013)' +copyright = u'2012, Mahadevan R (2008-2010), Continuum Analytics (2012)' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # -try: - import llvm - version_strs = llvm.__version__.split('.') - # The short X.Y version. - version = '.'.join(version_strs[:2]) - # The full version, including alpha/beta/rc tags. - release = '%s.%s' % (version, '-'.join(version_strs[2].split('-')[:2])) -except ImportError: - version = 'unknown-version' - release = 'unknown-release' +# The short X.Y version. +version = '0.9' +# The full version, including alpha/beta/rc tags. +release = '0.9.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/doc/examples/JITTutorial2.rst b/docs/source/doc/examples/JITTutorial2.rst index 6e76150..a9a9979 100644 --- a/docs/source/doc/examples/JITTutorial2.rst +++ b/docs/source/doc/examples/JITTutorial2.rst @@ -1,5 +1,5 @@ A More Complicated Function -=========================== +==================== .. code-block:: python diff --git a/docs/source/doc/getting_started.rst b/docs/source/doc/getting_started.rst index 53c2982..f9b9c56 100644 --- a/docs/source/doc/getting_started.rst +++ b/docs/source/doc/getting_started.rst @@ -38,7 +38,7 @@ supported, for a variety of reasons. Versions -------- -llvmpy 0.11.2 uses LLVM 3.2 (or at least 3.1). It may not work with +llvmpy 0.9 requires version 3.1 of LLVM. It may not work with previous versions. llvmpy has been built and tested with Python 2.7 and 3.2. It should work with @@ -65,6 +65,22 @@ It does not matter which compiler LLVM itself was built with (``g++``, ``llvm-g++`` or any other); llvmpy can be built with any compiler. It has been tried only with gcc/g++ though. + +LLVM and ``--enable-pic`` +------------------------- + +The result of an LLVM build is a set of static libraries and object +files. The llvmpy contains an extension package that is built into a +shared object (\_core.so) which links to these static libraries and +object files. It is therefore required that the LLVM libraries and +object files be built with the ``-fPIC`` option (generate position +independent code). Be sure to use the ``--enable-pic`` option while +configuring LLVM (default is no PIC), like this: + +.. code-block:: bash + + $ ~/llvm ./configure --enable-pic --enable-optimized + llvm-config ----------- @@ -82,34 +98,13 @@ is different from that of 'root', so even if ``llvm-config`` is in your Steps ----- -1. Get and extract LLVM 3.2 source tarball from - `llvm.org `_. Then, ``cd`` into - the extracted directory. +Get 3.1 version of LLVM, build it. Make sure '--enable-pic' is passed to +LLVM's 'configure'. -2. Run ``./configure --enable-optimized --prefix=LLVM_INSTALL_PATH``. +Get llvmpy and install it: - **Note**: Without the ``--enable-optimized`` flag, debug build will be - selected. Unless you are developing LLVM or llvmpy, it is recommended - that the flag is used to reduce build time and binary size. - - **Note**: Use prefix to select the installation path. It is recommended - to separate your custom build from the default system package. Please - replace ``LLVM_INSTALL_PATH`` with your own path. -3. Run ``REQUIRES_RTTI=1 make`` to build. +.. code-block:: bash - **Note**: With LLVM 3.2, the default build configuration has C++ RTTI - disabled. However, llvmpy requires RTTI. - -4. Get llvm-py and install it:: - - $ git clone git@github.com:llvmpy/llvmpy.git - $ cd llvmpy - $ LLVM_CONFIG_PATH=LLVM_INSTALL_PATH/bin/llvm-config python setup.py install - - Run the tests:: - - $ python -c "import llvm; llvm.test()" - -5. See documentation at 'http://www.llvmpy.org' and examples - under 'test'. + $ git clone git@github.com:numba/llvmpy.git + $ cd llvmpy $ python setup.py install diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl1.rst b/docs/source/doc/kaleidoscope/PythonLangImpl1.rst index ae4b80d..00b16fb 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl1.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl1.rst @@ -6,7 +6,7 @@ Written by `Chris Lattner `_ and `Max Shawabkeh `_ Introduction -============ +========= Welcome to the "Implementing a language with LLVM" tutorial. This tutorial runs through the implementation of a simple language, showing diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl5.rst b/docs/source/doc/kaleidoscope/PythonLangImpl5.rst index 33edba2..5a096da 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl5.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl5.rst @@ -217,8 +217,7 @@ Kaleidoscope looks something like this: br i1 %ifcond, label %then, label %else then: ; preds = %entry - %calltmp = call double @foo() - br label %ifcont + %calltmp1 = call double @bar() else: ; preds = %entry %calltmp1 = call double @bar() diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl7.rst b/docs/source/doc/kaleidoscope/PythonLangImpl7.rst index dee1c31..629608c 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl7.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl7.rst @@ -121,8 +121,8 @@ to talk about how LLVM represents stack variables. In LLVM, all memory accesses are explicit with load/store instructions, and it is carefully designed not to have (or need) an "address-of" operator. Notice how the type of the @G/@H global variables is actually -"i32\*" even though the variable is defined as "i32". What this means -is that @G defines *space* for an i32 in the global data area, but its +"i32\ *" even though the variable is defined as "i32". What this means +is that @G defines* space* for an i32 in the global data area, but its *name* actually refers to the address for that space. Stack variables work the same way, except that instead of being declared with global variable definitions, they are declared with the `LLVM alloca @@ -133,11 +133,11 @@ instruction `_: define i32 @example() { entry: - %X = alloca i32 ; type of %X is i32* + %X = alloca i32 ; type of %X is i32 *. ... - %tmp = load i32* %X ; load the stack value %X from the stack - %tmp2 = add i32 %tmp, 1 ; increment it - store i32 %tmp2, i32* %X ; store it back + %tmp = load i32* %X ; load the stack value %X from the stack. + %tmp2 = add i32 %tmp, 1 ; increment it store i32 %tmp2, + i32* %X ; store it back ... @@ -295,7 +295,7 @@ variables is a useful thing regardless of whether you will be mutating them. Here's a motivating example that shows how we could use these: -.. code-block:: none +.. code-block:: # Define ':' for sequencing: as a low-precedence operator that ignores operands # and just returns the RHS. @@ -352,7 +352,7 @@ function that ensures that the allocas are created in the entry block of the function: -.. code-block:: python +.. code-block:: # Creates an alloca instruction in the entry block of the function. This is used # for mutable variables. @@ -475,7 +475,7 @@ It is interesting to see what the code looks like before and after the mem2reg optimization runs. For example, this is the before/after code for our recursive fib function. Before the optimization: -.. code-block:: llvm +.. code-block:: define double @fib(double %x) { entry: @@ -515,7 +515,7 @@ still just make the PHI. Here is the code after the mem2reg pass runs: -.. code-block:: llvm +.. code-block:: define double @fib(double %x) { entry: @@ -651,7 +651,7 @@ Now that we have an assignment operator, we can mutate loop variables and arguments. For example, we can now run code like this: -.. code-block:: none +.. code-block:: # Function to print a double. extern printd(x) diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl8.rst b/docs/source/doc/kaleidoscope/PythonLangImpl8.rst index eb13dd0..dd4abc1 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl8.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl8.rst @@ -1,6 +1,6 @@ -*************************************************** +************************************************* Chapter 8: Conclusion and other useful LLVM tidbits -*************************************************** +************************************************* Written by Chris Lattner @@ -106,7 +106,7 @@ generating LLVM IR. These are some of the more subtle things that may not be obv but are very useful if you want to take advantage of LLVM's capabilities. Properties of the LLVM IR -========================= +======================== We have a couple common questions about code in the LLVM IR form - let's just get these out of the way right now, shall we? @@ -164,7 +164,7 @@ This can make sense for specialized domains such as an in-kernel language. -------------- Safety Guarantees ------------------ +---------------- Many of the languages above are also "safe" languages: it is impossible for a program written in Java to corrupt its address space and @@ -236,7 +236,7 @@ you desire in your front-end, on the language-specific AST. -------------- Tips and Tricks -=============== +============== There is a variety of useful tips and tricks that you come to know after working on/with LLVM that aren't obvious at first glance. diff --git a/docs/source/doc/llvm.core.Argument.rst b/docs/source/doc/llvm.core.Argument.rst index a2ffbfa..2481665 100644 --- a/docs/source/doc/llvm.core.Argument.rst +++ b/docs/source/doc/llvm.core.Argument.rst @@ -56,10 +56,3 @@ Add an attribute ``attr`` to the argument, from the set listed above. ~~~~~~~~~~~~~~~~~~~~~~~~~~ Remove the attribute ``attr`` of the argument. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Argument - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.ArrayType.rst b/docs/source/doc/llvm.core.ArrayType.rst index 3a4e645..f8b5e0c 100644 --- a/docs/source/doc/llvm.core.ArrayType.rst +++ b/docs/source/doc/llvm.core.ArrayType.rst @@ -28,10 +28,3 @@ A ``Type`` object representing the type of the element of the array. [read-only] The number of elements in the array. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.ArrayType - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.BasicBlock.rst b/docs/source/doc/llvm.core.BasicBlock.rst index eb10be3..74806a6 100644 --- a/docs/source/doc/llvm.core.BasicBlock.rst +++ b/docs/source/doc/llvm.core.BasicBlock.rst @@ -42,10 +42,3 @@ The parent function of this basicblock. ~~~~~~~~~~~~~~~~ A list of instructions in this basicblock. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.BasicBlock - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.Builder.rst b/docs/source/doc/llvm.core.Builder.rst index 24b9361..1e90908 100644 --- a/docs/source/doc/llvm.core.Builder.rst +++ b/docs/source/doc/llvm.core.Builder.rst @@ -409,10 +409,3 @@ positioned. ~~~~~~~~~ Deprecated. Same as ``basic_block`` - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Builder - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.Constant.rst b/docs/source/doc/llvm.core.Constant.rst index 3822046..4f2ed08 100644 --- a/docs/source/doc/llvm.core.Constant.rst +++ b/docs/source/doc/llvm.core.Constant.rst @@ -4,9 +4,6 @@ | title: Constant (llvm.core) | +-------------------------------+ -llvm.core.Constant -================== - ``Constant``-s represents constants that appear within the code. The values of such objects are known at creation time. Constants can be created from Python constants. A constant expression is also a constant @@ -26,338 +23,331 @@ some examples: tr = Type.float() - r1 = Constant.real(tr, "3.141592") # create from a string - r2 = Constant.real(tr, 1.61803399) # create from a Python float - - -# llvm.core.Constant -- This will become a table of contents (this text will be scraped). -{:toc} - - -Static factory methods ----------------------- - -``null(ty)`` -~~~~~~~~~~~~ - -A null value (all zeros) of type ``ty`` - -``all_ones(ty)`` -~~~~~~~~~~~~~~~~ - -All 1's value of type ``ty`` - -``undef(ty)`` -~~~~~~~~~~~~~ - -An undefined value of type ``ty`` - -``int(ty, value)`` -~~~~~~~~~~~~~~~~~~ - -Integer of type ``ty``, with value ``value`` (a Python int or long) - -``int_signextend(ty, value)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Integer of signed type ``ty`` (use for signed types) - -``real(ty, value)`` -~~~~~~~~~~~~~~~~~~~ - -Floating point value of type ``ty``, with value ``value`` (a Python -float) - -``stringz(value)`` -~~~~~~~~~~~~~~~~~~ - -A null-terminated string. ``value`` is a Python string - -``string(value)`` -~~~~~~~~~~~~~~~~~ - -As ``string(ty)``, but not null terminated - -``array(ty, consts)`` -~~~~~~~~~~~~~~~~~~~~~ - -Array of type ``ty``, initialized with ``consts`` (an iterable yielding -``Constant`` objects of the appropriate type) - -``struct(ty, consts)`` -~~~~~~~~~~~~~~~~~~~~~~ - -Struct (unpacked) of type ``ty``, initialized with ``consts`` (an -iterable yielding ``Constant`` objects of the appropriate type) - -``packed_struct(ty, consts)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -As ``struct(ty, consts)`` but packed - -``vector(consts)`` -~~~~~~~~~~~~~~~~~~ - -Vector, initialized with ``consts`` (an iterable yielding ``Constant`` -objects of the appropriate type) - -``sizeof(ty)`` -~~~~~~~~~~~~~~ - -Constant value representing the sizeof the type ``ty`` - -Methods -------- - -The following operations on constants are supported. For more details on -any operation, consult the `Constant -Expressions `_ -section of the LLVM Language Reference. - -``k.neg()`` -~~~~~~~~~~~ - -negation, same as ``0 - k`` - -``k.not_()`` -~~~~~~~~~~~~ - -1's complement of ``k``. Note trailing underscore. - -``k.add(k2)`` -~~~~~~~~~~~~~ - -``k + k2``, where ``k`` and ``k2`` are integers. - -``k.fadd(k2)`` -~~~~~~~~~~~~~~ - -``k + k2``, where ``k`` and ``k2`` are floating-point. - -``k.sub(k2)`` -~~~~~~~~~~~~~ - -``k - k2``, where ``k`` and ``k2`` are integers. - -``k.fsub(k2)`` -~~~~~~~~~~~~~~ - -``k - k2``, where ``k`` and ``k2`` are floating-point. - -``k.mul(k2)`` -~~~~~~~~~~~~~ - -``k * k2``, where ``k`` and ``k2`` are integers. - -``k.fmul(k2)`` -~~~~~~~~~~~~~~ - -``k * k2``, where ``k`` and ``k2`` are floating-point. - -``k.udiv(k2)`` -~~~~~~~~~~~~~~ - -Quotient of unsigned division of ``k`` with ``k2`` - -``k.sdiv(k2)`` -~~~~~~~~~~~~~~ - -Quotient of signed division of ``k`` with ``k2`` - -``k.fdiv(k2)`` -~~~~~~~~~~~~~~ - -Quotient of floating point division of ``k`` with ``k2`` - -``k.urem(k2)`` -~~~~~~~~~~~~~~ - -Reminder of unsigned division of ``k`` with ``k2`` - -``k.srem(k2)`` -~~~~~~~~~~~~~~ - -Reminder of signed division of ``k`` with ``k2`` - -``k.frem(k2)`` -~~~~~~~~~~~~~~ - -Reminder of floating point division of ``k`` with ``k2`` - -``k.and_(k2)`` -~~~~~~~~~~~~~~ - -Bitwise and of ``k`` and ``k2``. Note trailing underscore. - -``k.or_(k2)`` -~~~~~~~~~~~~~ - -Bitwise or of ``k`` and ``k2``. Note trailing underscore. - -``k.xor(k2)`` -~~~~~~~~~~~~~ - -Bitwise exclusive-or of ``k`` and ``k2``. - -``k.icmp(icmp, k2)`` -~~~~~~~~~~~~~~~~~~~~ - -Compare ``k`` with ``k2`` using the predicate ``icmp``. See -`here `_ for list of predicates for integer -operands. - -``k.fcmp(fcmp, k2)`` -~~~~~~~~~~~~~~~~~~~~ - -Compare ``k`` with ``k2`` using the predicate ``fcmp``. See -`here `_ for list of predicates for real -operands. - -``k.shl(k2)`` -~~~~~~~~~~~~~ - -Shift ``k`` left by ``k2`` bits. - -``k.lshr(k2)`` -~~~~~~~~~~~~~~ - -Shift ``k`` logically right by ``k2`` bits (new bits are 0s). - -``k.ashr(k2)`` -~~~~~~~~~~~~~~ - -Shift ``k`` arithmetically right by ``k2`` bits (new bits are same as -previous sign bit). - -``k.gep(indices)`` -~~~~~~~~~~~~~~~~~~ - -GEP, see `LLVM docs `_. - -``k.trunc(ty)`` -~~~~~~~~~~~~~~~ - -Truncate ``k`` to a type ``ty`` of lower bitwidth. - -``k.sext(ty)`` -~~~~~~~~~~~~~~ - -Sign extend ``k`` to a type ``ty`` of higher bitwidth, while extending -the sign bit. - -``k.zext(ty)`` -~~~~~~~~~~~~~~ - -Sign extend ``k`` to a type ``ty`` of higher bitwidth, all new bits are -0s. - -``k.fptrunc(ty)`` -~~~~~~~~~~~~~~~~~ - -Truncate floating point constant ``k`` to floating point type ``ty`` of -lower size than k's. - -``k.fpext(ty)`` -~~~~~~~~~~~~~~~ - -Extend floating point constant ``k`` to floating point type ``ty`` of -higher size than k's. - -``k.uitofp(ty)`` -~~~~~~~~~~~~~~~~ - -Convert an unsigned integer constant ``k`` to floating point constant of -type ``ty``. - -``k.sitofp(ty)`` -~~~~~~~~~~~~~~~~ - -Convert a signed integer constant ``k`` to floating point constant of -type ``ty``. - -``k.fptoui(ty)`` -~~~~~~~~~~~~~~~~ - -Convert a floating point constant ``k`` to an unsigned integer constant -of type ``ty``. - -``k.fptosi(ty)`` -~~~~~~~~~~~~~~~~ - -Convert a floating point constant ``k`` to a signed integer constant of -type ``ty``. - -``k.ptrtoint(ty)`` -~~~~~~~~~~~~~~~~~~ - -Convert a pointer constant ``k`` to an integer constant of type ``ty``. - -``k.inttoptr(ty)`` -~~~~~~~~~~~~~~~~~~ - -Convert an integer constant ``k`` to a pointer constant of type ``ty``. - -``k.bitcast(ty)`` -~~~~~~~~~~~~~~~~~ - -Convert ``k`` to a (equal-width) constant of type ``ty``. - -``k.select(cond,k2,k3)`` -~~~~~~~~~~~~~~~~~~~~~~~~ - -Replace value with ``k2`` if the 1-bit integer constant ``cond`` is 1, -else with ``k3``. - -``k.extract_element(idx)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Extract value at ``idx`` (integer constant) from a vector constant -``k``. - -``k.insert_element(k2,idx)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Insert value ``k2`` (scalar constant) at index ``idx`` (integer -constant) of vector constant ``k``. - -``k.shuffle_vector(k2,mask)`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Shuffle vector constant ``k`` based on vector constants ``k2`` and -``mask``. - --------------- - -# Other Constant Classes -The following subclasses of ``Constant`` do not provide additional -methods, **they serve only to provide richer type information.** - -Subclass \| LLVM C++ Class \| Remarks \| ----------\|----------------\|---------\| ``ConstantExpr`` \| -``llvmConstantExpr`` \| A constant expression \| -``ConstantAggregateZero``\ \| ``llvmConstantAggregateZero``\ \| All-zero -constant \| ``ConstantInt``\ \| ``llvmConstantInt``\ \| An integer -constant \| ``ConstantFP``\ \| ``llvmConstantFP``\ \| A floating-point -constant \| ``ConstantArray``\ \| ``llvmConstantArray``\ \| An array -constant \| ``ConstantStruct``\ \| ``llvmConstantStruct``\ \| A -structure constant \| ``ConstantVector``\ \| ``llvmConstantVector``\ \| -A vector constant \| ``ConstantPointerNull``\ \| -``llvmConstantPointerNull``\ \| All-zero pointer constant \| -``UndefValue``\ \| ``llvmUndefValue``\ \| corresponds to ``undef`` of -LLVM IR \| - -These types are helpful in ``isinstance`` checks, like so: - -{% highlight python %} ti = Type.int(32) k1 = Constant.int(ti, 42) # -int32_t k1 = 42; k2 = Constant.array(ti, [k1, k1]) # int32_t k2[] = { -k1, k1 }; - -assert isinstance(k1, ConstantInt) assert isinstance(k2, ConstantArray) - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Constant - :members: - :undoc-members: + r1 = Constant.real(tr, "3.141592") # create from a string r2 = + Constant.real(tr, 1.61803399) # create from a Python float {% + endhighlight %} + + # llvm.core.Constant + - This will become a table of contents (this text will be scraped). + {:toc} + + Static factory methods + ---------------------- + + ``null(ty)`` + ~~~~~~~~~~~~ + + A null value (all zeros) of type ``ty`` + + ``all_ones(ty)`` + ~~~~~~~~~~~~~~~~ + + All 1's value of type ``ty`` + + ``undef(ty)`` + ~~~~~~~~~~~~~ + + An undefined value of type ``ty`` + + ``int(ty, value)`` + ~~~~~~~~~~~~~~~~~~ + + Integer of type ``ty``, with value ``value`` (a Python int or long) + + ``int_signextend(ty, value)`` + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Integer of signed type ``ty`` (use for signed types) + + ``real(ty, value)`` + ~~~~~~~~~~~~~~~~~~~ + + Floating point value of type ``ty``, with value ``value`` (a Python + float) + + ``stringz(value)`` + ~~~~~~~~~~~~~~~~~~ + + A null-terminated string. ``value`` is a Python string + + ``string(value)`` + ~~~~~~~~~~~~~~~~~ + + As ``string(ty)``, but not null terminated + + ``array(ty, consts)`` + ~~~~~~~~~~~~~~~~~~~~~ + + Array of type ``ty``, initialized with ``consts`` (an iterable yielding + ``Constant`` objects of the appropriate type) + + ``struct(ty, consts)`` + ~~~~~~~~~~~~~~~~~~~~~~ + + Struct (unpacked) of type ``ty``, initialized with ``consts`` (an + iterable yielding ``Constant`` objects of the appropriate type) + + ``packed_struct(ty, consts)`` + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + As ``struct(ty, consts)`` but packed + + ``vector(consts)`` + ~~~~~~~~~~~~~~~~~~ + + Vector, initialized with ``consts`` (an iterable yielding ``Constant`` + objects of the appropriate type) + + ``sizeof(ty)`` + ~~~~~~~~~~~~~~ + + Constant value representing the sizeof the type ``ty`` + + Methods + ------- + + The following operations on constants are supported. For more details on + any operation, consult the `Constant + Expressions `_ + section of the LLVM Language Reference. + + ``k.neg()`` + ~~~~~~~~~~~ + + negation, same as ``0 - k`` + + ``k.not_()`` + ~~~~~~~~~~~~ + + 1's complement of ``k``. Note trailing underscore. + + ``k.add(k2)`` + ~~~~~~~~~~~~~ + + ``k + k2``, where ``k`` and ``k2`` are integers. + + ``k.fadd(k2)`` + ~~~~~~~~~~~~~~ + + ``k + k2``, where ``k`` and ``k2`` are floating-point. + + ``k.sub(k2)`` + ~~~~~~~~~~~~~ + + ``k - k2``, where ``k`` and ``k2`` are integers. + + ``k.fsub(k2)`` + ~~~~~~~~~~~~~~ + + ``k - k2``, where ``k`` and ``k2`` are floating-point. + + ``k.mul(k2)`` + ~~~~~~~~~~~~~ + + ``k * k2``, where ``k`` and ``k2`` are integers. + + ``k.fmul(k2)`` + ~~~~~~~~~~~~~~ + + ``k * k2``, where ``k`` and ``k2`` are floating-point. + + ``k.udiv(k2)`` + ~~~~~~~~~~~~~~ + + Quotient of unsigned division of ``k`` with ``k2`` + + ``k.sdiv(k2)`` + ~~~~~~~~~~~~~~ + + Quotient of signed division of ``k`` with ``k2`` + + ``k.fdiv(k2)`` + ~~~~~~~~~~~~~~ + + Quotient of floating point division of ``k`` with ``k2`` + + ``k.urem(k2)`` + ~~~~~~~~~~~~~~ + + Reminder of unsigned division of ``k`` with ``k2`` + + ``k.srem(k2)`` + ~~~~~~~~~~~~~~ + + Reminder of signed division of ``k`` with ``k2`` + + ``k.frem(k2)`` + ~~~~~~~~~~~~~~ + + Reminder of floating point division of ``k`` with ``k2`` + + ``k.and_(k2)`` + ~~~~~~~~~~~~~~ + + Bitwise and of ``k`` and ``k2``. Note trailing underscore. + + ``k.or_(k2)`` + ~~~~~~~~~~~~~ + + Bitwise or of ``k`` and ``k2``. Note trailing underscore. + + ``k.xor(k2)`` + ~~~~~~~~~~~~~ + + Bitwise exclusive-or of ``k`` and ``k2``. + + ``k.icmp(icmp, k2)`` + ~~~~~~~~~~~~~~~~~~~~ + + Compare ``k`` with ``k2`` using the predicate ``icmp``. See + `here `_ for list of predicates for integer + operands. + + ``k.fcmp(fcmp, k2)`` + ~~~~~~~~~~~~~~~~~~~~ + + Compare ``k`` with ``k2`` using the predicate ``fcmp``. See + `here `_ for list of predicates for real + operands. + + ``k.shl(k2)`` + ~~~~~~~~~~~~~ + + Shift ``k`` left by ``k2`` bits. + + ``k.lshr(k2)`` + ~~~~~~~~~~~~~~ + + Shift ``k`` logically right by ``k2`` bits (new bits are 0s). + + ``k.ashr(k2)`` + ~~~~~~~~~~~~~~ + + Shift ``k`` arithmetically right by ``k2`` bits (new bits are same as + previous sign bit). + + ``k.gep(indices)`` + ~~~~~~~~~~~~~~~~~~ + + GEP, see `LLVM docs `_. + + ``k.trunc(ty)`` + ~~~~~~~~~~~~~~~ + + Truncate ``k`` to a type ``ty`` of lower bitwidth. + + ``k.sext(ty)`` + ~~~~~~~~~~~~~~ + + Sign extend ``k`` to a type ``ty`` of higher bitwidth, while extending + the sign bit. + + ``k.zext(ty)`` + ~~~~~~~~~~~~~~ + + Sign extend ``k`` to a type ``ty`` of higher bitwidth, all new bits are + 0s. + + ``k.fptrunc(ty)`` + ~~~~~~~~~~~~~~~~~ + + Truncate floating point constant ``k`` to floating point type ``ty`` of + lower size than k's. + + ``k.fpext(ty)`` + ~~~~~~~~~~~~~~~ + + Extend floating point constant ``k`` to floating point type ``ty`` of + higher size than k's. + + ``k.uitofp(ty)`` + ~~~~~~~~~~~~~~~~ + + Convert an unsigned integer constant ``k`` to floating point constant of + type ``ty``. + + ``k.sitofp(ty)`` + ~~~~~~~~~~~~~~~~ + + Convert a signed integer constant ``k`` to floating point constant of + type ``ty``. + + ``k.fptoui(ty)`` + ~~~~~~~~~~~~~~~~ + + Convert a floating point constant ``k`` to an unsigned integer constant + of type ``ty``. + + ``k.fptosi(ty)`` + ~~~~~~~~~~~~~~~~ + + Convert a floating point constant ``k`` to a signed integer constant of + type ``ty``. + + ``k.ptrtoint(ty)`` + ~~~~~~~~~~~~~~~~~~ + + Convert a pointer constant ``k`` to an integer constant of type ``ty``. + + ``k.inttoptr(ty)`` + ~~~~~~~~~~~~~~~~~~ + + Convert an integer constant ``k`` to a pointer constant of type ``ty``. + + ``k.bitcast(ty)`` + ~~~~~~~~~~~~~~~~~ + + Convert ``k`` to a (equal-width) constant of type ``ty``. + + ``k.select(cond,k2,k3)`` + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Replace value with ``k2`` if the 1-bit integer constant ``cond`` is 1, + else with ``k3``. + + ``k.extract_element(idx)`` + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Extract value at ``idx`` (integer constant) from a vector constant + ``k``. + + ``k.insert_element(k2,idx)`` + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Insert value ``k2`` (scalar constant) at index ``idx`` (integer + constant) of vector constant ``k``. + + ``k.shuffle_vector(k2,mask)`` + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Shuffle vector constant ``k`` based on vector constants ``k2`` and + ``mask``. + + -------------- + + # Other Constant Classes + The following subclasses of ``Constant`` do not provide additional + methods, **they serve only to provide richer type information.** + + Subclass \| LLVM C++ Class \| Remarks \| + ---------\|----------------\|---------\| ``ConstantExpr`` \| + ``llvmConstantExpr`` \| A constant expression \| + ``ConstantAggregateZero``\ \| ``llvmConstantAggregateZero``\ \| All-zero + constant \| ``ConstantInt``\ \| ``llvmConstantInt``\ \| An integer + constant \| ``ConstantFP``\ \| ``llvmConstantFP``\ \| A floating-point + constant \| ``ConstantArray``\ \| ``llvmConstantArray``\ \| An array + constant \| ``ConstantStruct``\ \| ``llvmConstantStruct``\ \| A + structure constant \| ``ConstantVector``\ \| ``llvmConstantVector``\ \| + A vector constant \| ``ConstantPointerNull``\ \| + ``llvmConstantPointerNull``\ \| All-zero pointer constant \| + ``UndefValue``\ \| ``llvmUndefValue``\ \| corresponds to ``undef`` of + LLVM IR \| + + These types are helpful in ``isinstance`` checks, like so: + + {% highlight python %} ti = Type.int(32) k1 = Constant.int(ti, 42) # + int32_t k1 = 42; k2 = Constant.array(ti, [k1, k1]) # int32_t k2[] = { + k1, k1 }; + + assert isinstance(k1, ConstantInt) assert isinstance(k2, ConstantArray) + diff --git a/docs/source/doc/llvm.core.Function.rst b/docs/source/doc/llvm.core.Function.rst index cda101e..1d6070c 100644 --- a/docs/source/doc/llvm.core.Function.rst +++ b/docs/source/doc/llvm.core.Function.rst @@ -149,10 +149,3 @@ function bodies. Verifies the function. See `LLVM docs `_. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Function - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.FunctionType.rst b/docs/source/doc/llvm.core.FunctionType.rst index 7b728a8..8d40009 100644 --- a/docs/source/doc/llvm.core.FunctionType.rst +++ b/docs/source/doc/llvm.core.FunctionType.rst @@ -46,10 +46,3 @@ the function. Used like this: Type.int(), Type.int() ] ) for arg in func_type.args: assert arg.kind == TYPE_INTEGER assert arg == Type.int() assert func_type.arg_count == len(func_type.args) - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.FunctionType - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.GlobalValue.rst b/docs/source/doc/llvm.core.GlobalValue.rst index a5c2383..70dee7b 100644 --- a/docs/source/doc/llvm.core.GlobalValue.rst +++ b/docs/source/doc/llvm.core.GlobalValue.rst @@ -95,9 +95,3 @@ A power-of-2 integer indicating the boundary to align to. The module object to which this global belongs to. - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.GlobalValue - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.GlobalVariable.rst b/docs/source/doc/llvm.core.GlobalVariable.rst index 1ba69d8..392a6a0 100644 --- a/docs/source/doc/llvm.core.GlobalVariable.rst +++ b/docs/source/doc/llvm.core.GlobalVariable.rst @@ -4,9 +4,6 @@ | title: GlobalVariable (llvm.core) | +-------------------------------------+ -llvm.core.GlobalVariable -======================== - Global variables (``llvm.core.GlobalVariable``) are subclasses of `llvm.core.GlobalValue `_ and represent module-level variables. These can have optional initializers and can be @@ -40,10 +37,3 @@ class, or by using the static method ``GlobalVariable.new``. # list all global variables in a module for gv in module_obj.global_variables: print gv.name, "of type", gv.type - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.GlobalVariable - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.Instruction.rst b/docs/source/doc/llvm.core.Instruction.rst index 67c43f0..95aeb81 100644 --- a/docs/source/doc/llvm.core.Instruction.rst +++ b/docs/source/doc/llvm.core.Instruction.rst @@ -240,10 +240,3 @@ Properties The predicate of the compare instruction, one of the ``ICMP_*`` or ``FCMP_*`` constants. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Instruction - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.IntegerType.rst b/docs/source/doc/llvm.core.IntegerType.rst index 6f1e2b1..f62907c 100644 --- a/docs/source/doc/llvm.core.IntegerType.rst +++ b/docs/source/doc/llvm.core.IntegerType.rst @@ -21,10 +21,3 @@ Properties [read-only] The width of the integer type, in number of bits. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.IntegerType - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.Module.rst b/docs/source/doc/llvm.core.Module.rst index 75cc174..3dbd5c8 100644 --- a/docs/source/doc/llvm.core.Module.rst +++ b/docs/source/doc/llvm.core.Module.rst @@ -4,26 +4,16 @@ | title: Module (llvm.core) | +-----------------------------+ -llvm.core.Module -================ - Modules are top-level container objects. You need to create a module object first, before you can add global variables, aliases or functions. Modules are created using the static method ``Module.new``: + .. code-block:: python #!/usr/bin/env python - from llvm import * - from llvm.core import * + from llvm import \* from llvm.core import \* # create a module my_module = Module.new('my_module') - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Module - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.PointerType.rst b/docs/source/doc/llvm.core.PointerType.rst index cc65139..a869fba 100644 --- a/docs/source/doc/llvm.core.PointerType.rst +++ b/docs/source/doc/llvm.core.PointerType.rst @@ -29,10 +29,3 @@ The address space of the pointer. A `Type `_ object representing the type of the value pointed to. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.PointerType - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.StructType.rst b/docs/source/doc/llvm.core.StructType.rst index f3b0786..e69de29 100644 --- a/docs/source/doc/llvm.core.StructType.rst +++ b/docs/source/doc/llvm.core.StructType.rst @@ -1,8 +0,0 @@ -llvm.core.StructType -==================== - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.StructType - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.Type.rst b/docs/source/doc/llvm.core.Type.rst index b1eb354..58883d7 100644 --- a/docs/source/doc/llvm.core.Type.rst +++ b/docs/source/doc/llvm.core.Type.rst @@ -126,10 +126,3 @@ Example: assert Type.int().kind == TYPE_INTEGER assert Type.void().kind == TYPE_VOID - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Type - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.User.rst b/docs/source/doc/llvm.core.User.rst index 12d40c5..0762729 100644 --- a/docs/source/doc/llvm.core.User.rst +++ b/docs/source/doc/llvm.core.User.rst @@ -37,10 +37,3 @@ The list of operands (values, of type The number of operands that this value referes to. Same as ``len(uses.operands)`` but faster if you just want the count. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.User - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.Value.rst b/docs/source/doc/llvm.core.Value.rst index 081d328..fdff4cc 100644 --- a/docs/source/doc/llvm.core.Value.rst +++ b/docs/source/doc/llvm.core.Value.rst @@ -63,10 +63,3 @@ representation. ``Value`` objects can be compared for equality. Internally, this converts both arguments into their LLVM assembly representations and compares the resultant strings. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.Value - :members: - :undoc-members: diff --git a/docs/source/doc/llvm.core.VectorType.rst b/docs/source/doc/llvm.core.VectorType.rst index a18f6ea..19b98e6 100644 --- a/docs/source/doc/llvm.core.VectorType.rst +++ b/docs/source/doc/llvm.core.VectorType.rst @@ -29,10 +29,3 @@ element of the vector. [read-only] The number of elements in the vector. - - -Automatically Generated Documentation -------------------------------------- -.. autoclass:: llvm.core.VectorType - :members: - :undoc-members: diff --git a/docs/source/doc/llvm_cbuilder.rst b/docs/source/doc/llvm_cbuilder.rst index c8623c2..990bfb0 100644 --- a/docs/source/doc/llvm_cbuilder.rst +++ b/docs/source/doc/llvm_cbuilder.rst @@ -1,5 +1,5 @@ llvm_cbuilder -============= +========= llvm_cbuilder is a set of Python-contexts you can use to write C-like constructs in Python which generates llvmpy code directly. diff --git a/docs/source/doc/llvm_concepts.rst b/docs/source/doc/llvm_concepts.rst index 8690e49..c642994 100644 --- a/docs/source/doc/llvm_concepts.rst +++ b/docs/source/doc/llvm_concepts.rst @@ -28,7 +28,6 @@ follow these steps: - add a *basic block* to the function - using a helper object called an *instruction builder*, add two instructions into the basic block: - - an instruction to add the two arguments and store the result into a temporary variable - a return diff --git a/docs/source/index.rst b/docs/source/index.rst index fbf5c8b..9f86b32 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -llvmpy -====== +Documentation for llvmpy +================= Contents: @@ -22,7 +22,7 @@ Contents: Indices and tables ------------------- +================== * :ref:`genindex` * :ref:`modindex` diff --git a/example/vector_instr.py b/example/vector_instr.py deleted file mode 100644 index e49d06a..0000000 --- a/example/vector_instr.py +++ /dev/null @@ -1,152 +0,0 @@ -''' -This example shows: -1) how to use vector instructions -2) how to take advantage of LLVM loop vectorization to transform scalar - operations to vector operations -''' - -from __future__ import print_function -import llvm.core as lc -import llvm.ee as le -import llvm.passes as lp -from ctypes import CFUNCTYPE, POINTER, c_int, c_float - -def build_manual_vector(): - mod = lc.Module.new('manual.vector') - intty = lc.Type.int(32) - vecty = lc.Type.vector(lc.Type.float(), 4) - aryty = lc.Type.pointer(lc.Type.float()) - fnty = lc.Type.function(lc.Type.void(), [aryty, aryty, aryty, intty]) - fn = mod.add_function(fnty, name='vector_add') - bbentry = fn.append_basic_block('entry') - bbloopcond = fn.append_basic_block('loop.cond') - bbloopbody = fn.append_basic_block('loop.body') - bbexit = fn.append_basic_block('exit') - builder = lc.Builder.new(bbentry) - - # populate function body - in1, in2, out, size = fn.args - ZERO = lc.Constant.null(intty) - loopi_ptr = builder.alloca(intty) - builder.store(ZERO, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbloopcond) - - loopi = builder.load(loopi_ptr) - loopcond = builder.icmp(lc.ICMP_ULT, loopi, size) - - builder.cbranch(loopcond, bbloopbody, bbexit) - builder.position_at_end(bbloopbody) - - vecaryty = lc.Type.pointer(vecty) - in1asvec = builder.bitcast(builder.gep(in1, [loopi]), vecaryty) - in2asvec = builder.bitcast(builder.gep(in2, [loopi]), vecaryty) - outasvec = builder.bitcast(builder.gep(out, [loopi]), vecaryty) - - vec1 = builder.load(in1asvec) - vec2 = builder.load(in2asvec) - - vecout = builder.fadd(vec1, vec2) - - builder.store(vecout, outasvec) - - next = builder.add(loopi, lc.Constant.int(intty, 4)) - builder.store(next, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbexit) - - builder.ret_void() - - return mod, fn - - -def build_auto_vector(): - mod = lc.Module.new('auto.vector') - # Loop vectorize is sensitive to the size of the index size(!?) - intty = lc.Type.int(tuple.__itemsize__ * 8) - aryty = lc.Type.pointer(lc.Type.float()) - fnty = lc.Type.function(lc.Type.void(), [aryty, aryty, aryty, intty]) - fn = mod.add_function(fnty, name='vector_add') - bbentry = fn.append_basic_block('entry') - bbloopcond = fn.append_basic_block('loop.cond') - bbloopbody = fn.append_basic_block('loop.body') - bbexit = fn.append_basic_block('exit') - builder = lc.Builder.new(bbentry) - - # populate function body - in1, in2, out, size = fn.args - in1.add_attribute(lc.ATTR_NO_ALIAS) - in2.add_attribute(lc.ATTR_NO_ALIAS) - out.add_attribute(lc.ATTR_NO_ALIAS) - ZERO = lc.Constant.null(intty) - loopi_ptr = builder.alloca(intty) - builder.store(ZERO, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbloopcond) - - loopi = builder.load(loopi_ptr) - loopcond = builder.icmp(lc.ICMP_ULT, loopi, size) - - builder.cbranch(loopcond, bbloopbody, bbexit) - builder.position_at_end(bbloopbody) - - in1elem = builder.load(builder.gep(in1, [loopi])) - in2elem = builder.load(builder.gep(in2, [loopi])) - - outelem = builder.fadd(in1elem, in2elem) - - builder.store(outelem, builder.gep(out, [loopi])) - - next = builder.add(loopi, lc.Constant.int(intty, 1)) - builder.store(next, loopi_ptr) - - builder.branch(bbloopcond) - builder.position_at_end(bbexit) - - builder.ret_void() - - return mod, fn - -def example(title, module_builder, opt): - print(title.center(80, '=')) - mod, fn = module_builder() - - eb = le.EngineBuilder.new(mod).opt(3) - if opt: - print('opt') - tm = eb.select_target() - pms = lp.build_pass_managers(mod=mod, tm=tm, opt=3, loop_vectorize=True, - fpm=False) - pms.pm.run(mod) - - print(mod) - print(mod.to_native_assembly()) - - engine = eb.create() - ptr = engine.get_pointer_to_function(fn) - - callable = CFUNCTYPE(None, POINTER(c_float), POINTER(c_float), - POINTER(c_float), c_int)(ptr) - - N = 20 - in1 = (c_float * N)(*range(N)) - in2 = (c_float * N)(*range(N)) - out = (c_float * N)() - - print('in1: ', list(in1)) - print('in1: ', list(in2)) - - callable(in1, in2, out, N) - - print('out', list(out)) - - -def main(): - example('manual vector function', build_manual_vector, False) - example('auto vector function', build_auto_vector, True) - -if __name__ == '__main__': - main() diff --git a/llpython/byte_control.py b/llpython/byte_control.py index 8ca407e..34ebae4 100644 --- a/llpython/byte_control.py +++ b/llpython/byte_control.py @@ -1,16 +1,17 @@ +#! /usr/bin/env python # ______________________________________________________________________ -from __future__ import absolute_import + import opcode -from . import opcode_util +import opcode_util import pprint -from .bytecode_visitor import BasicBlockVisitor, BenignBytecodeVisitorMixin -from .control_flow import ControlFlowGraph +from bytecode_visitor import BytecodeFlowVisitor, BenignBytecodeVisitorMixin +from control_flow import ControlFlowGraph # ______________________________________________________________________ -class ControlFlowBuilder (BenignBytecodeVisitorMixin, BasicBlockVisitor): - '''Visitor responsible for traversing a bytecode basic block map and +class ControlFlowBuilder (BenignBytecodeVisitorMixin, BytecodeFlowVisitor): + '''Visitor responsible for traversing a bytecode flow object and building a control flow graph (CFG). The primary purpose of this transformation is to create a CFG, @@ -26,26 +27,21 @@ class ControlFlowBuilder (BenignBytecodeVisitorMixin, BasicBlockVisitor): del self.nargs return ret_val - def enter_blocks (self, blocks): - super(ControlFlowBuilder, self).enter_blocks(blocks) - self.blocks = blocks - self.block_list = list(blocks.keys()) - self.block_list.sort() + def enter_flow_object (self, flow): + super(ControlFlowBuilder, self).enter_flow_object(flow) + self.flow = flow self.cfg = ControlFlowGraph() - self.loop_stack = [] - for block in self.block_list: - self.cfg.add_block(block, blocks[block]) + for block in flow.keys(): + self.cfg.add_block(block, flow[block]) - def exit_blocks (self, blocks): - super(ControlFlowBuilder, self).exit_blocks(blocks) - assert self.blocks == blocks + def exit_flow_object (self, flow): + super(ControlFlowBuilder, self).exit_flow_object(flow) + assert self.flow == flow self.cfg.compute_dataflow() self.cfg.update_for_ssa() ret_val = self.cfg - del self.loop_stack del self.cfg - del self.block_list - del self.blocks + del self.flow return ret_val def enter_block (self, block): @@ -62,15 +58,13 @@ class ControlFlowBuilder (BenignBytecodeVisitorMixin, BasicBlockVisitor): def exit_block (self, block): assert block == self.block del self.block - i, op, arg = self.blocks[block][-1] - opname = opcode.opname[op] + i, op, opname, arg, args = self.flow[block][-1] if op in opcode.hasjabs: self.cfg.add_edge(block, arg) elif op in opcode.hasjrel: self.cfg.add_edge(block, i + arg + 3) elif opname == 'BREAK_LOOP': - loop_i, _, loop_arg = self.loop_stack[-1] - self.cfg.add_edge(block, loop_i + loop_arg + 3) + self.cfg.add_edge(block, arg) elif opname != 'RETURN_VALUE': self.cfg.add_edge(block, self._get_next_block(block)) if op in opcode_util.hascbranch: @@ -86,24 +80,15 @@ class ControlFlowBuilder (BenignBytecodeVisitorMixin, BasicBlockVisitor): return super(ControlFlowBuilder, self).op_STORE_FAST(i, op, arg, *args, **kws) - def op_SETUP_LOOP (self, i, op, arg, *args, **kws): - self.loop_stack.append((i, op, arg)) - return super(ControlFlowBuilder, self).op_SETUP_LOOP(i, op, arg, *args, - **kws) - - def op_POP_BLOCK (self, i, op, arg, *args, **kws): - self.loop_stack.pop() - return super(ControlFlowBuilder, self).op_POP_BLOCK(i, op, arg, *args, - **kws) - # ______________________________________________________________________ def build_cfg (func): '''Given a Python function, create a bytecode flow, visit the flow object, and return a control flow graph.''' - co_obj = opcode_util.get_code_object(func) - return ControlFlowBuilder().visit(opcode_util.build_basic_blocks(co_obj), - co_obj.co_argcount) + import byte_flow + return ControlFlowBuilder().visit( + byte_flow.build_flow(func), + opcode_util.get_code_object(func).co_argcount) # ______________________________________________________________________ # Main (self-test) routine diff --git a/llpython/byte_flow.py b/llpython/byte_flow.py index 197c839..822e564 100644 --- a/llpython/byte_flow.py +++ b/llpython/byte_flow.py @@ -1,15 +1,16 @@ +#! /usr/bin/env python # ______________________________________________________________________ -from __future__ import absolute_import + import dis import opcode -from .bytecode_visitor import BasicBlockVisitor -from . import opcode_util +from bytecode_visitor import BytecodeIterVisitor +import opcode_util # ______________________________________________________________________ -class BytecodeFlowBuilder (BasicBlockVisitor): - '''Transforms a CFG into a bytecode "flow tree". +class BytecodeFlowBuilder (BytecodeIterVisitor): + '''Transforms a bytecode vector into a bytecode "flow tree". The flow tree is a Python dictionary, described loosely by the following set of productions: @@ -35,8 +36,6 @@ class BytecodeFlowBuilder (BasicBlockVisitor): if pops: if pops < 0: pops = arg - pops - 1 - assert pops <= len(self.stack), ("Stack underflow at instruction " - "%d (%s)!" % (i, opname)) stk_args = self.stack[-pops:] del self.stack[-pops:] else: @@ -52,50 +51,27 @@ class BytecodeFlowBuilder (BasicBlockVisitor): opname, pops, pushes, appends = self.opmap[op] return self._visit_op(i, op, arg, opname, pops, pushes, appends) - def visit_cfg (self, cfg): - self.cfg = cfg - ret_val = self.visit(cfg.blocks) - del self.cfg - return ret_val - - def enter_blocks (self, blocks): - labels = list(blocks.keys()) - labels.sort() + def enter_code_object (self, co_obj): + labels = dis.findlabels(co_obj.co_code) + labels = opcode_util.extendlabels(co_obj.co_code, labels) self.blocks = dict((index, []) for index in labels) + self.stack = [] self.loop_stack = [] - self.stacks = {} + self.blocks[0] = self.block = [] - def exit_blocks (self, blocks): + def exit_code_object (self, co_obj): ret_val = self.blocks - del self.stacks + del self.stack del self.loop_stack + del self.block del self.blocks return ret_val - def enter_block (self, block): - self.block_no = block - self.block = self.blocks[block] - in_blocks = self.cfg.blocks_in[block] - if len(in_blocks) == 0: - self.stack = [] - else: - pred_stack = None - for pred in in_blocks: - if pred in self.stacks: - pred_stack = self.stacks[pred] - break - if pred_stack is not None: - self.stack = pred_stack[:] - else: - raise NotImplementedError() - - def exit_block (self, block): - assert self.block_no == block - self.stacks[block] = self.stack - del self.stack - del self.block - del self.block_no + def visit_op (self, i, op, arg): + if i in self.blocks: + self.block = self.blocks[i] + return super(BytecodeFlowBuilder, self).visit_op(i, op, arg) op_BINARY_ADD = _op op_BINARY_AND = _op @@ -164,14 +140,8 @@ class BytecodeFlowBuilder (BasicBlockVisitor): op_INPLACE_XOR = _op op_JUMP_ABSOLUTE = _op op_JUMP_FORWARD = _op - - def op_JUMP_IF_FALSE (self, i, op, arg): - opname, _, _, _ = self.opmap[op] - ret_val = (i, op, opname, arg, [self.stack[-1]]) - self.block.append(ret_val) - return ret_val - - op_JUMP_IF_TRUE = op_JUMP_IF_FALSE + op_JUMP_IF_FALSE = _op + op_JUMP_IF_TRUE = _op op_LIST_APPEND = _op op_LOAD_ATTR = _op op_LOAD_CLOSURE = _op @@ -241,9 +211,7 @@ class BytecodeFlowBuilder (BasicBlockVisitor): def build_flow (func): '''Given a Python function, return a bytecode flow tree for that function.''' - import byte_control - cfg = byte_control.build_cfg(func) - return BytecodeFlowBuilder().visit_cfg(cfg) + return BytecodeFlowBuilder().visit(opcode_util.get_code_object(func)) # ______________________________________________________________________ # Main (self-test) routine diff --git a/llpython/byte_translator.py b/llpython/byte_translator.py index a6e5864..08b4560 100644 --- a/llpython/byte_translator.py +++ b/llpython/byte_translator.py @@ -1,21 +1,22 @@ +#! /usr/bin/env python # ______________________________________________________________________ '''Defines a bytecode based LLVM translator for llpython code. ''' # ______________________________________________________________________ # Module imports -from __future__ import absolute_import + import opcode import types import logging import llvm.core as lc -from . import opcode_util -from . import bytetype -from .bytecode_visitor import BytecodeFlowVisitor -from .byte_flow import BytecodeFlowBuilder -from .byte_control import ControlFlowBuilder -from .phi_injector import PhiInjector, synthetic_opname +import opcode_util +import bytetype +from bytecode_visitor import BytecodeFlowVisitor +from byte_flow import BytecodeFlowBuilder +from byte_control import ControlFlowBuilder +from phi_injector import PhiInjector, synthetic_opname # ______________________________________________________________________ # Module data @@ -152,7 +153,7 @@ class LLVMTranslator (BytecodeFlowVisitor): environment.''' if llvm_type is None: if llvm_function is None: - llvm_type = lc.Type.function(bytetype.lvoid, ()) + llvm_type = lc.Type.function(lvoid, ()) else: llvm_type = llvm_function.type.pointee if env is None: @@ -177,8 +178,7 @@ class LLVMTranslator (BytecodeFlowVisitor): self.globals = func_globals nargs = self.code_obj.co_argcount self.cfg = self.control_flow_builder.visit( - opcode_util.build_basic_blocks(self.code_obj), nargs) - self.cfg.blocks = self.bytecode_flow_builder.visit_cfg(self.cfg) + self.bytecode_flow_builder.visit(self.code_obj), nargs) self.llvm_function = llvm_function flow = self.phi_injector.visit_cfg(self.cfg, nargs) ret_val = self.visit(flow) @@ -224,12 +224,6 @@ class LLVMTranslator (BytecodeFlowVisitor): return ret_val def exit_block (self, block): - bb_instrs = self.llvm_block.instructions - if ((len(bb_instrs) == 0) or - (not bb_instrs[-1].is_terminator)): - out_blocks = list(self.cfg.blocks_out[block]) - assert len(out_blocks) == 1 - self.builder.branch(self.llvm_blocks[out_blocks[0]]) del self.llvm_block del self.builder @@ -455,11 +449,7 @@ class LLVMTranslator (BytecodeFlowVisitor): return [self.builder.branch(self.llvm_blocks[i + arg + 3])] def op_JUMP_IF_FALSE (self, i, op, arg, *args, **kws): - cond = args[0] - block_false = self.llvm_blocks[i + 3 + arg] - block_true = self.llvm_blocks[i + 3] - return [self.builder.cbranch(cond, block_true, block_false)] - # raise NotImplementedError("LLVMTranslator.op_JUMP_IF_FALSE") + raise NotImplementedError("LLVMTranslator.op_JUMP_IF_FALSE") def op_JUMP_IF_FALSE_OR_POP (self, i, op, arg, *args, **kws): raise NotImplementedError("LLVMTranslator.op_JUMP_IF_FALSE_OR_POP") diff --git a/llpython/bytecode_visitor.py b/llpython/bytecode_visitor.py index 3fa3f48..091e138 100644 --- a/llpython/bytecode_visitor.py +++ b/llpython/bytecode_visitor.py @@ -1,9 +1,10 @@ +#! /usr/bin/env python # ______________________________________________________________________ -from __future__ import absolute_import + import itertools import opcode -from .opcode_util import itercode +from opcode_util import itercode # ______________________________________________________________________ @@ -163,32 +164,6 @@ class BytecodeIterVisitor (BytecodeVisitor): # ______________________________________________________________________ -class BasicBlockVisitor (BytecodeVisitor): - def visit (self, blocks): - self.enter_blocks(blocks) - block_indices = list(blocks.keys()) - block_indices.sort() - for block_index in block_indices: - self.enter_block(block_index) - for i, op, arg in blocks[block_index]: - self.visit_op(i, op, arg) - self.exit_block(block_index) - return self.exit_blocks(blocks) - - def enter_blocks (self, blocks): - pass - - def exit_blocks (self, blocks): - pass - - def enter_block (self, block_index): - pass - - def exit_block (self, block_index): - pass - -# ______________________________________________________________________ - class BytecodeFlowVisitor (BytecodeVisitor): def visit (self, flow): self.block_list = list(flow.keys()) diff --git a/llpython/bytetype.py b/llpython/bytetype.py index 484d09e..211f3f8 100644 --- a/llpython/bytetype.py +++ b/llpython/bytetype.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import ctypes diff --git a/llpython/control_flow.py b/llpython/control_flow.py index 8026aba..5ea030a 100644 --- a/llpython/control_flow.py +++ b/llpython/control_flow.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import pprint diff --git a/llpython/gen_bytecode_visitor.py b/llpython/gen_bytecode_visitor.py index a60b345..7f922e2 100644 --- a/llpython/gen_bytecode_visitor.py +++ b/llpython/gen_bytecode_visitor.py @@ -1,6 +1,7 @@ +#! /usr/bin/env python # ______________________________________________________________________ -from __future__ import absolute_import -from . import opcode_util + +import opcode_util # ______________________________________________________________________ diff --git a/llpython/nobitey.py b/llpython/nobitey.py index 4236d29..b756fc8 100644 --- a/llpython/nobitey.py +++ b/llpython/nobitey.py @@ -1,5 +1,6 @@ +#! /usr/bin/env python # ______________________________________________________________________ -from __future__ import absolute_import + import sys import os.path import imp @@ -9,12 +10,13 @@ import types import llvm.core as lc import llvm.ee as le -from . import bytetype, byte_translator -from .pyaddfunc import pyaddfunc +import bytetype +import byte_translator +from pyaddfunc import pyaddfunc LLVM_TO_INT_PARSE_STR_MAP = { 8 : 'b', - 16 : 'h', + 16 : 'h', 32 : 'i', # Note that on 32-bit systems sizeof(int) == sizeof(long) 64 : 'L', # Seeing sizeof(long long) == 8 on both 32 and 64-bit platforms } diff --git a/llpython/opcode_util.py b/llpython/opcode_util.py index 7a1972b..5c0cff9 100644 --- a/llpython/opcode_util.py +++ b/llpython/opcode_util.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import dis @@ -78,9 +79,9 @@ OPCODE_MAP = { 'INPLACE_XOR': (2, 1, None), 'JUMP_ABSOLUTE': (0, None, 1), 'JUMP_FORWARD': (0, None, 1), - 'JUMP_IF_FALSE': (1, 1, 1), + 'JUMP_IF_FALSE': (1, None, 1), 'JUMP_IF_FALSE_OR_POP': (None, None, None), - 'JUMP_IF_TRUE': (1, 1, 1), + 'JUMP_IF_TRUE': (1, None, 1), 'JUMP_IF_TRUE_OR_POP': (None, None, None), 'LIST_APPEND': (2, 0, 1), 'LOAD_ATTR': (1, 1, None), @@ -147,7 +148,7 @@ OPCODE_MAP = { # ______________________________________________________________________ # Module functions -def itercode(code, start = 0): +def itercode(code): """Return a generator of byte-offset, opcode, and argument from a byte-code-string """ @@ -158,7 +159,7 @@ def itercode(code, start = 0): n = len(code) while i < n: op = code[i] - num = i + start + num = i i = i + 1 oparg = None if op >= opcode.HAVE_ARGUMENT: @@ -210,16 +211,5 @@ def extendlabels(code, labels = None): def get_code_object (func): return getattr(func, '__code__', getattr(func, 'func_code', None)) -# ______________________________________________________________________ - -def build_basic_blocks (co_obj): - co_code = co_obj.co_code - labels = extendlabels(co_code, dis.findlabels(co_code)) - labels.sort() - blocks = dict((index, list(itercode(co_code[index:next_index], index))) - for index, next_index in zip([0] + labels, - labels + [len(co_code)])) - return blocks - # ______________________________________________________________________ # End of opcode_util.py diff --git a/llpython/phi_injector.py b/llpython/phi_injector.py index dfa1061..2618e97 100644 --- a/llpython/phi_injector.py +++ b/llpython/phi_injector.py @@ -1,6 +1,7 @@ +#! /usr/bin/env python # ______________________________________________________________________ -from .bytecode_visitor import BytecodeFlowVisitor, BenignBytecodeVisitorMixin +from bytecode_visitor import BytecodeFlowVisitor, BenignBytecodeVisitorMixin # ______________________________________________________________________ @@ -126,10 +127,9 @@ class PhiInjector (BenignBytecodeVisitorMixin, BytecodeFlowVisitor): def inject_phis (func): '''Given a Python function, return a bytecode flow object that has been transformed by a fresh PhiInjector instance.''' - import byte_control, byte_flow + import byte_control argcount = byte_control.opcode_util.get_code_object(func).co_argcount cfg = byte_control.build_cfg(func) - cfg.blocks = byte_flow.BytecodeFlowBuilder().visit_cfg(cfg) return PhiInjector().visit_cfg(cfg, argcount) # ______________________________________________________________________ diff --git a/llpython/pyaddfunc.py b/llpython/pyaddfunc.py index d6a2945..8e09839 100644 --- a/llpython/pyaddfunc.py +++ b/llpython/pyaddfunc.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import ctypes diff --git a/llpython/tests/llfuncs.py b/llpython/tests/llfuncs.py index 8b5b1f3..2a8614f 100644 --- a/llpython/tests/llfuncs.py +++ b/llpython/tests/llfuncs.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ def doslice (in_string, lower, upper): diff --git a/llpython/tests/llfunctys.py b/llpython/tests/llfunctys.py index 8335044..b552cf4 100644 --- a/llpython/tests/llfunctys.py +++ b/llpython/tests/llfunctys.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import llvm.core as lc diff --git a/llrtc/Makefile b/llrtc/Makefile deleted file mode 100644 index b15eac5..0000000 --- a/llrtc/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -all: - make -C lib - -ir: - make -C lib ir - -test: - make -C lib test - -clean-test: - make -C lib clean-test - -clean-temp: - make -C lib clean-temp - -clean: - make -C lib clean - -install: ir - cp llrt_*.ll ../llvm/llrt - make -C lib clean-temp - \ No newline at end of file diff --git a/llrtc/README.md b/llrtc/README.md deleted file mode 100644 index 539d9c3..0000000 --- a/llrtc/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# LLRT: Low Level Runtime - -## Why? - -The same reason for LLVM compiler-rt. LLVM generates libgcc symbols, such as -__divdi3 for 64-bit division on 32-bit platform. They are not also available. -We need to ship compiler-rt but it is not Windows ready. -This subproject aims to provide a small portable subset of compiler-rt. -Start small and add only the things we really needed. -Performance is not crucial but should not be terrible. -Functionality and usefullness should be more important than performance. - -## Developer Instructions - -LLRT implements some functionalities in compiler-rt in ANSI C. -The C files are compiled using clang to produce LLVM IR which are shipped. -The IR files are committed in the repository. -So, remember to build the IR files commit them after modifying the C files. - -## Build Requirement - -- Make -- Clang -- Python - diff --git a/llrtc/lib/.gitignore b/llrtc/lib/.gitignore deleted file mode 100644 index fbcf76a..0000000 --- a/llrtc/lib/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.o -*.run -*.out -*.ll diff --git a/llrtc/lib/Makefile b/llrtc/lib/Makefile deleted file mode 100644 index 9dbfb27..0000000 --- a/llrtc/lib/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -OUTPUT = llrt -SOURCES = udivmod64.c sdivmod64.c div64.c mod64.c -TESTS = test_udivmod64.c test_sdivmod64.c - -CLANG = clang -LLVM_LINK = llvm-link -CF = -Wall -ansi -CF_TEST = $(CF) -ftrapv -CF_BUILD = $(CF) -O0 -emit-llvm -OUTDIR = .. -STRIPPER = ../tools/striptriple.py - -all: ir - -ir: $(OUTDIR)/$(OUTPUT)_x86.ll $(OUTDIR)/$(OUTPUT)_x86_64.ll - -$(OUTDIR)/$(OUTPUT)_x86.ll: $(SOURCES:.c=_x86.bc) - $(LLVM_LINK) -S $+ -o $@ - python $(STRIPPER) $@ - -$(OUTDIR)/$(OUTPUT)_x86_64.ll: $(SOURCES:.c=_x86_64.bc) - $(LLVM_LINK) -S $+ -o $@ - python $(STRIPPER) $@ - -build-test: $(SOURCES:.c=.o) $(TESTS:.c=.run) - -lib$(OUTPUT).a: $(SOURCES:.c=.o) - $(CLANG) -static $+ -o $@ - -test: $(TESTS:.c=.run) - for src in $+; do \ - echo "testing $${src}"; \ - python $${src%.*}.py > $${src%.*}.out; \ - done; - -clean-test: - rm -f *.out - rm -f *.o - rm -f *.run - -clean-dist: clean-temp - rm -f *.ll - -clean-temp: - rm -f *.bc - rm -f *.o - rm -f *.out - -clean: clean-test clean-dist - -%.c: llrt.h - -%_x86.bc: %.c - $(CLANG) -m32 $(CF_BUILD) -c $< -o $@ - -%_x86_64.bc: %.c - $(CLANG) -m64 $(CF_BUILD) -c $< -o $@ - -%.o: %.c - $(CLANG) $(CF_TEST) -c $< - -%.run: %.c - $(CLANG) $(CF_TEST) -o $@ $+ - -test_udivmod64.run: udivmod64.o -test_sdivmod64.run: udivmod64.o sdivmod64.o diff --git a/llrtc/lib/div64.c b/llrtc/lib/div64.c deleted file mode 100644 index 8466965..0000000 --- a/llrtc/lib/div64.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "llrt.h" - -uint64_t udiv64(uint64_t dividend, uint64_t divisor) -{ - return udivmod64(dividend, divisor, NULL); -} - -int64_t sdiv64(int64_t dividend, int64_t divisor) -{ - return sdivmod64(dividend, divisor, NULL); -} diff --git a/llrtc/lib/llrt.h b/llrtc/lib/llrt.h deleted file mode 100644 index 4e9e348..0000000 --- a/llrtc/lib/llrt.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LLRT_H_ -#define LLRT_H_ - -#include - -#define NULL 0 -#define BITS_PER_BYTE 8 - -uint64_t udivmod64(uint64_t dividend, uint64_t divisor, uint64_t *remainder); -int64_t sdivmod64(int64_t dividend, int64_t divisor, int64_t *remainder); - -uint64_t udiv64(uint64_t dividend, uint64_t divisor); -int64_t sdiv64(int64_t dividend, int64_t divisor); - -uint64_t umod64(uint64_t dividend, uint64_t divisor); -int64_t smod64(int64_t dividend, int64_t divisor); - -#endif /* LLRT_H_ */ - diff --git a/llrtc/lib/mod64.c b/llrtc/lib/mod64.c deleted file mode 100644 index 875f6b9..0000000 --- a/llrtc/lib/mod64.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "llrt.h" - -uint64_t umod64(uint64_t dividend, uint64_t divisor) -{ - uint64_t rem; - udivmod64(dividend, divisor, &rem); - return rem; -} - -int64_t smod64(int64_t dividend, int64_t divisor) -{ - int64_t rem; - sdivmod64(dividend, divisor, &rem); - return rem; -} diff --git a/llrtc/lib/sdivmod64.c b/llrtc/lib/sdivmod64.c deleted file mode 100644 index df294b3..0000000 --- a/llrtc/lib/sdivmod64.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "llrt.h" -#include - -/* -Calls to udivmod64 internally. -Note: remainder uses sign of divisor. -*/ -int64_t sdivmod64(int64_t dividend, int64_t divisor, int64_t *remainder) -{ - int signbitidx = BITS_PER_BYTE * sizeof(dividend) - 1; - int signed_dividend = dividend < 0; - int signed_divisor = divisor < 0; - int signed_result = signed_divisor ^ signed_dividend; - - int64_t quotient; - uint64_t udvd, udvr, uquotient, uremainder; - - udvd = signed_dividend ? -dividend : dividend; - udvr = signed_divisor ? -divisor : divisor; - uquotient = udivmod64(udvd, udvr, &uremainder); - - if (signed_result){ - if (uremainder) { - quotient = -(int64_t)uquotient - 1; - } else { - quotient = -(int64_t)uquotient; - } - if (remainder) { - /* if signed, there could be unsigned overflow - causing undefined behavior */ - *remainder = (uint64_t)dividend - (uint64_t)quotient * (uint64_t)divisor; - } - } else { - quotient = (int64_t)uquotient; - if (remainder) { - *remainder = signed_divisor ? -uremainder : uremainder; - } - } - return quotient; -} diff --git a/llrtc/lib/test_sdivmod64.c b/llrtc/lib/test_sdivmod64.c deleted file mode 100644 index 1e804d6..0000000 --- a/llrtc/lib/test_sdivmod64.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include "llrt.h" - -int main(int argc, char * argv[]){ - int64_t n, d, q, r; - - if (argc != 3) { - printf("invalid argument: %s dividend divisor", argv[0]); - return 1; - } - sscanf(argv[1], "%lld", &n); - sscanf(argv[2], "%lld", &d); - - q = sdivmod64(n, d, &r); - - printf("%lld\n", q); - printf("%lld\n", r); - - return 0; -} diff --git a/llrtc/lib/test_sdivmod64.py b/llrtc/lib/test_sdivmod64.py deleted file mode 100644 index 4aa49a9..0000000 --- a/llrtc/lib/test_sdivmod64.py +++ /dev/null @@ -1,56 +0,0 @@ -import math -import os -import subprocess -udt = os.path.join('.', 'test_sdivmod64.run') - -def testcase(dividend, divisor): - print 'divmod64(%d, %d)' % (dividend, divisor) - - procargs = ('%s %s %s' % (udt, dividend, divisor)).split() - result = subprocess.check_output(procargs) - gotQ, gotR = map(int, result.splitlines()) - - expectQ = dividend // divisor - expectR = dividend % divisor - - print 'Q = %d, R = %d' % (gotQ, gotR) - - if expectQ != gotQ: - raise ValueError("invalid quotient: got=%d but expect=%d" % - (gotQ, expectQ)) - if expectR != gotR: - raise ValueError("invalid remainder: got=%d but expect=%d" % - (gotR, expectR)) - print 'OK' - -def testsequence(): - subjects = [ - (0, 1), - (0, 0xffffffff), - (1, 2), - (1, 983219), - (2, 2), - (3, 2), - (1024, 2), - (2048, 512), - (21321, 512), - (9329189, 1031), - (0xffffffff, 2), - (0xffffffff, 0xffff), - (0x1ffffffff, 2), - (0x1ffffffff, 0xffff), - (0xffff, 0xffffffff), - (0x0fffffffffffffff, 0xffff), - (0x7fffffffffffffff, 0x7fffffffffffffff), - (0x7fffffffffffffff, 0x7ffffffffffffff0), - (0x7fffffffffffffff, 87655678587161901), - ] - - for dvd, dvr in subjects: - testcase(dvd, dvr) - testcase(dvd, -dvr) - testcase(-dvd, dvr) - testcase(-dvd, -dvr) - -if __name__ == '__main__': - testsequence() diff --git a/llrtc/lib/test_udivmod64.c b/llrtc/lib/test_udivmod64.c deleted file mode 100644 index 70b44aa..0000000 --- a/llrtc/lib/test_udivmod64.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include "llrt.h" - -int main(int argc, char * argv[]){ - uint64_t n, d, q, r; - if (argc != 3) { - printf("invalid argument: %s dividend divisor", argv[0]); - return 1; - } - sscanf(argv[1], "%llu", &n); - sscanf(argv[2], "%llu", &d); - - q = udivmod64(n, d, &r); - - printf("%llu\n", q); - printf("%llu\n", r); - - return 0; -} diff --git a/llrtc/lib/test_udivmod64.py b/llrtc/lib/test_udivmod64.py deleted file mode 100644 index da07ccb..0000000 --- a/llrtc/lib/test_udivmod64.py +++ /dev/null @@ -1,53 +0,0 @@ -import math -import os -import subprocess -udt = os.path.join('.', 'test_udivmod64.run') - -def testcase(dividend, divisor): - print 'divmod64(%d, %d)' % (dividend, divisor) - - procargs = ('%s %s %s' % (udt, dividend, divisor)).split() - result = subprocess.check_output(procargs) - gotQ, gotR = map(int, result.splitlines()) - - expectQ = dividend // divisor - expectR = dividend % divisor - - print 'Q = %d, R = %d' % (gotQ, gotR) - - if expectQ != gotQ: - raise ValueError("invalid quotient: got=%d but expect=%d" % - (gotQ, expectQ)) - if expectR != gotR: - raise ValueError("invalid remainder: got=%d but expect=%d" % - (gotR, expectR)) - print 'OK' - -def testsequence(): - subjects = [ - (0, 1), - (0, 0xffffffffffffffff), - (1, 2), - (1, 983219), - (2, 2), - (3, 2), - (1024, 2), - (2048, 512), - (21321, 512), - (9329189, 1031), - (0xffffffff, 2), - (0xffffffff, 0xffff), - (0x1ffffffff, 2), - (0x1ffffffff, 0xffff), - (0xffff, 0xffffffff), - (0xffffffffffffffff, 0xffff), - (0xffffffffffffffff, 0x7fffffffffffffff), - (0xffffffffffffffff, 0xfffffffffffffff0), - (0xffffffffffffffff, 87655678587161901), - ] - - for dvd, dvr in subjects: - testcase(dvd, dvr) - -if __name__ == '__main__': - testsequence() diff --git a/llrtc/lib/udivmod64.c b/llrtc/lib/udivmod64.c deleted file mode 100644 index 5936f98..0000000 --- a/llrtc/lib/udivmod64.c +++ /dev/null @@ -1,84 +0,0 @@ -/* -Implements unsigned divmod using for platform missing 64-bit division and/or -modulo functions. -*/ -#include "llrt.h" - -/* -count left zero for 64-bit words - -*/ -static -int clz64(uint64_t x) -{ - const int total_bits = sizeof(x) * BITS_PER_BYTE; - int zc = 0; - - while (zc < total_bits && ((x >> (total_bits - zc - 1)) & 1) == 0) { - ++zc; - } - return zc; -} - -typedef struct div_state_ -{ - uint64_t tmp, dvd; -} div_state; - -/* -Left shift div_state by 1 bit -*/ -static -void div_state_lshift(div_state *state) -{ - state->tmp = (state->tmp << 1) | (state->dvd >> 63); - state->dvd = state->dvd << 1; -} - -/* -Division of unsigned 64-bit word using 64-bit addition and subtration following -the shift-restore division algorithm. -For those interested in 32-bit implementation, -mapping of 64-bit addition and subtraction to 32-bit should be trivial. - -Reference: - - IBM. The PowerPC Compiler Writer's Guide - - LLVM compiler-rt - -Assumptions: - - all operands and results are positive - - unsigned wrapped around -*/ -uint64_t udivmod64(uint64_t dividend, uint64_t divisor, uint64_t *remainder) -{ - div_state state = {0, dividend}; - uint64_t quotient = 0; - int i; - int skipahead; - - if (divisor == 0) { - return 1 / 0; /* intentionally div by zero */ - } - - /* - skipahead to reduce iteration - */ - skipahead = clz64(dividend); - - for (i = 0; i < skipahead; ++i) { - div_state_lshift(&state); - } - - /* - division loop - */ - for (i = skipahead; i < 64; ++i) { - div_state_lshift(&state); - if (state.tmp >= divisor) { - state.tmp = state.tmp - divisor; - quotient |= 1ull << (63 - i); - } - } - if (remainder) *remainder = state.tmp; - return quotient; -} diff --git a/llrtc/tools/striptriple.py b/llrtc/tools/striptriple.py deleted file mode 100644 index a20ba34..0000000 --- a/llrtc/tools/striptriple.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys -import re - -buf = [] -with open(sys.argv[1], 'r') as fin: - tripleline = re.compile('^target\s+triple\s+=\s+') - for line in fin.readlines(): - if not tripleline.match(line): - buf.append(line) - -with open(sys.argv[1], 'w') as fout: - for line in buf: - fout.write(line) - - diff --git a/llvm-config-win32.py b/llvm-config-win32.py index 3f756ee..d8fa5c1 100644 --- a/llvm-config-win32.py +++ b/llvm-config-win32.py @@ -1,88 +1,78 @@ -import re -import sys -from distutils.spawn import find_executable -from os.path import abspath, dirname, isfile, join -from os import listdir -from subprocess import Popen, PIPE +import sys, os +def find_path_of(filename, envvar='PATH'): + """Finds the path from $PATH where the file exists, returns None if not found.""" + pathlist = os.getenv(envvar).split(os.pathsep) + for path in pathlist: + if os.path.exists(os.path.join(path, filename)): + return os.path.abspath(path) + return None -def find_llvm_tblgen(): - path = find_executable('llvm-tblgen') - if path is None: - sys.exit('Error: could not locate llvm-tblgen') - return path - - -def find_llvm_prefix(): - return abspath(dirname(dirname(find_llvm_tblgen()))) - - -def ensure_file(path): - if not isfile(path): - sys.exit('Error: no file: %r' % path) - - -def get_llvm_version(): - args = [find_llvm_tblgen(), '--version'] - p = Popen(args, stdout=PIPE, stderr=PIPE) - stdout, stderr = p.communicate() - if stderr: - sys.exit("Error: %r stderr is:\n%s" % (args, stderr.decode())) - out = stdout.decode().strip() - pat = re.compile(r'llvm\s+version\s+(\d+\.\d+\S*)', re.I) - m = pat.search(out) - if m is None: - sys.exit('Error: could not parse version in:' + out) - return m.group(1) - - -def libs_options(): +if sys.argv[1] == '--version': + cmd = 'llvm-tblgen --version' + # Hardcoded extraction, only tested on llvm 3.1 + result = os.popen(cmd).read().split('\n')[1].strip().split(' ')[2] + print result +elif sys.argv[1] == '--libs': # NOTE: instead of actually looking at the components requested, - # we just print out a bunch of libs + # we just spit out a bunch of libs for lib in """ +LLVMAnalysis +LLVMAsmParser +LLVMAsmPrinter +LLVMBitReader +LLVMBitWriter +LLVMCodeGen +LLVMCore +LLVMExecutionEngine +LLVMInstCombine +LLVMInstrumentation +LLVMInterpreter +LLVMipa +LLVMipo +LLVMJIT +LLVMLinker +LLVMMC +LLVMMCParser +LLVMObject +LLVMRuntimeDyld +LLVMScalarOpts +LLVMSelectionDAG +LLVMSupport +LLVMTarget +LLVMTransformUtils +LLVMVectorize +LLVMX86AsmParser +LLVMX86AsmPrinter +LLVMX86CodeGen +LLVMX86Desc +LLVMX86Info +LLVMX86Utils Advapi32 Shell32 """.split(): print('-l%s' % lib) - - bpath = join(find_llvm_prefix(), 'lib') - for filename in listdir(bpath): - filepath = join(bpath, filename) - if isfile(filepath) and filename.endswith('.lib') and filename.startswith('LLVM'): - name = filename.split('.', 1)[0] - print('-l%s' % name) - -def main(): - try: - option = sys.argv[1] - except IndexError: - sys.exit('Error: option missing') - - if option == '--version': - print(get_llvm_version()) - - elif option == '--targets-built': - print('X86') # just do X86 - - elif option == '--libs': - libs_options() - - elif option == '--includedir': - incdir = join(find_llvm_prefix(), 'include') - ensure_file(join(incdir, 'llvm' , 'Linker.h')) - print(incdir) - - elif option == '--libdir': - libdir = join(find_llvm_prefix(), 'lib') - ensure_file(join(libdir, 'LLVMCore.lib')) - print(libdir) - - elif option in ('--ldflags', '--components'): - pass - - else: - sys.exit('Error: Unrecognized llvm-config option %r' % option) - - -if __name__ == '__main__': - main() + llvmbin = find_path_of('llvm-tblgen.exe') + if os.path.exists(os.path.join(llvmbin, '../lib/LLVMPTXCodeGen.lib')): + print('-lLLVMPTXAsmPrinter') + print('-lLLVMPTXCodeGen') + print('-lLLVMPTXDesc') + print('-lLLVMPTXInfo') +elif sys.argv[1] == '--includedir': + llvmbin = find_path_of('llvm-tblgen.exe') + if llvmbin is None: + raise RuntimeError('Could not find LLVM') + incdir = os.path.abspath(os.path.join(llvmbin, '../include')) + if not os.path.exists(os.path.join(incdir, 'llvm/BasicBlock.h')): + raise RuntimeError('Could not find LLVM include dir') + print incdir +elif sys.argv[1] == '--libdir': + llvmbin = find_path_of('llvm-tblgen.exe') + if llvmbin is None: + raise RuntimeError('Could not find LLVM') + libdir = os.path.abspath(os.path.join(llvmbin, '../lib')) + if not os.path.exists(os.path.join(libdir, 'LLVMCore.lib')): + raise RuntimeError('Could not find LLVM lib dir') + print libdir +else: + raise RuntimeError('Unrecognized llvm-config command %s' % sys.argv[1]) diff --git a/llvm/2.9_update.diff b/llvm/2.9_update.diff new file mode 100644 index 0000000..5572286 --- /dev/null +++ b/llvm/2.9_update.diff @@ -0,0 +1,2117 @@ +Index: core.py +=================================================================== +--- core.py (revision 105) ++++ core.py (working copy) +@@ -51,14 +51,15 @@ + TYPE_FP128 = 4 + TYPE_PPC_FP128 = 5 + TYPE_LABEL = 6 +-TYPE_INTEGER = 7 +-TYPE_FUNCTION = 8 +-TYPE_STRUCT = 9 +-TYPE_ARRAY = 10 +-TYPE_POINTER = 11 +-TYPE_OPAQUE = 12 +-TYPE_VECTOR = 13 +-TYPE_METADATA = 14 ++TYPE_METADATA = 7 ++TYPE_X86_MMX = 8 ++TYPE_INTEGER = 9 ++TYPE_FUNCTION = 10 ++TYPE_STRUCT = 11 ++TYPE_ARRAY = 12 ++TYPE_POINTER = 13 ++TYPE_OPAQUE = 14 ++TYPE_VECTOR = 15 + + # value IDs (llvm::Value::ValueTy enum) + VALUE_ARGUMENT = 0 +@@ -140,11 +141,21 @@ + OPCODE_INSERTVALUE = 54 + + # calling conventions +-CC_C = 0 +-CC_FASTCALL = 8 +-CC_COLDCALL = 9 +-CC_X86_STDCALL = 64 +-CC_X86_FASTCALL = 65 ++CC_C = 0 ++CC_FASTCALL = 8 ++CC_COLDCALL = 9 ++CC_GHC = 10 ++CC_X86_STDCALL = 64 ++CC_X86_FASTCALL = 65 ++CC_ARM_APCS = 66 ++CC_ARM_AAPCS = 67 ++CC_ARM_AAPCS_VFP = 68 ++CC_MSP430_INTR = 69 ++CC_X86_THISCALL = 70 ++CC_PTX_KERNEL = 71 ++CC_PTX_DEVICE = 72 ++CC_MBLAZE_INTR = 73 ++CC_MBLAZE_SVOL = 74 + + # int predicates + ICMP_EQ = 32 +@@ -248,11 +259,14 @@ + ATTR_OPTIMIZE_FOR_SIZE = 1<<13 + ATTR_STACK_PROTECT = 1<<14 + ATTR_STACK_PROTECT_REQ = 1<<15 ++ATTR_ALIGNMENT = 1<<16 + ATTR_NO_CAPTURE = 1<<21 + ATTR_NO_REDZONE = 1<<22 + ATTR_NO_IMPLICIT_FLOAT = 1<<23 + ATTR_NAKED = 1<<24 + ATTR_INLINE_HINT = 1<<25 ++ATTR_STACK_ALIGNMENT = 7<<26 ++ATTR_HOTPATCH = 1<<29 + + # intrinsic IDs + from llvm._intrinsic_ids import * +Index: extra.cpp +=================================================================== +--- extra.cpp (revision 105) ++++ extra.cpp (working copy) +@@ -54,7 +54,7 @@ + #include "llvm/IntrinsicInst.h" + #include "llvm/Analysis/Verifier.h" + #include "llvm/Assembly/Parser.h" +-#include "llvm/System/DynamicLibrary.h" ++#include "llvm/Support/DynamicLibrary.h" + #include "llvm/PassManager.h" + #include "llvm/ExecutionEngine/ExecutionEngine.h" + #include "llvm/Analysis/LoopPass.h" +@@ -452,12 +452,19 @@ + return eep->getPointerToFunction(fnp); + } + ++ + int LLVMInlineFunction(LLVMValueRef call) + { + llvm::Value *callp = llvm::unwrap(call); + assert(callp); + +- llvm::CallSite cs = llvm::CallSite::get(callp); ++// llvm::CallSite cs = llvm::CallSite::get(callp); ++ llvm::CallSite cs; ++ llvm::Instruction *II = llvm::dyn_cast(callp); ++ if (II->getOpcode() == llvm::Instruction::Call) ++ cs = llvm::CallSite(static_cast(II)); ++ else if (II->getOpcode() == llvm::Instruction::Invoke) ++ cs = llvm::CallSite(static_cast(II)); + + llvm::InlineFunctionInfo unused; + return llvm::InlineFunction(cs, unused); +@@ -501,13 +508,13 @@ + define_pass( DomPrinter ) + define_pass( DomViewer ) + define_pass( EdgeProfiler ) +-define_pass( GEPSplitter ) ++//define_pass( GEPSplitter ) + define_pass( GlobalsModRef ) + define_pass( InstCount ) + define_pass( InstructionNamer ) + define_pass( LazyValueInfo ) + define_pass( LCSSA ) +-define_pass( LiveValues ) ++//define_pass( LiveValues ) + define_pass( LoopDependenceAnalysis ) + define_pass( LoopExtractor ) + define_pass( LoopSimplify ) +@@ -519,7 +526,7 @@ + define_pass( NoProfileInfo ) + define_pass( OptimalEdgeProfiler ) + define_pass( PartialInlining ) +-define_pass( PartialSpecialization ) ++//define_pass( PartialSpecialization ) + define_pass( PostDomOnlyPrinter ) + define_pass( PostDomOnlyViewer ) + define_pass( PostDomPrinter ) +@@ -528,7 +535,7 @@ + define_pass( ProfileLoader ) + define_pass( ProfileVerifier ) + define_pass( ScalarEvolutionAliasAnalysis ) +-define_pass( SimplifyHalfPowrLibCalls ) ++//define_pass( SimplifyHalfPowrLibCalls ) + define_pass( SingleLoopExtractor ) + define_pass( StripNonDebugSymbols ) + define_pass( StructRetPromotion ) +Index: passes.py +=================================================================== +--- passes.py (revision 105) ++++ passes.py (working copy) +@@ -68,7 +68,7 @@ + PASS_EDGE_PROFILER = 25 + PASS_FUNCTION_ATTRS = 26 + PASS_FUNCTION_INLINING = 27 +-PASS_GEP_SPLITTER = 28 ++#PASS_GEP_SPLITTER = 28 + PASS_GLOBAL_DCE = 29 + PASS_GLOBAL_OPTIMIZER = 30 + PASS_GLOBALS_MOD_REF = 31 +@@ -83,11 +83,11 @@ + PASS_LAZY_VALUE_INFO = 40 + PASS_LCSSA = 41 + PASS_LICM = 42 +-PASS_LIVE_VALUES = 43 ++#PASS_LIVE_VALUES = 43 + PASS_LOOP_DELETION = 44 + PASS_LOOP_DEPENDENCE_ANALYSIS = 45 + PASS_LOOP_EXTRACTOR = 46 +-PASS_LOOP_INDEX_SPLIT = 47 ++#PASS_LOOP_INDEX_SPLIT = 47 + PASS_LOOP_ROTATE = 48 + PASS_LOOP_SIMPLIFY = 49 + PASS_LOOP_STRENGTH_REDUCE = 50 +@@ -102,11 +102,11 @@ + PASS_NO_PROFILE_INFO = 59 + PASS_OPTIMAL_EDGE_PROFILER = 60 + PASS_PARTIAL_INLINING = 61 +-PASS_PARTIAL_SPECIALIZATION = 62 +-PASS_POST_DOM_ONLY_PRINTER = 63 +-PASS_POST_DOM_ONLY_VIEWER = 64 +-PASS_POST_DOM_PRINTER = 65 +-PASS_POST_DOM_VIEWER = 66 ++#PASS_PARTIAL_SPECIALIZATION = 62 ++#PASS_POST_DOM_ONLY_PRINTER = 63 ++#PASS_POST_DOM_ONLY_VIEWER = 64 ++#PASS_POST_DOM_PRINTER = 65 ++#PASS_POST_DOM_VIEWER = 66 + PASS_PROFILE_ESTIMATOR = 67 + PASS_PROFILE_LOADER = 68 + PASS_PROFILE_VERIFIER = 69 +@@ -116,7 +116,7 @@ + PASS_SCALAR_EVOLUTION_ALIAS_ANALYSIS = 73 + PASS_SCALAR_REPL_AGGREGATES = 74 + PASS_SCCP = 76 +-PASS_SIMPLIFY_HALF_POWR_LIB_CALLS = 77 ++#PASS_SIMPLIFY_HALF_POWR_LIB_CALLS = 77 + PASS_SIMPLIFY_LIB_CALLS = 78 + PASS_SINGLE_LOOP_EXTRACTOR = 79 + PASS_STRIP_DEAD_PROTOTYPES = 82 +@@ -161,7 +161,7 @@ + PASS_EDGE_PROFILER : _core.LLVMAddEdgeProfilerPass, + PASS_FUNCTION_ATTRS : _core.LLVMAddFunctionAttrsPass, + PASS_FUNCTION_INLINING : _core.LLVMAddFunctionInliningPass, +- PASS_GEP_SPLITTER : _core.LLVMAddGEPSplitterPass, ++ #PASS_GEP_SPLITTER : _core.LLVMAddGEPSplitterPass, + PASS_GLOBAL_DCE : _core.LLVMAddGlobalDCEPass, + PASS_GLOBAL_OPTIMIZER : _core.LLVMAddGlobalOptimizerPass, + PASS_GLOBALS_MOD_REF : _core.LLVMAddGlobalsModRefPass, +@@ -176,11 +176,11 @@ + PASS_LAZY_VALUE_INFO : _core.LLVMAddLazyValueInfoPass, + PASS_LCSSA : _core.LLVMAddLCSSAPass, + PASS_LICM : _core.LLVMAddLICMPass, +- PASS_LIVE_VALUES : _core.LLVMAddLiveValuesPass, ++ #PASS_LIVE_VALUES : _core.LLVMAddLiveValuesPass, + PASS_LOOP_DELETION : _core.LLVMAddLoopDeletionPass, + PASS_LOOP_DEPENDENCE_ANALYSIS : _core.LLVMAddLoopDependenceAnalysisPass, + PASS_LOOP_EXTRACTOR : _core.LLVMAddLoopExtractorPass, +- PASS_LOOP_INDEX_SPLIT : _core.LLVMAddLoopIndexSplitPass, ++ #PASS_LOOP_INDEX_SPLIT : _core.LLVMAddLoopIndexSplitPass, + PASS_LOOP_ROTATE : _core.LLVMAddLoopRotatePass, + PASS_LOOP_SIMPLIFY : _core.LLVMAddLoopSimplifyPass, + PASS_LOOP_STRENGTH_REDUCE : _core.LLVMAddLoopStrengthReducePass, +@@ -195,11 +195,11 @@ + PASS_NO_PROFILE_INFO : _core.LLVMAddNoProfileInfoPass, + PASS_OPTIMAL_EDGE_PROFILER : _core.LLVMAddOptimalEdgeProfilerPass, + PASS_PARTIAL_INLINING : _core.LLVMAddPartialInliningPass, +- PASS_PARTIAL_SPECIALIZATION : _core.LLVMAddPartialSpecializationPass, +- PASS_POST_DOM_ONLY_PRINTER : _core.LLVMAddPostDomOnlyPrinterPass, +- PASS_POST_DOM_ONLY_VIEWER : _core.LLVMAddPostDomOnlyViewerPass, +- PASS_POST_DOM_PRINTER : _core.LLVMAddPostDomPrinterPass, +- PASS_POST_DOM_VIEWER : _core.LLVMAddPostDomViewerPass, ++ #PASS_PARTIAL_SPECIALIZATION : _core.LLVMAddPartialSpecializationPass, ++ #PASS_POST_DOM_ONLY_PRINTER : _core.LLVMAddPostDomOnlyPrinterPass, ++ #PASS_POST_DOM_ONLY_VIEWER : _core.LLVMAddPostDomOnlyViewerPass, ++ #PASS_POST_DOM_PRINTER : _core.LLVMAddPostDomPrinterPass, ++ #PASS_POST_DOM_VIEWER : _core.LLVMAddPostDomViewerPass, + PASS_PROFILE_ESTIMATOR : _core.LLVMAddProfileEstimatorPass, + PASS_PROFILE_LOADER : _core.LLVMAddProfileLoaderPass, + PASS_PROFILE_VERIFIER : _core.LLVMAddProfileVerifierPass, +@@ -209,7 +209,7 @@ + PASS_SCALAR_EVOLUTION_ALIAS_ANALYSIS : _core.LLVMAddScalarEvolutionAliasAnalysisPass, + PASS_SCALAR_REPL_AGGREGATES : _core.LLVMAddScalarReplAggregatesPass, + PASS_SCCP : _core.LLVMAddSCCPPass, +- PASS_SIMPLIFY_HALF_POWR_LIB_CALLS : _core.LLVMAddSimplifyHalfPowrLibCallsPass, ++ #PASS_SIMPLIFY_HALF_POWR_LIB_CALLS : _core.LLVMAddSimplifyHalfPowrLibCallsPass, + PASS_SIMPLIFY_LIB_CALLS : _core.LLVMAddSimplifyLibCallsPass, + PASS_SINGLE_LOOP_EXTRACTOR : _core.LLVMAddSingleLoopExtractorPass, + PASS_STRIP_DEAD_PROTOTYPES : _core.LLVMAddStripDeadPrototypesPass, +Index: _intrinsic_ids.py +=================================================================== +--- _intrinsic_ids.py (revision 105) ++++ _intrinsic_ids.py (working copy) +@@ -49,854 +49,879 @@ + INTR_ARM_NEON_VCNT = 14 + INTR_ARM_NEON_VCVTFP2FXS = 15 + INTR_ARM_NEON_VCVTFP2FXU = 16 +-INTR_ARM_NEON_VCVTFXS2FP = 17 +-INTR_ARM_NEON_VCVTFXU2FP = 18 +-INTR_ARM_NEON_VHADDS = 19 +-INTR_ARM_NEON_VHADDU = 20 +-INTR_ARM_NEON_VHSUBS = 21 +-INTR_ARM_NEON_VHSUBU = 22 +-INTR_ARM_NEON_VLD1 = 23 +-INTR_ARM_NEON_VLD2 = 24 +-INTR_ARM_NEON_VLD2LANE = 25 +-INTR_ARM_NEON_VLD3 = 26 +-INTR_ARM_NEON_VLD3LANE = 27 +-INTR_ARM_NEON_VLD4 = 28 +-INTR_ARM_NEON_VLD4LANE = 29 +-INTR_ARM_NEON_VMAXS = 30 +-INTR_ARM_NEON_VMAXU = 31 +-INTR_ARM_NEON_VMINS = 32 +-INTR_ARM_NEON_VMINU = 33 +-INTR_ARM_NEON_VMULLP = 34 +-INTR_ARM_NEON_VMULP = 35 +-INTR_ARM_NEON_VPADALS = 36 +-INTR_ARM_NEON_VPADALU = 37 +-INTR_ARM_NEON_VPADD = 38 +-INTR_ARM_NEON_VPADDLS = 39 +-INTR_ARM_NEON_VPADDLU = 40 +-INTR_ARM_NEON_VPMAXS = 41 +-INTR_ARM_NEON_VPMAXU = 42 +-INTR_ARM_NEON_VPMINS = 43 +-INTR_ARM_NEON_VPMINU = 44 +-INTR_ARM_NEON_VQABS = 45 +-INTR_ARM_NEON_VQADDS = 46 +-INTR_ARM_NEON_VQADDU = 47 +-INTR_ARM_NEON_VQDMLAL = 48 +-INTR_ARM_NEON_VQDMLSL = 49 +-INTR_ARM_NEON_VQDMULH = 50 +-INTR_ARM_NEON_VQDMULL = 51 +-INTR_ARM_NEON_VQMOVNS = 52 +-INTR_ARM_NEON_VQMOVNSU = 53 +-INTR_ARM_NEON_VQMOVNU = 54 +-INTR_ARM_NEON_VQNEG = 55 +-INTR_ARM_NEON_VQRDMULH = 56 +-INTR_ARM_NEON_VQRSHIFTNS = 57 +-INTR_ARM_NEON_VQRSHIFTNSU = 58 +-INTR_ARM_NEON_VQRSHIFTNU = 59 +-INTR_ARM_NEON_VQRSHIFTS = 60 +-INTR_ARM_NEON_VQRSHIFTU = 61 +-INTR_ARM_NEON_VQSHIFTNS = 62 +-INTR_ARM_NEON_VQSHIFTNSU = 63 +-INTR_ARM_NEON_VQSHIFTNU = 64 +-INTR_ARM_NEON_VQSHIFTS = 65 +-INTR_ARM_NEON_VQSHIFTSU = 66 +-INTR_ARM_NEON_VQSHIFTU = 67 +-INTR_ARM_NEON_VQSUBS = 68 +-INTR_ARM_NEON_VQSUBU = 69 +-INTR_ARM_NEON_VRADDHN = 70 +-INTR_ARM_NEON_VRECPE = 71 +-INTR_ARM_NEON_VRECPS = 72 +-INTR_ARM_NEON_VRHADDS = 73 +-INTR_ARM_NEON_VRHADDU = 74 +-INTR_ARM_NEON_VRSHIFTN = 75 +-INTR_ARM_NEON_VRSHIFTS = 76 +-INTR_ARM_NEON_VRSHIFTU = 77 +-INTR_ARM_NEON_VRSQRTE = 78 +-INTR_ARM_NEON_VRSQRTS = 79 +-INTR_ARM_NEON_VRSUBHN = 80 +-INTR_ARM_NEON_VSHIFTINS = 81 +-INTR_ARM_NEON_VSHIFTLS = 82 +-INTR_ARM_NEON_VSHIFTLU = 83 +-INTR_ARM_NEON_VSHIFTN = 84 +-INTR_ARM_NEON_VSHIFTS = 85 +-INTR_ARM_NEON_VSHIFTU = 86 +-INTR_ARM_NEON_VST1 = 87 +-INTR_ARM_NEON_VST2 = 88 +-INTR_ARM_NEON_VST2LANE = 89 +-INTR_ARM_NEON_VST3 = 90 +-INTR_ARM_NEON_VST3LANE = 91 +-INTR_ARM_NEON_VST4 = 92 +-INTR_ARM_NEON_VST4LANE = 93 +-INTR_ARM_NEON_VSUBHN = 94 +-INTR_ARM_NEON_VTBL1 = 95 +-INTR_ARM_NEON_VTBL2 = 96 +-INTR_ARM_NEON_VTBL3 = 97 +-INTR_ARM_NEON_VTBL4 = 98 +-INTR_ARM_NEON_VTBX1 = 99 +-INTR_ARM_NEON_VTBX2 = 100 +-INTR_ARM_NEON_VTBX3 = 101 +-INTR_ARM_NEON_VTBX4 = 102 +-INTR_ARM_QADD = 103 +-INTR_ARM_QSUB = 104 +-INTR_ARM_SET_FPSCR = 105 +-INTR_ARM_SSAT = 106 +-INTR_ARM_THREAD_POINTER = 107 +-INTR_ARM_USAT = 108 +-INTR_ARM_VCVTR = 109 +-INTR_ARM_VCVTRU = 110 +-INTR_ATOMIC_CMP_SWAP = 111 +-INTR_ATOMIC_LOAD_ADD = 112 +-INTR_ATOMIC_LOAD_AND = 113 +-INTR_ATOMIC_LOAD_MAX = 114 +-INTR_ATOMIC_LOAD_MIN = 115 +-INTR_ATOMIC_LOAD_NAND = 116 +-INTR_ATOMIC_LOAD_OR = 117 +-INTR_ATOMIC_LOAD_SUB = 118 +-INTR_ATOMIC_LOAD_UMAX = 119 +-INTR_ATOMIC_LOAD_UMIN = 120 +-INTR_ATOMIC_LOAD_XOR = 121 +-INTR_ATOMIC_SWAP = 122 +-INTR_BSWAP = 123 +-INTR_CONVERT_FROM_FP16 = 124 +-INTR_CONVERT_TO_FP16 = 125 +-INTR_CONVERTFF = 126 +-INTR_CONVERTFSI = 127 +-INTR_CONVERTFUI = 128 +-INTR_CONVERTSIF = 129 +-INTR_CONVERTSS = 130 +-INTR_CONVERTSU = 131 +-INTR_CONVERTUIF = 132 +-INTR_CONVERTUS = 133 +-INTR_CONVERTUU = 134 +-INTR_COS = 135 +-INTR_CTLZ = 136 +-INTR_CTPOP = 137 +-INTR_CTTZ = 138 +-INTR_DBG_DECLARE = 139 +-INTR_DBG_VALUE = 140 +-INTR_EH_DWARF_CFA = 141 +-INTR_EH_EXCEPTION = 142 +-INTR_EH_RETURN_I32 = 143 +-INTR_EH_RETURN_I64 = 144 +-INTR_EH_SELECTOR = 145 +-INTR_EH_SJLJ_CALLSITE = 146 +-INTR_EH_SJLJ_LONGJMP = 147 +-INTR_EH_SJLJ_LSDA = 148 +-INTR_EH_SJLJ_SETJMP = 149 +-INTR_EH_TYPEID_FOR = 150 +-INTR_EH_UNWIND_INIT = 151 +-INTR_EXP = 152 +-INTR_EXP2 = 153 +-INTR_FLT_ROUNDS = 154 +-INTR_FRAMEADDRESS = 155 +-INTR_GCREAD = 156 +-INTR_GCROOT = 157 +-INTR_GCWRITE = 158 +-INTR_INIT_TRAMPOLINE = 159 +-INTR_INVARIANT_END = 160 +-INTR_INVARIANT_START = 161 +-INTR_LIFETIME_END = 162 +-INTR_LIFETIME_START = 163 +-INTR_LOG = 164 +-INTR_LOG10 = 165 +-INTR_LOG2 = 166 +-INTR_LONGJMP = 167 +-INTR_MEMCPY = 168 +-INTR_MEMMOVE = 169 +-INTR_MEMORY_BARRIER = 170 +-INTR_MEMSET = 171 +-INTR_OBJECTSIZE = 172 +-INTR_PCMARKER = 173 +-INTR_POW = 174 +-INTR_POWI = 175 +-INTR_PPC_ALTIVEC_DSS = 176 +-INTR_PPC_ALTIVEC_DSSALL = 177 +-INTR_PPC_ALTIVEC_DST = 178 +-INTR_PPC_ALTIVEC_DSTST = 179 +-INTR_PPC_ALTIVEC_DSTSTT = 180 +-INTR_PPC_ALTIVEC_DSTT = 181 +-INTR_PPC_ALTIVEC_LVEBX = 182 +-INTR_PPC_ALTIVEC_LVEHX = 183 +-INTR_PPC_ALTIVEC_LVEWX = 184 +-INTR_PPC_ALTIVEC_LVSL = 185 +-INTR_PPC_ALTIVEC_LVSR = 186 +-INTR_PPC_ALTIVEC_LVX = 187 +-INTR_PPC_ALTIVEC_LVXL = 188 +-INTR_PPC_ALTIVEC_MFVSCR = 189 +-INTR_PPC_ALTIVEC_MTVSCR = 190 +-INTR_PPC_ALTIVEC_STVEBX = 191 +-INTR_PPC_ALTIVEC_STVEHX = 192 +-INTR_PPC_ALTIVEC_STVEWX = 193 +-INTR_PPC_ALTIVEC_STVX = 194 +-INTR_PPC_ALTIVEC_STVXL = 195 +-INTR_PPC_ALTIVEC_VADDCUW = 196 +-INTR_PPC_ALTIVEC_VADDSBS = 197 +-INTR_PPC_ALTIVEC_VADDSHS = 198 +-INTR_PPC_ALTIVEC_VADDSWS = 199 +-INTR_PPC_ALTIVEC_VADDUBS = 200 +-INTR_PPC_ALTIVEC_VADDUHS = 201 +-INTR_PPC_ALTIVEC_VADDUWS = 202 +-INTR_PPC_ALTIVEC_VAVGSB = 203 +-INTR_PPC_ALTIVEC_VAVGSH = 204 +-INTR_PPC_ALTIVEC_VAVGSW = 205 +-INTR_PPC_ALTIVEC_VAVGUB = 206 +-INTR_PPC_ALTIVEC_VAVGUH = 207 +-INTR_PPC_ALTIVEC_VAVGUW = 208 +-INTR_PPC_ALTIVEC_VCFSX = 209 +-INTR_PPC_ALTIVEC_VCFUX = 210 +-INTR_PPC_ALTIVEC_VCMPBFP = 211 +-INTR_PPC_ALTIVEC_VCMPBFP_P = 212 +-INTR_PPC_ALTIVEC_VCMPEQFP = 213 +-INTR_PPC_ALTIVEC_VCMPEQFP_P = 214 +-INTR_PPC_ALTIVEC_VCMPEQUB = 215 +-INTR_PPC_ALTIVEC_VCMPEQUB_P = 216 +-INTR_PPC_ALTIVEC_VCMPEQUH = 217 +-INTR_PPC_ALTIVEC_VCMPEQUH_P = 218 +-INTR_PPC_ALTIVEC_VCMPEQUW = 219 +-INTR_PPC_ALTIVEC_VCMPEQUW_P = 220 +-INTR_PPC_ALTIVEC_VCMPGEFP = 221 +-INTR_PPC_ALTIVEC_VCMPGEFP_P = 222 +-INTR_PPC_ALTIVEC_VCMPGTFP = 223 +-INTR_PPC_ALTIVEC_VCMPGTFP_P = 224 +-INTR_PPC_ALTIVEC_VCMPGTSB = 225 +-INTR_PPC_ALTIVEC_VCMPGTSB_P = 226 +-INTR_PPC_ALTIVEC_VCMPGTSH = 227 +-INTR_PPC_ALTIVEC_VCMPGTSH_P = 228 +-INTR_PPC_ALTIVEC_VCMPGTSW = 229 +-INTR_PPC_ALTIVEC_VCMPGTSW_P = 230 +-INTR_PPC_ALTIVEC_VCMPGTUB = 231 +-INTR_PPC_ALTIVEC_VCMPGTUB_P = 232 +-INTR_PPC_ALTIVEC_VCMPGTUH = 233 +-INTR_PPC_ALTIVEC_VCMPGTUH_P = 234 +-INTR_PPC_ALTIVEC_VCMPGTUW = 235 +-INTR_PPC_ALTIVEC_VCMPGTUW_P = 236 +-INTR_PPC_ALTIVEC_VCTSXS = 237 +-INTR_PPC_ALTIVEC_VCTUXS = 238 +-INTR_PPC_ALTIVEC_VEXPTEFP = 239 +-INTR_PPC_ALTIVEC_VLOGEFP = 240 +-INTR_PPC_ALTIVEC_VMADDFP = 241 +-INTR_PPC_ALTIVEC_VMAXFP = 242 +-INTR_PPC_ALTIVEC_VMAXSB = 243 +-INTR_PPC_ALTIVEC_VMAXSH = 244 +-INTR_PPC_ALTIVEC_VMAXSW = 245 +-INTR_PPC_ALTIVEC_VMAXUB = 246 +-INTR_PPC_ALTIVEC_VMAXUH = 247 +-INTR_PPC_ALTIVEC_VMAXUW = 248 +-INTR_PPC_ALTIVEC_VMHADDSHS = 249 +-INTR_PPC_ALTIVEC_VMHRADDSHS = 250 +-INTR_PPC_ALTIVEC_VMINFP = 251 +-INTR_PPC_ALTIVEC_VMINSB = 252 +-INTR_PPC_ALTIVEC_VMINSH = 253 +-INTR_PPC_ALTIVEC_VMINSW = 254 +-INTR_PPC_ALTIVEC_VMINUB = 255 +-INTR_PPC_ALTIVEC_VMINUH = 256 +-INTR_PPC_ALTIVEC_VMINUW = 257 +-INTR_PPC_ALTIVEC_VMLADDUHM = 258 +-INTR_PPC_ALTIVEC_VMSUMMBM = 259 +-INTR_PPC_ALTIVEC_VMSUMSHM = 260 +-INTR_PPC_ALTIVEC_VMSUMSHS = 261 +-INTR_PPC_ALTIVEC_VMSUMUBM = 262 +-INTR_PPC_ALTIVEC_VMSUMUHM = 263 +-INTR_PPC_ALTIVEC_VMSUMUHS = 264 +-INTR_PPC_ALTIVEC_VMULESB = 265 +-INTR_PPC_ALTIVEC_VMULESH = 266 +-INTR_PPC_ALTIVEC_VMULEUB = 267 +-INTR_PPC_ALTIVEC_VMULEUH = 268 +-INTR_PPC_ALTIVEC_VMULOSB = 269 +-INTR_PPC_ALTIVEC_VMULOSH = 270 +-INTR_PPC_ALTIVEC_VMULOUB = 271 +-INTR_PPC_ALTIVEC_VMULOUH = 272 +-INTR_PPC_ALTIVEC_VNMSUBFP = 273 +-INTR_PPC_ALTIVEC_VPERM = 274 +-INTR_PPC_ALTIVEC_VPKPX = 275 +-INTR_PPC_ALTIVEC_VPKSHSS = 276 +-INTR_PPC_ALTIVEC_VPKSHUS = 277 +-INTR_PPC_ALTIVEC_VPKSWSS = 278 +-INTR_PPC_ALTIVEC_VPKSWUS = 279 +-INTR_PPC_ALTIVEC_VPKUHUS = 280 +-INTR_PPC_ALTIVEC_VPKUWUS = 281 +-INTR_PPC_ALTIVEC_VREFP = 282 +-INTR_PPC_ALTIVEC_VRFIM = 283 +-INTR_PPC_ALTIVEC_VRFIN = 284 +-INTR_PPC_ALTIVEC_VRFIP = 285 +-INTR_PPC_ALTIVEC_VRFIZ = 286 +-INTR_PPC_ALTIVEC_VRLB = 287 +-INTR_PPC_ALTIVEC_VRLH = 288 +-INTR_PPC_ALTIVEC_VRLW = 289 +-INTR_PPC_ALTIVEC_VRSQRTEFP = 290 +-INTR_PPC_ALTIVEC_VSEL = 291 +-INTR_PPC_ALTIVEC_VSL = 292 +-INTR_PPC_ALTIVEC_VSLB = 293 +-INTR_PPC_ALTIVEC_VSLH = 294 +-INTR_PPC_ALTIVEC_VSLO = 295 +-INTR_PPC_ALTIVEC_VSLW = 296 +-INTR_PPC_ALTIVEC_VSR = 297 +-INTR_PPC_ALTIVEC_VSRAB = 298 +-INTR_PPC_ALTIVEC_VSRAH = 299 +-INTR_PPC_ALTIVEC_VSRAW = 300 +-INTR_PPC_ALTIVEC_VSRB = 301 +-INTR_PPC_ALTIVEC_VSRH = 302 +-INTR_PPC_ALTIVEC_VSRO = 303 +-INTR_PPC_ALTIVEC_VSRW = 304 +-INTR_PPC_ALTIVEC_VSUBCUW = 305 +-INTR_PPC_ALTIVEC_VSUBSBS = 306 +-INTR_PPC_ALTIVEC_VSUBSHS = 307 +-INTR_PPC_ALTIVEC_VSUBSWS = 308 +-INTR_PPC_ALTIVEC_VSUBUBS = 309 +-INTR_PPC_ALTIVEC_VSUBUHS = 310 +-INTR_PPC_ALTIVEC_VSUBUWS = 311 +-INTR_PPC_ALTIVEC_VSUM2SWS = 312 +-INTR_PPC_ALTIVEC_VSUM4SBS = 313 +-INTR_PPC_ALTIVEC_VSUM4SHS = 314 +-INTR_PPC_ALTIVEC_VSUM4UBS = 315 +-INTR_PPC_ALTIVEC_VSUMSWS = 316 +-INTR_PPC_ALTIVEC_VUPKHPX = 317 +-INTR_PPC_ALTIVEC_VUPKHSB = 318 +-INTR_PPC_ALTIVEC_VUPKHSH = 319 +-INTR_PPC_ALTIVEC_VUPKLPX = 320 +-INTR_PPC_ALTIVEC_VUPKLSB = 321 +-INTR_PPC_ALTIVEC_VUPKLSH = 322 +-INTR_PPC_DCBA = 323 +-INTR_PPC_DCBF = 324 +-INTR_PPC_DCBI = 325 +-INTR_PPC_DCBST = 326 +-INTR_PPC_DCBT = 327 +-INTR_PPC_DCBTST = 328 +-INTR_PPC_DCBZ = 329 +-INTR_PPC_DCBZL = 330 +-INTR_PPC_SYNC = 331 +-INTR_PREFETCH = 332 +-INTR_PTR_ANNOTATION = 333 +-INTR_READCYCLECOUNTER = 334 +-INTR_RETURNADDRESS = 335 +-INTR_SADD_WITH_OVERFLOW = 336 +-INTR_SETJMP = 337 +-INTR_SIGLONGJMP = 338 +-INTR_SIGSETJMP = 339 +-INTR_SIN = 340 +-INTR_SMUL_WITH_OVERFLOW = 341 +-INTR_SPU_SI_A = 342 +-INTR_SPU_SI_ADDX = 343 +-INTR_SPU_SI_AH = 344 +-INTR_SPU_SI_AHI = 345 +-INTR_SPU_SI_AI = 346 +-INTR_SPU_SI_AND = 347 +-INTR_SPU_SI_ANDBI = 348 +-INTR_SPU_SI_ANDC = 349 +-INTR_SPU_SI_ANDHI = 350 +-INTR_SPU_SI_ANDI = 351 +-INTR_SPU_SI_BG = 352 +-INTR_SPU_SI_BGX = 353 +-INTR_SPU_SI_CEQ = 354 +-INTR_SPU_SI_CEQB = 355 +-INTR_SPU_SI_CEQBI = 356 +-INTR_SPU_SI_CEQH = 357 +-INTR_SPU_SI_CEQHI = 358 +-INTR_SPU_SI_CEQI = 359 +-INTR_SPU_SI_CG = 360 +-INTR_SPU_SI_CGT = 361 +-INTR_SPU_SI_CGTB = 362 +-INTR_SPU_SI_CGTBI = 363 +-INTR_SPU_SI_CGTH = 364 +-INTR_SPU_SI_CGTHI = 365 +-INTR_SPU_SI_CGTI = 366 +-INTR_SPU_SI_CGX = 367 +-INTR_SPU_SI_CLGT = 368 +-INTR_SPU_SI_CLGTB = 369 +-INTR_SPU_SI_CLGTBI = 370 +-INTR_SPU_SI_CLGTH = 371 +-INTR_SPU_SI_CLGTHI = 372 +-INTR_SPU_SI_CLGTI = 373 +-INTR_SPU_SI_DFA = 374 +-INTR_SPU_SI_DFM = 375 +-INTR_SPU_SI_DFMA = 376 +-INTR_SPU_SI_DFMS = 377 +-INTR_SPU_SI_DFNMA = 378 +-INTR_SPU_SI_DFNMS = 379 +-INTR_SPU_SI_DFS = 380 +-INTR_SPU_SI_FA = 381 +-INTR_SPU_SI_FCEQ = 382 +-INTR_SPU_SI_FCGT = 383 +-INTR_SPU_SI_FCMEQ = 384 +-INTR_SPU_SI_FCMGT = 385 +-INTR_SPU_SI_FM = 386 +-INTR_SPU_SI_FMA = 387 +-INTR_SPU_SI_FMS = 388 +-INTR_SPU_SI_FNMS = 389 +-INTR_SPU_SI_FS = 390 +-INTR_SPU_SI_FSMBI = 391 +-INTR_SPU_SI_MPY = 392 +-INTR_SPU_SI_MPYA = 393 +-INTR_SPU_SI_MPYH = 394 +-INTR_SPU_SI_MPYHH = 395 +-INTR_SPU_SI_MPYHHA = 396 +-INTR_SPU_SI_MPYHHAU = 397 +-INTR_SPU_SI_MPYHHU = 398 +-INTR_SPU_SI_MPYI = 399 +-INTR_SPU_SI_MPYS = 400 +-INTR_SPU_SI_MPYU = 401 +-INTR_SPU_SI_MPYUI = 402 +-INTR_SPU_SI_NAND = 403 +-INTR_SPU_SI_NOR = 404 +-INTR_SPU_SI_OR = 405 +-INTR_SPU_SI_ORBI = 406 +-INTR_SPU_SI_ORC = 407 +-INTR_SPU_SI_ORHI = 408 +-INTR_SPU_SI_ORI = 409 +-INTR_SPU_SI_SF = 410 +-INTR_SPU_SI_SFH = 411 +-INTR_SPU_SI_SFHI = 412 +-INTR_SPU_SI_SFI = 413 +-INTR_SPU_SI_SFX = 414 +-INTR_SPU_SI_SHLI = 415 +-INTR_SPU_SI_SHLQBI = 416 +-INTR_SPU_SI_SHLQBII = 417 +-INTR_SPU_SI_SHLQBY = 418 +-INTR_SPU_SI_SHLQBYI = 419 +-INTR_SPU_SI_XOR = 420 +-INTR_SPU_SI_XORBI = 421 +-INTR_SPU_SI_XORHI = 422 +-INTR_SPU_SI_XORI = 423 +-INTR_SQRT = 424 +-INTR_SSUB_WITH_OVERFLOW = 425 +-INTR_STACKPROTECTOR = 426 +-INTR_STACKRESTORE = 427 +-INTR_STACKSAVE = 428 +-INTR_TRAP = 429 +-INTR_UADD_WITH_OVERFLOW = 430 +-INTR_UMUL_WITH_OVERFLOW = 431 +-INTR_USUB_WITH_OVERFLOW = 432 +-INTR_VACOPY = 433 +-INTR_VAEND = 434 +-INTR_VAR_ANNOTATION = 435 +-INTR_VASTART = 436 +-INTR_X86_AESNI_AESDEC = 437 +-INTR_X86_AESNI_AESDECLAST = 438 +-INTR_X86_AESNI_AESENC = 439 +-INTR_X86_AESNI_AESENCLAST = 440 +-INTR_X86_AESNI_AESIMC = 441 +-INTR_X86_AESNI_AESKEYGENASSIST = 442 +-INTR_X86_AVX_ADDSUB_PD_256 = 443 +-INTR_X86_AVX_ADDSUB_PS_256 = 444 +-INTR_X86_AVX_BLEND_PD_256 = 445 +-INTR_X86_AVX_BLEND_PS_256 = 446 +-INTR_X86_AVX_BLENDV_PD_256 = 447 +-INTR_X86_AVX_BLENDV_PS_256 = 448 +-INTR_X86_AVX_CMP_PD_256 = 449 +-INTR_X86_AVX_CMP_PS_256 = 450 +-INTR_X86_AVX_CVT_PD2_PS_256 = 451 +-INTR_X86_AVX_CVT_PD2DQ_256 = 452 +-INTR_X86_AVX_CVT_PS2_PD_256 = 453 +-INTR_X86_AVX_CVT_PS2DQ_256 = 454 +-INTR_X86_AVX_CVTDQ2_PD_256 = 455 +-INTR_X86_AVX_CVTDQ2_PS_256 = 456 +-INTR_X86_AVX_CVTT_PD2DQ_256 = 457 +-INTR_X86_AVX_CVTT_PS2DQ_256 = 458 +-INTR_X86_AVX_DP_PS_256 = 459 +-INTR_X86_AVX_HADD_PD_256 = 460 +-INTR_X86_AVX_HADD_PS_256 = 461 +-INTR_X86_AVX_HSUB_PD_256 = 462 +-INTR_X86_AVX_HSUB_PS_256 = 463 +-INTR_X86_AVX_LDU_DQ_256 = 464 +-INTR_X86_AVX_LOADU_DQ_256 = 465 +-INTR_X86_AVX_LOADU_PD_256 = 466 +-INTR_X86_AVX_LOADU_PS_256 = 467 +-INTR_X86_AVX_MASKLOAD_PD = 468 +-INTR_X86_AVX_MASKLOAD_PD_256 = 469 +-INTR_X86_AVX_MASKLOAD_PS = 470 +-INTR_X86_AVX_MASKLOAD_PS_256 = 471 +-INTR_X86_AVX_MASKSTORE_PD = 472 +-INTR_X86_AVX_MASKSTORE_PD_256 = 473 +-INTR_X86_AVX_MASKSTORE_PS = 474 +-INTR_X86_AVX_MASKSTORE_PS_256 = 475 +-INTR_X86_AVX_MAX_PD_256 = 476 +-INTR_X86_AVX_MAX_PS_256 = 477 +-INTR_X86_AVX_MIN_PD_256 = 478 +-INTR_X86_AVX_MIN_PS_256 = 479 +-INTR_X86_AVX_MOVMSK_PD_256 = 480 +-INTR_X86_AVX_MOVMSK_PS_256 = 481 +-INTR_X86_AVX_MOVNT_DQ_256 = 482 +-INTR_X86_AVX_MOVNT_PD_256 = 483 +-INTR_X86_AVX_MOVNT_PS_256 = 484 +-INTR_X86_AVX_PTESTC_256 = 485 +-INTR_X86_AVX_PTESTNZC_256 = 486 +-INTR_X86_AVX_PTESTZ_256 = 487 +-INTR_X86_AVX_RCP_PS_256 = 488 +-INTR_X86_AVX_ROUND_PD_256 = 489 +-INTR_X86_AVX_ROUND_PS_256 = 490 +-INTR_X86_AVX_RSQRT_PS_256 = 491 +-INTR_X86_AVX_SQRT_PD_256 = 492 +-INTR_X86_AVX_SQRT_PS_256 = 493 +-INTR_X86_AVX_STOREU_DQ_256 = 494 +-INTR_X86_AVX_STOREU_PD_256 = 495 +-INTR_X86_AVX_STOREU_PS_256 = 496 +-INTR_X86_AVX_VBROADCAST_SD_256 = 497 +-INTR_X86_AVX_VBROADCASTF128_PD_256 = 498 +-INTR_X86_AVX_VBROADCASTF128_PS_256 = 499 +-INTR_X86_AVX_VBROADCASTSS = 500 +-INTR_X86_AVX_VBROADCASTSS_256 = 501 +-INTR_X86_AVX_VEXTRACTF128_PD_256 = 502 +-INTR_X86_AVX_VEXTRACTF128_PS_256 = 503 +-INTR_X86_AVX_VEXTRACTF128_SI_256 = 504 +-INTR_X86_AVX_VINSERTF128_PD_256 = 505 +-INTR_X86_AVX_VINSERTF128_PS_256 = 506 +-INTR_X86_AVX_VINSERTF128_SI_256 = 507 +-INTR_X86_AVX_VPERM2F128_PD_256 = 508 +-INTR_X86_AVX_VPERM2F128_PS_256 = 509 +-INTR_X86_AVX_VPERM2F128_SI_256 = 510 +-INTR_X86_AVX_VPERMIL_PD = 511 +-INTR_X86_AVX_VPERMIL_PD_256 = 512 +-INTR_X86_AVX_VPERMIL_PS = 513 +-INTR_X86_AVX_VPERMIL_PS_256 = 514 +-INTR_X86_AVX_VPERMILVAR_PD = 515 +-INTR_X86_AVX_VPERMILVAR_PD_256 = 516 +-INTR_X86_AVX_VPERMILVAR_PS = 517 +-INTR_X86_AVX_VPERMILVAR_PS_256 = 518 +-INTR_X86_AVX_VTESTC_PD = 519 +-INTR_X86_AVX_VTESTC_PD_256 = 520 +-INTR_X86_AVX_VTESTC_PS = 521 +-INTR_X86_AVX_VTESTC_PS_256 = 522 +-INTR_X86_AVX_VTESTNZC_PD = 523 +-INTR_X86_AVX_VTESTNZC_PD_256 = 524 +-INTR_X86_AVX_VTESTNZC_PS = 525 +-INTR_X86_AVX_VTESTNZC_PS_256 = 526 +-INTR_X86_AVX_VTESTZ_PD = 527 +-INTR_X86_AVX_VTESTZ_PD_256 = 528 +-INTR_X86_AVX_VTESTZ_PS = 529 +-INTR_X86_AVX_VTESTZ_PS_256 = 530 +-INTR_X86_AVX_VZEROALL = 531 +-INTR_X86_AVX_VZEROUPPER = 532 +-INTR_X86_INT = 533 +-INTR_X86_MMX_CVTSI32_SI64 = 534 +-INTR_X86_MMX_CVTSI64_SI32 = 535 +-INTR_X86_MMX_EMMS = 536 +-INTR_X86_MMX_FEMMS = 537 +-INTR_X86_MMX_MASKMOVQ = 538 +-INTR_X86_MMX_MOVNT_DQ = 539 +-INTR_X86_MMX_PACKSSDW = 540 +-INTR_X86_MMX_PACKSSWB = 541 +-INTR_X86_MMX_PACKUSWB = 542 +-INTR_X86_MMX_PADD_B = 543 +-INTR_X86_MMX_PADD_D = 544 +-INTR_X86_MMX_PADD_Q = 545 +-INTR_X86_MMX_PADD_W = 546 +-INTR_X86_MMX_PADDS_B = 547 +-INTR_X86_MMX_PADDS_W = 548 +-INTR_X86_MMX_PADDUS_B = 549 +-INTR_X86_MMX_PADDUS_W = 550 +-INTR_X86_MMX_PAND = 551 +-INTR_X86_MMX_PANDN = 552 +-INTR_X86_MMX_PAVG_B = 553 +-INTR_X86_MMX_PAVG_W = 554 +-INTR_X86_MMX_PCMPEQ_B = 555 +-INTR_X86_MMX_PCMPEQ_D = 556 +-INTR_X86_MMX_PCMPEQ_W = 557 +-INTR_X86_MMX_PCMPGT_B = 558 +-INTR_X86_MMX_PCMPGT_D = 559 +-INTR_X86_MMX_PCMPGT_W = 560 +-INTR_X86_MMX_PEXTR_W = 561 +-INTR_X86_MMX_PINSR_W = 562 +-INTR_X86_MMX_PMADD_WD = 563 +-INTR_X86_MMX_PMAXS_W = 564 +-INTR_X86_MMX_PMAXU_B = 565 +-INTR_X86_MMX_PMINS_W = 566 +-INTR_X86_MMX_PMINU_B = 567 +-INTR_X86_MMX_PMOVMSKB = 568 +-INTR_X86_MMX_PMULH_W = 569 +-INTR_X86_MMX_PMULHU_W = 570 +-INTR_X86_MMX_PMULL_W = 571 +-INTR_X86_MMX_PMULU_DQ = 572 +-INTR_X86_MMX_POR = 573 +-INTR_X86_MMX_PSAD_BW = 574 +-INTR_X86_MMX_PSLL_D = 575 +-INTR_X86_MMX_PSLL_Q = 576 +-INTR_X86_MMX_PSLL_W = 577 +-INTR_X86_MMX_PSLLI_D = 578 +-INTR_X86_MMX_PSLLI_Q = 579 +-INTR_X86_MMX_PSLLI_W = 580 +-INTR_X86_MMX_PSRA_D = 581 +-INTR_X86_MMX_PSRA_W = 582 +-INTR_X86_MMX_PSRAI_D = 583 +-INTR_X86_MMX_PSRAI_W = 584 +-INTR_X86_MMX_PSRL_D = 585 +-INTR_X86_MMX_PSRL_Q = 586 +-INTR_X86_MMX_PSRL_W = 587 +-INTR_X86_MMX_PSRLI_D = 588 +-INTR_X86_MMX_PSRLI_Q = 589 +-INTR_X86_MMX_PSRLI_W = 590 +-INTR_X86_MMX_PSUB_B = 591 +-INTR_X86_MMX_PSUB_D = 592 +-INTR_X86_MMX_PSUB_Q = 593 +-INTR_X86_MMX_PSUB_W = 594 +-INTR_X86_MMX_PSUBS_B = 595 +-INTR_X86_MMX_PSUBS_W = 596 +-INTR_X86_MMX_PSUBUS_B = 597 +-INTR_X86_MMX_PSUBUS_W = 598 +-INTR_X86_MMX_PUNPCKHBW = 599 +-INTR_X86_MMX_PUNPCKHDQ = 600 +-INTR_X86_MMX_PUNPCKHWD = 601 +-INTR_X86_MMX_PUNPCKLBW = 602 +-INTR_X86_MMX_PUNPCKLDQ = 603 +-INTR_X86_MMX_PUNPCKLWD = 604 +-INTR_X86_MMX_PXOR = 605 +-INTR_X86_MMX_VEC_EXT_D = 606 +-INTR_X86_MMX_VEC_INIT_B = 607 +-INTR_X86_MMX_VEC_INIT_D = 608 +-INTR_X86_MMX_VEC_INIT_W = 609 +-INTR_X86_SSE2_ADD_SD = 610 +-INTR_X86_SSE2_CLFLUSH = 611 +-INTR_X86_SSE2_CMP_PD = 612 +-INTR_X86_SSE2_CMP_SD = 613 +-INTR_X86_SSE2_COMIEQ_SD = 614 +-INTR_X86_SSE2_COMIGE_SD = 615 +-INTR_X86_SSE2_COMIGT_SD = 616 +-INTR_X86_SSE2_COMILE_SD = 617 +-INTR_X86_SSE2_COMILT_SD = 618 +-INTR_X86_SSE2_COMINEQ_SD = 619 +-INTR_X86_SSE2_CVTDQ2PD = 620 +-INTR_X86_SSE2_CVTDQ2PS = 621 +-INTR_X86_SSE2_CVTPD2DQ = 622 +-INTR_X86_SSE2_CVTPD2PS = 623 +-INTR_X86_SSE2_CVTPS2DQ = 624 +-INTR_X86_SSE2_CVTPS2PD = 625 +-INTR_X86_SSE2_CVTSD2SI = 626 +-INTR_X86_SSE2_CVTSD2SI64 = 627 +-INTR_X86_SSE2_CVTSD2SS = 628 +-INTR_X86_SSE2_CVTSI2SD = 629 +-INTR_X86_SSE2_CVTSI642SD = 630 +-INTR_X86_SSE2_CVTSS2SD = 631 +-INTR_X86_SSE2_CVTTPD2DQ = 632 +-INTR_X86_SSE2_CVTTPS2DQ = 633 +-INTR_X86_SSE2_CVTTSD2SI = 634 +-INTR_X86_SSE2_CVTTSD2SI64 = 635 +-INTR_X86_SSE2_DIV_SD = 636 +-INTR_X86_SSE2_LFENCE = 637 +-INTR_X86_SSE2_LOADU_DQ = 638 +-INTR_X86_SSE2_LOADU_PD = 639 +-INTR_X86_SSE2_MASKMOV_DQU = 640 +-INTR_X86_SSE2_MAX_PD = 641 +-INTR_X86_SSE2_MAX_SD = 642 +-INTR_X86_SSE2_MFENCE = 643 +-INTR_X86_SSE2_MIN_PD = 644 +-INTR_X86_SSE2_MIN_SD = 645 +-INTR_X86_SSE2_MOVMSK_PD = 646 +-INTR_X86_SSE2_MOVNT_DQ = 647 +-INTR_X86_SSE2_MOVNT_I = 648 +-INTR_X86_SSE2_MOVNT_PD = 649 +-INTR_X86_SSE2_MUL_SD = 650 +-INTR_X86_SSE2_PACKSSDW_128 = 651 +-INTR_X86_SSE2_PACKSSWB_128 = 652 +-INTR_X86_SSE2_PACKUSWB_128 = 653 +-INTR_X86_SSE2_PADDS_B = 654 +-INTR_X86_SSE2_PADDS_W = 655 +-INTR_X86_SSE2_PADDUS_B = 656 +-INTR_X86_SSE2_PADDUS_W = 657 +-INTR_X86_SSE2_PAVG_B = 658 +-INTR_X86_SSE2_PAVG_W = 659 +-INTR_X86_SSE2_PCMPEQ_B = 660 +-INTR_X86_SSE2_PCMPEQ_D = 661 +-INTR_X86_SSE2_PCMPEQ_W = 662 +-INTR_X86_SSE2_PCMPGT_B = 663 +-INTR_X86_SSE2_PCMPGT_D = 664 +-INTR_X86_SSE2_PCMPGT_W = 665 +-INTR_X86_SSE2_PMADD_WD = 666 +-INTR_X86_SSE2_PMAXS_W = 667 +-INTR_X86_SSE2_PMAXU_B = 668 +-INTR_X86_SSE2_PMINS_W = 669 +-INTR_X86_SSE2_PMINU_B = 670 +-INTR_X86_SSE2_PMOVMSKB_128 = 671 +-INTR_X86_SSE2_PMULH_W = 672 +-INTR_X86_SSE2_PMULHU_W = 673 +-INTR_X86_SSE2_PMULU_DQ = 674 +-INTR_X86_SSE2_PSAD_BW = 675 +-INTR_X86_SSE2_PSLL_D = 676 +-INTR_X86_SSE2_PSLL_DQ = 677 +-INTR_X86_SSE2_PSLL_DQ_BS = 678 +-INTR_X86_SSE2_PSLL_Q = 679 +-INTR_X86_SSE2_PSLL_W = 680 +-INTR_X86_SSE2_PSLLI_D = 681 +-INTR_X86_SSE2_PSLLI_Q = 682 +-INTR_X86_SSE2_PSLLI_W = 683 +-INTR_X86_SSE2_PSRA_D = 684 +-INTR_X86_SSE2_PSRA_W = 685 +-INTR_X86_SSE2_PSRAI_D = 686 +-INTR_X86_SSE2_PSRAI_W = 687 +-INTR_X86_SSE2_PSRL_D = 688 +-INTR_X86_SSE2_PSRL_DQ = 689 +-INTR_X86_SSE2_PSRL_DQ_BS = 690 +-INTR_X86_SSE2_PSRL_Q = 691 +-INTR_X86_SSE2_PSRL_W = 692 +-INTR_X86_SSE2_PSRLI_D = 693 +-INTR_X86_SSE2_PSRLI_Q = 694 +-INTR_X86_SSE2_PSRLI_W = 695 +-INTR_X86_SSE2_PSUBS_B = 696 +-INTR_X86_SSE2_PSUBS_W = 697 +-INTR_X86_SSE2_PSUBUS_B = 698 +-INTR_X86_SSE2_PSUBUS_W = 699 +-INTR_X86_SSE2_SQRT_PD = 700 +-INTR_X86_SSE2_SQRT_SD = 701 +-INTR_X86_SSE2_STOREL_DQ = 702 +-INTR_X86_SSE2_STOREU_DQ = 703 +-INTR_X86_SSE2_STOREU_PD = 704 +-INTR_X86_SSE2_SUB_SD = 705 +-INTR_X86_SSE2_UCOMIEQ_SD = 706 +-INTR_X86_SSE2_UCOMIGE_SD = 707 +-INTR_X86_SSE2_UCOMIGT_SD = 708 +-INTR_X86_SSE2_UCOMILE_SD = 709 +-INTR_X86_SSE2_UCOMILT_SD = 710 +-INTR_X86_SSE2_UCOMINEQ_SD = 711 +-INTR_X86_SSE3_ADDSUB_PD = 712 +-INTR_X86_SSE3_ADDSUB_PS = 713 +-INTR_X86_SSE3_HADD_PD = 714 +-INTR_X86_SSE3_HADD_PS = 715 +-INTR_X86_SSE3_HSUB_PD = 716 +-INTR_X86_SSE3_HSUB_PS = 717 +-INTR_X86_SSE3_LDU_DQ = 718 +-INTR_X86_SSE3_MONITOR = 719 +-INTR_X86_SSE3_MWAIT = 720 +-INTR_X86_SSE41_BLENDPD = 721 +-INTR_X86_SSE41_BLENDPS = 722 +-INTR_X86_SSE41_BLENDVPD = 723 +-INTR_X86_SSE41_BLENDVPS = 724 +-INTR_X86_SSE41_DPPD = 725 +-INTR_X86_SSE41_DPPS = 726 +-INTR_X86_SSE41_EXTRACTPS = 727 +-INTR_X86_SSE41_INSERTPS = 728 +-INTR_X86_SSE41_MOVNTDQA = 729 +-INTR_X86_SSE41_MPSADBW = 730 +-INTR_X86_SSE41_PACKUSDW = 731 +-INTR_X86_SSE41_PBLENDVB = 732 +-INTR_X86_SSE41_PBLENDW = 733 +-INTR_X86_SSE41_PCMPEQQ = 734 +-INTR_X86_SSE41_PEXTRB = 735 +-INTR_X86_SSE41_PEXTRD = 736 +-INTR_X86_SSE41_PEXTRQ = 737 +-INTR_X86_SSE41_PHMINPOSUW = 738 +-INTR_X86_SSE41_PMAXSB = 739 +-INTR_X86_SSE41_PMAXSD = 740 +-INTR_X86_SSE41_PMAXUD = 741 +-INTR_X86_SSE41_PMAXUW = 742 +-INTR_X86_SSE41_PMINSB = 743 +-INTR_X86_SSE41_PMINSD = 744 +-INTR_X86_SSE41_PMINUD = 745 +-INTR_X86_SSE41_PMINUW = 746 +-INTR_X86_SSE41_PMOVSXBD = 747 +-INTR_X86_SSE41_PMOVSXBQ = 748 +-INTR_X86_SSE41_PMOVSXBW = 749 +-INTR_X86_SSE41_PMOVSXDQ = 750 +-INTR_X86_SSE41_PMOVSXWD = 751 +-INTR_X86_SSE41_PMOVSXWQ = 752 +-INTR_X86_SSE41_PMOVZXBD = 753 +-INTR_X86_SSE41_PMOVZXBQ = 754 +-INTR_X86_SSE41_PMOVZXBW = 755 +-INTR_X86_SSE41_PMOVZXDQ = 756 +-INTR_X86_SSE41_PMOVZXWD = 757 +-INTR_X86_SSE41_PMOVZXWQ = 758 +-INTR_X86_SSE41_PMULDQ = 759 +-INTR_X86_SSE41_PTESTC = 760 +-INTR_X86_SSE41_PTESTNZC = 761 +-INTR_X86_SSE41_PTESTZ = 762 +-INTR_X86_SSE41_ROUND_PD = 763 +-INTR_X86_SSE41_ROUND_PS = 764 +-INTR_X86_SSE41_ROUND_SD = 765 +-INTR_X86_SSE41_ROUND_SS = 766 +-INTR_X86_SSE42_CRC32_16 = 767 +-INTR_X86_SSE42_CRC32_32 = 768 +-INTR_X86_SSE42_CRC32_8 = 769 +-INTR_X86_SSE42_CRC64_64 = 770 +-INTR_X86_SSE42_CRC64_8 = 771 +-INTR_X86_SSE42_PCMPESTRI128 = 772 +-INTR_X86_SSE42_PCMPESTRIA128 = 773 +-INTR_X86_SSE42_PCMPESTRIC128 = 774 +-INTR_X86_SSE42_PCMPESTRIO128 = 775 +-INTR_X86_SSE42_PCMPESTRIS128 = 776 +-INTR_X86_SSE42_PCMPESTRIZ128 = 777 +-INTR_X86_SSE42_PCMPESTRM128 = 778 +-INTR_X86_SSE42_PCMPGTQ = 779 +-INTR_X86_SSE42_PCMPISTRI128 = 780 +-INTR_X86_SSE42_PCMPISTRIA128 = 781 +-INTR_X86_SSE42_PCMPISTRIC128 = 782 +-INTR_X86_SSE42_PCMPISTRIO128 = 783 +-INTR_X86_SSE42_PCMPISTRIS128 = 784 +-INTR_X86_SSE42_PCMPISTRIZ128 = 785 +-INTR_X86_SSE42_PCMPISTRM128 = 786 +-INTR_X86_SSE_ADD_SS = 787 +-INTR_X86_SSE_CMP_PS = 788 +-INTR_X86_SSE_CMP_SS = 789 +-INTR_X86_SSE_COMIEQ_SS = 790 +-INTR_X86_SSE_COMIGE_SS = 791 +-INTR_X86_SSE_COMIGT_SS = 792 +-INTR_X86_SSE_COMILE_SS = 793 +-INTR_X86_SSE_COMILT_SS = 794 +-INTR_X86_SSE_COMINEQ_SS = 795 +-INTR_X86_SSE_CVTPD2PI = 796 +-INTR_X86_SSE_CVTPI2PD = 797 +-INTR_X86_SSE_CVTPI2PS = 798 +-INTR_X86_SSE_CVTPS2PI = 799 +-INTR_X86_SSE_CVTSI2SS = 800 +-INTR_X86_SSE_CVTSI642SS = 801 +-INTR_X86_SSE_CVTSS2SI = 802 +-INTR_X86_SSE_CVTSS2SI64 = 803 +-INTR_X86_SSE_CVTTPD2PI = 804 +-INTR_X86_SSE_CVTTPS2PI = 805 +-INTR_X86_SSE_CVTTSS2SI = 806 +-INTR_X86_SSE_CVTTSS2SI64 = 807 +-INTR_X86_SSE_DIV_SS = 808 +-INTR_X86_SSE_LDMXCSR = 809 +-INTR_X86_SSE_LOADU_PS = 810 +-INTR_X86_SSE_MAX_PS = 811 +-INTR_X86_SSE_MAX_SS = 812 +-INTR_X86_SSE_MIN_PS = 813 +-INTR_X86_SSE_MIN_SS = 814 +-INTR_X86_SSE_MOVMSK_PS = 815 +-INTR_X86_SSE_MOVNT_PS = 816 +-INTR_X86_SSE_MUL_SS = 817 +-INTR_X86_SSE_RCP_PS = 818 +-INTR_X86_SSE_RCP_SS = 819 +-INTR_X86_SSE_RSQRT_PS = 820 +-INTR_X86_SSE_RSQRT_SS = 821 +-INTR_X86_SSE_SFENCE = 822 +-INTR_X86_SSE_SQRT_PS = 823 +-INTR_X86_SSE_SQRT_SS = 824 +-INTR_X86_SSE_STMXCSR = 825 +-INTR_X86_SSE_STOREU_PS = 826 +-INTR_X86_SSE_SUB_SS = 827 +-INTR_X86_SSE_UCOMIEQ_SS = 828 +-INTR_X86_SSE_UCOMIGE_SS = 829 +-INTR_X86_SSE_UCOMIGT_SS = 830 +-INTR_X86_SSE_UCOMILE_SS = 831 +-INTR_X86_SSE_UCOMILT_SS = 832 +-INTR_X86_SSE_UCOMINEQ_SS = 833 +-INTR_X86_SSSE3_PABS_B = 834 +-INTR_X86_SSSE3_PABS_B_128 = 835 +-INTR_X86_SSSE3_PABS_D = 836 +-INTR_X86_SSSE3_PABS_D_128 = 837 +-INTR_X86_SSSE3_PABS_W = 838 +-INTR_X86_SSSE3_PABS_W_128 = 839 +-INTR_X86_SSSE3_PHADD_D = 840 +-INTR_X86_SSSE3_PHADD_D_128 = 841 +-INTR_X86_SSSE3_PHADD_SW = 842 +-INTR_X86_SSSE3_PHADD_SW_128 = 843 +-INTR_X86_SSSE3_PHADD_W = 844 +-INTR_X86_SSSE3_PHADD_W_128 = 845 +-INTR_X86_SSSE3_PHSUB_D = 846 +-INTR_X86_SSSE3_PHSUB_D_128 = 847 +-INTR_X86_SSSE3_PHSUB_SW = 848 +-INTR_X86_SSSE3_PHSUB_SW_128 = 849 +-INTR_X86_SSSE3_PHSUB_W = 850 +-INTR_X86_SSSE3_PHSUB_W_128 = 851 +-INTR_X86_SSSE3_PMADD_UB_SW = 852 +-INTR_X86_SSSE3_PMADD_UB_SW_128 = 853 +-INTR_X86_SSSE3_PMUL_HR_SW = 854 +-INTR_X86_SSSE3_PMUL_HR_SW_128 = 855 +-INTR_X86_SSSE3_PSHUF_B = 856 +-INTR_X86_SSSE3_PSHUF_B_128 = 857 +-INTR_X86_SSSE3_PSHUF_W = 858 +-INTR_X86_SSSE3_PSIGN_B = 859 +-INTR_X86_SSSE3_PSIGN_B_128 = 860 +-INTR_X86_SSSE3_PSIGN_D = 861 +-INTR_X86_SSSE3_PSIGN_D_128 = 862 +-INTR_X86_SSSE3_PSIGN_W = 863 +-INTR_X86_SSSE3_PSIGN_W_128 = 864 +-INTR_XCORE_BITREV = 865 +-INTR_XCORE_GETID = 866 +- ++INTR_ARM_NEON_VCVTFP2HF = 17 ++INTR_ARM_NEON_VCVTFXS2FP = 18 ++INTR_ARM_NEON_VCVTFXU2FP = 19 ++INTR_ARM_NEON_VCVTHF2FP = 20 ++INTR_ARM_NEON_VHADDS = 21 ++INTR_ARM_NEON_VHADDU = 22 ++INTR_ARM_NEON_VHSUBS = 23 ++INTR_ARM_NEON_VHSUBU = 24 ++INTR_ARM_NEON_VLD1 = 25 ++INTR_ARM_NEON_VLD2 = 26 ++INTR_ARM_NEON_VLD2LANE = 27 ++INTR_ARM_NEON_VLD3 = 28 ++INTR_ARM_NEON_VLD3LANE = 29 ++INTR_ARM_NEON_VLD4 = 30 ++INTR_ARM_NEON_VLD4LANE = 31 ++INTR_ARM_NEON_VMAXS = 32 ++INTR_ARM_NEON_VMAXU = 33 ++INTR_ARM_NEON_VMINS = 34 ++INTR_ARM_NEON_VMINU = 35 ++INTR_ARM_NEON_VMULLP = 36 ++INTR_ARM_NEON_VMULP = 37 ++INTR_ARM_NEON_VPADALS = 38 ++INTR_ARM_NEON_VPADALU = 39 ++INTR_ARM_NEON_VPADD = 40 ++INTR_ARM_NEON_VPADDLS = 41 ++INTR_ARM_NEON_VPADDLU = 42 ++INTR_ARM_NEON_VPMAXS = 43 ++INTR_ARM_NEON_VPMAXU = 44 ++INTR_ARM_NEON_VPMINS = 45 ++INTR_ARM_NEON_VPMINU = 46 ++INTR_ARM_NEON_VQABS = 47 ++INTR_ARM_NEON_VQADDS = 48 ++INTR_ARM_NEON_VQADDU = 49 ++INTR_ARM_NEON_VQDMLAL = 50 ++INTR_ARM_NEON_VQDMLSL = 51 ++INTR_ARM_NEON_VQDMULH = 52 ++INTR_ARM_NEON_VQDMULL = 53 ++INTR_ARM_NEON_VQMOVNS = 54 ++INTR_ARM_NEON_VQMOVNSU = 55 ++INTR_ARM_NEON_VQMOVNU = 56 ++INTR_ARM_NEON_VQNEG = 57 ++INTR_ARM_NEON_VQRDMULH = 58 ++INTR_ARM_NEON_VQRSHIFTNS = 59 ++INTR_ARM_NEON_VQRSHIFTNSU = 60 ++INTR_ARM_NEON_VQRSHIFTNU = 61 ++INTR_ARM_NEON_VQRSHIFTS = 62 ++INTR_ARM_NEON_VQRSHIFTU = 63 ++INTR_ARM_NEON_VQSHIFTNS = 64 ++INTR_ARM_NEON_VQSHIFTNSU = 65 ++INTR_ARM_NEON_VQSHIFTNU = 66 ++INTR_ARM_NEON_VQSHIFTS = 67 ++INTR_ARM_NEON_VQSHIFTSU = 68 ++INTR_ARM_NEON_VQSHIFTU = 69 ++INTR_ARM_NEON_VQSUBS = 70 ++INTR_ARM_NEON_VQSUBU = 71 ++INTR_ARM_NEON_VRADDHN = 72 ++INTR_ARM_NEON_VRECPE = 73 ++INTR_ARM_NEON_VRECPS = 74 ++INTR_ARM_NEON_VRHADDS = 75 ++INTR_ARM_NEON_VRHADDU = 76 ++INTR_ARM_NEON_VRSHIFTN = 77 ++INTR_ARM_NEON_VRSHIFTS = 78 ++INTR_ARM_NEON_VRSHIFTU = 79 ++INTR_ARM_NEON_VRSQRTE = 80 ++INTR_ARM_NEON_VRSQRTS = 81 ++INTR_ARM_NEON_VRSUBHN = 82 ++INTR_ARM_NEON_VSHIFTINS = 83 ++INTR_ARM_NEON_VSHIFTLS = 84 ++INTR_ARM_NEON_VSHIFTLU = 85 ++INTR_ARM_NEON_VSHIFTN = 86 ++INTR_ARM_NEON_VSHIFTS = 87 ++INTR_ARM_NEON_VSHIFTU = 88 ++INTR_ARM_NEON_VST1 = 89 ++INTR_ARM_NEON_VST2 = 90 ++INTR_ARM_NEON_VST2LANE = 91 ++INTR_ARM_NEON_VST3 = 92 ++INTR_ARM_NEON_VST3LANE = 93 ++INTR_ARM_NEON_VST4 = 94 ++INTR_ARM_NEON_VST4LANE = 95 ++INTR_ARM_NEON_VSUBHN = 96 ++INTR_ARM_NEON_VTBL1 = 97 ++INTR_ARM_NEON_VTBL2 = 98 ++INTR_ARM_NEON_VTBL3 = 99 ++INTR_ARM_NEON_VTBL4 = 100 ++INTR_ARM_NEON_VTBX1 = 101 ++INTR_ARM_NEON_VTBX2 = 102 ++INTR_ARM_NEON_VTBX3 = 103 ++INTR_ARM_NEON_VTBX4 = 104 ++INTR_ARM_QADD = 105 ++INTR_ARM_QSUB = 106 ++INTR_ARM_SET_FPSCR = 107 ++INTR_ARM_SSAT = 108 ++INTR_ARM_THREAD_POINTER = 109 ++INTR_ARM_USAT = 110 ++INTR_ARM_VCVTR = 111 ++INTR_ARM_VCVTRU = 112 ++INTR_ATOMIC_CMP_SWAP = 113 ++INTR_ATOMIC_LOAD_ADD = 114 ++INTR_ATOMIC_LOAD_AND = 115 ++INTR_ATOMIC_LOAD_MAX = 116 ++INTR_ATOMIC_LOAD_MIN = 117 ++INTR_ATOMIC_LOAD_NAND = 118 ++INTR_ATOMIC_LOAD_OR = 119 ++INTR_ATOMIC_LOAD_SUB = 120 ++INTR_ATOMIC_LOAD_UMAX = 121 ++INTR_ATOMIC_LOAD_UMIN = 122 ++INTR_ATOMIC_LOAD_XOR = 123 ++INTR_ATOMIC_SWAP = 124 ++INTR_BSWAP = 125 ++INTR_CONVERT_FROM_FP16 = 126 ++INTR_CONVERT_TO_FP16 = 127 ++INTR_CONVERTFF = 128 ++INTR_CONVERTFSI = 129 ++INTR_CONVERTFUI = 130 ++INTR_CONVERTSIF = 131 ++INTR_CONVERTSS = 132 ++INTR_CONVERTSU = 133 ++INTR_CONVERTUIF = 134 ++INTR_CONVERTUS = 135 ++INTR_CONVERTUU = 136 ++INTR_COS = 137 ++INTR_CTLZ = 138 ++INTR_CTPOP = 139 ++INTR_CTTZ = 140 ++INTR_DBG_DECLARE = 141 ++INTR_DBG_VALUE = 142 ++INTR_EH_DWARF_CFA = 143 ++INTR_EH_EXCEPTION = 144 ++INTR_EH_RETURN_I32 = 145 ++INTR_EH_RETURN_I64 = 146 ++INTR_EH_SELECTOR = 147 ++INTR_EH_SJLJ_CALLSITE = 148 ++INTR_EH_SJLJ_DISPATCH_SETUP = 149 ++INTR_EH_SJLJ_LONGJMP = 150 ++INTR_EH_SJLJ_LSDA = 151 ++INTR_EH_SJLJ_SETJMP = 152 ++INTR_EH_TYPEID_FOR = 153 ++INTR_EH_UNWIND_INIT = 154 ++INTR_EXP = 155 ++INTR_EXP2 = 156 ++INTR_FLT_ROUNDS = 157 ++INTR_FRAMEADDRESS = 158 ++INTR_GCREAD = 159 ++INTR_GCROOT = 160 ++INTR_GCWRITE = 161 ++INTR_INIT_TRAMPOLINE = 162 ++INTR_INVARIANT_END = 163 ++INTR_INVARIANT_START = 164 ++INTR_LIFETIME_END = 165 ++INTR_LIFETIME_START = 166 ++INTR_LOG = 167 ++INTR_LOG10 = 168 ++INTR_LOG2 = 169 ++INTR_LONGJMP = 170 ++INTR_MEMCPY = 171 ++INTR_MEMMOVE = 172 ++INTR_MEMORY_BARRIER = 173 ++INTR_MEMSET = 174 ++INTR_OBJECTSIZE = 175 ++INTR_PCMARKER = 176 ++INTR_POW = 177 ++INTR_POWI = 178 ++INTR_PPC_ALTIVEC_DSS = 179 ++INTR_PPC_ALTIVEC_DSSALL = 180 ++INTR_PPC_ALTIVEC_DST = 181 ++INTR_PPC_ALTIVEC_DSTST = 182 ++INTR_PPC_ALTIVEC_DSTSTT = 183 ++INTR_PPC_ALTIVEC_DSTT = 184 ++INTR_PPC_ALTIVEC_LVEBX = 185 ++INTR_PPC_ALTIVEC_LVEHX = 186 ++INTR_PPC_ALTIVEC_LVEWX = 187 ++INTR_PPC_ALTIVEC_LVSL = 188 ++INTR_PPC_ALTIVEC_LVSR = 189 ++INTR_PPC_ALTIVEC_LVX = 190 ++INTR_PPC_ALTIVEC_LVXL = 191 ++INTR_PPC_ALTIVEC_MFVSCR = 192 ++INTR_PPC_ALTIVEC_MTVSCR = 193 ++INTR_PPC_ALTIVEC_STVEBX = 194 ++INTR_PPC_ALTIVEC_STVEHX = 195 ++INTR_PPC_ALTIVEC_STVEWX = 196 ++INTR_PPC_ALTIVEC_STVX = 197 ++INTR_PPC_ALTIVEC_STVXL = 198 ++INTR_PPC_ALTIVEC_VADDCUW = 199 ++INTR_PPC_ALTIVEC_VADDSBS = 200 ++INTR_PPC_ALTIVEC_VADDSHS = 201 ++INTR_PPC_ALTIVEC_VADDSWS = 202 ++INTR_PPC_ALTIVEC_VADDUBS = 203 ++INTR_PPC_ALTIVEC_VADDUHS = 204 ++INTR_PPC_ALTIVEC_VADDUWS = 205 ++INTR_PPC_ALTIVEC_VAVGSB = 206 ++INTR_PPC_ALTIVEC_VAVGSH = 207 ++INTR_PPC_ALTIVEC_VAVGSW = 208 ++INTR_PPC_ALTIVEC_VAVGUB = 209 ++INTR_PPC_ALTIVEC_VAVGUH = 210 ++INTR_PPC_ALTIVEC_VAVGUW = 211 ++INTR_PPC_ALTIVEC_VCFSX = 212 ++INTR_PPC_ALTIVEC_VCFUX = 213 ++INTR_PPC_ALTIVEC_VCMPBFP = 214 ++INTR_PPC_ALTIVEC_VCMPBFP_P = 215 ++INTR_PPC_ALTIVEC_VCMPEQFP = 216 ++INTR_PPC_ALTIVEC_VCMPEQFP_P = 217 ++INTR_PPC_ALTIVEC_VCMPEQUB = 218 ++INTR_PPC_ALTIVEC_VCMPEQUB_P = 219 ++INTR_PPC_ALTIVEC_VCMPEQUH = 220 ++INTR_PPC_ALTIVEC_VCMPEQUH_P = 221 ++INTR_PPC_ALTIVEC_VCMPEQUW = 222 ++INTR_PPC_ALTIVEC_VCMPEQUW_P = 223 ++INTR_PPC_ALTIVEC_VCMPGEFP = 224 ++INTR_PPC_ALTIVEC_VCMPGEFP_P = 225 ++INTR_PPC_ALTIVEC_VCMPGTFP = 226 ++INTR_PPC_ALTIVEC_VCMPGTFP_P = 227 ++INTR_PPC_ALTIVEC_VCMPGTSB = 228 ++INTR_PPC_ALTIVEC_VCMPGTSB_P = 229 ++INTR_PPC_ALTIVEC_VCMPGTSH = 230 ++INTR_PPC_ALTIVEC_VCMPGTSH_P = 231 ++INTR_PPC_ALTIVEC_VCMPGTSW = 232 ++INTR_PPC_ALTIVEC_VCMPGTSW_P = 233 ++INTR_PPC_ALTIVEC_VCMPGTUB = 234 ++INTR_PPC_ALTIVEC_VCMPGTUB_P = 235 ++INTR_PPC_ALTIVEC_VCMPGTUH = 236 ++INTR_PPC_ALTIVEC_VCMPGTUH_P = 237 ++INTR_PPC_ALTIVEC_VCMPGTUW = 238 ++INTR_PPC_ALTIVEC_VCMPGTUW_P = 239 ++INTR_PPC_ALTIVEC_VCTSXS = 240 ++INTR_PPC_ALTIVEC_VCTUXS = 241 ++INTR_PPC_ALTIVEC_VEXPTEFP = 242 ++INTR_PPC_ALTIVEC_VLOGEFP = 243 ++INTR_PPC_ALTIVEC_VMADDFP = 244 ++INTR_PPC_ALTIVEC_VMAXFP = 245 ++INTR_PPC_ALTIVEC_VMAXSB = 246 ++INTR_PPC_ALTIVEC_VMAXSH = 247 ++INTR_PPC_ALTIVEC_VMAXSW = 248 ++INTR_PPC_ALTIVEC_VMAXUB = 249 ++INTR_PPC_ALTIVEC_VMAXUH = 250 ++INTR_PPC_ALTIVEC_VMAXUW = 251 ++INTR_PPC_ALTIVEC_VMHADDSHS = 252 ++INTR_PPC_ALTIVEC_VMHRADDSHS = 253 ++INTR_PPC_ALTIVEC_VMINFP = 254 ++INTR_PPC_ALTIVEC_VMINSB = 255 ++INTR_PPC_ALTIVEC_VMINSH = 256 ++INTR_PPC_ALTIVEC_VMINSW = 257 ++INTR_PPC_ALTIVEC_VMINUB = 258 ++INTR_PPC_ALTIVEC_VMINUH = 259 ++INTR_PPC_ALTIVEC_VMINUW = 260 ++INTR_PPC_ALTIVEC_VMLADDUHM = 261 ++INTR_PPC_ALTIVEC_VMSUMMBM = 262 ++INTR_PPC_ALTIVEC_VMSUMSHM = 263 ++INTR_PPC_ALTIVEC_VMSUMSHS = 264 ++INTR_PPC_ALTIVEC_VMSUMUBM = 265 ++INTR_PPC_ALTIVEC_VMSUMUHM = 266 ++INTR_PPC_ALTIVEC_VMSUMUHS = 267 ++INTR_PPC_ALTIVEC_VMULESB = 268 ++INTR_PPC_ALTIVEC_VMULESH = 269 ++INTR_PPC_ALTIVEC_VMULEUB = 270 ++INTR_PPC_ALTIVEC_VMULEUH = 271 ++INTR_PPC_ALTIVEC_VMULOSB = 272 ++INTR_PPC_ALTIVEC_VMULOSH = 273 ++INTR_PPC_ALTIVEC_VMULOUB = 274 ++INTR_PPC_ALTIVEC_VMULOUH = 275 ++INTR_PPC_ALTIVEC_VNMSUBFP = 276 ++INTR_PPC_ALTIVEC_VPERM = 277 ++INTR_PPC_ALTIVEC_VPKPX = 278 ++INTR_PPC_ALTIVEC_VPKSHSS = 279 ++INTR_PPC_ALTIVEC_VPKSHUS = 280 ++INTR_PPC_ALTIVEC_VPKSWSS = 281 ++INTR_PPC_ALTIVEC_VPKSWUS = 282 ++INTR_PPC_ALTIVEC_VPKUHUS = 283 ++INTR_PPC_ALTIVEC_VPKUWUS = 284 ++INTR_PPC_ALTIVEC_VREFP = 285 ++INTR_PPC_ALTIVEC_VRFIM = 286 ++INTR_PPC_ALTIVEC_VRFIN = 287 ++INTR_PPC_ALTIVEC_VRFIP = 288 ++INTR_PPC_ALTIVEC_VRFIZ = 289 ++INTR_PPC_ALTIVEC_VRLB = 290 ++INTR_PPC_ALTIVEC_VRLH = 291 ++INTR_PPC_ALTIVEC_VRLW = 292 ++INTR_PPC_ALTIVEC_VRSQRTEFP = 293 ++INTR_PPC_ALTIVEC_VSEL = 294 ++INTR_PPC_ALTIVEC_VSL = 295 ++INTR_PPC_ALTIVEC_VSLB = 296 ++INTR_PPC_ALTIVEC_VSLH = 297 ++INTR_PPC_ALTIVEC_VSLO = 298 ++INTR_PPC_ALTIVEC_VSLW = 299 ++INTR_PPC_ALTIVEC_VSR = 300 ++INTR_PPC_ALTIVEC_VSRAB = 301 ++INTR_PPC_ALTIVEC_VSRAH = 302 ++INTR_PPC_ALTIVEC_VSRAW = 303 ++INTR_PPC_ALTIVEC_VSRB = 304 ++INTR_PPC_ALTIVEC_VSRH = 305 ++INTR_PPC_ALTIVEC_VSRO = 306 ++INTR_PPC_ALTIVEC_VSRW = 307 ++INTR_PPC_ALTIVEC_VSUBCUW = 308 ++INTR_PPC_ALTIVEC_VSUBSBS = 309 ++INTR_PPC_ALTIVEC_VSUBSHS = 310 ++INTR_PPC_ALTIVEC_VSUBSWS = 311 ++INTR_PPC_ALTIVEC_VSUBUBS = 312 ++INTR_PPC_ALTIVEC_VSUBUHS = 313 ++INTR_PPC_ALTIVEC_VSUBUWS = 314 ++INTR_PPC_ALTIVEC_VSUM2SWS = 315 ++INTR_PPC_ALTIVEC_VSUM4SBS = 316 ++INTR_PPC_ALTIVEC_VSUM4SHS = 317 ++INTR_PPC_ALTIVEC_VSUM4UBS = 318 ++INTR_PPC_ALTIVEC_VSUMSWS = 319 ++INTR_PPC_ALTIVEC_VUPKHPX = 320 ++INTR_PPC_ALTIVEC_VUPKHSB = 321 ++INTR_PPC_ALTIVEC_VUPKHSH = 322 ++INTR_PPC_ALTIVEC_VUPKLPX = 323 ++INTR_PPC_ALTIVEC_VUPKLSB = 324 ++INTR_PPC_ALTIVEC_VUPKLSH = 325 ++INTR_PPC_DCBA = 326 ++INTR_PPC_DCBF = 327 ++INTR_PPC_DCBI = 328 ++INTR_PPC_DCBST = 329 ++INTR_PPC_DCBT = 330 ++INTR_PPC_DCBTST = 331 ++INTR_PPC_DCBZ = 332 ++INTR_PPC_DCBZL = 333 ++INTR_PPC_SYNC = 334 ++INTR_PREFETCH = 335 ++INTR_PTR_ANNOTATION = 336 ++INTR_PTX_BAR_SYNC = 337 ++INTR_PTX_READ_TID_R64 = 338 ++INTR_PTX_READ_TID_V4I16 = 339 ++INTR_PTX_READ_TID_W = 340 ++INTR_PTX_READ_TID_X = 341 ++INTR_PTX_READ_TID_Y = 342 ++INTR_PTX_READ_TID_Z = 343 ++INTR_READCYCLECOUNTER = 344 ++INTR_RETURNADDRESS = 345 ++INTR_SADD_WITH_OVERFLOW = 346 ++INTR_SETJMP = 347 ++INTR_SIGLONGJMP = 348 ++INTR_SIGSETJMP = 349 ++INTR_SIN = 350 ++INTR_SMUL_WITH_OVERFLOW = 351 ++INTR_SPU_SI_A = 352 ++INTR_SPU_SI_ADDX = 353 ++INTR_SPU_SI_AH = 354 ++INTR_SPU_SI_AHI = 355 ++INTR_SPU_SI_AI = 356 ++INTR_SPU_SI_AND = 357 ++INTR_SPU_SI_ANDBI = 358 ++INTR_SPU_SI_ANDC = 359 ++INTR_SPU_SI_ANDHI = 360 ++INTR_SPU_SI_ANDI = 361 ++INTR_SPU_SI_BG = 362 ++INTR_SPU_SI_BGX = 363 ++INTR_SPU_SI_CEQ = 364 ++INTR_SPU_SI_CEQB = 365 ++INTR_SPU_SI_CEQBI = 366 ++INTR_SPU_SI_CEQH = 367 ++INTR_SPU_SI_CEQHI = 368 ++INTR_SPU_SI_CEQI = 369 ++INTR_SPU_SI_CG = 370 ++INTR_SPU_SI_CGT = 371 ++INTR_SPU_SI_CGTB = 372 ++INTR_SPU_SI_CGTBI = 373 ++INTR_SPU_SI_CGTH = 374 ++INTR_SPU_SI_CGTHI = 375 ++INTR_SPU_SI_CGTI = 376 ++INTR_SPU_SI_CGX = 377 ++INTR_SPU_SI_CLGT = 378 ++INTR_SPU_SI_CLGTB = 379 ++INTR_SPU_SI_CLGTBI = 380 ++INTR_SPU_SI_CLGTH = 381 ++INTR_SPU_SI_CLGTHI = 382 ++INTR_SPU_SI_CLGTI = 383 ++INTR_SPU_SI_DFA = 384 ++INTR_SPU_SI_DFM = 385 ++INTR_SPU_SI_DFMA = 386 ++INTR_SPU_SI_DFMS = 387 ++INTR_SPU_SI_DFNMA = 388 ++INTR_SPU_SI_DFNMS = 389 ++INTR_SPU_SI_DFS = 390 ++INTR_SPU_SI_FA = 391 ++INTR_SPU_SI_FCEQ = 392 ++INTR_SPU_SI_FCGT = 393 ++INTR_SPU_SI_FCMEQ = 394 ++INTR_SPU_SI_FCMGT = 395 ++INTR_SPU_SI_FM = 396 ++INTR_SPU_SI_FMA = 397 ++INTR_SPU_SI_FMS = 398 ++INTR_SPU_SI_FNMS = 399 ++INTR_SPU_SI_FS = 400 ++INTR_SPU_SI_FSMBI = 401 ++INTR_SPU_SI_MPY = 402 ++INTR_SPU_SI_MPYA = 403 ++INTR_SPU_SI_MPYH = 404 ++INTR_SPU_SI_MPYHH = 405 ++INTR_SPU_SI_MPYHHA = 406 ++INTR_SPU_SI_MPYHHAU = 407 ++INTR_SPU_SI_MPYHHU = 408 ++INTR_SPU_SI_MPYI = 409 ++INTR_SPU_SI_MPYS = 410 ++INTR_SPU_SI_MPYU = 411 ++INTR_SPU_SI_MPYUI = 412 ++INTR_SPU_SI_NAND = 413 ++INTR_SPU_SI_NOR = 414 ++INTR_SPU_SI_OR = 415 ++INTR_SPU_SI_ORBI = 416 ++INTR_SPU_SI_ORC = 417 ++INTR_SPU_SI_ORHI = 418 ++INTR_SPU_SI_ORI = 419 ++INTR_SPU_SI_SF = 420 ++INTR_SPU_SI_SFH = 421 ++INTR_SPU_SI_SFHI = 422 ++INTR_SPU_SI_SFI = 423 ++INTR_SPU_SI_SFX = 424 ++INTR_SPU_SI_SHLI = 425 ++INTR_SPU_SI_SHLQBI = 426 ++INTR_SPU_SI_SHLQBII = 427 ++INTR_SPU_SI_SHLQBY = 428 ++INTR_SPU_SI_SHLQBYI = 429 ++INTR_SPU_SI_XOR = 430 ++INTR_SPU_SI_XORBI = 431 ++INTR_SPU_SI_XORHI = 432 ++INTR_SPU_SI_XORI = 433 ++INTR_SQRT = 434 ++INTR_SSUB_WITH_OVERFLOW = 435 ++INTR_STACKPROTECTOR = 436 ++INTR_STACKRESTORE = 437 ++INTR_STACKSAVE = 438 ++INTR_TRAP = 439 ++INTR_UADD_WITH_OVERFLOW = 440 ++INTR_UMUL_WITH_OVERFLOW = 441 ++INTR_USUB_WITH_OVERFLOW = 442 ++INTR_VACOPY = 443 ++INTR_VAEND = 444 ++INTR_VAR_ANNOTATION = 445 ++INTR_VASTART = 446 ++INTR_X86_AESNI_AESDEC = 447 ++INTR_X86_AESNI_AESDECLAST = 448 ++INTR_X86_AESNI_AESENC = 449 ++INTR_X86_AESNI_AESENCLAST = 450 ++INTR_X86_AESNI_AESIMC = 451 ++INTR_X86_AESNI_AESKEYGENASSIST = 452 ++INTR_X86_AVX_ADDSUB_PD_256 = 453 ++INTR_X86_AVX_ADDSUB_PS_256 = 454 ++INTR_X86_AVX_BLEND_PD_256 = 455 ++INTR_X86_AVX_BLEND_PS_256 = 456 ++INTR_X86_AVX_BLENDV_PD_256 = 457 ++INTR_X86_AVX_BLENDV_PS_256 = 458 ++INTR_X86_AVX_CMP_PD_256 = 459 ++INTR_X86_AVX_CMP_PS_256 = 460 ++INTR_X86_AVX_CVT_PD2_PS_256 = 461 ++INTR_X86_AVX_CVT_PD2DQ_256 = 462 ++INTR_X86_AVX_CVT_PS2_PD_256 = 463 ++INTR_X86_AVX_CVT_PS2DQ_256 = 464 ++INTR_X86_AVX_CVTDQ2_PD_256 = 465 ++INTR_X86_AVX_CVTDQ2_PS_256 = 466 ++INTR_X86_AVX_CVTT_PD2DQ_256 = 467 ++INTR_X86_AVX_CVTT_PS2DQ_256 = 468 ++INTR_X86_AVX_DP_PS_256 = 469 ++INTR_X86_AVX_HADD_PD_256 = 470 ++INTR_X86_AVX_HADD_PS_256 = 471 ++INTR_X86_AVX_HSUB_PD_256 = 472 ++INTR_X86_AVX_HSUB_PS_256 = 473 ++INTR_X86_AVX_LDU_DQ_256 = 474 ++INTR_X86_AVX_LOADU_DQ_256 = 475 ++INTR_X86_AVX_LOADU_PD_256 = 476 ++INTR_X86_AVX_LOADU_PS_256 = 477 ++INTR_X86_AVX_MASKLOAD_PD = 478 ++INTR_X86_AVX_MASKLOAD_PD_256 = 479 ++INTR_X86_AVX_MASKLOAD_PS = 480 ++INTR_X86_AVX_MASKLOAD_PS_256 = 481 ++INTR_X86_AVX_MASKSTORE_PD = 482 ++INTR_X86_AVX_MASKSTORE_PD_256 = 483 ++INTR_X86_AVX_MASKSTORE_PS = 484 ++INTR_X86_AVX_MASKSTORE_PS_256 = 485 ++INTR_X86_AVX_MAX_PD_256 = 486 ++INTR_X86_AVX_MAX_PS_256 = 487 ++INTR_X86_AVX_MIN_PD_256 = 488 ++INTR_X86_AVX_MIN_PS_256 = 489 ++INTR_X86_AVX_MOVMSK_PD_256 = 490 ++INTR_X86_AVX_MOVMSK_PS_256 = 491 ++INTR_X86_AVX_MOVNT_DQ_256 = 492 ++INTR_X86_AVX_MOVNT_PD_256 = 493 ++INTR_X86_AVX_MOVNT_PS_256 = 494 ++INTR_X86_AVX_PTESTC_256 = 495 ++INTR_X86_AVX_PTESTNZC_256 = 496 ++INTR_X86_AVX_PTESTZ_256 = 497 ++INTR_X86_AVX_RCP_PS_256 = 498 ++INTR_X86_AVX_ROUND_PD_256 = 499 ++INTR_X86_AVX_ROUND_PS_256 = 500 ++INTR_X86_AVX_RSQRT_PS_256 = 501 ++INTR_X86_AVX_SQRT_PD_256 = 502 ++INTR_X86_AVX_SQRT_PS_256 = 503 ++INTR_X86_AVX_STOREU_DQ_256 = 504 ++INTR_X86_AVX_STOREU_PD_256 = 505 ++INTR_X86_AVX_STOREU_PS_256 = 506 ++INTR_X86_AVX_VBROADCAST_SD_256 = 507 ++INTR_X86_AVX_VBROADCASTF128_PD_256 = 508 ++INTR_X86_AVX_VBROADCASTF128_PS_256 = 509 ++INTR_X86_AVX_VBROADCASTSS = 510 ++INTR_X86_AVX_VBROADCASTSS_256 = 511 ++INTR_X86_AVX_VEXTRACTF128_PD_256 = 512 ++INTR_X86_AVX_VEXTRACTF128_PS_256 = 513 ++INTR_X86_AVX_VEXTRACTF128_SI_256 = 514 ++INTR_X86_AVX_VINSERTF128_PD_256 = 515 ++INTR_X86_AVX_VINSERTF128_PS_256 = 516 ++INTR_X86_AVX_VINSERTF128_SI_256 = 517 ++INTR_X86_AVX_VPERM2F128_PD_256 = 518 ++INTR_X86_AVX_VPERM2F128_PS_256 = 519 ++INTR_X86_AVX_VPERM2F128_SI_256 = 520 ++INTR_X86_AVX_VPERMIL_PD = 521 ++INTR_X86_AVX_VPERMIL_PD_256 = 522 ++INTR_X86_AVX_VPERMIL_PS = 523 ++INTR_X86_AVX_VPERMIL_PS_256 = 524 ++INTR_X86_AVX_VPERMILVAR_PD = 525 ++INTR_X86_AVX_VPERMILVAR_PD_256 = 526 ++INTR_X86_AVX_VPERMILVAR_PS = 527 ++INTR_X86_AVX_VPERMILVAR_PS_256 = 528 ++INTR_X86_AVX_VTESTC_PD = 529 ++INTR_X86_AVX_VTESTC_PD_256 = 530 ++INTR_X86_AVX_VTESTC_PS = 531 ++INTR_X86_AVX_VTESTC_PS_256 = 532 ++INTR_X86_AVX_VTESTNZC_PD = 533 ++INTR_X86_AVX_VTESTNZC_PD_256 = 534 ++INTR_X86_AVX_VTESTNZC_PS = 535 ++INTR_X86_AVX_VTESTNZC_PS_256 = 536 ++INTR_X86_AVX_VTESTZ_PD = 537 ++INTR_X86_AVX_VTESTZ_PD_256 = 538 ++INTR_X86_AVX_VTESTZ_PS = 539 ++INTR_X86_AVX_VTESTZ_PS_256 = 540 ++INTR_X86_AVX_VZEROALL = 541 ++INTR_X86_AVX_VZEROUPPER = 542 ++INTR_X86_INT = 543 ++INTR_X86_MMX_EMMS = 544 ++INTR_X86_MMX_FEMMS = 545 ++INTR_X86_MMX_MASKMOVQ = 546 ++INTR_X86_MMX_MOVNT_DQ = 547 ++INTR_X86_MMX_PACKSSDW = 548 ++INTR_X86_MMX_PACKSSWB = 549 ++INTR_X86_MMX_PACKUSWB = 550 ++INTR_X86_MMX_PADD_B = 551 ++INTR_X86_MMX_PADD_D = 552 ++INTR_X86_MMX_PADD_Q = 553 ++INTR_X86_MMX_PADD_W = 554 ++INTR_X86_MMX_PADDS_B = 555 ++INTR_X86_MMX_PADDS_W = 556 ++INTR_X86_MMX_PADDUS_B = 557 ++INTR_X86_MMX_PADDUS_W = 558 ++INTR_X86_MMX_PALIGNR_B = 559 ++INTR_X86_MMX_PAND = 560 ++INTR_X86_MMX_PANDN = 561 ++INTR_X86_MMX_PAVG_B = 562 ++INTR_X86_MMX_PAVG_W = 563 ++INTR_X86_MMX_PCMPEQ_B = 564 ++INTR_X86_MMX_PCMPEQ_D = 565 ++INTR_X86_MMX_PCMPEQ_W = 566 ++INTR_X86_MMX_PCMPGT_B = 567 ++INTR_X86_MMX_PCMPGT_D = 568 ++INTR_X86_MMX_PCMPGT_W = 569 ++INTR_X86_MMX_PEXTR_W = 570 ++INTR_X86_MMX_PINSR_W = 571 ++INTR_X86_MMX_PMADD_WD = 572 ++INTR_X86_MMX_PMAXS_W = 573 ++INTR_X86_MMX_PMAXU_B = 574 ++INTR_X86_MMX_PMINS_W = 575 ++INTR_X86_MMX_PMINU_B = 576 ++INTR_X86_MMX_PMOVMSKB = 577 ++INTR_X86_MMX_PMULH_W = 578 ++INTR_X86_MMX_PMULHU_W = 579 ++INTR_X86_MMX_PMULL_W = 580 ++INTR_X86_MMX_PMULU_DQ = 581 ++INTR_X86_MMX_POR = 582 ++INTR_X86_MMX_PSAD_BW = 583 ++INTR_X86_MMX_PSLL_D = 584 ++INTR_X86_MMX_PSLL_Q = 585 ++INTR_X86_MMX_PSLL_W = 586 ++INTR_X86_MMX_PSLLI_D = 587 ++INTR_X86_MMX_PSLLI_Q = 588 ++INTR_X86_MMX_PSLLI_W = 589 ++INTR_X86_MMX_PSRA_D = 590 ++INTR_X86_MMX_PSRA_W = 591 ++INTR_X86_MMX_PSRAI_D = 592 ++INTR_X86_MMX_PSRAI_W = 593 ++INTR_X86_MMX_PSRL_D = 594 ++INTR_X86_MMX_PSRL_Q = 595 ++INTR_X86_MMX_PSRL_W = 596 ++INTR_X86_MMX_PSRLI_D = 597 ++INTR_X86_MMX_PSRLI_Q = 598 ++INTR_X86_MMX_PSRLI_W = 599 ++INTR_X86_MMX_PSUB_B = 600 ++INTR_X86_MMX_PSUB_D = 601 ++INTR_X86_MMX_PSUB_Q = 602 ++INTR_X86_MMX_PSUB_W = 603 ++INTR_X86_MMX_PSUBS_B = 604 ++INTR_X86_MMX_PSUBS_W = 605 ++INTR_X86_MMX_PSUBUS_B = 606 ++INTR_X86_MMX_PSUBUS_W = 607 ++INTR_X86_MMX_PUNPCKHBW = 608 ++INTR_X86_MMX_PUNPCKHDQ = 609 ++INTR_X86_MMX_PUNPCKHWD = 610 ++INTR_X86_MMX_PUNPCKLBW = 611 ++INTR_X86_MMX_PUNPCKLDQ = 612 ++INTR_X86_MMX_PUNPCKLWD = 613 ++INTR_X86_MMX_PXOR = 614 ++INTR_X86_SSE2_ADD_SD = 615 ++INTR_X86_SSE2_CLFLUSH = 616 ++INTR_X86_SSE2_CMP_PD = 617 ++INTR_X86_SSE2_CMP_SD = 618 ++INTR_X86_SSE2_COMIEQ_SD = 619 ++INTR_X86_SSE2_COMIGE_SD = 620 ++INTR_X86_SSE2_COMIGT_SD = 621 ++INTR_X86_SSE2_COMILE_SD = 622 ++INTR_X86_SSE2_COMILT_SD = 623 ++INTR_X86_SSE2_COMINEQ_SD = 624 ++INTR_X86_SSE2_CVTDQ2PD = 625 ++INTR_X86_SSE2_CVTDQ2PS = 626 ++INTR_X86_SSE2_CVTPD2DQ = 627 ++INTR_X86_SSE2_CVTPD2PS = 628 ++INTR_X86_SSE2_CVTPS2DQ = 629 ++INTR_X86_SSE2_CVTPS2PD = 630 ++INTR_X86_SSE2_CVTSD2SI = 631 ++INTR_X86_SSE2_CVTSD2SI64 = 632 ++INTR_X86_SSE2_CVTSD2SS = 633 ++INTR_X86_SSE2_CVTSI2SD = 634 ++INTR_X86_SSE2_CVTSI642SD = 635 ++INTR_X86_SSE2_CVTSS2SD = 636 ++INTR_X86_SSE2_CVTTPD2DQ = 637 ++INTR_X86_SSE2_CVTTPS2DQ = 638 ++INTR_X86_SSE2_CVTTSD2SI = 639 ++INTR_X86_SSE2_CVTTSD2SI64 = 640 ++INTR_X86_SSE2_DIV_SD = 641 ++INTR_X86_SSE2_LFENCE = 642 ++INTR_X86_SSE2_LOADU_DQ = 643 ++INTR_X86_SSE2_LOADU_PD = 644 ++INTR_X86_SSE2_MASKMOV_DQU = 645 ++INTR_X86_SSE2_MAX_PD = 646 ++INTR_X86_SSE2_MAX_SD = 647 ++INTR_X86_SSE2_MFENCE = 648 ++INTR_X86_SSE2_MIN_PD = 649 ++INTR_X86_SSE2_MIN_SD = 650 ++INTR_X86_SSE2_MOVMSK_PD = 651 ++INTR_X86_SSE2_MOVNT_DQ = 652 ++INTR_X86_SSE2_MOVNT_I = 653 ++INTR_X86_SSE2_MOVNT_PD = 654 ++INTR_X86_SSE2_MUL_SD = 655 ++INTR_X86_SSE2_PACKSSDW_128 = 656 ++INTR_X86_SSE2_PACKSSWB_128 = 657 ++INTR_X86_SSE2_PACKUSWB_128 = 658 ++INTR_X86_SSE2_PADDS_B = 659 ++INTR_X86_SSE2_PADDS_W = 660 ++INTR_X86_SSE2_PADDUS_B = 661 ++INTR_X86_SSE2_PADDUS_W = 662 ++INTR_X86_SSE2_PAVG_B = 663 ++INTR_X86_SSE2_PAVG_W = 664 ++INTR_X86_SSE2_PCMPEQ_B = 665 ++INTR_X86_SSE2_PCMPEQ_D = 666 ++INTR_X86_SSE2_PCMPEQ_W = 667 ++INTR_X86_SSE2_PCMPGT_B = 668 ++INTR_X86_SSE2_PCMPGT_D = 669 ++INTR_X86_SSE2_PCMPGT_W = 670 ++INTR_X86_SSE2_PMADD_WD = 671 ++INTR_X86_SSE2_PMAXS_W = 672 ++INTR_X86_SSE2_PMAXU_B = 673 ++INTR_X86_SSE2_PMINS_W = 674 ++INTR_X86_SSE2_PMINU_B = 675 ++INTR_X86_SSE2_PMOVMSKB_128 = 676 ++INTR_X86_SSE2_PMULH_W = 677 ++INTR_X86_SSE2_PMULHU_W = 678 ++INTR_X86_SSE2_PMULU_DQ = 679 ++INTR_X86_SSE2_PSAD_BW = 680 ++INTR_X86_SSE2_PSLL_D = 681 ++INTR_X86_SSE2_PSLL_DQ = 682 ++INTR_X86_SSE2_PSLL_DQ_BS = 683 ++INTR_X86_SSE2_PSLL_Q = 684 ++INTR_X86_SSE2_PSLL_W = 685 ++INTR_X86_SSE2_PSLLI_D = 686 ++INTR_X86_SSE2_PSLLI_Q = 687 ++INTR_X86_SSE2_PSLLI_W = 688 ++INTR_X86_SSE2_PSRA_D = 689 ++INTR_X86_SSE2_PSRA_W = 690 ++INTR_X86_SSE2_PSRAI_D = 691 ++INTR_X86_SSE2_PSRAI_W = 692 ++INTR_X86_SSE2_PSRL_D = 693 ++INTR_X86_SSE2_PSRL_DQ = 694 ++INTR_X86_SSE2_PSRL_DQ_BS = 695 ++INTR_X86_SSE2_PSRL_Q = 696 ++INTR_X86_SSE2_PSRL_W = 697 ++INTR_X86_SSE2_PSRLI_D = 698 ++INTR_X86_SSE2_PSRLI_Q = 699 ++INTR_X86_SSE2_PSRLI_W = 700 ++INTR_X86_SSE2_PSUBS_B = 701 ++INTR_X86_SSE2_PSUBS_W = 702 ++INTR_X86_SSE2_PSUBUS_B = 703 ++INTR_X86_SSE2_PSUBUS_W = 704 ++INTR_X86_SSE2_SQRT_PD = 705 ++INTR_X86_SSE2_SQRT_SD = 706 ++INTR_X86_SSE2_STOREL_DQ = 707 ++INTR_X86_SSE2_STOREU_DQ = 708 ++INTR_X86_SSE2_STOREU_PD = 709 ++INTR_X86_SSE2_SUB_SD = 710 ++INTR_X86_SSE2_UCOMIEQ_SD = 711 ++INTR_X86_SSE2_UCOMIGE_SD = 712 ++INTR_X86_SSE2_UCOMIGT_SD = 713 ++INTR_X86_SSE2_UCOMILE_SD = 714 ++INTR_X86_SSE2_UCOMILT_SD = 715 ++INTR_X86_SSE2_UCOMINEQ_SD = 716 ++INTR_X86_SSE3_ADDSUB_PD = 717 ++INTR_X86_SSE3_ADDSUB_PS = 718 ++INTR_X86_SSE3_HADD_PD = 719 ++INTR_X86_SSE3_HADD_PS = 720 ++INTR_X86_SSE3_HSUB_PD = 721 ++INTR_X86_SSE3_HSUB_PS = 722 ++INTR_X86_SSE3_LDU_DQ = 723 ++INTR_X86_SSE3_MONITOR = 724 ++INTR_X86_SSE3_MWAIT = 725 ++INTR_X86_SSE41_BLENDPD = 726 ++INTR_X86_SSE41_BLENDPS = 727 ++INTR_X86_SSE41_BLENDVPD = 728 ++INTR_X86_SSE41_BLENDVPS = 729 ++INTR_X86_SSE41_DPPD = 730 ++INTR_X86_SSE41_DPPS = 731 ++INTR_X86_SSE41_EXTRACTPS = 732 ++INTR_X86_SSE41_INSERTPS = 733 ++INTR_X86_SSE41_MOVNTDQA = 734 ++INTR_X86_SSE41_MPSADBW = 735 ++INTR_X86_SSE41_PACKUSDW = 736 ++INTR_X86_SSE41_PBLENDVB = 737 ++INTR_X86_SSE41_PBLENDW = 738 ++INTR_X86_SSE41_PCMPEQQ = 739 ++INTR_X86_SSE41_PEXTRB = 740 ++INTR_X86_SSE41_PEXTRD = 741 ++INTR_X86_SSE41_PEXTRQ = 742 ++INTR_X86_SSE41_PHMINPOSUW = 743 ++INTR_X86_SSE41_PMAXSB = 744 ++INTR_X86_SSE41_PMAXSD = 745 ++INTR_X86_SSE41_PMAXUD = 746 ++INTR_X86_SSE41_PMAXUW = 747 ++INTR_X86_SSE41_PMINSB = 748 ++INTR_X86_SSE41_PMINSD = 749 ++INTR_X86_SSE41_PMINUD = 750 ++INTR_X86_SSE41_PMINUW = 751 ++INTR_X86_SSE41_PMOVSXBD = 752 ++INTR_X86_SSE41_PMOVSXBQ = 753 ++INTR_X86_SSE41_PMOVSXBW = 754 ++INTR_X86_SSE41_PMOVSXDQ = 755 ++INTR_X86_SSE41_PMOVSXWD = 756 ++INTR_X86_SSE41_PMOVSXWQ = 757 ++INTR_X86_SSE41_PMOVZXBD = 758 ++INTR_X86_SSE41_PMOVZXBQ = 759 ++INTR_X86_SSE41_PMOVZXBW = 760 ++INTR_X86_SSE41_PMOVZXDQ = 761 ++INTR_X86_SSE41_PMOVZXWD = 762 ++INTR_X86_SSE41_PMOVZXWQ = 763 ++INTR_X86_SSE41_PMULDQ = 764 ++INTR_X86_SSE41_PTESTC = 765 ++INTR_X86_SSE41_PTESTNZC = 766 ++INTR_X86_SSE41_PTESTZ = 767 ++INTR_X86_SSE41_ROUND_PD = 768 ++INTR_X86_SSE41_ROUND_PS = 769 ++INTR_X86_SSE41_ROUND_SD = 770 ++INTR_X86_SSE41_ROUND_SS = 771 ++INTR_X86_SSE42_CRC32_16 = 772 ++INTR_X86_SSE42_CRC32_32 = 773 ++INTR_X86_SSE42_CRC32_8 = 774 ++INTR_X86_SSE42_CRC64_64 = 775 ++INTR_X86_SSE42_CRC64_8 = 776 ++INTR_X86_SSE42_PCMPESTRI128 = 777 ++INTR_X86_SSE42_PCMPESTRIA128 = 778 ++INTR_X86_SSE42_PCMPESTRIC128 = 779 ++INTR_X86_SSE42_PCMPESTRIO128 = 780 ++INTR_X86_SSE42_PCMPESTRIS128 = 781 ++INTR_X86_SSE42_PCMPESTRIZ128 = 782 ++INTR_X86_SSE42_PCMPESTRM128 = 783 ++INTR_X86_SSE42_PCMPGTQ = 784 ++INTR_X86_SSE42_PCMPISTRI128 = 785 ++INTR_X86_SSE42_PCMPISTRIA128 = 786 ++INTR_X86_SSE42_PCMPISTRIC128 = 787 ++INTR_X86_SSE42_PCMPISTRIO128 = 788 ++INTR_X86_SSE42_PCMPISTRIS128 = 789 ++INTR_X86_SSE42_PCMPISTRIZ128 = 790 ++INTR_X86_SSE42_PCMPISTRM128 = 791 ++INTR_X86_SSE_ADD_SS = 792 ++INTR_X86_SSE_CMP_PS = 793 ++INTR_X86_SSE_CMP_SS = 794 ++INTR_X86_SSE_COMIEQ_SS = 795 ++INTR_X86_SSE_COMIGE_SS = 796 ++INTR_X86_SSE_COMIGT_SS = 797 ++INTR_X86_SSE_COMILE_SS = 798 ++INTR_X86_SSE_COMILT_SS = 799 ++INTR_X86_SSE_COMINEQ_SS = 800 ++INTR_X86_SSE_CVTPD2PI = 801 ++INTR_X86_SSE_CVTPI2PD = 802 ++INTR_X86_SSE_CVTPI2PS = 803 ++INTR_X86_SSE_CVTPS2PI = 804 ++INTR_X86_SSE_CVTSI2SS = 805 ++INTR_X86_SSE_CVTSI642SS = 806 ++INTR_X86_SSE_CVTSS2SI = 807 ++INTR_X86_SSE_CVTSS2SI64 = 808 ++INTR_X86_SSE_CVTTPD2PI = 809 ++INTR_X86_SSE_CVTTPS2PI = 810 ++INTR_X86_SSE_CVTTSS2SI = 811 ++INTR_X86_SSE_CVTTSS2SI64 = 812 ++INTR_X86_SSE_DIV_SS = 813 ++INTR_X86_SSE_LDMXCSR = 814 ++INTR_X86_SSE_LOADU_PS = 815 ++INTR_X86_SSE_MAX_PS = 816 ++INTR_X86_SSE_MAX_SS = 817 ++INTR_X86_SSE_MIN_PS = 818 ++INTR_X86_SSE_MIN_SS = 819 ++INTR_X86_SSE_MOVMSK_PS = 820 ++INTR_X86_SSE_MOVNT_PS = 821 ++INTR_X86_SSE_MUL_SS = 822 ++INTR_X86_SSE_PSHUF_W = 823 ++INTR_X86_SSE_RCP_PS = 824 ++INTR_X86_SSE_RCP_SS = 825 ++INTR_X86_SSE_RSQRT_PS = 826 ++INTR_X86_SSE_RSQRT_SS = 827 ++INTR_X86_SSE_SFENCE = 828 ++INTR_X86_SSE_SQRT_PS = 829 ++INTR_X86_SSE_SQRT_SS = 830 ++INTR_X86_SSE_STMXCSR = 831 ++INTR_X86_SSE_STOREU_PS = 832 ++INTR_X86_SSE_SUB_SS = 833 ++INTR_X86_SSE_UCOMIEQ_SS = 834 ++INTR_X86_SSE_UCOMIGE_SS = 835 ++INTR_X86_SSE_UCOMIGT_SS = 836 ++INTR_X86_SSE_UCOMILE_SS = 837 ++INTR_X86_SSE_UCOMILT_SS = 838 ++INTR_X86_SSE_UCOMINEQ_SS = 839 ++INTR_X86_SSSE3_PABS_B = 840 ++INTR_X86_SSSE3_PABS_B_128 = 841 ++INTR_X86_SSSE3_PABS_D = 842 ++INTR_X86_SSSE3_PABS_D_128 = 843 ++INTR_X86_SSSE3_PABS_W = 844 ++INTR_X86_SSSE3_PABS_W_128 = 845 ++INTR_X86_SSSE3_PHADD_D = 846 ++INTR_X86_SSSE3_PHADD_D_128 = 847 ++INTR_X86_SSSE3_PHADD_SW = 848 ++INTR_X86_SSSE3_PHADD_SW_128 = 849 ++INTR_X86_SSSE3_PHADD_W = 850 ++INTR_X86_SSSE3_PHADD_W_128 = 851 ++INTR_X86_SSSE3_PHSUB_D = 852 ++INTR_X86_SSSE3_PHSUB_D_128 = 853 ++INTR_X86_SSSE3_PHSUB_SW = 854 ++INTR_X86_SSSE3_PHSUB_SW_128 = 855 ++INTR_X86_SSSE3_PHSUB_W = 856 ++INTR_X86_SSSE3_PHSUB_W_128 = 857 ++INTR_X86_SSSE3_PMADD_UB_SW = 858 ++INTR_X86_SSSE3_PMADD_UB_SW_128 = 859 ++INTR_X86_SSSE3_PMUL_HR_SW = 860 ++INTR_X86_SSSE3_PMUL_HR_SW_128 = 861 ++INTR_X86_SSSE3_PSHUF_B = 862 ++INTR_X86_SSSE3_PSHUF_B_128 = 863 ++INTR_X86_SSSE3_PSIGN_B = 864 ++INTR_X86_SSSE3_PSIGN_B_128 = 865 ++INTR_X86_SSSE3_PSIGN_D = 866 ++INTR_X86_SSSE3_PSIGN_D_128 = 867 ++INTR_X86_SSSE3_PSIGN_W = 868 ++INTR_X86_SSSE3_PSIGN_W_128 = 869 ++INTR_XCORE_BITREV = 870 ++INTR_XCORE_CHKCT = 871 ++INTR_XCORE_CLRE = 872 ++INTR_XCORE_EEU = 873 ++INTR_XCORE_FREER = 874 ++INTR_XCORE_GETID = 875 ++INTR_XCORE_GETR = 876 ++INTR_XCORE_GETTS = 877 ++INTR_XCORE_IN = 878 ++INTR_XCORE_INCT = 879 ++INTR_XCORE_INSHR = 880 ++INTR_XCORE_INT = 881 ++INTR_XCORE_OUT = 882 ++INTR_XCORE_OUTCT = 883 ++INTR_XCORE_OUTSHR = 884 ++INTR_XCORE_OUTT = 885 ++INTR_XCORE_SETC = 886 ++INTR_XCORE_SETD = 887 ++INTR_XCORE_SETPT = 888 ++INTR_XCORE_SETTW = 889 ++INTR_XCORE_SETV = 890 ++INTR_XCORE_SYNCR = 891 ++INTR_XCORE_WAITEVENT = 892 +Index: _core.c +=================================================================== +--- _core.c (revision 105) ++++ _core.c (working copy) +@@ -807,7 +807,7 @@ + _wrap_pass( EdgeProfiler ) + _wrap_pass( FunctionAttrs ) + _wrap_pass( FunctionInlining ) +-_wrap_pass( GEPSplitter ) ++//_wrap_pass( GEPSplitter ) + _wrap_pass( GlobalDCE ) + _wrap_pass( GlobalOptimizer ) + _wrap_pass( GlobalsModRef ) +@@ -822,11 +822,11 @@ + _wrap_pass( LazyValueInfo ) + _wrap_pass( LCSSA ) + _wrap_pass( LICM ) +-_wrap_pass( LiveValues ) ++//_wrap_pass( LiveValues ) + _wrap_pass( LoopDeletion ) + _wrap_pass( LoopDependenceAnalysis ) + _wrap_pass( LoopExtractor ) +-_wrap_pass( LoopIndexSplit ) ++//_wrap_pass( LoopIndexSplit ) + _wrap_pass( LoopRotate ) + _wrap_pass( LoopSimplify ) + _wrap_pass( LoopStrengthReduce ) +@@ -841,7 +841,7 @@ + _wrap_pass( NoProfileInfo ) + _wrap_pass( OptimalEdgeProfiler ) + _wrap_pass( PartialInlining ) +-_wrap_pass( PartialSpecialization ) ++//_wrap_pass( PartialSpecialization ) + _wrap_pass( PostDomOnlyPrinter ) + _wrap_pass( PostDomOnlyViewer ) + _wrap_pass( PostDomPrinter ) +@@ -855,7 +855,7 @@ + _wrap_pass( ScalarEvolutionAliasAnalysis ) + _wrap_pass( ScalarReplAggregates ) + _wrap_pass( SCCP ) +-_wrap_pass( SimplifyHalfPowrLibCalls ) ++//_wrap_pass( SimplifyHalfPowrLibCalls ) + _wrap_pass( SimplifyLibCalls ) + _wrap_pass( SingleLoopExtractor ) + _wrap_pass( StripDeadPrototypes ) +@@ -1162,7 +1162,7 @@ + Py_RETURN_NONE; + } + +-_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) ++//_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) + + /* Expose the void* inside a PyCObject as a PyLong. This allows us to + * use it as a unique ID. */ +@@ -1569,7 +1569,7 @@ + _pass( EdgeProfiler ) + _pass( FunctionAttrs ) + _pass( FunctionInlining ) +- _pass( GEPSplitter ) ++ //_pass( GEPSplitter ) + _pass( GlobalDCE ) + _pass( GlobalOptimizer ) + _pass( GlobalsModRef ) +@@ -1584,11 +1584,11 @@ + _pass( LazyValueInfo ) + _pass( LCSSA ) + _pass( LICM ) +- _pass( LiveValues ) ++ //_pass( LiveValues ) + _pass( LoopDeletion ) + _pass( LoopDependenceAnalysis ) + _pass( LoopExtractor ) +- _pass( LoopIndexSplit ) ++ //_pass( LoopIndexSplit ) + _pass( LoopRotate ) + _pass( LoopSimplify ) + _pass( LoopStrengthReduce ) +@@ -1603,7 +1603,7 @@ + _pass( NoProfileInfo ) + _pass( OptimalEdgeProfiler ) + _pass( PartialInlining ) +- _pass( PartialSpecialization ) ++ //_pass( PartialSpecialization ) + _pass( PostDomOnlyPrinter ) + _pass( PostDomOnlyViewer ) + _pass( PostDomPrinter ) +@@ -1617,7 +1617,7 @@ + _pass( ScalarEvolutionAliasAnalysis ) + _pass( ScalarReplAggregates ) + _pass( SCCP ) +- _pass( SimplifyHalfPowrLibCalls ) ++ //_pass( SimplifyHalfPowrLibCalls ) + _pass( SimplifyLibCalls ) + _pass( SingleLoopExtractor ) + _pass( StripDeadPrototypes ) +@@ -1672,7 +1672,7 @@ + /* Misc */ + _method( LLVMGetIntrinsic ) + _method( LLVMLoadLibraryPermanently ) +- _method( LLVMInlineFunction ) ++ //_method( LLVMInlineFunction ) + _method( PyCObjectVoidPtrToPyLong ) + + { NULL } +Index: extra.h +=================================================================== +--- extra.h (revision 105) ++++ extra.h (working copy) +@@ -181,7 +181,7 @@ + /* Wraps llvm::InlineFunction(). Inlines a function. C is the call + * instruction, created by LLVMBuildCall. Even if it fails, the Function + * containing the call is still in a proper state (not changed). */ +-int LLVMInlineFunction(LLVMValueRef call); ++//int LLVMInlineFunction(LLVMValueRef call); + + /* Wraps llvm::getAlignmentFromAttrs from Attributes.h. Compliments the + * already available LLVMSetParamAlignment(). */ +@@ -209,13 +209,13 @@ + declare_pass( DomPrinter ) + declare_pass( DomViewer ) + declare_pass( EdgeProfiler ) +-declare_pass( GEPSplitter ) ++//declare_pass( GEPSplitter ) + declare_pass( GlobalsModRef ) + declare_pass( InstCount ) + declare_pass( InstructionNamer ) + declare_pass( LazyValueInfo ) + declare_pass( LCSSA ) +-declare_pass( LiveValues ) ++//declare_pass( LiveValues ) + declare_pass( LoopDependenceAnalysis ) + declare_pass( LoopExtractor ) + declare_pass( LoopSimplify ) +@@ -227,7 +227,7 @@ + declare_pass( NoProfileInfo ) + declare_pass( OptimalEdgeProfiler ) + declare_pass( PartialInlining ) +-declare_pass( PartialSpecialization ) ++//declare_pass( PartialSpecialization ) + declare_pass( PostDomOnlyPrinter ) + declare_pass( PostDomOnlyViewer ) + declare_pass( PostDomPrinter ) diff --git a/llvm/__init__.py b/llvm/__init__.py index 9b24112..b89e5a9 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -1,47 +1,152 @@ -from ._version import get_versions -__version__ = get_versions()['version'] -del get_versions +""" +Common classes related to LLVM. +""" + +__version__ = '0.10.0' -from llvmpy import extra +from weakref import WeakValueDictionary +import _core -version = extra.get_llvm_version() -del extra +#===----------------------------------------------------------------------=== +# LLVM Version +#===----------------------------------------------------------------------=== -class Wrapper(object): - __slots__ = '__ptr' +version = _core.LLVMGetVersion() - def __init__(self, ptr): - assert ptr - self.__ptr = ptr +def require_version_at_least(major, minor): + '''Sentry to guard version requirement + ''' + if version < (major, minor): + raise Exception(major, minor) - @property - def _ptr(self): - try: - return self.__ptr - except AttributeError: - raise AttributeError("_ptr resource has been removed") - - @_ptr.deleter - def _ptr(self): - del self.__ptr - - -def _extract_ptrs(objs): - return [(x._ptr if x is not None else None) - for x in objs] +#===----------------------------------------------------------------------=== +# Exceptions +#===----------------------------------------------------------------------=== class LLVMException(Exception): + """Generic LLVM exception.""" + + def __init__(self, msg=""): + Exception.__init__(self, msg) + + +#===----------------------------------------------------------------------=== +# Ownables +#===----------------------------------------------------------------------=== + +class Ownable(object): + """Objects that can be owned. + + Modules and Module Providers can be owned, i.e., the responsibility of + destruction of ownable objects can be handed over to other objects. The + llvm.Ownable class represents objects that can be so owned. This class + is NOT intended for public use. + """ + + def __init__(self, ptr, del_fn): + self.ptr = ptr + self.owner = None + self.del_fn = del_fn + + def _own(self, owner): + if self.owner: + raise LLVMException("object already owned") + self.owner = owner + + def _disown(self): + if not self.owner: + raise LLVMException("not owned") + self.owner = None + + def __del__(self): + if not self.owner: + self.del_fn(self.ptr) + + +#===----------------------------------------------------------------------=== +# Dummy owner, will not delete ownee. Be careful. +#===----------------------------------------------------------------------=== + +class DummyOwner(object): pass -def test(verbosity=3, run_isolated=True): + +#===----------------------------------------------------------------------=== +# A metaclass to prevent aliasing. It stores a (weak) reference to objects +# constructed based on a PyCObject. If an object is constructed based on a +# PyCObject with the same underlying pointer as a previous object, a reference +# to the previous object is returned rather than a new one. +#===----------------------------------------------------------------------=== + +class _ObjectCache(type): + """A metaclass to prevent aliasing. + + Classes using 'ObjectCache' as a metaclass must have constructors + that take a PyCObject as their first argument. When the class is + called (to create a new instance of the class), the value of the + pointer wrapped by the PyCObj is checked: + + If no previous object has been created based on the same + underlying pointer (note that different PyCObject objects can + wrap the same pointer), the object will be initialized as + usual and returned. + + If a previous has been created based on the same pointer, + then a reference to that object will be returned, and no + object initialization is performed. + """ + + __instances = WeakValueDictionary() + + def __call__(cls, ptr, *args, **kwargs): + objid = _core.PyCObjectVoidPtrToPyLong(ptr) + key = "%s:%d" % (cls.__name__, objid) + obj = _ObjectCache.__instances.get(key) + if obj is None: + obj = super(_ObjectCache, cls).__call__(ptr, *args, **kwargs) + _ObjectCache.__instances[key] = obj + return obj + + @staticmethod + def forget(obj): + objid = _core.PyCObjectVoidPtrToPyLong(obj.ptr) + key = "%s:%d" % (type(obj).__name__, objid) + if key in _ObjectCache.__instances: + del _ObjectCache.__instances[key] + + +#===----------------------------------------------------------------------=== +# Cacheables +#===----------------------------------------------------------------------=== + +# version 2/3 compatibility help +# version 2 metaclass +# class Cacheable(object): +# __metaclass__ = _ObjectCache # Doing nothing for version 3 +# +# version 3 metaclass +# class Cacheable(metaclass=_ObjectCache): +# +# Reference: http://mikewatkins.ca/2008/11/29/python-2-and-3-metaclasses/#using-the-metaclass-in-python-3-x +ObjectCache = _ObjectCache('ObjectCache', (object, ), {}) + +class Cacheable(ObjectCache): + """Objects that can be cached. + + Objects that wrap a PyCObject are cached to avoid "aliasing", i.e., + two Python objects each containing a PyCObject which internally points + to the same C pointer.""" + + def forget(self): + ObjectCache.forget(self) + + +def test(verbosity=1): """test(verbosity=1) -> TextTestResult - Run self-test, and return the number of failures + errors - """ - from llvm.tests import run + Run self-test, and return unittest.runner.TextTestResult object. + """ + from llvm.test_llvmpy import run - result = run(verbosity=verbosity, run_isolated=run_isolated) - errct = len(result.failures) + len(result.errors) - - return errct + return run(verbosity=verbosity) diff --git a/llvm/_core.cpp b/llvm/_core.cpp new file mode 100644 index 0000000..db5287e --- /dev/null +++ b/llvm/_core.cpp @@ -0,0 +1,2212 @@ +/* + * Copyright (c) 2008-10, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* our includes */ +#include "wrap.h" +#include "extra.h" + + + +// Python include +#include "Python.h" + +/* LLVM includes */ +#include "llvm-c/Analysis.h" +#include "llvm-c/Transforms/Scalar.h" +#include "llvm-c/ExecutionEngine.h" +#include "llvm-c/Target.h" +#include "llvm-c/Transforms/IPO.h" + +#include "llvm/Support/CommandLine.h" +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 + #include "llvm-c/Linker.h" +#else + typedef unsigned int LLVMLinkerMode; +#endif + +/* Compatibility with Python 2.4: Py_ssize_t is not available. */ +#ifndef PY_SSIZE_T_MAX +typedef int Py_ssize_t; +#endif + + +// explicit specializations +template <> PyObject* pycap_new(int i) +{ + return PyLong_FromLong(static_cast(i)); +} + +template <> PyObject* pycap_new(unsigned long i) +{ + return PyLong_FromLong(static_cast(i)); +} + +template <> PyObject* pycap_new(LLVMTypeKind i) +{ + return PyLong_FromLong(static_cast(i)); +} + +template <> PyObject* pycap_new(LLVMLinkage i) +{ + return PyLong_FromLong(static_cast(i)); +} + +template <> PyObject* pycap_new(LLVMVisibility i) +{ + return PyLong_FromLong(static_cast(i)); +} + +template <> PyObject* pycap_new(LLVMByteOrdering i) +{ + return PyLong_FromLong(static_cast(i)); +} + +template <> PyObject* pycap_new(unsigned PY_LONG_LONG ull) +{ + return PyLong_FromUnsignedLongLong(ull); +} + +template <> PyObject* pycap_new(PY_LONG_LONG ll) +{ + return PyLong_FromLongLong(ll); +} + +/*===----------------------------------------------------------------------===*/ +/* Modules */ +/*===----------------------------------------------------------------------===*/ + +static PyObject * +_wLLVMModuleCreateWithName(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const char *s; + + if (!PyArg_ParseTuple(args, "s:LLVMModuleCreateWithName", &s)) { + return NULL; + } + + const LLVMModuleRef module = LLVMModuleCreateWithName(s); + return pycap_new(module); + LLVMPY_CATCH_ALL +} + +_wrap_obj2str(LLVMGetDataLayout, LLVMModuleRef) +_wrap_objstr2none(LLVMSetDataLayout, LLVMModuleRef) +_wrap_obj2str(LLVMGetModuleIdentifier, LLVMModuleRef) +_wrap_objstr2none(LLVMSetModuleIdentifier, LLVMModuleRef) +_wrap_obj2str(LLVMGetTarget, LLVMModuleRef) +_wrap_objstr2none(LLVMSetTarget, LLVMModuleRef) +_wrap_objstr2none(LLVMModuleAddLibrary, LLVMModuleRef) +_wrap_objstr2obj(LLVMGetTypeByName, LLVMModuleRef, LLVMTypeRef) +_wrap_obj2none(LLVMDumpModule, LLVMModuleRef) +_wrap_obj2none(LLVMDisposeModule, LLVMModuleRef) +_wrap_dumper(LLVMDumpModuleToString, LLVMModuleRef) + _wrap_obj2obj( LLVMModuleGetPointerSize, LLVMModuleRef, int) +_wrap_objstrobj2obj(LLVMModuleGetOrInsertFunction, LLVMModuleRef, + LLVMTypeRef, LLVMValueRef) + +static PyObject * +_wLLVMVerifyModule(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const LLVMModuleRef m = get_object_arg(args) ; + if (!m) return NULL; + + char *outmsg = 0; + (void) LLVMVerifyModule(m, LLVMReturnStatusAction, &outmsg); + + PyObject *ret; + if (outmsg) { + ret = PyUnicode_FromString(outmsg); + LLVMDisposeMessage(outmsg); + } else { + ret = PyUnicode_FromString(""); + } + + return ret; + LLVMPY_CATCH_ALL +} + +///// unused +// typedef LLVMModuleRef (*asm_or_bc_fn_t)(const char *A, unsigned Len, char **OutMessage); + + +static PyObject* +_wLLVMGetModuleFromAssembly(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const char * str; +#if (PY_MAJOR_VERSION >= 3) + if ( !PyArg_ParseTuple(args, "y", &str) ){ +#else + if ( !PyArg_ParseTuple(args, "s", &str) ){ +#endif + return NULL; + } + + char * outmsg = 0; + const LLVMModuleRef mod = LLVMGetModuleFromAssembly(str, &outmsg); + + if ( !mod ){ + if ( outmsg ){ + PyObject * ret = PyUnicode_FromString(outmsg); + LLVMDisposeMessage(outmsg); + return ret; + } else { + Py_RETURN_NONE; + } + } + + return pycap_new(mod); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGetModuleFromBitcode(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj ; + + if (!PyArg_ParseTuple(args, "S", &obj)) + return NULL; + + const char *start = PyBytes_AsString(obj); + const Py_ssize_t len = PyBytes_Size(obj); + + char *outmsg = 0; + LLVMModuleRef m = LLVMGetModuleFromBitcode(start, len, &outmsg); + + PyObject *ret; + if (!m) { + if (outmsg) { + ret = PyUnicode_FromString(outmsg); + LLVMDisposeMessage(outmsg); + return ret; + } else { + Py_RETURN_NONE; + } + } + + return pycap_new(m); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGetBitcodeFromModule(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const LLVMModuleRef m = get_object_arg(args) ; + if (!m ) return NULL; + + size_t len; + const unsigned char *ubytes = LLVMGetBitcodeFromModule(m, &len) ; + if ( !ubytes ) Py_RETURN_NONE; + + const char *chars = reinterpret_cast(ubytes) ; + PyObject *ret = PyBytes_FromStringAndSize(chars, len); + delete [] ubytes; + return ret; + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGetNativeCodeFromModule(PyObject * self, PyObject * args) +{ + LLVMPY_TRY + PyObject * arg_m; + int arg_use_asm; + + if (!PyArg_ParseTuple(args, "Oi", &arg_m, &arg_use_asm)) + return NULL; + + const LLVMModuleRef m = pycap_get( arg_m ) ; + + std::string error; + size_t len; + unsigned const char * ubytes + = LLVMGetNativeCodeFromModule(m, arg_use_asm, &len, error); + if ( !error.empty() ){ + PyErr_SetString(PyExc_RuntimeError, error.c_str()); + } + + const char *chars = reinterpret_cast(ubytes) ; + PyObject * ret = PyBytes_FromStringAndSize(chars, len); + + delete [] ubytes; + + return ret; + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMLinkModules(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + size_t mode = 0; + + PyObject *dest_obj, *src_obj ; + if (!PyArg_ParseTuple(args, "OO|I", &dest_obj, &src_obj, &mode)) + return NULL; + + const LLVMModuleRef dest = pycap_get(dest_obj ) ; + const LLVMModuleRef src = pycap_get(src_obj) ; + + PyObject *ret = NULL; + char *errmsg = NULL; + if (LLVMLinkModules(dest, src, (LLVMLinkerMode)mode, &errmsg)) { + if (errmsg) { + ret = PyUnicode_FromString(errmsg); + LLVMDisposeMessage(errmsg); + } else { + ret = PyUnicode_FromString("Link error"); + } + return ret; + } + + /* note: success => None, failure => string with error message */ + Py_RETURN_NONE; + LLVMPY_CATCH_ALL +} + +_wrap_objstr2obj(LLVMModuleGetOrInsertNamedMetaData, LLVMModuleRef, LLVMNamedMDRef) +_wrap_objstr2obj(LLVMModuleGetNamedMetaData, LLVMModuleRef, LLVMNamedMDRef) +_wrap_obj2obj(LLVMCloneModule, LLVMModuleRef, LLVMModuleRef) + +/*===----------------------------------------------------------------------===*/ +/* Types */ +/*===----------------------------------------------------------------------===*/ + +/*===-- General ----------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetTypeKind, LLVMTypeRef, int) +_wrap_dumper(LLVMDumpTypeToString, LLVMTypeRef) + +/*===-- Integer types ----------------------------------------------------===*/ + +_wrap_none2obj(LLVMInt1Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt8Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt16Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt32Type, LLVMTypeRef) +_wrap_none2obj(LLVMInt64Type, LLVMTypeRef) +_wrap_int2obj(LLVMIntType, LLVMTypeRef) +_wrap_obj2obj(LLVMGetIntTypeWidth, LLVMTypeRef, int) + +/*===-- Floating-point types ---------------------------------------------===*/ + +_wrap_none2obj(LLVMFloatType, LLVMTypeRef) +_wrap_none2obj(LLVMDoubleType, LLVMTypeRef) +_wrap_none2obj(LLVMX86FP80Type, LLVMTypeRef) +_wrap_none2obj(LLVMFP128Type, LLVMTypeRef) +_wrap_none2obj(LLVMPPCFP128Type, LLVMTypeRef) + +/*===-- Function types ---------------------------------------------------===*/ + +_wrap_objlistint2obj(LLVMFunctionType, LLVMTypeRef, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMIsFunctionVarArg, LLVMTypeRef, int) +_wrap_obj2obj(LLVMGetReturnType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMCountParamTypes, LLVMTypeRef, int) + +/* The LLVMGetParamTypes and LLVMGetStructElementTypes functions both + * have the same signatures. The following implementation takes advantage + * of this. + */ + +typedef void (*obj2arr_fn_t)(LLVMTypeRef ty, LLVMTypeRef *outv); +typedef unsigned (*arrcnt_fn_t)(LLVMTypeRef ty); + +static PyObject * +obj2arr(PyObject *self, PyObject *args, arrcnt_fn_t cntfunc, obj2arr_fn_t arrfunc) +{ + size_t param_count; + + /* get the function object ptr */ + const LLVMTypeRef type = get_object_arg(args) ; + + /* get param count */ + param_count = cntfunc(type); + + /* alloc enough space for all of them */ + LLVMTypeRef* param_types = new LLVMTypeRef[param_count] ; + + /* call LLVM func */ + arrfunc(type, param_types); + + /* create a list from the array */ + PyObject *list = make_list(param_types, param_count); + + /* free temp storage */ + delete [] param_types ; + + return list; +} + +static PyObject * +_wLLVMGetFunctionTypeParams(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + return obj2arr(self, args, LLVMCountParamTypes, LLVMGetParamTypes); + LLVMPY_CATCH_ALL +} + +/*===-- Struct types -----------------------------------------------------===*/ + +_wrap_listint2obj(LLVMStructType, LLVMTypeRef, LLVMTypeRef) +_wrap_str2obj(LLVMStructTypeIdentified, LLVMTypeRef) +_wrap_objlistint2none(LLVMSetStructBody, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMCountStructElementTypes, LLVMTypeRef, int) +_wrap_obj2str(LLVMGetStructName, LLVMTypeRef) +_wrap_objstr2none(LLVMSetStructName, LLVMTypeRef) + + +static PyObject * +_wLLVMGetStructElementTypes(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + return obj2arr(self, args, LLVMCountStructElementTypes, + LLVMGetStructElementTypes); + LLVMPY_CATCH_ALL +} + + +_wrap_obj2obj(LLVMIsPackedStruct, LLVMTypeRef, int) +_wrap_obj2obj(LLVMIsOpaqueStruct, LLVMTypeRef, int) +_wrap_obj2obj(LLVMIsLiteralStruct, LLVMTypeRef, int) + +/*===-- Array types ------------------------------------------------------===*/ + +_wrap_objint2obj(LLVMArrayType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetElementType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetArrayLength, LLVMTypeRef, int) + +/*===-- Pointer types ----------------------------------------------------===*/ + +_wrap_objint2obj(LLVMPointerType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetPointerAddressSpace, LLVMTypeRef, int) + +/*===-- Vector type ------------------------------------------------------===*/ + +_wrap_objint2obj(LLVMVectorType, LLVMTypeRef, LLVMTypeRef) +_wrap_obj2obj(LLVMGetVectorSize, LLVMTypeRef, int) + +/*===-- Other types ------------------------------------------------------===*/ + +_wrap_none2obj(LLVMVoidType, LLVMTypeRef) +_wrap_none2obj(LLVMLabelType, LLVMTypeRef) + +/*===-- Type handles -----------------------------------------------------===*/ + +/* +_wrap_obj2obj(LLVMCreateTypeHandle, LLVMTypeRef, LLVMTypeHandleRef) +_wrap_obj2obj(LLVMResolveTypeHandle, LLVMTypeHandleRef, LLVMTypeRef) +_wrap_obj2none(LLVMDisposeTypeHandle, LLVMTypeHandleRef) +*/ + + +/*===----------------------------------------------------------------------===*/ +/* Values */ +/*===----------------------------------------------------------------------===*/ + +/* Operations on all values */ + +_wrap_obj2obj(LLVMTypeOf, LLVMValueRef, LLVMTypeRef) +_wrap_obj2str(LLVMGetValueName, LLVMValueRef) +_wrap_objstr2none(LLVMSetValueName, LLVMValueRef) +_wrap_obj2none(LLVMDumpValue, LLVMValueRef) +_wrap_dumper(LLVMDumpValueToString, LLVMValueRef) +_wrap_obj2obj(LLVMValueGetID, LLVMValueRef, int) +_wrap_obj2obj(LLVMValueGetNumUses, LLVMValueRef, int) + +static PyObject * +_wLLVMValueGetUses(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const LLVMValueRef value = get_object_arg(args) ; + + LLVMValueRef *uses = 0; + size_t n = LLVMValueGetUses(value, &uses); + + PyObject *list = make_list(uses, n); + if (n > 0) + LLVMDisposeValueRefArray(uses); + + return list; + LLVMPY_CATCH_ALL +} + +/*===-- Users ------------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMUserGetNumOperands, LLVMValueRef, int) +_wrap_objint2obj(LLVMUserGetOperand, LLVMValueRef, LLVMValueRef) + +/*===-- Constant Values --------------------------------------------------===*/ + +/* Operations on constants of any type */ + +_wrap_obj2obj(LLVMConstNull, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMConstAllOnes, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetUndef, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMIsConstant, LLVMValueRef, int) +_wrap_obj2obj(LLVMIsNull, LLVMValueRef, int) +_wrap_obj2obj(LLVMIsUndef, LLVMValueRef, int) + +/* Operations on scalar constants */ + +static PyObject * +_wLLVMConstInt(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj; + unsigned PY_LONG_LONG n; + int sign_extend; + + if (!PyArg_ParseTuple(args, "OKi", &obj, &n, &sign_extend)) + return NULL; + + const LLVMTypeRef ty = pycap_get( obj ) ; + + const LLVMValueRef val = LLVMConstInt(ty, n, sign_extend); + + return pycap_new(val); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMConstReal(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj; + double d; + + if (!PyArg_ParseTuple(args, "Od", &obj, &d)) + return NULL; + + const LLVMTypeRef ty = pycap_get( obj ) ; + + const LLVMValueRef val = LLVMConstReal(ty, d); + return pycap_new(val); + LLVMPY_CATCH_ALL +} + +_wrap_objstr2obj(LLVMConstRealOfString, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMConstIntGetZExtValue, LLVMValueRef, llvmwrap_ull) +_wrap_obj2obj(LLVMConstIntGetSExtValue, LLVMValueRef, llvmwrap_ll) + +/* Operations on composite constants */ + +static PyObject * +_wLLVMConstString(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const char *s; + int dont_null_terminate; + + if (!PyArg_ParseTuple(args, "si:LLVMConstString", &s, &dont_null_terminate)) { + return NULL; + } + + LLVMValueRef val = LLVMConstString(s, strlen(s), dont_null_terminate); + return pycap_new(val); + LLVMPY_CATCH_ALL +} + +_wrap_objlist2obj(LLVMConstArray, LLVMTypeRef, LLVMValueRef, LLVMValueRef) +_wrap_listint2obj(LLVMConstStruct, LLVMValueRef, LLVMValueRef) +_wrap_list2obj(LLVMConstVector, LLVMValueRef, LLVMValueRef) + +/* Constant expressions */ + +_wrap_obj2obj(LLVMGetConstExprOpcode, LLVMValueRef, int) +_wrap_obj2str(LLVMGetConstExprOpcodeName, LLVMValueRef) +_wrap_obj2obj(LLVMSizeOf, LLVMTypeRef, LLVMValueRef) +_wrap_obj2obj(LLVMConstNeg, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMConstNot, LLVMValueRef, LLVMValueRef) + +_wrap_objobj2obj(LLVMConstAdd, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFAdd, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSub, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFSub, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstMul, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFMul, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstUDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFDiv, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstURem, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSRem, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFRem, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstAnd, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstOr, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstXor, LLVMValueRef, LLVMValueRef, LLVMValueRef) + +_wrap_enumobjobj2obj(LLVMConstICmp, LLVMIntPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_enumobjobj2obj(LLVMConstFCmp, LLVMRealPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) + +_wrap_objobj2obj(LLVMConstShl, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstLShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstAShr, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objlist2obj(LLVMConstGEP, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstTrunc, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstZExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPTrunc, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPExt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstUIToFP, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstSIToFP, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPToUI, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstFPToSI, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstPtrToInt, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstIntToPtr, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstBitCast, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMConstSelect, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMConstExtractElement, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMConstInsertElement, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMConstShuffleVector, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) + + +/*===----------------------------------------------------------------------===*/ +/* Globals */ +/*===----------------------------------------------------------------------===*/ + +/*===-- Globals ----------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetGlobalParent, LLVMValueRef, LLVMModuleRef) +_wrap_obj2obj(LLVMIsDeclaration, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetLinkage, LLVMValueRef, int) +_wrap_objenum2none(LLVMSetLinkage, LLVMValueRef, LLVMLinkage) +_wrap_obj2str(LLVMGetSection, LLVMValueRef) +_wrap_objstr2none(LLVMSetSection, LLVMValueRef) +_wrap_obj2obj(LLVMGetVisibility, LLVMValueRef, int) +_wrap_objenum2none(LLVMSetVisibility, LLVMValueRef, LLVMVisibility) +_wrap_obj2obj(LLVMGetAlignment, LLVMValueRef, int) +_wrap_objint2none(LLVMSetAlignment, LLVMValueRef) + +/*===-- Global Variables -------------------------------------------------===*/ + +_wrap_objobjstr2obj(LLVMAddGlobal, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjstrint2obj(LLVMAddGlobalInAddressSpace, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) +_wrap_objstr2obj(LLVMGetNamedGlobal, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetFirstGlobal, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextGlobal, LLVMValueRef, LLVMValueRef) +_wrap_obj2none(LLVMDeleteGlobal, LLVMValueRef) +_wrap_obj2obj(LLVMHasInitializer, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetInitializer, LLVMValueRef, LLVMValueRef) +_wrap_objobj2none(LLVMSetInitializer, LLVMValueRef, LLVMValueRef) +_wrap_objint2none(LLVMSetGlobalConstant, LLVMValueRef) +_wrap_obj2obj(LLVMIsGlobalConstant, LLVMValueRef, int) +_wrap_objint2none(LLVMSetThreadLocal, LLVMValueRef) +_wrap_obj2obj(LLVMIsThreadLocal, LLVMValueRef, int) + + +/*===-- Functions --------------------------------------------------------===*/ + +_wrap_objstrobj2obj(LLVMAddFunction, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) +_wrap_objstr2obj(LLVMGetNamedFunction, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetFirstFunction, LLVMModuleRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextFunction, LLVMValueRef, LLVMValueRef) +_wrap_obj2none(LLVMDeleteFunction, LLVMValueRef) +_wrap_obj2obj(LLVMGetIntrinsicID, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetFunctionCallConv, LLVMValueRef, int) +_wrap_objint2none(LLVMSetFunctionCallConv, LLVMValueRef) +_wrap_obj2str(LLVMGetGC, LLVMValueRef) +_wrap_objstr2none(LLVMSetGC, LLVMValueRef) +_wrap_obj2obj(LLVMGetDoesNotThrow, LLVMValueRef, int) +_wrap_objint2none(LLVMSetDoesNotThrow, LLVMValueRef) +_wrap_obj2none(LLVMViewFunctionCFG, LLVMValueRef) +_wrap_obj2none(LLVMViewFunctionCFGOnly, LLVMValueRef) +_wrap_objenum2none(LLVMAddFunctionAttr, LLVMValueRef, LLVMAttribute) +_wrap_objenum2none(LLVMRemoveFunctionAttr, LLVMValueRef, LLVMAttribute) + +static PyObject * +_wLLVMVerifyFunction(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const LLVMValueRef fn = get_object_arg(args); + if (!fn) return NULL; + + return pycap_new(LLVMVerifyFunction(fn, LLVMReturnStatusAction)); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGetFunctionFromInlineAsm(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *pycapFuncType; + const char *inlineAsm = NULL; + const char *constrains = NULL; + int hasSideEffect; + int isAlignStack; + int asmDialect; + + if (!PyArg_ParseTuple(args, "Ossiii", &pycapFuncType, &inlineAsm, + &constrains, &hasSideEffect, + &isAlignStack, &asmDialect)) + return NULL; + + + LLVMTypeRef funcType = pycap_get(pycapFuncType); + LLVMValueRef inlineAsmRef; + inlineAsmRef = LLVMGetFunctionFromInlineAsm(funcType, inlineAsm, constrains, + hasSideEffect, isAlignStack, + asmDialect); + + return pycap_new(inlineAsmRef); + LLVMPY_CATCH_ALL +} + + +/*===-- Arguments --------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMCountParams, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetFirstParam, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextParam, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetParamParent, LLVMValueRef, LLVMValueRef) +_wrap_objenum2none(LLVMAddAttribute, LLVMValueRef, LLVMAttribute) +_wrap_objenum2none(LLVMRemoveAttribute, LLVMValueRef, LLVMAttribute) +_wrap_objenum2none(LLVMSetParamAlignment, LLVMValueRef, LLVMAttribute) +_wrap_obj2obj(LLVMGetParamAlignment, LLVMValueRef, int) + +/*===-- Basic Blocks -----------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetBasicBlockParent, LLVMBasicBlockRef, LLVMValueRef) +_wrap_obj2obj(LLVMCountBasicBlocks, LLVMValueRef, int) +_wrap_obj2obj(LLVMGetFirstBasicBlock, LLVMValueRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetNextBasicBlock, LLVMBasicBlockRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetEntryBasicBlock, LLVMValueRef, LLVMBasicBlockRef) +_wrap_objstr2obj(LLVMAppendBasicBlock, LLVMValueRef, LLVMBasicBlockRef) +_wrap_objstr2obj(LLVMInsertBasicBlock, LLVMBasicBlockRef, LLVMBasicBlockRef) +_wrap_obj2none(LLVMDeleteBasicBlock, LLVMBasicBlockRef) + + +/*===-- MetaData -----------------------------------------------------===*/ + +_wrap_objlist2obj(LLVMMetaDataGet, LLVMModuleRef, LLVMValueRef, LLVMValueRef) +_wrap_objstrobj2none(LLVMAddNamedMetadataOperand, LLVMModuleRef, LLVMValueRef) +_wrap_objint2obj(LLVMMetaDataGetOperand, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMMetaDataGetNumOperands, LLVMValueRef, int) +_wrap_objstr2obj(LLVMMetaDataStringGet, LLVMModuleRef, LLVMValueRef) + +static PyObject * +_wLLVMGetNamedMetadataOperands(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj_module; + const char *name; + + if (!PyArg_ParseTuple(args, "Os", &obj_module, &name)) + return NULL; + + LLVMModuleRef module = pycap_get(obj_module); + unsigned num_operands = LLVMGetNamedMetadataNumOperands(module, name); + LLVMValueRef *operands = new LLVMValueRef[num_operands]; + LLVMGetNamedMetadataOperands(module, name, operands); + + PyObject *list = make_list(operands, num_operands); + delete [] operands; + + return list; + LLVMPY_CATCH_ALL +} + + +/*===-- NamedMetaData -----------------------------------------------------===*/ + +_wrap_obj2str( LLVMNamedMetaDataGetName, LLVMNamedMDRef ) +_wrap_objobj2none( LLVMNamedMetaDataAddOperand, LLVMNamedMDRef, LLVMValueRef ) +_wrap_obj2none( LLVMEraseNamedMetaData, LLVMNamedMDRef ) +_wrap_dumper(LLVMDumpNamedMDToString, LLVMNamedMDRef) + +/*===-- Instructions -----------------------------------------------------===*/ + +_wrap_obj2obj(LLVMGetInstructionParent, LLVMValueRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetFirstInstruction, LLVMBasicBlockRef, LLVMValueRef) +_wrap_obj2obj(LLVMGetNextInstruction, LLVMValueRef, LLVMValueRef) +_wrap_obj2obj(LLVMInstIsTerminator, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsBinaryOp, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsShift, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsCast, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsLogicalShift, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsArithmeticShift, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsAssociative, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsCommutative, LLVMValueRef, int) +_wrap_obj2obj(LLVMInstIsVolatile, LLVMValueRef, int) +_wrap_objint2none(LLVMSetVolatile, LLVMValueRef) +_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int) +_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef) + +_wrap_objstrobj2none(LLVMInstSetMetaData, LLVMValueRef, LLVMValueRef) +_wrap_obj2none(LLVMInstructionEraseFromParent, LLVMValueRef) + +/*===-- Call Sites (Call or Invoke) --------------------------------------===*/ + +_wrap_objint2none(LLVMSetInstructionCallConv, LLVMValueRef) +_wrap_obj2obj(LLVMGetInstructionCallConv, LLVMValueRef, int) +_wrap_objintenum2none(LLVMAddInstrAttribute, LLVMValueRef, LLVMAttribute) +_wrap_objintenum2none(LLVMRemoveInstrAttribute, LLVMValueRef, LLVMAttribute) +_wrap_objintint2none(LLVMSetInstrParamAlignment, LLVMValueRef) +_wrap_obj2obj(LLVMIsTailCall, LLVMValueRef, int) +_wrap_objint2none(LLVMSetTailCall, LLVMValueRef) +_wrap_obj2obj(LLVMInstGetCalledFunction, LLVMValueRef, LLVMValueRef) +_wrap_objobj2none(LLVMInstSetCalledFunction, LLVMValueRef, LLVMValueRef) + +/*===-- PHI Nodes --------------------------------------------------------===*/ + +static void LLVMAddIncoming1(LLVMValueRef PhiNode, LLVMValueRef IncomingValue, LLVMBasicBlockRef IncomingBlock) +{ + LLVMAddIncoming(PhiNode, &IncomingValue, &IncomingBlock, 1); +} + +_wrap_objobjobj2none(LLVMAddIncoming1, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMCountIncoming, LLVMValueRef, int) +_wrap_objint2obj(LLVMGetIncomingValue, LLVMValueRef, LLVMValueRef) +_wrap_objint2obj(LLVMGetIncomingBlock, LLVMValueRef, LLVMBasicBlockRef) + +/*===-- Compare Instructions ---------------------------------------------===*/ + +_wrap_obj2obj(LLVMCmpInstGetPredicate, LLVMValueRef, int) + +/*===-- Instruction builders ----------------------------------------------===*/ + +_wrap_none2obj(LLVMCreateBuilder, LLVMBuilderRef) +_wrap_objobj2none(LLVMPositionBuilderBefore, LLVMBuilderRef, LLVMValueRef) +_wrap_objobj2none(LLVMPositionBuilderAtEnd, LLVMBuilderRef, LLVMBasicBlockRef) +_wrap_obj2obj(LLVMGetInsertBlock, LLVMBuilderRef, LLVMBasicBlockRef) +_wrap_obj2none(LLVMDisposeBuilder, LLVMBuilderRef) + +/* Terminators */ + +_wrap_obj2obj(LLVMBuildRetVoid, LLVMBuilderRef, LLVMValueRef) +_wrap_objobj2obj(LLVMBuildRet, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objlist2obj(LLVMBuildRetMultiple, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMBuildBr, LLVMBuilderRef, LLVMBasicBlockRef, LLVMValueRef) +_wrap_objobjobjobj2obj(LLVMBuildCondBr, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMBasicBlockRef, LLVMValueRef) +_wrap_objobjobjint2obj(LLVMBuildSwitch, LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMValueRef) + +static PyObject * +_wLLVMBuildInvoke(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj1, *obj2, *obj3, *obj4, *obj5; + const char *name; + + if (!PyArg_ParseTuple(args, "OOOOOs:LLVMBuildInvoke", &obj1, &obj2, &obj3, &obj4, &obj5, &name)) { + return NULL; + } + + const LLVMBuilderRef builder = pycap_get( obj1); + const LLVMValueRef func = pycap_get( obj2 ) ; + + size_t fnarg_count = PyList_Size(obj3); + LLVMValueRef *fnargs + = make_array_from_list(obj3, fnarg_count); + + const LLVMBasicBlockRef then_blk = pycap_get ( obj4 ) ; + const LLVMBasicBlockRef catch_blk = pycap_get ( obj5 ) ; + + const LLVMValueRef inst + = LLVMBuildInvoke(builder, func, fnargs, fnarg_count, then_blk, + catch_blk, name); + + delete [] fnargs; + + return pycap_new(inst); + LLVMPY_CATCH_ALL +} + +_wrap_obj2obj(LLVMBuildUnreachable, LLVMBuilderRef, LLVMValueRef) + +/* Add a case to the switch instruction */ + +_wrap_objobjobj2none(LLVMAddCase, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef) + +/* Arithmetic */ + +_wrap_objobjobjstr2obj(LLVMBuildAdd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFAdd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSub, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFSub, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildMul, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFMul, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildUDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFDiv, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildURem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSRem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFRem, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildShl, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildLShr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildAShr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildAnd, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildOr, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildXor, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildNeg, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildNot, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) + +/* Memory */ + +_wrap_objobjstr2obj(LLVMBuildMalloc, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildArrayMalloc, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildAlloca, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildArrayAlloca, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, LLVMValueRef) +_wrap_objobj2obj(LLVMBuildFree, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobj2obj(LLVMBuildStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjliststr2obj(LLVMBuildGEP, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjliststr2obj(LLVMBuildInBoundsGEP, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) + + + +_wrap_objint2none(LLVMLdSetAlignment, LLVMValueRef) +_wrap_objint2none(LLVMStSetAlignment, LLVMValueRef) + +/* Casts */ + +_wrap_objobjobjstr2obj(LLVMBuildTrunc, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildZExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPToUI, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPToSI, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildUIToFP, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildSIToFP, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPTrunc, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildFPExt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildPtrToInt, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildIntToPtr, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildBitCast, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) + +/* Comparisons */ + +_wrap_objenumobjobjstr2obj(LLVMBuildICmp, LLVMBuilderRef, LLVMIntPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objenumobjobjstr2obj(LLVMBuildFCmp, LLVMBuilderRef, LLVMRealPredicate, LLVMValueRef, LLVMValueRef, LLVMValueRef) + + +/* Atomics */ +_wrap_objobjobjobjstrint2obj(LLVMBuildAtomicCmpXchg, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objstrobjobjstrint2obj(LLVMBuildAtomicRMW, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjintstrint2obj(LLVMBuildAtomicLoad, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjintstrint2obj(LLVMBuildAtomicStore, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objstrint2obj(LLVMBuildFence, LLVMBuilderRef, LLVMValueRef) + +/* Miscellaneous instructions */ + +_wrap_objobjintstr2obj(LLVMBuildGetResult, LLVMBuilderRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjintstr2obj(LLVMBuildInsertValue, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjstr2obj(LLVMBuildPhi, LLVMBuilderRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjliststr2obj(LLVMBuildCall, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjobjstr2obj(LLVMBuildSelect, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildVAArg, LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, LLVMValueRef) +_wrap_objobjobjstr2obj(LLVMBuildExtractElement, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjobjstr2obj(LLVMBuildInsertElement, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) +_wrap_objobjobjobjstr2obj(LLVMBuildShuffleVector, LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, LLVMValueRef) + + +/*===----------------------------------------------------------------------===*/ +/* Memory Buffer */ +/*===----------------------------------------------------------------------===*/ + +static PyObject * +_wLLVMCreateMemoryBufferWithContentsOfFile(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const char *path; + LLVMMemoryBufferRef ref; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s:LLVMCreateMemoryBufferWithContentsOfFile", &path)) { + return NULL; + } + + char *outmsg; + if (!LLVMCreateMemoryBufferWithContentsOfFile(path, &ref, &outmsg)) { + ret = pycap_new(ref); + } else { + ret = PyUnicode_FromString(outmsg); + LLVMDisposeMessage(outmsg); + } + + return ret; + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMCreateMemoryBufferWithSTDIN(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *ret; + LLVMMemoryBufferRef ref; + char *outmsg; + if (!LLVMCreateMemoryBufferWithSTDIN(&ref, &outmsg)) { + ret = pycap_new(ref); + } else { + ret = PyUnicode_FromString(outmsg); + LLVMDisposeMessage(outmsg); + } + + return ret; + LLVMPY_CATCH_ALL +} + +_wrap_obj2none(LLVMDisposeMemoryBuffer, LLVMMemoryBufferRef) + + +/*===----------------------------------------------------------------------===*/ +/* Pass Manager Builder */ +/*===----------------------------------------------------------------------===*/ + +_wrap_none2obj(LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderRef) +_wrap_obj2none(LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderRef) + +_wrap_objint2none(LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderRef) +_wrap_obj2obj(LLVMPassManagerBuilderGetOptLevel, LLVMPassManagerBuilderRef, int) + +_wrap_objint2none(LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderRef) +_wrap_obj2obj(LLVMPassManagerBuilderGetSizeLevel, LLVMPassManagerBuilderRef, int) + +_wrap_objint2none(LLVMPassManagerBuilderSetVectorize, LLVMPassManagerBuilderRef) +_wrap_obj2obj(LLVMPassManagerBuilderGetVectorize, LLVMPassManagerBuilderRef, int) + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 +_wrap_objint2none(LLVMPassManagerBuilderSetLoopVectorize, LLVMPassManagerBuilderRef) +_wrap_obj2obj(LLVMPassManagerBuilderGetLoopVectorize, LLVMPassManagerBuilderRef, int) +#endif //llvm-3.2 + +_wrap_objint2none(LLVMPassManagerBuilderSetDisableUnitAtATime, + LLVMPassManagerBuilderRef) +_wrap_obj2obj(LLVMPassManagerBuilderGetDisableUnitAtATime, + LLVMPassManagerBuilderRef, int) + +_wrap_objint2none(LLVMPassManagerBuilderSetDisableUnrollLoops, + LLVMPassManagerBuilderRef) +_wrap_obj2obj(LLVMPassManagerBuilderGetDisableUnrollLoops, + LLVMPassManagerBuilderRef, int) + +_wrap_objint2none(LLVMPassManagerBuilderSetDisableSimplifyLibCalls, + LLVMPassManagerBuilderRef) +_wrap_obj2obj(LLVMPassManagerBuilderGetDisableSimplifyLibCalls, + LLVMPassManagerBuilderRef, int) + +_wrap_objint2none(LLVMPassManagerBuilderUseInlinerWithThreshold, + LLVMPassManagerBuilderRef) + + +_wrap_objobj2none(LLVMPassManagerBuilderPopulateFunctionPassManager, + LLVMPassManagerBuilderRef, + LLVMPassManagerRef) + +_wrap_objobj2none(LLVMPassManagerBuilderPopulateModulePassManager, + LLVMPassManagerBuilderRef, + LLVMPassManagerRef) + + +/*===----------------------------------------------------------------------===*/ +/* Pass Manager */ +/*===----------------------------------------------------------------------===*/ + +_wrap_none2obj(LLVMCreatePassManager, LLVMPassManagerRef) +_wrap_obj2obj(LLVMCreateFunctionPassManagerForModule, LLVMModuleRef, LLVMPassManagerRef) +_wrap_objobj2obj(LLVMRunPassManager, LLVMPassManagerRef, LLVMModuleRef, int) +_wrap_obj2obj(LLVMInitializeFunctionPassManager, LLVMPassManagerRef, int) +_wrap_objobj2obj(LLVMRunFunctionPassManager, LLVMPassManagerRef, LLVMValueRef, int) +_wrap_obj2obj(LLVMFinalizeFunctionPassManager, LLVMPassManagerRef, int) +_wrap_obj2none(LLVMDisposePassManager, LLVMPassManagerRef) +_wrap_none2str(LLVMDumpPasses) +_wrap_objstr2obj(LLVMAddPassByName, LLVMPassManagerRef, int) + + +_wrap_objobj2none(LLVMAddPass, LLVMPassManagerRef, LLVMPassRef) +_wrap_none2none(LLVMInitializePasses) + +_wrap_none2obj(LLVMInitializeNativeTarget, int) +_wrap_none2obj(LLVMInitializeNativeTargetAsmPrinter, int) +#if !defined(LLVM_DISABLE_PTX) +# if LLVM_HAS_NVPTX +_wrap_none2none(LLVMInitializeNVPTXTarget) +_wrap_none2none(LLVMInitializeNVPTXTargetInfo) +_wrap_none2none( LLVMInitializeNVPTXTargetMC ) +_wrap_none2none(LLVMInitializeNVPTXAsmPrinter) +# else +_wrap_none2none(LLVMInitializePTXTarget) +_wrap_none2none(LLVMInitializePTXTargetInfo) +_wrap_none2none( LLVMInitializePTXTargetMC ) +_wrap_none2none(LLVMInitializePTXAsmPrinter) +# endif +#endif + +/*===----------------------------------------------------------------------===*/ +/* Passes */ +/*===----------------------------------------------------------------------===*/ + +_wrap_str2obj(LLVMCreatePassByName, LLVMPassRef) +_wrap_obj2none(LLVMDisposePass, LLVMPassRef) +_wrap_obj2str(LLVMGetPassName, LLVMPassRef) +_wrap_obj2none(LLVMPassDump, LLVMPassRef) + +_wrap_str2obj(LLVMCreateTargetLibraryInfo, LLVMPassRef) + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 +_wrap_obj2obj(LLVMCreateTargetTransformInfo, LLVMTargetMachineRef, LLVMPassRef) +#endif + + +/*===----------------------------------------------------------------------===*/ +/* Target Machine */ +/*===----------------------------------------------------------------------===*/ + +_wrap_none2str(LLVMGetHostCPUName); + +_wrap_obj2obj(LLVMTargetMachineFromEngineBuilder, LLVMEngineBuilderRef, + LLVMTargetMachineRef) +_wrap_obj2none(LLVMDisposeTargetMachine, LLVMTargetMachineRef) + +static PyObject * +_wLLVMTargetMachineLookup(PyObject * self, PyObject * args) +{ + LLVMPY_TRY + const char *triple; + const char *cpu; + const char *features; + int opt, codemodel; + + if (!PyArg_ParseTuple(args, "sssii", &triple, &cpu, &features, + &opt, &codemodel)) + return NULL; + + std::string error; + LLVMTargetMachineRef tm = LLVMTargetMachineLookup(triple, cpu, features, + opt, codemodel, error); + if(!error.empty()){ + PyErr_SetString(PyExc_RuntimeError, error.c_str()); + return NULL; + } + return pycap_new(tm); + LLVMPY_CATCH_ALL +} + + +static PyObject * +_wLLVMCreateTargetMachine(PyObject * self, PyObject * args) +{ + LLVMPY_TRY + const char *triple; + const char *cpu; + const char *features; + int opt, codemodel; + + if (!PyArg_ParseTuple(args, "sssii", &triple, &cpu, &features, + &opt, &codemodel)) + return NULL; + + std::string error; + LLVMTargetMachineRef tm = LLVMCreateTargetMachine(triple, cpu, features, + opt, codemodel, error); + if(!error.empty()){ + PyErr_SetString(PyExc_RuntimeError, error.c_str()); + return NULL; + } + return pycap_new(tm); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMTargetMachineEmitFile(PyObject * self, PyObject * args) +{ + LLVMPY_TRY + PyObject *arg_tm, *arg_m; + int arg_use_asm; + + if (!PyArg_ParseTuple(args, "OOi", &arg_tm, &arg_m, &arg_use_asm)) + return NULL; + + const LLVMTargetMachineRef tm + = pycap_get( arg_tm ) ; + const LLVMModuleRef m = pycap_get( arg_m ) ; + + std::string error; + size_t len; + unsigned const char * ubytes + = LLVMTargetMachineEmitFile(tm, m, arg_use_asm, &len, error); + if ( !error.empty() ){ + PyErr_SetString(PyExc_RuntimeError, error.c_str()); + return NULL; + } + + const char *chars = reinterpret_cast(ubytes) ; + PyObject * ret = PyBytes_FromStringAndSize(chars, len); + delete [] ubytes; + return ret; + LLVMPY_CATCH_ALL +} + +_wrap_obj2obj(LLVMTargetMachineGetTargetData, LLVMTargetMachineRef, + LLVMTargetDataRef) +_wrap_obj2str(LLVMTargetMachineGetTargetName, LLVMTargetMachineRef) +_wrap_obj2str(LLVMTargetMachineGetTargetShortDescription, LLVMTargetMachineRef) +_wrap_obj2str(LLVMTargetMachineGetTriple, LLVMTargetMachineRef) +_wrap_obj2str(LLVMTargetMachineGetCPU, LLVMTargetMachineRef) +_wrap_obj2str(LLVMTargetMachineGetFS, LLVMTargetMachineRef) +_wrap_none2none(LLVMPrintRegisteredTargetsForVersion) + + +/*===----------------------------------------------------------------------===*/ +/* Target Data */ +/*===----------------------------------------------------------------------===*/ + +_wrap_str2obj(LLVMCreateTargetData, LLVMTargetDataRef) +_wrap_obj2none(LLVMDisposeTargetData, LLVMTargetDataRef) + +static PyObject * +_wLLVMTargetDataAsString(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const LLVMTargetDataRef td = get_object_arg(args); + + char *tdrep = LLVMCopyStringRepOfTargetData(td); + PyObject *ret = PyUnicode_FromString(tdrep); + LLVMDisposeMessage(tdrep); + return ret; + LLVMPY_CATCH_ALL +} + +_wrap_objobj2none(LLVMAddTargetData, LLVMTargetDataRef, LLVMPassManagerRef) +_wrap_obj2obj(LLVMByteOrder, LLVMTargetDataRef, int) +_wrap_obj2obj(LLVMPointerSize, LLVMTargetDataRef, int) +_wrap_obj2obj(LLVMIntPtrType, LLVMTargetDataRef, LLVMTypeRef) +_wrap_objobj2obj(LLVMSizeOfTypeInBits, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) +_wrap_objobj2obj(LLVMStoreSizeOfType, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) +_wrap_objobj2obj(LLVMABISizeOfType, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) +_wrap_objobj2obj(LLVMABIAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, + int) +_wrap_objobj2obj(LLVMCallFrameAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, + int) +_wrap_objobj2obj(LLVMPreferredAlignmentOfType, LLVMTargetDataRef, LLVMTypeRef, + int) +_wrap_objobj2obj(LLVMPreferredAlignmentOfGlobal, LLVMTargetDataRef, + LLVMValueRef, int) +_wrap_objobjull2obj(LLVMElementAtOffset, LLVMTargetDataRef, LLVMTypeRef, int) +_wrap_objobjint2obj(LLVMOffsetOfElement, LLVMTargetDataRef, LLVMTypeRef, + llvmwrap_ull) + + +/*===----------------------------------------------------------------------===*/ +/* Engine Builder */ +/*===----------------------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMCreateEngineBuilder, LLVMModuleRef, LLVMEngineBuilderRef) +_wrap_obj2none(LLVMDisposeEngineBuilder, LLVMEngineBuilderRef) +_wrap_obj2none(LLVMEngineBuilderForceJIT, LLVMEngineBuilderRef) +_wrap_obj2none(LLVMEngineBuilderForceInterpreter, LLVMEngineBuilderRef) +_wrap_objint2none(LLVMEngineBuilderSetOptLevel, LLVMEngineBuilderRef) +_wrap_objstr2none(LLVMEngineBuilderSetMCPU, LLVMEngineBuilderRef) +_wrap_objstr2none(LLVMEngineBuilderSetMAttrs, LLVMEngineBuilderRef) + +static PyObject * +_wLLVMEngineBuilderCreate(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const LLVMEngineBuilderRef obj + = get_object_arg(args) ; + + std::string outmsg; + const LLVMExecutionEngineRef ee = LLVMEngineBuilderCreate(obj, outmsg); + + PyObject * ret; + if( !ee ){ // check if error message is set. + ret = PyUnicode_FromString(outmsg.c_str()); + }else{ + ret = pycap_new(ee); + } + + return ret; + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMEngineBuilderCreateTM(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj, *tm; + if (!PyArg_ParseTuple(args, "OO", &obj, &tm)) + return NULL; + + const LLVMEngineBuilderRef objref = pycap_get( obj ); + const LLVMTargetMachineRef tmref = pycap_get( tm ); + std::string outmsg; + + const LLVMExecutionEngineRef ee = LLVMEngineBuilderCreateTM(objref, tmref, + outmsg); + + PyObject * ret; + if( !ee ){ // check if error message is set. + ret = PyUnicode_FromString(outmsg.c_str()); + }else{ + ret = pycap_new(ee); + } + + return ret; + LLVMPY_CATCH_ALL +} + +/*===----------------------------------------------------------------------===*/ +/* Execution Engine */ +/*===----------------------------------------------------------------------===*/ + +// Use EngineBuilder +//static PyObject * +//_wLLVMCreateExecutionEngine(PyObject *self, PyObject *args) +//{ +// LLVMPY_TRY +// PyObject *obj; +// int force_interpreter; +// char *outmsg = 0; +// int error; +// +// if (!PyArg_ParseTuple(args, "Oi", &obj, &force_interpreter)) +// return NULL; +// +// const LLVMModuleRef mod = pycap_get( obj ) ; +// +// LLVMExecutionEngineRef ee; +// if (force_interpreter) +// error = LLVMCreateInterpreterForModule(&ee, mod, &outmsg); +// else +// error = LLVMCreateJITCompilerForModule(&ee, mod, 1 /*fast*/, &outmsg); +// +// PyObject *ret; +// if (error) { +// ret = PyUnicode_FromString(outmsg); +// LLVMDisposeMessage(outmsg); +// } else { +// ret = pycap_new(ee); +// } +// +// return ret; +// LLVMPY_CATCH_ALL +//} + +static PyObject * +_wLLVMGetPointerToFunction(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj_ee; + PyObject *obj_fn; + + if (!PyArg_ParseTuple(args, "OO", &obj_ee, &obj_fn)) + return NULL; + + const LLVMExecutionEngineRef ee = pycap_get(obj_ee ) ; + const LLVMValueRef fn = pycap_get( obj_fn ) ; + + return PyLong_FromVoidPtr(LLVMGetPointerToFunction(ee,fn)); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGetPointerToGlobal(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj_ee; + PyObject *obj_val; + + if (!PyArg_ParseTuple(args, "OO", &obj_ee, &obj_val)) + return NULL; + + const LLVMExecutionEngineRef ee = pycap_get( obj_ee ) ; + const LLVMValueRef val = pycap_get( obj_val ) ; + + return PyLong_FromVoidPtr(LLVMGetPointerToGlobal(ee, val)); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMAddGlobalMapping(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj_ee; + PyObject *obj_val; + PyObject *obj_long; + void* address; + + if (!PyArg_ParseTuple(args, "OOO", &obj_ee, &obj_val, &obj_long)) + return NULL; + + address = PyLong_AsVoidPtr(obj_long); + if (PyErr_Occurred()) return NULL; + + const LLVMExecutionEngineRef ee = pycap_get( obj_ee ); + const LLVMValueRef val = pycap_get( obj_val ); + + LLVMAddGlobalMapping(ee, val, address); + + Py_RETURN_NONE; + + LLVMPY_CATCH_ALL +} + +/* the args should have been ptr, num */ +LLVMGenericValueRef LLVMRunFunction2(LLVMExecutionEngineRef EE, + LLVMValueRef F, LLVMGenericValueRef *Args, unsigned NumArgs) +{ + return LLVMRunFunction(EE, F, NumArgs, Args); +} + +static PyObject * +_wLLVMRemoveModule2(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj_ee; + PyObject *obj_mod; + if (!PyArg_ParseTuple(args, "OO", &obj_ee, &obj_mod)) + return NULL; + + const LLVMExecutionEngineRef ee = pycap_get( obj_ee ) ; + const LLVMModuleRef mod = pycap_get(obj_mod) ; + + char *outmsg = 0; + LLVMModuleRef mod_new = 0; + LLVMRemoveModule(ee, mod, &mod_new, &outmsg); + PyObject *ret; + if (mod_new) { + ret = pycap_new(mod_new); + } else { + if (outmsg) { + ret = PyUnicode_FromString(outmsg); + LLVMDisposeMessage(outmsg); + } else { + ret = PyUnicode_FromString("error"); + } + } + + return ret; + LLVMPY_CATCH_ALL +} + +_wrap_obj2none(LLVMDisposeExecutionEngine, LLVMExecutionEngineRef) +_wrap_objint2none(LLVMExecutionEngineDisableLazyCompilation, + LLVMExecutionEngineRef) +_wrap_objobjlist2obj(LLVMRunFunction2, LLVMExecutionEngineRef, + LLVMValueRef, LLVMGenericValueRef, LLVMGenericValueRef) +_wrap_obj2obj(LLVMGetExecutionEngineTargetData, LLVMExecutionEngineRef, + LLVMTargetDataRef) +_wrap_obj2none(LLVMRunStaticConstructors, LLVMExecutionEngineRef) +_wrap_obj2none(LLVMRunStaticDestructors, LLVMExecutionEngineRef) +_wrap_objobj2none(LLVMFreeMachineCodeForFunction, LLVMExecutionEngineRef, + LLVMValueRef) +_wrap_objobj2none(LLVMAddModule, LLVMExecutionEngineRef, + LLVMModuleRef) + + +/*===----------------------------------------------------------------------===*/ +/* Generic Value */ +/*===----------------------------------------------------------------------===*/ + +static PyObject * +_wLLVMCreateGenericValueOfInt(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj1; + unsigned PY_LONG_LONG n; + int is_signed; + LLVMGenericValueRef gv; + + if (!PyArg_ParseTuple(args, "OKi", &obj1, &n, &is_signed)) + return NULL; + + const LLVMTypeRef ty = pycap_get( obj1 ) ; + + gv = LLVMCreateGenericValueOfInt(ty, n, is_signed); + return pycap_new(gv); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMCreateGenericValueOfFloat(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj1; + double d; + LLVMGenericValueRef gv; + + if (!PyArg_ParseTuple(args, "Od", &obj1, &d)) + return NULL; + + const LLVMTypeRef ty = pycap_get( obj1 ) ; + + gv = LLVMCreateGenericValueOfFloat(ty, d); + return pycap_new(gv); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMCreateGenericValueOfPointer(PyObject *self, PyObject *args) +{ + LLVMPY_TRY +// PyObject *obj1; +// LLVMTypeRef ty; //unused? + unsigned PY_LONG_LONG n_; + size_t n; + + if (!PyArg_ParseTuple(args, "K", &n_)) + return NULL; + + n=n_; + + const LLVMGenericValueRef gv = LLVMCreateGenericValueOfPointer((void*)n); + return pycap_new(gv); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGenericValueToInt(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj1; + int is_signed; + unsigned PY_LONG_LONG val; + + if (!PyArg_ParseTuple(args, "Oi", &obj1, &is_signed)) + return NULL; + + LLVMGenericValueRef gv = pycap_get(obj1); + + val = LLVMGenericValueToInt(gv, is_signed); + return is_signed ? + PyLong_FromLongLong((PY_LONG_LONG)val) : + PyLong_FromUnsignedLongLong(val); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGenericValueToFloat(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj1, *obj2; + + if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) + return NULL; + + const LLVMTypeRef ty = pycap_get( obj1 ) ; + const LLVMGenericValueRef gv = pycap_get( obj2 ) ; + + double val = LLVMGenericValueToFloat(ty, gv); + return PyFloat_FromDouble(val); + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMGenericValueToPointer(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + PyObject *obj1; + + if (!PyArg_ParseTuple(args, "O", &obj1)) + return NULL; + + const LLVMGenericValueRef gv = pycap_get( obj1 ) ; + + void * val = LLVMGenericValueToPointer(gv); + return PyLong_FromVoidPtr(val); + LLVMPY_CATCH_ALL +} + +_wrap_obj2none(LLVMDisposeGenericValue, LLVMGenericValueRef) + + +/*===----------------------------------------------------------------------===*/ +/* Misc */ +/*===----------------------------------------------------------------------===*/ + +static PyObject * +_wLLVMGetVersion(PyObject *self, PyObject *args) +{ + int major = LLVM_VERSION_MAJOR; + int minor = LLVM_VERSION_MINOR; + return Py_BuildValue("(i,i)", major, minor); +} + +_wrap_objintlist2obj(LLVMGetIntrinsic, LLVMModuleRef, LLVMTypeRef, + LLVMValueRef) + +static PyObject * +_wLLVMLoadLibraryPermanently(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const char *filename; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s:LLVMLoadLibraryPermanently", &filename)) { + return NULL; + } + + char *outmsg = 0; + if (!LLVMLoadLibraryPermanently(filename, &outmsg)) { + if (outmsg) { + ret = PyUnicode_FromString(outmsg); + LLVMDisposeMessage(outmsg); + return ret; + } + } + + /* note: success => None, failure => string with error message */ + Py_RETURN_NONE; + LLVMPY_CATCH_ALL +} + +static PyObject * +_wLLVMParseEnvOpts(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + const char * progname; + const char * envname; + if(!PyArg_ParseTuple(args, "ss", &progname, &envname)) { + return NULL; + } + + llvm::cl::ParseEnvironmentOptions(progname, envname); + + Py_RETURN_NONE; + LLVMPY_CATCH_ALL +} + +_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) + +_wrap_none2str(LLVMDefaultTargetTriple) + + +/* Expose the void* inside a PyCObject as a PyLong. This allows us to + * use it as a unique ID. */ +static PyObject * +_wPyCObjectVoidPtrToPyLong(PyObject *self, PyObject *args) +{ + LLVMPY_TRY + void *p = get_object_arg(args); + return PyLong_FromVoidPtr(p); + LLVMPY_CATCH_ALL +} + + +/*===----------------------------------------------------------------------===*/ +/* Python member method table */ +/*===----------------------------------------------------------------------===*/ + +#define _method( func ) { # func , ( PyCFunction )_w ## func , METH_VARARGS , NULL }, +#define _pass( P ) _method( LLVMAdd ## P ## Pass ) + +static PyMethodDef core_methods[] = { + + /* Modules */ + _method( LLVMModuleCreateWithName ) + _method( LLVMGetDataLayout ) + _method( LLVMSetDataLayout ) + _method( LLVMGetModuleIdentifier ) + _method( LLVMSetModuleIdentifier ) + _method( LLVMGetTarget ) + _method( LLVMSetTarget ) + _method( LLVMModuleAddLibrary ) + _method( LLVMGetTypeByName ) + _method( LLVMDumpModule ) + _method( LLVMDisposeModule ) + _method( LLVMDumpModuleToString ) + _method( LLVMVerifyModule ) + _method( LLVMGetModuleFromAssembly ) + _method( LLVMGetModuleFromBitcode ) + _method( LLVMGetBitcodeFromModule ) + _method( LLVMGetNativeCodeFromModule ) + _method( LLVMModuleGetPointerSize ) + _method( LLVMModuleGetOrInsertFunction ) + _method( LLVMLinkModules ) + _method( LLVMModuleGetOrInsertNamedMetaData ) + _method( LLVMModuleGetNamedMetaData ) + _method( LLVMCloneModule ) + + /* Types */ + + /* General */ + _method( LLVMGetTypeKind ) + _method( LLVMDumpTypeToString ) + + /* Integer types */ + _method( LLVMInt1Type ) + _method( LLVMInt8Type ) + _method( LLVMInt16Type ) + _method( LLVMInt32Type ) + _method( LLVMInt64Type ) + _method( LLVMIntType ) + _method( LLVMGetIntTypeWidth ) + + /* Floating-point types */ + _method( LLVMFloatType ) + _method( LLVMDoubleType ) + _method( LLVMX86FP80Type ) + _method( LLVMFP128Type ) + _method( LLVMPPCFP128Type ) + + /* Function types */ + _method( LLVMFunctionType ) + _method( LLVMIsFunctionVarArg ) + _method( LLVMGetReturnType ) + _method( LLVMCountParamTypes ) + _method( LLVMGetFunctionTypeParams ) + + /* Struct types */ + _method( LLVMStructType ) + _method( LLVMStructTypeIdentified ) + _method( LLVMSetStructBody ) + _method( LLVMCountStructElementTypes ) + _method( LLVMGetStructElementTypes ) + _method( LLVMIsPackedStruct ) + _method( LLVMIsOpaqueStruct ) + _method( LLVMIsLiteralStruct ) + _method( LLVMGetStructName ) + _method( LLVMSetStructName ) + + /* Array types */ + _method( LLVMArrayType ) + _method( LLVMGetElementType ) + _method( LLVMGetArrayLength ) + + /* Pointer types */ + _method( LLVMPointerType ) + _method( LLVMGetPointerAddressSpace ) + + /* Vector type */ + _method( LLVMVectorType ) + _method( LLVMGetVectorSize ) + + /* Other types */ + _method( LLVMVoidType ) + _method( LLVMLabelType ) + + /* Type handles */ + /* + _method( LLVMResolveTypeHandle ) + _method( LLVMDisposeTypeHandle ) + */ + + /* Values */ + + /* Operations on all values */ + _method( LLVMTypeOf ) + _method( LLVMGetValueName ) + _method( LLVMSetValueName ) + _method( LLVMDumpValue ) + _method( LLVMDumpValueToString ) + _method( LLVMValueGetID ) + _method( LLVMValueGetNumUses ) + _method( LLVMValueGetUses ) + + /* Users */ + + _method( LLVMUserGetNumOperands ) + _method( LLVMUserGetOperand ) + + /* Constant Values */ + + /* Operations on constants of any type */ + _method( LLVMConstNull ) + _method( LLVMConstAllOnes ) + _method( LLVMGetUndef ) + _method( LLVMIsConstant ) + _method( LLVMIsNull ) + _method( LLVMIsUndef ) + + /* Operations on scalar constants */ + _method( LLVMConstInt ) + _method( LLVMConstReal ) + _method( LLVMConstRealOfString ) + _method( LLVMConstIntGetZExtValue ) + _method( LLVMConstIntGetSExtValue ) + + /* Operations on composite constants */ + _method( LLVMConstString ) + _method( LLVMConstArray ) + _method( LLVMConstStruct ) + _method( LLVMConstVector ) + + /* Constant expressions */ + _method( LLVMGetConstExprOpcode ) + _method( LLVMGetConstExprOpcodeName ) + _method( LLVMSizeOf ) + _method( LLVMConstNeg ) + _method( LLVMConstNot ) + _method( LLVMConstAdd ) + _method( LLVMConstFAdd ) + _method( LLVMConstSub ) + _method( LLVMConstFSub ) + _method( LLVMConstMul ) + _method( LLVMConstFMul ) + _method( LLVMConstUDiv ) + _method( LLVMConstSDiv ) + _method( LLVMConstFDiv ) + _method( LLVMConstURem ) + _method( LLVMConstSRem ) + _method( LLVMConstFRem ) + _method( LLVMConstAnd ) + _method( LLVMConstOr ) + _method( LLVMConstXor ) + _method( LLVMConstICmp ) + _method( LLVMConstFCmp ) + _method( LLVMConstShl ) + _method( LLVMConstLShr ) + _method( LLVMConstAShr ) + _method( LLVMConstGEP ) + _method( LLVMConstTrunc ) + _method( LLVMConstSExt ) + _method( LLVMConstZExt ) + _method( LLVMConstFPTrunc ) + _method( LLVMConstFPExt ) + _method( LLVMConstUIToFP ) + _method( LLVMConstSIToFP ) + _method( LLVMConstFPToUI ) + _method( LLVMConstFPToSI ) + _method( LLVMConstPtrToInt ) + _method( LLVMConstIntToPtr ) + _method( LLVMConstBitCast ) + _method( LLVMConstSelect ) + _method( LLVMConstExtractElement ) + _method( LLVMConstInsertElement ) + _method( LLVMConstShuffleVector ) + + /* Globals */ + + /* Globals (general) */ + _method( LLVMGetGlobalParent ) + _method( LLVMIsDeclaration ) + _method( LLVMGetLinkage ) + _method( LLVMSetLinkage ) + _method( LLVMGetSection ) + _method( LLVMSetSection ) + _method( LLVMGetVisibility ) + _method( LLVMSetVisibility ) + _method( LLVMGetAlignment ) + _method( LLVMSetAlignment ) + + /* Global Variables */ + _method( LLVMAddGlobal ) + _method( LLVMAddGlobalInAddressSpace ) + _method( LLVMGetNamedGlobal ) + _method( LLVMGetFirstGlobal ) + _method( LLVMGetNextGlobal ) + _method( LLVMDeleteGlobal ) + _method( LLVMHasInitializer ) + _method( LLVMGetInitializer ) + _method( LLVMSetInitializer ) + _method( LLVMSetThreadLocal ) + _method( LLVMIsThreadLocal ) + _method( LLVMSetGlobalConstant ) + _method( LLVMIsGlobalConstant ) + + /* Functions */ + _method( LLVMAddFunction ) + _method( LLVMGetNamedFunction ) + _method( LLVMGetFirstFunction ) + _method( LLVMGetNextFunction ) + _method( LLVMDeleteFunction ) + _method( LLVMGetIntrinsicID ) + _method( LLVMGetFunctionCallConv ) + _method( LLVMSetFunctionCallConv ) + _method( LLVMGetGC ) + _method( LLVMSetGC ) + _method( LLVMGetDoesNotThrow ) + _method( LLVMSetDoesNotThrow ) + _method( LLVMVerifyFunction ) + _method( LLVMViewFunctionCFG ) + _method( LLVMViewFunctionCFGOnly ) + _method( LLVMAddFunctionAttr ) + _method( LLVMRemoveFunctionAttr ) + _method( LLVMGetFunctionFromInlineAsm ) + + /* Arguments */ + _method( LLVMCountParams ) + _method( LLVMGetFirstParam ) + _method( LLVMGetNextParam ) + _method( LLVMGetParamParent ) + _method( LLVMAddAttribute ) + _method( LLVMRemoveAttribute ) + _method( LLVMSetParamAlignment ) + _method( LLVMGetParamAlignment ) + + /* Basic Blocks */ + _method( LLVMGetBasicBlockParent ) + _method( LLVMCountBasicBlocks ) + _method( LLVMGetFirstBasicBlock ) + _method( LLVMGetNextBasicBlock ) + _method( LLVMGetEntryBasicBlock ) + _method( LLVMAppendBasicBlock ) + _method( LLVMInsertBasicBlock ) + _method( LLVMDeleteBasicBlock ) + + /* MetaData */ + _method( LLVMMetaDataGet ) + _method( LLVMGetNamedMetadataOperands ) + _method( LLVMAddNamedMetadataOperand ) + _method( LLVMMetaDataGetOperand ) + _method( LLVMMetaDataGetNumOperands ) + _method( LLVMMetaDataStringGet ) + + /* NamedMetaData */ + _method( LLVMNamedMetaDataGetName ) + _method( LLVMNamedMetaDataAddOperand ) + _method( LLVMEraseNamedMetaData ) + _method( LLVMDumpNamedMDToString ) + + /* Instructions */ + _method( LLVMGetInstructionParent ) + _method( LLVMGetFirstInstruction ) + _method( LLVMGetNextInstruction ) + _method( LLVMInstIsTerminator ) + _method( LLVMInstIsBinaryOp ) + _method( LLVMInstIsShift ) + _method( LLVMInstIsCast ) + _method( LLVMInstIsLogicalShift ) + _method( LLVMInstIsArithmeticShift ) + _method( LLVMInstIsAssociative ) + _method( LLVMInstIsCommutative ) + _method( LLVMInstIsVolatile ) + _method( LLVMSetVolatile ) + _method( LLVMInstGetOpcode ) + _method( LLVMInstGetOpcodeName ) + + _method( LLVMInstSetMetaData ) + _method( LLVMInstructionEraseFromParent ) + + /* Call Sites (Call or Invoke) */ + _method( LLVMSetInstructionCallConv ) + _method( LLVMGetInstructionCallConv ) + _method( LLVMIsTailCall ) + _method( LLVMSetTailCall ) + _method( LLVMAddInstrAttribute ) + _method( LLVMRemoveInstrAttribute ) + _method( LLVMSetInstrParamAlignment ) + _method( LLVMInstGetCalledFunction ) + _method( LLVMInstSetCalledFunction ) + + /* PHI Nodes */ + _method( LLVMAddIncoming1 ) + _method( LLVMCountIncoming ) + _method( LLVMGetIncomingValue ) + _method( LLVMGetIncomingBlock ) + + /* Comparison Instructions */ + _method( LLVMCmpInstGetPredicate ) + + /* Instruction builders */ + _method( LLVMCreateBuilder ) + _method( LLVMPositionBuilderBefore ) + _method( LLVMPositionBuilderAtEnd ) + _method( LLVMGetInsertBlock ) + _method( LLVMDisposeBuilder ) + + /* Terminators */ + _method( LLVMBuildRetVoid ) + _method( LLVMBuildRet ) + _method( LLVMBuildRetMultiple ) + _method( LLVMBuildBr ) + _method( LLVMBuildCondBr ) + _method( LLVMBuildSwitch ) + _method( LLVMBuildInvoke ) + _method( LLVMBuildUnreachable ) + + /* Add a case to the switch instruction */ + _method( LLVMAddCase ) + + /* Arithmetic */ + _method( LLVMBuildAdd ) + _method( LLVMBuildFAdd) + _method( LLVMBuildSub ) + _method( LLVMBuildFSub) + _method( LLVMBuildMul ) + _method( LLVMBuildFMul) + _method( LLVMBuildUDiv ) + _method( LLVMBuildSDiv ) + _method( LLVMBuildFDiv ) + _method( LLVMBuildURem ) + _method( LLVMBuildSRem ) + _method( LLVMBuildFRem ) + _method( LLVMBuildShl ) + _method( LLVMBuildLShr ) + _method( LLVMBuildAShr ) + _method( LLVMBuildAnd ) + _method( LLVMBuildOr ) + _method( LLVMBuildXor ) + _method( LLVMBuildNeg ) + _method( LLVMBuildNot ) + + /* Memory */ + _method( LLVMBuildMalloc ) + _method( LLVMBuildArrayMalloc ) + _method( LLVMBuildAlloca ) + _method( LLVMBuildArrayAlloca ) + _method( LLVMBuildFree ) + _method( LLVMBuildLoad ) + _method( LLVMBuildStore ) + _method( LLVMBuildGEP ) + _method( LLVMBuildInBoundsGEP ) + + _method( LLVMLdSetAlignment ) + _method( LLVMStSetAlignment ) + + /* Casts */ + _method( LLVMBuildTrunc ) + _method( LLVMBuildZExt ) + _method( LLVMBuildSExt ) + _method( LLVMBuildFPToUI ) + _method( LLVMBuildFPToSI ) + _method( LLVMBuildUIToFP ) + _method( LLVMBuildSIToFP ) + _method( LLVMBuildFPTrunc ) + _method( LLVMBuildFPExt ) + _method( LLVMBuildPtrToInt ) + _method( LLVMBuildIntToPtr ) + _method( LLVMBuildBitCast ) + + /* Comparisons */ + _method( LLVMBuildICmp ) + _method( LLVMBuildFCmp ) + + /* Atomics */ + _method( LLVMBuildAtomicCmpXchg ) + _method( LLVMBuildAtomicRMW ) + _method( LLVMBuildAtomicLoad ) + _method( LLVMBuildAtomicStore ) + _method( LLVMBuildFence ) + + /* Miscellaneous instructions */ + _method( LLVMBuildGetResult ) + _method( LLVMBuildInsertValue ) + _method( LLVMBuildPhi ) + _method( LLVMBuildCall ) + _method( LLVMBuildSelect ) + _method( LLVMBuildVAArg ) + _method( LLVMBuildExtractElement ) + _method( LLVMBuildInsertElement ) + _method( LLVMBuildShuffleVector ) + + /* Memory Buffer */ + _method( LLVMCreateMemoryBufferWithContentsOfFile ) + _method( LLVMCreateMemoryBufferWithSTDIN ) + _method( LLVMDisposeMemoryBuffer ) + + /* Pass Manager Builder */ + + _method( LLVMPassManagerBuilderCreate ) + _method( LLVMPassManagerBuilderDispose ) + + _method( LLVMPassManagerBuilderSetOptLevel ) + _method( LLVMPassManagerBuilderGetOptLevel ) + + _method( LLVMPassManagerBuilderSetSizeLevel ) + _method( LLVMPassManagerBuilderGetSizeLevel ) + + _method( LLVMPassManagerBuilderSetVectorize ) + _method( LLVMPassManagerBuilderGetVectorize ) +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 + _method( LLVMPassManagerBuilderSetLoopVectorize ) + _method( LLVMPassManagerBuilderGetLoopVectorize ) +#endif // llvm-3.2 + + _method( LLVMPassManagerBuilderSetDisableUnitAtATime ) + _method( LLVMPassManagerBuilderGetDisableUnitAtATime ) + + _method( LLVMPassManagerBuilderSetDisableUnrollLoops ) + _method( LLVMPassManagerBuilderGetDisableUnrollLoops ) + + _method( LLVMPassManagerBuilderSetDisableSimplifyLibCalls ) + _method( LLVMPassManagerBuilderGetDisableSimplifyLibCalls ) + + _method( LLVMPassManagerBuilderUseInlinerWithThreshold ) + + _method( LLVMPassManagerBuilderPopulateFunctionPassManager ) + _method( LLVMPassManagerBuilderPopulateModulePassManager ) + + /* Pass Manager */ + _method( LLVMCreatePassManager ) + _method( LLVMCreateFunctionPassManagerForModule ) + _method( LLVMRunPassManager ) + _method( LLVMInitializeFunctionPassManager ) + _method( LLVMRunFunctionPassManager ) + _method( LLVMFinalizeFunctionPassManager ) + _method( LLVMDisposePassManager ) + _method( LLVMDumpPasses ) + _method( LLVMAddPassByName ) + _method( LLVMAddPass ) + _method( LLVMInitializePasses ) + + _method( LLVMInitializeNativeTarget ) + _method( LLVMInitializeNativeTargetAsmPrinter ) +#if !defined(LLVM_DISABLE_PTX) +# if LLVM_HAS_NVPTX + _method( LLVMInitializeNVPTXTarget ) + _method( LLVMInitializeNVPTXTargetInfo ) + _method( LLVMInitializeNVPTXTargetMC ) + _method( LLVMInitializeNVPTXAsmPrinter ) +# else + _method( LLVMInitializePTXTarget ) + _method( LLVMInitializePTXTargetInfo ) + _method( LLVMInitializePTXTargetMC ) + _method( LLVMInitializePTXAsmPrinter ) +# endif +#endif + + /* Target Machine */ + _method( LLVMTargetMachineFromEngineBuilder ) + _method( LLVMDisposeTargetMachine ) + _method( LLVMCreateTargetMachine ) + _method( LLVMTargetMachineLookup ) + _method( LLVMTargetMachineEmitFile ) + _method( LLVMTargetMachineGetTargetData ) + _method( LLVMTargetMachineGetTargetName ) + _method( LLVMTargetMachineGetTargetShortDescription ) + _method( LLVMTargetMachineGetTriple ) + _method( LLVMTargetMachineGetCPU ) + _method( LLVMTargetMachineGetFS ) + + _method( LLVMPrintRegisteredTargetsForVersion ) + _method( LLVMGetHostCPUName ) + + /* Target Data */ + _method( LLVMCreateTargetData ) + _method( LLVMDisposeTargetData ) + _method( LLVMTargetDataAsString ) + _method( LLVMAddTargetData ) + _method( LLVMByteOrder ) + _method( LLVMPointerSize ) + _method( LLVMIntPtrType ) + _method( LLVMSizeOfTypeInBits ) + _method( LLVMStoreSizeOfType ) + _method( LLVMABISizeOfType ) + _method( LLVMABIAlignmentOfType ) + _method( LLVMCallFrameAlignmentOfType ) + _method( LLVMPreferredAlignmentOfType ) + _method( LLVMPreferredAlignmentOfGlobal ) + _method( LLVMElementAtOffset ) + _method( LLVMOffsetOfElement ) + + /* Engine Builder */ + + _method( LLVMCreateEngineBuilder ) + _method( LLVMDisposeEngineBuilder ) + _method( LLVMEngineBuilderForceJIT ) + _method( LLVMEngineBuilderForceInterpreter ) + _method( LLVMEngineBuilderSetOptLevel ) + _method( LLVMEngineBuilderSetMCPU ) + _method( LLVMEngineBuilderSetMAttrs ) + _method( LLVMEngineBuilderCreate ) + _method( LLVMEngineBuilderCreateTM ) + + /* Execution Engine */ +// Use EngineBuilder instead +// _method( LLVMCreateExecutionEngine ) + _method( LLVMDisposeExecutionEngine ) + _method( LLVMExecutionEngineDisableLazyCompilation ) + _method( LLVMRunFunction2 ) + _method( LLVMGetPointerToFunction ) + _method( LLVMGetPointerToGlobal ) + _method( LLVMAddGlobalMapping ) + _method( LLVMGetExecutionEngineTargetData ) + _method( LLVMRunStaticConstructors ) + _method( LLVMRunStaticDestructors ) + _method( LLVMFreeMachineCodeForFunction ) + _method( LLVMAddModule ) + _method( LLVMRemoveModule2 ) + + /* Generic Value */ + _method( LLVMCreateGenericValueOfInt ) + _method( LLVMCreateGenericValueOfFloat ) + _method( LLVMCreateGenericValueOfPointer ) + _method( LLVMGenericValueToInt ) + _method( LLVMGenericValueToFloat ) + _method( LLVMGenericValueToPointer ) + _method( LLVMDisposeGenericValue ) + + /* Passes */ + _method( LLVMCreatePassByName ) + _method( LLVMDisposePass ) + _method( LLVMGetPassName ) + _method( LLVMPassDump ) + + _method( LLVMCreateTargetLibraryInfo ) + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 + _method( LLVMCreateTargetTransformInfo ) +#endif + + /* Misc */ + _method( LLVMGetVersion ) + _method( LLVMGetIntrinsic ) + _method( LLVMLoadLibraryPermanently ) + _method( LLVMParseEnvOpts ) + _method( LLVMDefaultTargetTriple ) + _method( LLVMInlineFunction ) + _method( PyCObjectVoidPtrToPyLong ) + { NULL } +}; + + + +// Module main function, hairy because of py3k port +extern "C" { + +#if (PY_MAJOR_VERSION >= 3) +struct PyModuleDef module_def = { + PyModuleDef_HEAD_INIT, + "_core", + NULL, + -1, + core_methods, + NULL, NULL, NULL, NULL +}; +#define INITERROR return NULL +PyObject * +PyInit__core(void) +#else +#define INITERROR return +PyMODINIT_FUNC +init_core(void) +#endif +{ + LLVMLinkInJIT(); + LLVMLinkInInterpreter(); + LLVMInitializeNativeTarget(); +#if PY_MAJOR_VERSION >= 3 + PyObject *module = PyModule_Create( &module_def ); +#else + PyObject *module = Py_InitModule("_core", core_methods); +#endif + if (module == NULL) + INITERROR; +#if PY_MAJOR_VERSION >= 3 + + return module; +#endif +} + +} // end extern C diff --git a/llvm/_dwarf.cpp b/llvm/_dwarf.cpp new file mode 100644 index 0000000..43f75aa --- /dev/null +++ b/llvm/_dwarf.cpp @@ -0,0 +1,86 @@ +#include +#include + +namespace llvmpy { +namespace dwarf { + +using namespace llvm::dwarf; + +const char *constant_names[] = { + "LLVMDebugVersion", + + #define define(x) #x, + #include "_dwarf.h" + #undef define +}; + +int constant_values[] = { + llvm::LLVMDebugVersion, + + #define define(x) x, + #include "_dwarf.h" + #undef define +}; + +enum enum_values { + __llvmpy_LLVMDebugVersion, + + #define define(x) __llvmpy_##x, + #include "_dwarf.h" + #undef define + + NVALUES /* Get the number of constants */ +}; + +} // End namespace dwarf + +int +set_dwarf_constants(PyObject *module) +{ + int i; + for (i = 0; i < dwarf::NVALUES; i++) { + if (PyModule_AddIntConstant(module, dwarf::constant_names[i], + dwarf::constant_values[i]) > 0) + return -1; + } + + return 0; +} + +} // End namespace llvmpy + +#if (PY_MAJOR_VERSION >= 3) + struct PyModuleDef module_def = { + PyModuleDef_HEAD_INIT, + "_dwarf", + NULL, + -1, + NULL, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ + }; + + #define INITERROR return NULL + PyObject *PyInit__dwarf(void) +#else + #define INITERROR return + PyMODINIT_FUNC init_dwarf(void) +#endif +{ +#if PY_MAJOR_VERSION >= 3 + PyObject *module = PyModule_Create( &module_def ); +#else + PyObject *module = Py_InitModule("_dwarf", NULL); +#endif + if (module == NULL) + INITERROR; + + if (llvmpy::set_dwarf_constants(module) < 0) + INITERROR; + +#if PY_MAJOR_VERSION >= 3 + return module; +#endif +} diff --git a/llvm/_dwarf.h b/llvm/_dwarf.h new file mode 100644 index 0000000..78eada0 --- /dev/null +++ b/llvm/_dwarf.h @@ -0,0 +1,101 @@ +/* Dwarf constant wrapping. See include/llvm/Support/Dwarf.h */ + +define(DWARF_VERSION) + +/* Dwarf tags */ +define(DW_TAG_array_type) +define(DW_TAG_class_type) +define(DW_TAG_entry_point) +define(DW_TAG_enumeration_type) +define(DW_TAG_formal_parameter) +define(DW_TAG_imported_declaration) +define(DW_TAG_label) +define(DW_TAG_lexical_block) +define(DW_TAG_member) +define(DW_TAG_pointer_type) +define(DW_TAG_reference_type) +define(DW_TAG_compile_unit) +define(DW_TAG_string_type) +define(DW_TAG_structure_type) +define(DW_TAG_subroutine_type) +define(DW_TAG_typedef) +define(DW_TAG_union_type) +define(DW_TAG_unspecified_parameters) +define(DW_TAG_variant) +define(DW_TAG_common_block) +define(DW_TAG_common_inclusion) +define(DW_TAG_inheritance) +define(DW_TAG_inlined_subroutine) +define(DW_TAG_module) +define(DW_TAG_ptr_to_member_type) +define(DW_TAG_set_type) +define(DW_TAG_subrange_type) +define(DW_TAG_with_stmt) +define(DW_TAG_access_declaration) +define(DW_TAG_base_type) +define(DW_TAG_catch_block) +define(DW_TAG_const_type) +define(DW_TAG_constant) +define(DW_TAG_enumerator) +define(DW_TAG_file_type) +define(DW_TAG_friend) +define(DW_TAG_namelist) +define(DW_TAG_namelist_item) +define(DW_TAG_packed_type) +define(DW_TAG_subprogram) +define(DW_TAG_template_type_parameter) +define(DW_TAG_template_value_parameter) +define(DW_TAG_thrown_type) +define(DW_TAG_try_block) +define(DW_TAG_variant_part) +define(DW_TAG_variable) +define(DW_TAG_volatile_type) +define(DW_TAG_dwarf_procedure) +define(DW_TAG_restrict_type) +define(DW_TAG_interface_type) +define(DW_TAG_namespace) +define(DW_TAG_imported_module) +define(DW_TAG_unspecified_type) +define(DW_TAG_partial_unit) +define(DW_TAG_imported_unit) +define(DW_TAG_condition) +define(DW_TAG_shared_type) +define(DW_TAG_type_unit) +define(DW_TAG_rvalue_reference_type) +define(DW_TAG_template_alias) +define(DW_TAG_MIPS_loop) +define(DW_TAG_format_label) +define(DW_TAG_function_template) +define(DW_TAG_class_template) +define(DW_TAG_GNU_template_template_param) +define(DW_TAG_GNU_template_parameter_pack) +define(DW_TAG_GNU_formal_parameter_pack) +define(DW_TAG_lo_user) +define(DW_TAG_APPLE_property) +define(DW_TAG_hi_user) + +/* Dwarf language constants */ +define(DW_LANG_C89) +define(DW_LANG_C) +define(DW_LANG_Ada83) +define(DW_LANG_C_plus_plus) +define(DW_LANG_Cobol74) +define(DW_LANG_Cobol85) +define(DW_LANG_Fortran77) +define(DW_LANG_Fortran90) +define(DW_LANG_Pascal83) +define(DW_LANG_Modula2) +define(DW_LANG_Java) +define(DW_LANG_C99) +define(DW_LANG_Ada95) +define(DW_LANG_Fortran95) +define(DW_LANG_PLI) +define(DW_LANG_ObjC) +define(DW_LANG_ObjC_plus_plus) +define(DW_LANG_UPC) +define(DW_LANG_D) +define(DW_LANG_Python) +define(DW_LANG_lo_user) +define(DW_LANG_Mips_Assembler) +define(DW_LANG_hi_user) + diff --git a/llvm/_util.py b/llvm/_util.py new file mode 100644 index 0000000..da003b0 --- /dev/null +++ b/llvm/_util.py @@ -0,0 +1,108 @@ +# +# Copyright (c) 2008-10, Mahadevan R All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of this software, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +"""Utility functions and classes. + +Used only in other modules, not for public use.""" + +import llvm +import llvm._core as _core # for PyCObjectVoidPtrToPyLong + + +#===----------------------------------------------------------------------=== +# A set of helpers to check various things. Raises exceptions on +# failures. +#===----------------------------------------------------------------------=== + +def check_gen(obj, typ): + if not isinstance(obj, typ): + typ_str = typ.__name__ + msg = "argument not an instance of llvm.core.%s" % typ_str + raise TypeError(msg) + +def check_is_unowned(ownable): + if ownable.owner: + raise llvm.LLVMException("object is already owned") + + +#===----------------------------------------------------------------------=== +# A set of helpers to unpack a list of Python wrapper objects +# into a list of PyCObject wrapped objects, checking types along +# the way. +#===----------------------------------------------------------------------=== + +def unpack_gen(objlist, check_fn): + for obj in objlist: check_fn(obj) + return [ obj.ptr for obj in objlist ] + +def unpack_gen_allow_none(objlist, check_fn): + for obj in objlist: + if obj is not None: + check_fn(obj) + return [ (obj.ptr if obj is not None else None) for obj in objlist ] + +#===----------------------------------------------------------------------=== +# Helper to wrap over iterables (LLVMFirstXXX, LLVMNextXXX). This used +# to be a generator, but that loses subscriptability of the result, so +# we now return a list. +#===----------------------------------------------------------------------=== + +def wrapiter(first, next, container, wrapper): + ret = [] + ptr = first(container) + while ptr: + ret.append(wrapper(ptr)) + ptr = next(ptr) + return ret + + +#===----------------------------------------------------------------------=== +# Py2/3 compatibility string check +#===----------------------------------------------------------------------=== +def _isstring_py2(x): + return isinstance(x, basestring) + +def _isstring_py3(x): + return isinstance(x, str) + +def _isstring_choose(): + try: + basestring + return _isstring_py2 + except: + return _isstring_py3 + +isstring = _isstring_choose() + +try: + unicode_type = unicode +except NameError: # Py3 + unicode_type = str + diff --git a/llvm/_version.py b/llvm/_version.py deleted file mode 100644 index a90c5b8..0000000 --- a/llvm/_version.py +++ /dev/null @@ -1,193 +0,0 @@ - -IN_LONG_VERSION_PY = True -# This file helps to compute a version number in source trees obtained from -# git-archive tarball (such as those provided by github's download-from-tag -# feature). Distribution tarballs (build by setup.py sdist) and build -# directories (produced by setup.py build) will contain a much shorter file -# that just contains the computed version number. - -# This file is released into the public domain. Generated by -# versioneer-0.7+ (https://github.com/warner/python-versioneer) - -# these strings will be replaced by git during git-archive -git_refnames = "$Format:%d$" -git_full = "$Format:%H$" -GIT = "git" - -import subprocess -import sys - -def run_command(args, cwd=None, verbose=False): - try: - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd) - except EnvironmentError: - e = sys.exc_info()[1] - if verbose: - print("unable to run %s" % args[0]) - print(e) - return None - stdout = p.communicate()[0].strip() - if sys.version >= '3': - stdout = stdout.decode() - if p.returncode != 0: - if verbose: - print("unable to run %s (error)" % args[0]) - return None - return stdout - - -import sys -import re -import os.path - -def get_expanded_variables(versionfile_source): - # the code embedded in _version.py can just fetch the value of these - # variables. When used from setup.py, we don't want to import - # _version.py, so we do it with a regexp instead. This function is not - # used from _version.py. - variables = {} - try: - for line in open(versionfile_source,"r").readlines(): - if line.strip().startswith("git_refnames ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - variables["refnames"] = mo.group(1) - if line.strip().startswith("git_full ="): - mo = re.search(r'=\s*"(.*)"', line) - if mo: - variables["full"] = mo.group(1) - except EnvironmentError: - pass - return variables - -def versions_from_expanded_variables(variables, tag_prefix, verbose=False): - refnames = variables["refnames"].strip() - if refnames.startswith("$Format"): - if verbose: - print("variables are unexpanded, not using") - return {} # unexpanded, so not in an unpacked git-archive tarball - refs = set([r.strip() for r in refnames.strip("()").split(",")]) - for ref in list(refs): - if not re.search(r'\d', ref): - if verbose: - print("discarding '%s', no digits" % ref) - refs.discard(ref) - # Assume all version tags have a digit. git's %d expansion - # behaves like git log --decorate=short and strips out the - # refs/heads/ and refs/tags/ prefixes that would let us - # distinguish between branches and tags. By ignoring refnames - # without digits, we filter out many common branch names like - # "release" and "stabilization", as well as "HEAD" and "master". - if verbose: - print("remaining refs: %s" % ",".join(sorted(refs))) - for ref in sorted(refs): - # sorting will prefer e.g. "2.0" over "2.0rc1" - if ref.startswith(tag_prefix): - r = ref[len(tag_prefix):] - if verbose: - print("picking %s" % r) - return { "version": r, - "full": variables["full"].strip() } - # no suitable tags, so we use the full revision id - if verbose: - print("no suitable tags, using full revision id") - return { "version": variables["full"].strip(), - "full": variables["full"].strip() } - -def versions_from_vcs(tag_prefix, versionfile_source, verbose=False): - # this runs 'git' from the root of the source tree. That either means - # someone ran a setup.py command (and this code is in versioneer.py, so - # IN_LONG_VERSION_PY=False, thus the containing directory is the root of - # the source tree), or someone ran a project-specific entry point (and - # this code is in _version.py, so IN_LONG_VERSION_PY=True, thus the - # containing directory is somewhere deeper in the source tree). This only - # gets called if the git-archive 'subst' variables were *not* expanded, - # and _version.py hasn't already been rewritten with a short version - # string, meaning we're inside a checked out source tree. - - try: - here = os.path.abspath(__file__) - except NameError: - # some py2exe/bbfreeze/non-CPython implementations don't do __file__ - return {} # not always correct - - # versionfile_source is the relative path from the top of the source tree - # (where the .git directory might live) to this file. Invert this to find - # the root from __file__. - root = here - if IN_LONG_VERSION_PY: - for i in range(len(versionfile_source.split("/"))): - root = os.path.dirname(root) - else: - root = os.path.dirname(here) - if not os.path.exists(os.path.join(root, ".git")): - if verbose: - print("no .git in %s" % root) - return {} - - stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"], - cwd=root) - if stdout is None: - return {} - if not stdout.startswith(tag_prefix): - if verbose: - print("tag '%s' doesn't start with prefix '%s'" % (stdout, tag_prefix)) - return {} - tag = stdout[len(tag_prefix):] - stdout = run_command([GIT, "rev-parse", "HEAD"], cwd=root) - if stdout is None: - return {} - full = stdout.strip() - if tag.endswith("-dirty"): - full += "-dirty" - return {"version": tag, "full": full} - - -def versions_from_parentdir(parentdir_prefix, versionfile_source, verbose=False): - if IN_LONG_VERSION_PY: - # We're running from _version.py. If it's from a source tree - # (execute-in-place), we can work upwards to find the root of the - # tree, and then check the parent directory for a version string. If - # it's in an installed application, there's no hope. - try: - here = os.path.abspath(__file__) - except NameError: - # py2exe/bbfreeze/non-CPython don't have __file__ - return {} # without __file__, we have no hope - # versionfile_source is the relative path from the top of the source - # tree to _version.py. Invert this to find the root from __file__. - root = here - for i in range(len(versionfile_source.split("/"))): - root = os.path.dirname(root) - else: - # we're running from versioneer.py, which means we're running from - # the setup.py in a source tree. sys.argv[0] is setup.py in the root. - here = os.path.abspath(sys.argv[0]) - root = os.path.dirname(here) - - # Source tarballs conventionally unpack into a directory that includes - # both the project name and a version string. - dirname = os.path.basename(root) - if not dirname.startswith(parentdir_prefix): - if verbose: - print("guessing rootdir is '%s', but '%s' doesn't start with prefix '%s'" % - (root, dirname, parentdir_prefix)) - return None - return {"version": dirname[len(parentdir_prefix):], "full": ""} - -tag_prefix = "" -parentdir_prefix = "llvmpy-" -versionfile_source = "llvm/_version.py" - -def get_versions(default={"version": "unknown", "full": ""}, verbose=False): - variables = { "refnames": git_refnames, "full": git_full } - ver = versions_from_expanded_variables(variables, tag_prefix, verbose) - if not ver: - ver = versions_from_vcs(tag_prefix, versionfile_source, verbose) - if not ver: - ver = versions_from_parentdir(parentdir_prefix, versionfile_source, - verbose) - if not ver: - ver = default - return ver diff --git a/llvm/capsulethunk.h b/llvm/capsulethunk.h new file mode 100644 index 0000000..6b20564 --- /dev/null +++ b/llvm/capsulethunk.h @@ -0,0 +1,134 @@ +#ifndef __CAPSULETHUNK_H +#define __CAPSULETHUNK_H + +#if ( (PY_VERSION_HEX < 0x02070000) \ + || ((PY_VERSION_HEX >= 0x03000000) \ + && (PY_VERSION_HEX < 0x03010000)) ) + +#define __PyCapsule_GetField(capsule, field, default_value) \ + ( PyCapsule_CheckExact(capsule) \ + ? (((PyCObject *)capsule)->field) \ + : (default_value) \ + ) \ + +#define __PyCapsule_SetField(capsule, field, value) \ + ( PyCapsule_CheckExact(capsule) \ + ? (((PyCObject *)capsule)->field = value), 1 \ + : 0 \ + ) \ + + +#define PyCapsule_Type PyCObject_Type + +#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule)) +#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule)) + + +#define PyCapsule_New(pointer, name, destructor) \ + (PyCObject_FromVoidPtr(pointer, destructor)) + + +#define PyCapsule_GetPointer(capsule, name) \ + (PyCObject_AsVoidPtr(capsule)) + +/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */ +#define PyCapsule_SetPointer(capsule, pointer) \ + __PyCapsule_SetField(capsule, cobject, pointer) + + +#define PyCapsule_GetDestructor(capsule) \ + __PyCapsule_GetField(capsule, destructor) + +#define PyCapsule_SetDestructor(capsule, dtor) \ + __PyCapsule_SetField(capsule, destructor, dtor) + + +/* + * Sorry, there's simply no place + * to store a Capsule "name" in a CObject. + */ +#define PyCapsule_GetName(capsule) NULL + +static int +PyCapsule_SetName(PyObject *capsule, const char *unused) +{ + unused = unused; + PyErr_SetString(PyExc_NotImplementedError, + "can't use PyCapsule_SetName with CObjects"); + return 1; +} + + + +#define PyCapsule_GetContext(capsule) \ + __PyCapsule_GetField(capsule, descr) + +#define PyCapsule_SetContext(capsule, context) \ + __PyCapsule_SetField(capsule, descr, context) + + +static void * +PyCapsule_Import(const char *name, int no_block) +{ + PyObject *object = NULL; + void *return_value = NULL; + char *trace; + size_t name_length = (strlen(name) + 1) * sizeof(char); + char *name_dup = (char *)PyMem_MALLOC(name_length); + + if (!name_dup) { + return NULL; + } + + memcpy(name_dup, name, name_length); + + trace = name_dup; + while (trace) { + char *dot = strchr(trace, '.'); + if (dot) { + *dot++ = '\0'; + } + + if (object == NULL) { + if (no_block) { + object = PyImport_ImportModuleNoBlock(trace); + } else { + object = PyImport_ImportModule(trace); + if (!object) { + PyErr_Format(PyExc_ImportError, + "PyCapsule_Import could not " + "import module \"%s\"", trace); + } + } + } else { + PyObject *object2 = PyObject_GetAttrString(object, trace); + Py_DECREF(object); + object = object2; + } + if (!object) { + goto EXIT; + } + + trace = dot; + } + + if (PyCObject_Check(object)) { + PyCObject *cobject = (PyCObject *)object; + return_value = cobject->cobject; + } else { + PyErr_Format(PyExc_AttributeError, + "PyCapsule_Import \"%s\" is not valid", + name); + } + +EXIT: + Py_XDECREF(object); + if (name_dup) { + PyMem_FREE(name_dup); + } + return return_value; +} + +#endif /* #if PY_VERSION_HEX < 0x02070000 */ + +#endif /* __CAPSULETHUNK_H */ diff --git a/llvm/core.py b/llvm/core.py index 4db8135..fa9dc77 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -28,216 +28,156 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -from io import BytesIO -try: - from StringIO import StringIO -except ImportError: - try: - from cStringIO import StringIO - except ImportError: - from io import StringIO +"""Core classes of LLVM. -import contextlib, weakref +The llvm.core module contains classes and constants required to build the +in-memory intermediate representation (IR) data structures.""" + + +import llvm # top-level, for common stuff +import llvm._core as _core # C wrappers +import llvm._util as _util # utility functions -import llvm -from llvm._intrinsic_ids import * -from llvm.deprecated import deprecated -from llvmpy import api #===----------------------------------------------------------------------=== # Enumerations #===----------------------------------------------------------------------=== -class Enum(int): - '''Overload integer to print the name of the enum. - ''' - def __repr__(self): - return '%s(%d)' % (type(self).__name__, self) - @classmethod - def declare(cls): - declared = cls._declared_ = {} - scope = globals() - for name in filter(lambda s: s.startswith(cls.prefix), dir(cls)): - n = getattr(cls, name) - typ = type(name, (cls,), {}) - obj = typ(n) - declared[n] = obj - scope[name] = obj - - @classmethod - def get(cls, num): - return cls._declared_[num] - -# type id (llvm::Type::TypeID) -class TypeEnum(Enum): - prefix = 'TYPE_' - TypeID = api.llvm.Type.TypeID - - TYPE_VOID = TypeID.VoidTyID - TYPE_HALF = TypeID.HalfTyID - TYPE_FLOAT = TypeID.FloatTyID - TYPE_DOUBLE = TypeID.DoubleTyID - TYPE_X86_FP80 = TypeID.X86_FP80TyID - TYPE_FP128 = TypeID.FP128TyID - TYPE_PPC_FP128 = TypeID.PPC_FP128TyID - TYPE_LABEL = TypeID.LabelTyID - TYPE_INTEGER = TypeID.IntegerTyID - TYPE_FUNCTION = TypeID.FunctionTyID - TYPE_STRUCT = TypeID.StructTyID - TYPE_ARRAY = TypeID.ArrayTyID - TYPE_POINTER = TypeID.PointerTyID - TYPE_VECTOR = TypeID.VectorTyID - TYPE_METADATA = TypeID.MetadataTyID - TYPE_X86_MMX = TypeID.X86_MMXTyID - -TypeEnum.declare() +# type kinds (LLVMTypeKind enum) +TYPE_VOID = 0 +TYPE_HALF = 1 +TYPE_FLOAT = 2 +TYPE_DOUBLE = 3 +TYPE_X86_FP80 = 4 +TYPE_FP128 = 5 +TYPE_PPC_FP128 = 6 +TYPE_LABEL = 7 +TYPE_INTEGER = 8 +TYPE_FUNCTION = 9 +TYPE_STRUCT = 10 +TYPE_ARRAY = 11 +TYPE_POINTER = 12 +TYPE_VECTOR = 13 +TYPE_METADATA = 14 +TYPE_X86_MMX = 15 # value IDs (llvm::Value::ValueTy enum) -# According to the doxygen docs, it is not a good idea to use these enums. -# There are more values than those declared. -class ValueEnum(Enum): - prefix = 'VALUE_' - ValueTy = api.llvm.Value.ValueTy - - VALUE_ARGUMENT = ValueTy.ArgumentVal - VALUE_BASIC_BLOCK = ValueTy.BasicBlockVal - VALUE_FUNCTION = ValueTy.FunctionVal - VALUE_GLOBAL_ALIAS = ValueTy.GlobalAliasVal - VALUE_GLOBAL_VARIABLE = ValueTy.GlobalVariableVal - VALUE_UNDEF_VALUE = ValueTy.UndefValueVal - VALUE_BLOCK_ADDRESS = ValueTy.BlockAddressVal - VALUE_CONSTANT_EXPR = ValueTy.ConstantExprVal - VALUE_CONSTANT_AGGREGATE_ZERO = ValueTy.ConstantAggregateZeroVal - VALUE_CONSTANT_DATA_ARRAY = ValueTy.ConstantDataArrayVal - VALUE_CONSTANT_DATA_VECTOR = ValueTy.ConstantDataVectorVal - VALUE_CONSTANT_INT = ValueTy.ConstantIntVal - VALUE_CONSTANT_FP = ValueTy.ConstantFPVal - VALUE_CONSTANT_ARRAY = ValueTy.ConstantArrayVal - VALUE_CONSTANT_STRUCT = ValueTy.ConstantStructVal - VALUE_CONSTANT_VECTOR = ValueTy.ConstantVectorVal - VALUE_CONSTANT_POINTER_NULL = ValueTy.ConstantPointerNullVal - VALUE_MD_NODE = ValueTy.MDNodeVal - VALUE_MD_STRING = ValueTy.MDStringVal - VALUE_INLINE_ASM = ValueTy.InlineAsmVal - VALUE_PSEUDO_SOURCE_VALUE = ValueTy.PseudoSourceValueVal - VALUE_FIXED_STACK_PSEUDO_SOURCE_VALUE = ValueTy.FixedStackPseudoSourceValueVal - VALUE_INSTRUCTION = ValueTy.InstructionVal - -ValueEnum.declare() +VALUE_ARGUMENT = 0 +VALUE_BASIC_BLOCK = 1 +VALUE_FUNCTION = 2 +VALUE_GLOBAL_ALIAS = 3 +VALUE_GLOBAL_VARIABLE = 4 +VALUE_UNDEF_VALUE = 5 +VALUE_BLOCK_ADDRESS = 6 +VALUE_CONSTANT_EXPR = 7 +VALUE_CONSTANT_AGGREGATE_ZERO = 8 +VALUE_CONSTANT_DATA_ARRAY = 9 +VALUE_CONSTANT_DATA_VECTOR = 10 +VALUE_CONSTANT_INT = 11 +VALUE_CONSTANT_FP = 12 +VALUE_CONSTANT_ARRAY = 13 +VALUE_CONSTANT_STRUCT = 14 +VALUE_CONSTANT_VECTOR = 15 +VALUE_CONSTANT_POINTER_NULL = 16 +VALUE_MD_NODE = 17 +VALUE_MD_STRING = 18 +VALUE_INLINE_ASM = 19 +VALUE_PSEUDO_SOURCE_VALUE = 20 +VALUE_FIXED_STACK_PSEUDO_SOURCE_VALUE = 21 +VALUE_INSTRUCTION = 22 # instruction opcodes (from include/llvm/Instruction.def) -class OpcodeEnum(Enum): - prefix = 'OPCODE_' - - OPCODE_RET = 1 - OPCODE_BR = 2 - OPCODE_SWITCH = 3 - OPCODE_INDIRECT_BR = 4 - OPCODE_INVOKE = 5 - OPCODE_RESUME = 6 - OPCODE_UNREACHABLE = 7 - OPCODE_ADD = 8 - OPCODE_FADD = 9 - OPCODE_SUB = 10 - OPCODE_FSUB = 11 - OPCODE_MUL = 12 - OPCODE_FMUL = 13 - OPCODE_UDIV = 14 - OPCODE_SDIV = 15 - OPCODE_FDIV = 16 - OPCODE_UREM = 17 - OPCODE_SREM = 18 - OPCODE_FREM = 19 - OPCODE_SHL = 20 - OPCODE_LSHR = 21 - OPCODE_ASHR = 22 - OPCODE_AND = 23 - OPCODE_OR = 24 - OPCODE_XOR = 25 - OPCODE_ALLOCA = 26 - OPCODE_LOAD = 27 - OPCODE_STORE = 28 - OPCODE_GETELEMENTPTR = 29 - OPCODE_FENCE = 30 - OPCODE_ATOMICCMPXCHG = 31 - OPCODE_ATOMICRMW = 32 - OPCODE_TRUNC = 33 - OPCODE_ZEXT = 34 - OPCODE_SEXT = 35 - OPCODE_FPTOUI = 36 - OPCODE_FPTOSI = 37 - OPCODE_UITOFP = 38 - OPCODE_SITOFP = 39 - OPCODE_FPTRUNC = 40 - OPCODE_FPEXT = 41 - OPCODE_PTRTOINT = 42 - OPCODE_INTTOPTR = 43 - OPCODE_BITCAST = 44 - OPCODE_ICMP = 45 - OPCODE_FCMP = 46 - OPCODE_PHI = 47 - OPCODE_CALL = 48 - OPCODE_SELECT = 49 - OPCODE_USEROP1 = 50 - OPCODE_USEROP2 = 51 - OPCODE_VAARG = 52 - OPCODE_EXTRACTELEMENT = 53 - OPCODE_INSERTELEMENT = 54 - OPCODE_SHUFFLEVECTOR = 55 - OPCODE_EXTRACTVALUE = 56 - OPCODE_INSERTVALUE = 57 - OPCODE_LANDINGPAD = 58 - -OpcodeEnum.declare() +OPCODE_RET = 1 +OPCODE_BR = 2 +OPCODE_SWITCH = 3 +OPCODE_INDIRECT_BR = 4 +OPCODE_INVOKE = 5 +OPCODE_RESUME = 6 +OPCODE_UNREACHABLE = 7 +OPCODE_ADD = 8 +OPCODE_FADD = 9 +OPCODE_SUB = 10 +OPCODE_FSUB = 11 +OPCODE_MUL = 12 +OPCODE_FMUL = 13 +OPCODE_UDIV = 14 +OPCODE_SDIV = 15 +OPCODE_FDIV = 16 +OPCODE_UREM = 17 +OPCODE_SREM = 18 +OPCODE_FREM = 19 +OPCODE_SHL = 20 +OPCODE_LSHR = 21 +OPCODE_ASHR = 22 +OPCODE_AND = 23 +OPCODE_OR = 24 +OPCODE_XOR = 25 +OPCODE_ALLOCA = 26 +OPCODE_LOAD = 27 +OPCODE_STORE = 28 +OPCODE_GETELEMENTPTR = 29 +OPCODE_FENCE = 30 +OPCODE_ATOMICCMPXCHG = 31 +OPCODE_ATOMICRMW = 32 +OPCODE_TRUNC = 33 +OPCODE_ZEXT = 34 +OPCODE_SEXT = 35 +OPCODE_FPTOUI = 36 +OPCODE_FPTOSI = 37 +OPCODE_UITOFP = 38 +OPCODE_SITOFP = 39 +OPCODE_FPTRUNC = 40 +OPCODE_FPEXT = 41 +OPCODE_PTRTOINT = 42 +OPCODE_INTTOPTR = 43 +OPCODE_BITCAST = 44 +OPCODE_ICMP = 45 +OPCODE_FCMP = 46 +OPCODE_PHI = 47 +OPCODE_CALL = 48 +OPCODE_SELECT = 49 +OPCODE_USEROP1 = 50 +OPCODE_USEROP2 = 51 +OPCODE_VAARG = 52 +OPCODE_EXTRACTELEMENT = 53 +OPCODE_INSERTELEMENT = 54 +OPCODE_SHUFFLEVECTOR = 55 +OPCODE_EXTRACTVALUE = 56 +OPCODE_INSERTVALUE = 57 +OPCODE_LANDINGPAD = 58 # calling conventions +CC_C = 0 +CC_FASTCALL = 8 +CC_COLDCALL = 9 +CC_GHC = 10 +CC_X86_STDCALL = 64 +CC_X86_FASTCALL = 65 +CC_ARM_APCS = 66 +CC_ARM_AAPCS = 67 +CC_ARM_AAPCS_VFP = 68 +CC_MSP430_INTR = 69 +CC_X86_THISCALL = 70 +CC_PTX_KERNEL = 71 +CC_PTX_DEVICE = 72 +CC_MBLAZE_INTR = 73 +CC_MBLAZE_SVOL = 74 -class CCEnum(Enum): - prefix = 'CC_' - - ID = api.llvm.CallingConv.ID - - CC_C = ID.C - CC_FASTCALL = ID.Fast - CC_COLDCALL = ID.Cold - CC_GHC = ID.GHC - CC_X86_STDCALL = ID.X86_StdCall - CC_X86_FASTCALL = ID.X86_FastCall - CC_ARM_APCS = ID.ARM_APCS - CC_ARM_AAPCS = ID.ARM_AAPCS - CC_ARM_AAPCS_VFP = ID.ARM_AAPCS_VFP - CC_MSP430_INTR = ID.MSP430_INTR - CC_X86_THISCALL = ID.X86_ThisCall - CC_PTX_KERNEL = ID.PTX_Kernel - CC_PTX_DEVICE = ID.PTX_Device - - if llvm.version <= (3, 3): - CC_MBLAZE_INTR = ID.MBLAZE_INTR - CC_MBLAZE_SVOL = ID.MBLAZE_SVOL - -CCEnum.declare() # int predicates -class ICMPEnum(Enum): - prefix = 'ICMP_' +ICMP_EQ = 32 +ICMP_NE = 33 +ICMP_UGT = 34 +ICMP_UGE = 35 +ICMP_ULT = 36 +ICMP_ULE = 37 +ICMP_SGT = 38 +ICMP_SGE = 39 +ICMP_SLT = 40 +ICMP_SLE = 41 - Predicate = api.llvm.CmpInst.Predicate - - ICMP_EQ = Predicate.ICMP_EQ - ICMP_NE = Predicate.ICMP_NE - ICMP_UGT = Predicate.ICMP_UGT - ICMP_UGE = Predicate.ICMP_UGE - ICMP_ULT = Predicate.ICMP_ULT - ICMP_ULE = Predicate.ICMP_ULE - ICMP_SGT = Predicate.ICMP_SGT - ICMP_SGE = Predicate.ICMP_SGE - ICMP_SLT = Predicate.ICMP_SLT - ICMP_SLE = Predicate.ICMP_SLE - -ICMPEnum.declare() # same as ICMP_xx, for backward compatibility - IPRED_EQ = ICMP_EQ IPRED_NE = ICMP_NE IPRED_UGT = ICMP_UGT @@ -250,33 +190,24 @@ IPRED_SLT = ICMP_SLT IPRED_SLE = ICMP_SLE # real predicates - -class FCMPEnum(Enum): - prefix = 'FCMP_' - - Predicate = api.llvm.CmpInst.Predicate - - FCMP_FALSE = Predicate.FCMP_FALSE - FCMP_OEQ = Predicate.FCMP_OEQ - FCMP_OGT = Predicate.FCMP_OGT - FCMP_OGE = Predicate.FCMP_OGE - FCMP_OLT = Predicate.FCMP_OLT - FCMP_OLE = Predicate.FCMP_OLE - FCMP_ONE = Predicate.FCMP_ONE - FCMP_ORD = Predicate.FCMP_ORD - FCMP_UNO = Predicate.FCMP_UNO - FCMP_UEQ = Predicate.FCMP_UEQ - FCMP_UGT = Predicate.FCMP_UGT - FCMP_UGE = Predicate.FCMP_UGE - FCMP_ULT = Predicate.FCMP_ULT - FCMP_ULE = Predicate.FCMP_ULE - FCMP_UNE = Predicate.FCMP_UNE - FCMP_TRUE = Predicate.FCMP_TRUE - -FCMPEnum.declare() +FCMP_FALSE = 0 +FCMP_OEQ = 1 +FCMP_OGT = 2 +FCMP_OGE = 3 +FCMP_OLT = 4 +FCMP_OLE = 5 +FCMP_ONE = 6 +FCMP_ORD = 7 +FCMP_UNO = 8 +FCMP_UEQ = 9 +FCMP_UGT = 10 +FCMP_UGE = 11 +FCMP_ULT = 12 +FCMP_ULE = 13 +FCMP_UNE = 14 +FCMP_TRUE = 15 # real predicates - RPRED_FALSE = FCMP_FALSE RPRED_OEQ = FCMP_OEQ RPRED_OGT = FCMP_OGT @@ -294,78 +225,102 @@ RPRED_ULE = FCMP_ULE RPRED_UNE = FCMP_UNE RPRED_TRUE = FCMP_TRUE -# linkages (see llvm::GlobalValue::LinkageTypes) -class LinkageEnum(Enum): - prefix = 'LINKAGE_' - LinkageTypes = api.llvm.GlobalValue.LinkageTypes - - LINKAGE_EXTERNAL = LinkageTypes.ExternalLinkage - LINKAGE_AVAILABLE_EXTERNALLY = LinkageTypes.AvailableExternallyLinkage - LINKAGE_LINKONCE_ANY = LinkageTypes.LinkOnceAnyLinkage - LINKAGE_LINKONCE_ODR = LinkageTypes.LinkOnceODRLinkage - LINKAGE_WEAK_ANY = LinkageTypes.WeakAnyLinkage - LINKAGE_WEAK_ODR = LinkageTypes.WeakODRLinkage - LINKAGE_APPENDING = LinkageTypes.AppendingLinkage - LINKAGE_INTERNAL = LinkageTypes.InternalLinkage - LINKAGE_PRIVATE = LinkageTypes.PrivateLinkage - LINKAGE_DLLIMPORT = LinkageTypes.DLLImportLinkage - LINKAGE_DLLEXPORT = LinkageTypes.DLLExportLinkage - LINKAGE_EXTERNAL_WEAK = LinkageTypes.ExternalWeakLinkage - LINKAGE_COMMON = LinkageTypes.CommonLinkage - LINKAGE_LINKER_PRIVATE = LinkageTypes.LinkerPrivateLinkage - LINKAGE_LINKER_PRIVATE_WEAK = LinkageTypes.LinkerPrivateWeakLinkage - -LinkageEnum.declare() +# linkages (see llvm-c/Core.h) +LINKAGE_EXTERNAL = 0 +LINKAGE_AVAILABLE_EXTERNALLY = 1 +LINKAGE_LINKONCE_ANY = 2 +LINKAGE_LINKONCE_ODR = 3 +LINKAGE_WEAK_ANY = 4 +LINKAGE_WEAK_ODR = 5 +LINKAGE_APPENDING = 6 +LINKAGE_INTERNAL = 7 +LINKAGE_PRIVATE = 8 +LINKAGE_DLLIMPORT = 9 +LINKAGE_DLLEXPORT = 10 +LINKAGE_EXTERNAL_WEAK = 11 +LINKAGE_GHOST = 12 +LINKAGE_COMMON = 13 +LINKAGE_LINKER_PRIVATE = 14 +LINKAGE_LINKER_PRIVATE_WEAK = 15 +LINKAGE_LINKER_PRIVATE_WEAK_DEF_AUTO = 16 # visibility (see llvm/GlobalValue.h) -class VisibilityEnum(Enum): - prefix = 'VISIBILITY_' +VISIBILITY_DEFAULT = 0 +VISIBILITY_HIDDEN = 1 +VISIBILITY_PROTECTED = 2 - VISIBILITY_DEFAULT = api.llvm.GlobalValue.VisibilityTypes.DefaultVisibility - VISIBILITY_HIDDEN = api.llvm.GlobalValue.VisibilityTypes.HiddenVisibility - VISIBILITY_PROTECTED = api.llvm.GlobalValue.VisibilityTypes.ProtectedVisibility +# parameter attributes (see llvm/Attributes.h) +ATTR_NONE = 0 +ATTR_ZEXT = 1 +ATTR_SEXT = 2 +ATTR_NO_RETURN = 4 +ATTR_IN_REG = 8 +ATTR_STRUCT_RET = 16 +ATTR_NO_UNWIND = 32 +ATTR_NO_ALIAS = 64 +ATTR_BY_VAL = 128 +ATTR_NEST = 256 +ATTR_READ_NONE = 512 +ATTR_READONLY = 1024 +ATTR_NO_INLINE = 1<<11 +ATTR_ALWAYS_INLINE = 1<<12 +ATTR_OPTIMIZE_FOR_SIZE = 1<<13 +ATTR_STACK_PROTECT = 1<<14 +ATTR_STACK_PROTECT_REQ = 1<<15 +ATTR_ALIGNMENT = 1<<16 +ATTR_NO_CAPTURE = 1<<21 +ATTR_NO_REDZONE = 1<<22 +ATTR_NO_IMPLICIT_FLOAT = 1<<23 +ATTR_NAKED = 1<<24 +ATTR_INLINE_HINT = 1<<25 +ATTR_STACK_ALIGNMENT = 7<<26 +ATTR_HOTPATCH = 1<<29 -VisibilityEnum.declare() +# intrinsic IDs +from llvm._intrinsic_ids import * -# parameter attributes -# LLVM 3.2 llvm::Attributes::AttrVal (see llvm/Attributes.h) -# LLVM 3.3 llvm::Attribute::AttrKind (see llvm/Attributes.h) -class AttrEnum(Enum): - prefix = 'ATTR_' - if llvm.version >= (3, 3): - AttrVal = api.llvm.Attribute.AttrKind +#===----------------------------------------------------------------------=== +# Helpers (for internal use) +#===----------------------------------------------------------------------=== + +def check_is_type(obj): _util.check_gen(obj, Type) +def check_is_type_struct(obj): _util.check_gen(obj, StructType) +def check_is_value(obj): _util.check_gen(obj, Value) +def check_is_constant(obj): _util.check_gen(obj, Constant) +def check_is_function(obj): _util.check_gen(obj, Function) +def check_is_global_value(obj): _util.check_gen(obj, GlobalValue) +def check_is_basic_block(obj): _util.check_gen(obj, BasicBlock) +def check_is_module(obj): _util.check_gen(obj, Module) + +def unpack_types(objlst): return _util.unpack_gen(objlst, check_is_type) +def unpack_values(objlst): return _util.unpack_gen(objlst, check_is_value) +def unpack_constants(objlst): return _util.unpack_gen(objlst, check_is_constant) + +def unpack_values_or_none(objlst): + return _util.unpack_gen_allow_none(objlst, check_is_value) + +def check_is_callable(obj): + if isinstance(obj, Function): + return + typ = obj.type + if isinstance(typ, PointerType) and \ + isinstance(typ.pointee, FunctionType): + return + raise TypeError("argument is neither a function nor a function pointer") + +def _to_int(v): + if v: + return 1 else: - AttrVal = api.llvm.Attributes.AttrVal + return 0 - ATTR_NONE = AttrVal.None_ - ATTR_ZEXT = AttrVal.ZExt - ATTR_SEXT = AttrVal.SExt - ATTR_NO_RETURN = AttrVal.NoReturn - ATTR_IN_REG = AttrVal.InReg - ATTR_STRUCT_RET = AttrVal.StructRet - ATTR_NO_UNWIND = AttrVal.NoUnwind - ATTR_NO_ALIAS = AttrVal.NoAlias - ATTR_BY_VAL = AttrVal.ByVal - ATTR_NEST = AttrVal.Nest - ATTR_READ_NONE = AttrVal.ReadNone - ATTR_READONLY = AttrVal.ReadOnly - ATTR_NO_INLINE = AttrVal.NoInline - ATTR_ALWAYS_INLINE = AttrVal.AlwaysInline - ATTR_OPTIMIZE_FOR_SIZE = AttrVal.OptimizeForSize - ATTR_STACK_PROTECT = AttrVal.StackProtect - ATTR_STACK_PROTECT_REQ = AttrVal.StackProtectReq - ATTR_ALIGNMENT = AttrVal.Alignment - ATTR_NO_CAPTURE = AttrVal.NoCapture - ATTR_NO_REDZONE = AttrVal.NoRedZone - ATTR_NO_IMPLICIT_FLOAT = AttrVal.NoImplicitFloat - ATTR_NAKED = AttrVal.Naked - ATTR_INLINE_HINT = AttrVal.InlineHint - ATTR_STACK_ALIGNMENT = AttrVal.StackAlignment -AttrEnum.declare() +#===----------------------------------------------------------------------=== +# Module +#===----------------------------------------------------------------------=== -class Module(llvm.Wrapper): +class Module(llvm.Ownable, llvm.Cacheable): """A Module instance stores all the information related to an LLVM module. Modules are the top level container of all other LLVM Intermediate @@ -379,16 +334,6 @@ class Module(llvm.Wrapper): module_obj = Module.new('my_module') """ - __slots__ = '__weakref__' - __cache = weakref.WeakValueDictionary() - - def __new__(cls, ptr): - cached = cls.__cache.get(ptr) - if cached: - return cached - obj = object.__new__(cls) - cls.__cache[ptr] = obj - return obj @staticmethod def new(id): @@ -396,9 +341,7 @@ class Module(llvm.Wrapper): Creates an instance of Module, having the id `id'. """ - context = api.llvm.getGlobalContext() - m = api.llvm.Module.new(id, context) - return Module(m) + return Module(_core.LLVMModuleCreateWithName(id)) @staticmethod def from_bitcode(fileobj_or_str): @@ -406,20 +349,22 @@ class Module(llvm.Wrapper): file. fileobj_or_str -- takes a file-like object or string that contains - a module represented in bitcode. + a module represented in bitcode. """ - if isinstance(fileobj_or_str, str): - bc = fileobj_or_str - else: - bc = fileobj_or_str.read() - errbuf = BytesIO() - context = api.llvm.getGlobalContext() - m = api.llvm.ParseBitCodeFile(bc, context, errbuf) - if not m: - raise Exception(errbuf.getvalue()) - errbuf.close() - return Module(m) + if isinstance(fileobj_or_str, _util.unicode_type): + data = fileobj_or_str.encode('utf-8') + elif isinstance(fileobj_or_str, bytes): + data = fileobj_or_str + else: + data = fileobj_or_str.read() + ret = _core.LLVMGetModuleFromBitcode(data) + if not ret: + raise llvm.LLVMException("Unable to create module from bitcode") + elif _util.isstring(ret): + raise llvm.LLVMException(ret) + else: + return Module(ret) @staticmethod def from_assembly(fileobj_or_str): @@ -428,68 +373,83 @@ class Module(llvm.Wrapper): fileobj_or_str -- takes a file-like object or string that contains - a module represented in llvm-ir assembly. + a module represented in llvm-ir assembly. """ - if isinstance(fileobj_or_str, str): - ir = fileobj_or_str + + if isinstance(fileobj_or_str, _util.unicode_type): + data = fileobj_or_str.encode('utf-8') + elif isinstance(fileobj_or_str, bytes): + data = fileobj_or_str else: - ir = fileobj_or_str.read() - errbuf = BytesIO() - context = api.llvm.getGlobalContext() - m = api.llvm.ParseAssemblyString(ir, None, api.llvm.SMDiagnostic.new(), - context) - errbuf.close() - return Module(m) + data = fileobj_or_str.read() + if isinstance(data, _util.unicode_type): + data = data.encode() + ret = _core.LLVMGetModuleFromAssembly(data) + if not ret: + raise llvm.LLVMException("Unable to create module from assembly") + elif isinstance(ret, str): + raise llvm.LLVMException(ret) + else: + return Module(ret) + + def __init__(self, ptr): + """DO NOT CALL DIRECTLY. + + Use the static method `Module.new' instead. + """ + llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule) def __str__(self): """Text representation of a module. - Returns the textual representation (`llvm assembly') of the - module. Use it like this: + Returns the textual representation (`llvm assembly') of the + module. Use it like this: - ll = str(module_obj) - print module_obj # same as `print ll' - """ - return str(self._ptr) - - def __hash__(self): - return id(self._ptr) + ll = str(module_obj) + print module_obj # same as `print ll' + """ + return _core.LLVMDumpModuleToString(self.ptr) def __eq__(self, rhs): if isinstance(rhs, Module): - return self._ptr == rhs._ptr + return str(self) == str(rhs) + else: + return False def __ne__(self, rhs): - return not (self == rhs) - + return not self == rhs def _get_target(self): - return self._ptr.getTargetTriple() + return _core.LLVMGetTarget(self.ptr) def _set_target(self, value): - return self._ptr.setTargetTriple(value) + return _core.LLVMSetTarget(self.ptr, value) target = property(_get_target, _set_target, - doc="The target triple string describing the target host.") - + """The target triple string describing the target host.""" + ) def _get_data_layout(self): - return self._ptr.getDataLayout() + return _core.LLVMGetDataLayout(self.ptr) def _set_data_layout(self, value): - return self._ptr.setDataLayout(value) + _core.LLVMSetDataLayout(self.ptr, value) data_layout = property(_get_data_layout, _set_data_layout, - doc = """The data layout string for the module's target platform. + """The data layout string for the module's target platform. - The data layout strings is an encoded representation of - the type sizes and alignments expected by this module. - """ - ) + The data layout strings is an encoded representation of + the type sizes and alignments expected by this module. + """ + ) @property def pointer_size(self): - return self._ptr.getPointerSize() + """Pointer size of target platform. + + Can be 0, 32 or 64. Zero represents + llvm::Module::AnyPointerSize.""" + return _core.LLVMModuleGetPointerSize(self.ptr) def link_in(self, other, preserve=False): """Link the `other' module into this one. @@ -503,156 +463,111 @@ class Module(llvm.Wrapper): In the future, this API might be replaced with a full-fledged Linker class. """ - assert isinstance(other, Module) - enum_mode = api.llvm.Linker.LinkerMode - mode = enum_mode.PreserveSource if preserve else enum_mode.DestroySource - - with contextlib.closing(BytesIO()) as errmsg: - failed = api.llvm.Linker.LinkModules(self._ptr, - other._ptr, - mode, - errmsg) - if failed: - raise llvm.LLVMException(errmsg.getvalue()) + check_is_module(other) + if not preserve: + other.forget() # remove it from object cache + result = _core.LLVMLinkModules(self.ptr, other.ptr, int(bool(preserve))) + if result is not None: + raise llvm.LLVMException(result) + if not preserve: + # Prevent user from using the other module + other.ptr = None + # Use a dummy owner to prevent other.ptr to be deleted + other._own(llvm.DummyOwner()) def get_type_named(self, name): - typ = self._ptr.getTypeByName(name) - if typ: - return StructType(typ) + """Return a Type object with the given name.""" + ptr = _core.LLVMGetTypeByName(self.ptr, name) + if ptr: + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) + return None def add_global_variable(self, ty, name, addrspace=0): """Add a global variable of given type with given name.""" - external = api.llvm.GlobalVariable.LinkageTypes.ExternalLinkage - notthreadlocal = api.llvm.GlobalVariable.ThreadLocalMode.NotThreadLocal - init = None - insertbefore = None - ptr = api.llvm.GlobalVariable.new(self._ptr, - ty._ptr, - False, - external, - init, - name, - insertbefore, - notthreadlocal, - addrspace) - return _make_value(ptr) + return GlobalVariable.new(self, ty, name, addrspace) def get_global_variable_named(self, name): """Return a GlobalVariable object for the given name.""" - ptr = self._ptr.getNamedGlobal(name) - if ptr is None: - raise llvm.LLVMException("No global named: %s" % name) - return _make_value(ptr) + return GlobalVariable.get(self, name) @property def global_variables(self): - return list(map(_make_value, self._ptr.list_globals())) + """All global variables in this module.""" + return _util.wrapiter(_core.LLVMGetFirstGlobal, + _core.LLVMGetNextGlobal, self.ptr, _make_value) def add_function(self, ty, name): """Add a function of given type with given name.""" return Function.new(self, ty, name) -# fn = self.get_function_named(name) -# if fn is not None: -# raise llvm.LLVMException("Duplicated function %s" % name) -# return self.get_or_insert_function(ty, name) def get_function_named(self, name): """Return a Function object representing function with given name.""" return Function.get(self, name) -# fn = self._ptr.getFunction(name) -# if fn is not None: -# return _make_value(fn) def get_or_insert_function(self, ty, name): """Like get_function_named(), but does add_function() first, if - function is not present.""" + function is not present.""" return Function.get_or_insert(self, ty, name) -# constant = self._ptr.getOrInsertFunction(name, ty._ptr) -# try: -# fn = constant._downcast(api.llvm.Function) -# except ValueError: -# # bitcasted to function type -# return _make_value(constant) -# else: -# return _make_value(fn) @property def functions(self): """All functions in this module.""" - return list(map(_make_value, self._ptr.list_functions())) + return _util.wrapiter(_core.LLVMGetFirstFunction, + _core.LLVMGetNextFunction, self.ptr, _make_value) def verify(self): """Verify module. - Checks module for errors. Raises `llvm.LLVMException' on any - error.""" - action = api.llvm.VerifierFailureAction.ReturnStatusAction - errio = BytesIO() - broken = api.llvm.verifyModule(self._ptr, action, errio) - if broken: - raise llvm.LLVMException(errio.getvalue()) + Checks module for errors. Raises `llvm.LLVMException' on any + error.""" + ret = _core.LLVMVerifyModule(self.ptr) + # Note: LLVM has a bug in preverifier that will always abort + # the process upon failure. + if ret != "": + raise llvm.LLVMException(ret) def to_bitcode(self, fileobj=None): """Write bitcode representation of module to given file-like object. fileobj -- A file-like object to where the bitcode is written. - If it is None, the bitcode is returned. + If it is None, the bitcode is returned. Return value -- Returns None if fileobj is not None. - Otherwise, return the bitcode as a bytestring. + Otherwise, return the bitcode as a bytestring. """ - ret = False - if fileobj is None: - ret = True - fileobj = BytesIO() - api.llvm.WriteBitcodeToFile(self._ptr, fileobj) - if ret: - return fileobj.getvalue() + + data = _core.LLVMGetBitcodeFromModule(self.ptr) + if not data: + raise llvm.LLVMException("Unable to create bitcode") + if fileobj is not None: + fileobj.write(data) + else: + return data + + def add_library(self, name): + return _core.LLVMModuleAddLibrary(self.ptr, name) def _get_id(self): - return self._ptr.getModuleIdentifier() + return _core.LLVMGetModuleIdentifier(self.ptr) def _set_id(self, string): - self._ptr.setModuleIdentifier(string) + _core.LLVMSetModuleIdentifier(self.ptr, string) id = property(_get_id, _set_id) - def _to_native_something(self, fileobj, cgft): - - cgft = api.llvm.TargetMachine.CodeGenFileType.CGFT_AssemblyFile - cgft = api.llvm.TargetMachine.CodeGenFileType.CGFT_ObjectFile - - from llvm.ee import TargetMachine - from llvm.passes import PassManager - from llvmpy import extra - tm = TargetMachine.new()._ptr - pm = PassManager.new()._ptr - formatted - failed = tm.addPassesToEmitFile(pm, fileobj, cgft, False) - - if failed: - raise llvm.LLVMException("Failed to write native object file") - if ret: - return fileobj.getvalue() - - def to_native_object(self, fileobj=None): '''Outputs the byte string of the module as native object code If a fileobj is given, the output is written to it; Otherwise, the output is returned ''' - ret = False - if fileobj is None: - ret = True - fileobj = BytesIO() - from llvm.ee import TargetMachine - tm = TargetMachine.new() - fileobj.write(tm.emit_object(self)) - if ret: - return fileobj.getvalue() - + data = _core.LLVMGetNativeCodeFromModule(self.ptr, 0) + if fileobj is not None: + fileobj.write(data) + else: + return data def to_native_assembly(self, fileobj=None): '''Outputs the byte string of the module as native assembly code @@ -660,89 +575,76 @@ class Module(llvm.Wrapper): If a fileobj is given, the output is written to it; Otherwise, the output is returned ''' - ret = False - if fileobj is None: - ret = True - fileobj = StringIO() - from llvm.ee import TargetMachine - tm = TargetMachine.new() - asm = tm.emit_assembly(self) - fileobj.write(asm) - if ret: - return fileobj.getvalue() - + data = _core.LLVMGetNativeCodeFromModule(self.ptr, 1) + if fileobj is not None: + fileobj.write(data) + else: + return data def get_or_insert_named_metadata(self, name): - return NamedMetaData(self._ptr.getOrInsertNamedMetadata(name)) + ptr = _core.LLVMModuleGetOrInsertNamedMetaData(self.ptr, name) + return NamedMetaData(ptr) def get_named_metadata(self, name): - md = self._ptr.getNamedMetadata(name) - if md: - return NamedMetaData(md) + ptr = _core.LLVMModuleGetNamedMetaData(self.ptr, name) + return NamedMetaData(ptr) def clone(self): - return Module(api.llvm.CloneModule(self._ptr)) + return Module(_core.LLVMCloneModule(self.ptr)) -class Type(llvm.Wrapper): +#===----------------------------------------------------------------------=== +# Types +#===----------------------------------------------------------------------=== + +class Type(object): """Represents a type, like a 32-bit integer or an 80-bit x86 float. Use one of the static methods to create an instance. Example: - ty = Type.double() + ty = Type.double() """ - __slots__ = '__name__' - _type_ = api.llvm.Type - - def __init__(self, ptr): - ptr = ptr._downcast(type(self)._type_) - super(Type, self).__init__(ptr) - - @property - def kind(self): - return self._ptr.getTypeID() @staticmethod def int(bits=32): """Create an integer type having the given bit width.""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getIntNTy(context, bits) - return Type(ptr) + if bits == 1: + return _make_type(_core.LLVMInt1Type(), TYPE_INTEGER) + elif bits == 8: + return _make_type(_core.LLVMInt8Type(), TYPE_INTEGER) + elif bits == 16: + return _make_type(_core.LLVMInt16Type(), TYPE_INTEGER) + elif bits == 32: + return _make_type(_core.LLVMInt32Type(), TYPE_INTEGER) + elif bits == 64: + return _make_type(_core.LLVMInt64Type(), TYPE_INTEGER) + else: + bits = int(bits) # bits must be an int + return _make_type(_core.LLVMIntType(bits), TYPE_INTEGER) @staticmethod def float(): """Create a 32-bit floating point type.""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getFloatTy(context) - return Type(ptr) + return _make_type(_core.LLVMFloatType(), TYPE_FLOAT) @staticmethod def double(): """Create a 64-bit floating point type.""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getDoubleTy(context) - return Type(ptr) + return _make_type(_core.LLVMDoubleType(), TYPE_DOUBLE) @staticmethod def x86_fp80(): """Create a 80-bit x86 floating point type.""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getX86_FP80Ty(context) - return Type(ptr) + return _make_type(_core.LLVMX86FP80Type(), TYPE_X86_FP80) @staticmethod def fp128(): """Create a 128-bit floating point type (with 112-bit - mantissa).""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getFP128Ty(context) - return Type(ptr) + mantissa).""" + return _make_type(_core.LLVMFP128Type(), TYPE_FP128) @staticmethod def ppc_fp128(): """Create a 128-bit floating point type (two 64-bits).""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getPPC_FP128Ty(context) - return Type(ptr) - + return _make_type(_core.LLVMPPCFP128Type(), TYPE_PPC_FP128) @staticmethod def function(return_ty, param_tys, var_arg=False): @@ -752,19 +654,20 @@ class Type(llvm.Wrapper): `return_ty', takes arguments of types as given in the iterable `param_tys'. Set `var_arg' to True (default is False) for a variadic function.""" - ptr = api.llvm.FunctionType.get(return_ty._ptr, - llvm._extract_ptrs(param_tys), - var_arg) - return FunctionType(ptr) + check_is_type(return_ty) + var_arg = _to_int(var_arg) # ensure int + params = unpack_types(param_tys) + return _make_type(_core.LLVMFunctionType(return_ty.ptr, params, + var_arg), TYPE_FUNCTION) @staticmethod def opaque(name): """Create a opaque StructType""" - context = api.llvm.getGlobalContext() if not name: - raise llvm.LLVMException("Opaque type must have a non-empty name") - ptr = api.llvm.StructType.create(context, name) - return StructType(ptr) + raise llvm.LLVMException("Must specify a name") + + objptr = _core.LLVMStructTypeIdentified(name) + return _make_type(objptr, TYPE_STRUCT) @staticmethod def struct(element_tys, name=''): # not packed @@ -776,18 +679,7 @@ class Type(llvm.Wrapper): If name is not '', creates a identified type; otherwise, creates a literal type.""" - context = api.llvm.getGlobalContext() - is_packed = False - if name: - ptr = api.llvm.StructType.create(context, name) - ptr.setBody(llvm._extract_ptrs(element_tys), is_packed) - else: - ptr = api.llvm.StructType.get(context, - llvm._extract_ptrs(element_tys), - is_packed) - - - return StructType(ptr) + return Type.__struct(element_tys, packed=False, name=name) @staticmethod def packed_struct(element_tys, name=''): @@ -799,11 +691,21 @@ class Type(llvm.Wrapper): If name is not '', creates a identified type; otherwise, creates a literal type.""" - context = api.llvm.getGlobalContext() - is_packed = True - ptr = api.llvm.StructType.create(context, name) - ptr.setBody(llvm._extract_ptrs(element_tys), is_packed) - return StructType(ptr) + return Type.__struct(element_tys, packed=True, name=name) + + @staticmethod + def __struct(element_tys, packed, name): + elems = unpack_types(element_tys) + packed = int(bool(packed)) + + if name: # create Identified StructType + objptr = _core.LLVMStructTypeIdentified(name) + _core.LLVMSetStructBody(objptr, elems, packed) + else: # create Literal StructType + objptr = _core.LLVMStructType(elems, packed) + + return _make_type(objptr, TYPE_STRUCT) + @staticmethod def array(element_ty, count): @@ -811,8 +713,10 @@ class Type(llvm.Wrapper): Creates a type for an array of elements of type `element_ty', having 'count' elements.""" - ptr = api.llvm.ArrayType.get(element_ty._ptr, count) - return ArrayType(ptr) + check_is_type(element_ty) + count = int(count) # must be an int + return _make_type(_core.LLVMArrayType(element_ty.ptr, count), + TYPE_ARRAY) @staticmethod def pointer(pointee_ty, addr_space=0): @@ -820,8 +724,10 @@ class Type(llvm.Wrapper): Creates a pointer type, which can point to values of type `pointee_ty', in the address space `addr_space'.""" - ptr = api.llvm.PointerType.get(pointee_ty._ptr, addr_space) - return PointerType(ptr) + check_is_type(pointee_ty) + addr_space = int(addr_space) # must be an int + return _make_type(_core.LLVMPointerType(pointee_ty.ptr, + addr_space), TYPE_POINTER) @staticmethod def vector(element_ty, count): @@ -829,227 +735,222 @@ class Type(llvm.Wrapper): Creates a type for a vector of elements of type `element_ty', having `count' elements.""" - ptr = api.llvm.VectorType.get(element_ty._ptr, count) - return VectorType(ptr) + check_is_type(element_ty) + count = int(count) # must be an int + return _make_type(_core.LLVMVectorType(element_ty.ptr, count), + TYPE_VECTOR) @staticmethod def void(): """Create a void type. Represents the `void' type.""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getVoidTy(context) - return Type(ptr) + return _make_type(_core.LLVMVoidType(), TYPE_VOID) @staticmethod def label(): """Create a label type.""" - context = api.llvm.getGlobalContext() - ptr = api.llvm.Type.getLabelTy(context) - return Type(ptr) + return _make_type(_core.LLVMLabelType(), TYPE_LABEL) - def __new__(cls, ptr): - tyid = ptr.getTypeID() + def __init__(self, ptr, kind): + """DO NOT CALL DIRECTLY. - idmap = { - TYPE_HALF: IntegerType, - TYPE_INTEGER: IntegerType, - TYPE_FUNCTION: FunctionType, - TYPE_STRUCT: StructType, - TYPE_ARRAY: ArrayType, - TYPE_POINTER: PointerType, - TYPE_VECTOR: VectorType, - } + Use one of the static methods instead.""" + self.ptr = ptr + self.kind = kind + """An enum (int) value denoting which type this is. - try: - newcls = idmap[tyid] - except KeyError: - newcls = Type - obj = llvm.Wrapper.__new__(newcls) - return obj + Use the symbolic constants TYPE_* defined in llvm.core + module.""" def __str__(self): - return str(self._ptr) + """Text representation of a type. - def __hash__(self): - return hash(self._ptr) + Returns the textual representation (`llvm assembly') of the type.""" + return _core.LLVMDumpTypeToString(self.ptr) def __eq__(self, rhs): - return self._ptr is rhs._ptr + if isinstance(rhs, Type): + return str(self) == str(rhs) + else: + return False def __ne__(self, rhs): - return not (self == rhs) + return not self == rhs + class IntegerType(Type): """Represents an integer type.""" - __slots__ = () - _type_ = api.llvm.IntegerType @property def width(self): """The width of the integer type, in bits.""" - return self._ptr.getIntegerBitWidth() + return _core.LLVMGetIntTypeWidth(self.ptr) + class FunctionType(Type): """Represents a function type.""" - __slots__ = () - _type_ = api.llvm.FunctionType @property def return_type(self): """The type of the value returned by this function.""" - return Type(self._ptr.getReturnType()) + ptr = _core.LLVMGetReturnType(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) @property def vararg(self): """True if this function is variadic.""" - return self._ptr.isVarArg() + return _core.LLVMIsFunctionVarArg(self.ptr) != 0 @property def args(self): """An iterable that yields Type objects, representing the types of the - arguments accepted by this function, in order.""" - return [Type(self._ptr.getParamType(i)) for i in range(self.arg_count)] + arguments accepted by this function, in order.""" + pp = _core.LLVMGetFunctionTypeParams(self.ptr) + return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ] @property def arg_count(self): """Number of arguments accepted by this function. - Same as len(obj.args), but faster.""" - return self._ptr.getNumParams() + Same as len(obj.args), but faster.""" + return _core.LLVMCountParamTypes(self.ptr) class StructType(Type): """Represents a structure type.""" - _type_ = api.llvm.StructType - __slots__ = () @property def element_count(self): """Number of elements (members) in the structure. - Same as len(obj.elements), but faster.""" - return self._ptr.getNumElements() + Same as len(obj.elements), but faster.""" + return _core.LLVMCountStructElementTypes(self.ptr) @property def elements(self): - """An iterable that yields Type objects, representing the types of the - elements (members) of the structure, in order.""" - return [Type(self._ptr.getElementType(i)) - for i in range(self._ptr.getNumElements())] + """An iterable that yieldsd Type objects, representing the types of the + elements (members) of the structure, in order.""" + pp = _core.LLVMGetStructElementTypes(self.ptr) + return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ] def set_body(self, elems, packed=False): """Filled the body of a opaque type. - """ + """ # check if not self.is_opaque: raise llvm.LLVMException("Body is already defined.") - self._ptr.setBody(llvm._extract_ptrs(elems), packed) + # prepare arguments + elems = unpack_types(elems) + if packed: + packed = 1 + else: + packed = 0 + + # call c API + _core.LLVMSetStructBody(self.ptr, elems, packed) @property def packed(self): """True if the structure is packed, False otherwise.""" - return self._ptr.isPacked() + return _core.LLVMIsPackedStruct(self.ptr) != 0 def _set_name(self, name): - self._ptr.setName(name) + _core.LLVMSetStructName(self.ptr, name) def _get_name(self): - if self._ptr.isLiteral(): - return "" - else: - return self._ptr.getName() + return _core.LLVMGetStructName(self.ptr) name = property(_get_name, _set_name) @property def is_literal(self): - return self._ptr.isLiteral() + return bool(_core.LLVMIsLiteralStruct(self.ptr)) @property def is_identified(self): - return not self.is_literal + return not _core.LLVMIsLiteralStruct(self.ptr) @property def is_opaque(self): - return self._ptr.isOpaque() - - def is_layout_identical(self, other): - return self._ptr.isLayoutIdentical(other._ptr) + return bool(_core.LLVMIsOpaqueStruct(self.ptr)) class ArrayType(Type): """Represents an array type.""" - _type_ = api.llvm.ArrayType - __slots__ = () @property def element(self): - return Type(self._ptr.getArrayElementType()) + ptr = _core.LLVMGetElementType(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) @property def count(self): - return self._ptr.getNumElements() + return _core.LLVMGetArrayLength(self.ptr) + class PointerType(Type): - _type_ = api.llvm.PointerType - __slots__ = () @property def pointee(self): - return Type(self._ptr.getPointerElementType()) + ptr = _core.LLVMGetElementType(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) @property def address_space(self): - return self._ptr.getAddressSpace() + return _core.LLVMGetPointerAddressSpace(self.ptr) + class VectorType(Type): - _type_ = api.llvm.VectorType - __slots__ = () @property def element(self): - return Type(self._ptr.getVectorElementType()) + ptr = _core.LLVMGetElementType(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) @property def count(self): - return self._ptr.getNumElements() + return _core.LLVMGetVectorSize(self.ptr) -class Value(llvm.Wrapper): - _type_ = api.llvm.Value - __slots__ = '__weakref__' - def __init__(self, builder, ptr): - assert builder is _ValueFactory +#===----------------------------------------------------------------------=== +# Type factory method +#===----------------------------------------------------------------------=== - if type(self._type_) is type: - if isinstance(ptr, self._type_): # is not downcast - casted = ptr - else: - casted = ptr._downcast(self._type_) - else: - try: - for ty in self._type_: - if isinstance(ptr, ty): # is not downcast - casted = ptr - else: - try: - casted = ptr._downcast(ty) - except ValueError: - pass - else: - break - else: - casted = ptr - except TypeError: - casted = ptr - super(Value, self).__init__(casted) +# type ID -> class map +__class_for_typeid = { + TYPE_INTEGER : IntegerType, + TYPE_FUNCTION : FunctionType, + TYPE_STRUCT : StructType, + TYPE_ARRAY : ArrayType, + TYPE_POINTER : PointerType, + TYPE_VECTOR : VectorType, +} + +def _make_type(ptr, kind): + class_obj = __class_for_typeid.get(kind) + if class_obj: + return class_obj(ptr, kind) + else: + # "generic" type + return Type(ptr, kind) + + +#===----------------------------------------------------------------------=== +# Values +#===----------------------------------------------------------------------=== + +class Value(llvm.Cacheable): + + def __init__(self, ptr): + self.ptr = ptr def __str__(self): - return str(self._ptr) - - def __hash__(self): - return hash(self._ptr) + return _core.LLVMDumpValueToString(self.ptr) def __eq__(self, rhs): if isinstance(rhs, Value): @@ -1061,623 +962,550 @@ class Value(llvm.Wrapper): return not self == rhs def _get_name(self): - return self._ptr.getName() + return _core.LLVMGetValueName(self.ptr) def _set_name(self, value): - return self._ptr.setName(value) + return _core.LLVMSetValueName(self.ptr, value) name = property(_get_name, _set_name) @property def value_id(self): - return self._ptr.getValueID() + return _core.LLVMValueGetID(self.ptr) @property def type(self): - return Type(self._ptr.getType()) + ptr = _core.LLVMTypeOf(self.ptr) + kind = _core.LLVMGetTypeKind(ptr) + return _make_type(ptr, kind) @property def use_count(self): - return self._ptr.getNumUses() + return _core.LLVMValueGetNumUses(self.ptr) @property def uses(self): - return list(map(_make_value, self._ptr.list_use())) + return [ _make_value(v) for v in _core.LLVMValueGetUses(self.ptr) ] + class User(Value): - _type_ = api.llvm.User - __slots__ = () @property def operand_count(self): - return self._ptr.getNumOperands() + return _core.LLVMUserGetNumOperands(self.ptr) @property def operands(self): """Yields operands of this instruction.""" - return [_make_value(self._ptr.getOperand(i)) - for i in range(self.operand_count)] + return [self._get_operand(i) for i in range(self.operand_count)] + + def _get_operand(self, i): + return _make_value(_core.LLVMUserGetOperand(self.ptr, i)) class Constant(User): - _type_ = api.llvm.Constant - __slots__ = () @staticmethod def null(ty): - return _make_value(api.llvm.Constant.getNullValue(ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstNull(ty.ptr)) @staticmethod def all_ones(ty): - return _make_value(api.llvm.Constant.getAllOnesValue(ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstAllOnes(ty.ptr)) @staticmethod def undef(ty): - return _make_value(api.llvm.UndefValue.get(ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMGetUndef(ty.ptr)) @staticmethod def int(ty, value): - return _make_value(api.llvm.ConstantInt.get(ty._ptr, int(value), False)) + check_is_type(ty) + return _make_value(_core.LLVMConstInt(ty.ptr, value, 0)) @staticmethod def int_signextend(ty, value): - return _make_value(api.llvm.ConstantInt.get(ty._ptr, int(value), True)) + check_is_type(ty) + return _make_value(_core.LLVMConstInt(ty.ptr, value, 1)) @staticmethod def real(ty, value): - return _make_value(api.llvm.ConstantFP.get(ty._ptr, float(value))) + check_is_type(ty) + if isinstance(value, str): + return _make_value(_core.LLVMConstRealOfString(ty.ptr, value)) + else: + return _make_value(_core.LLVMConstReal(ty.ptr, value)) @staticmethod def string(strval): # dont_null_terminate=True - cxt = api.llvm.getGlobalContext() - return _make_value(api.llvm.ConstantDataArray.getString(cxt, strval, False)) + return _make_value(_core.LLVMConstString(strval, 1)) @staticmethod def stringz(strval): # dont_null_terminate=False - cxt = api.llvm.getGlobalContext() - return _make_value(api.llvm.ConstantDataArray.getString(cxt, strval, True)) + return _make_value(_core.LLVMConstString(strval, 0)) @staticmethod def array(ty, consts): - aryty = Type.array(ty, len(consts)) - return _make_value(api.llvm.ConstantArray.get(aryty._ptr, - llvm._extract_ptrs(consts))) + check_is_type(ty) + const_ptrs = unpack_constants(consts) + return _make_value(_core.LLVMConstArray(ty.ptr, const_ptrs)) @staticmethod def struct(consts): # not packed - return _make_value(api.llvm.ConstantStruct.getAnon(llvm._extract_ptrs(consts), - False)) + const_ptrs = unpack_constants(consts) + return _make_value(_core.LLVMConstStruct(const_ptrs, 0)) @staticmethod def packed_struct(consts): - return _make_value(api.llvm.ConstantStruct.getAnon(llvm._extract_ptrs(consts), - False)) + const_ptrs = unpack_constants(consts) + return _make_value(_core.LLVMConstStruct(const_ptrs, 1)) @staticmethod def vector(consts): - return _make_value(api.llvm.ConstantVector.get(llvm._extract_ptrs(consts))) + const_ptrs = unpack_constants(consts) + return _make_value(_core.LLVMConstVector(const_ptrs)) @staticmethod def sizeof(ty): - return _make_value(api.llvm.ConstantExpr.getSizeOf(ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMSizeOf(ty.ptr)) def neg(self): - return _make_value(api.llvm.ConstantExpr.getNeg(self._ptr)) + return _make_value(_core.LLVMConstNeg(self.ptr)) def not_(self): - return _make_value(api.llvm.ConstantExpr.getNot(self._ptr)) + return _make_value(_core.LLVMConstNot(self.ptr)) def add(self, rhs): - return _make_value(api.llvm.ConstantExpr.getAdd(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstAdd(self.ptr, rhs.ptr)) def fadd(self, rhs): - return _make_value(api.llvm.ConstantExpr.getFAdd(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstFAdd(self.ptr, rhs.ptr)) def sub(self, rhs): - return _make_value(api.llvm.ConstantExpr.getSub(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstSub(self.ptr, rhs.ptr)) def fsub(self, rhs): - return _make_value(api.llvm.ConstantExpr.getFSub(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstFSub(self.ptr, rhs.ptr)) def mul(self, rhs): - return _make_value(api.llvm.ConstantExpr.getMul(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstMul(self.ptr, rhs.ptr)) def fmul(self, rhs): - return _make_value(api.llvm.ConstantExpr.getFMul(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstFMul(self.ptr, rhs.ptr)) def udiv(self, rhs): - return _make_value(api.llvm.ConstantExpr.getUDiv(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstUDiv(self.ptr, rhs.ptr)) def sdiv(self, rhs): - return _make_value(api.llvm.ConstantExpr.getSDiv(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstSDiv(self.ptr, rhs.ptr)) def fdiv(self, rhs): - return _make_value(api.llvm.ConstantExpr.getFDiv(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstFDiv(self.ptr, rhs.ptr)) def urem(self, rhs): - return _make_value(api.llvm.ConstantExpr.getURem(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstURem(self.ptr, rhs.ptr)) def srem(self, rhs): - return _make_value(api.llvm.ConstantExpr.getSRem(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstSRem(self.ptr, rhs.ptr)) def frem(self, rhs): - return _make_value(api.llvm.ConstantExpr.getFRem(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstFRem(self.ptr, rhs.ptr)) def and_(self, rhs): - return _make_value(api.llvm.ConstantExpr.getAnd(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstAnd(self.ptr, rhs.ptr)) def or_(self, rhs): - return _make_value(api.llvm.ConstantExpr.getOr(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstOr(self.ptr, rhs.ptr)) def xor(self, rhs): - return _make_value(api.llvm.ConstantExpr.getXor(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstXor(self.ptr, rhs.ptr)) def icmp(self, int_pred, rhs): - return _make_value(api.llvm.ConstantExpr.getICmp(int_pred, self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstICmp(int_pred, self.ptr, rhs.ptr)) def fcmp(self, real_pred, rhs): - return _make_value(api.llvm.ConstantExpr.getFCmp(real_pred, self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstFCmp(real_pred, self.ptr, rhs.ptr)) def shl(self, rhs): - return _make_value(api.llvm.ConstantExpr.getShl(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstShl(self.ptr, rhs.ptr)) def lshr(self, rhs): - return _make_value(api.llvm.ConstantExpr.getLShr(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstLShr(self.ptr, rhs.ptr)) def ashr(self, rhs): - return _make_value(api.llvm.ConstantExpr.getAShr(self._ptr, rhs._ptr)) + check_is_constant(rhs) + return _make_value(_core.LLVMConstAShr(self.ptr, rhs.ptr)) def gep(self, indices): - indices = llvm._extract_ptrs(indices) - return _make_value(api.llvm.ConstantExpr.getGetElementPtr(self._ptr, indices)) + index_ptrs = unpack_constants(indices) + return _make_value(_core.LLVMConstGEP(self.ptr, index_ptrs)) def trunc(self, ty): - return _make_value(api.llvm.ConstantExpr.getTrunc(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstTrunc(self.ptr, ty.ptr)) def sext(self, ty): - return _make_value(api.llvm.ConstantExpr.getSExt(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstSExt(self.ptr, ty.ptr)) def zext(self, ty): - return _make_value(api.llvm.ConstantExpr.getZExt(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstZExt(self.ptr, ty.ptr)) def fptrunc(self, ty): - return _make_value(api.llvm.ConstantExpr.getFPTrunc(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstFPTrunc(self.ptr, ty.ptr)) def fpext(self, ty): - return _make_value(api.llvm.ConstantExpr.getFPExtend(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstFPExt(self.ptr, ty.ptr)) def uitofp(self, ty): - return _make_value(api.llvm.ConstantExpr.getUIToFP(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstUIToFP(self.ptr, ty.ptr)) def sitofp(self, ty): - return _make_value(api.llvm.ConstantExpr.getSIToFP(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstSIToFP(self.ptr, ty.ptr)) def fptoui(self, ty): - return _make_value(api.llvm.ConstantExpr.getFPToUI(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstFPToUI(self.ptr, ty.ptr)) def fptosi(self, ty): - return _make_value(api.llvm.ConstantExpr.getFPToSI(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstFPToSI(self.ptr, ty.ptr)) def ptrtoint(self, ty): - return _make_value(api.llvm.ConstantExpr.getPtrToInt(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstPtrToInt(self.ptr, ty.ptr)) def inttoptr(self, ty): - return _make_value(api.llvm.ConstantExpr.getIntToPtr(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstIntToPtr(self.ptr, ty.ptr)) def bitcast(self, ty): - return _make_value(api.llvm.ConstantExpr.getBitCast(self._ptr, ty._ptr)) + check_is_type(ty) + return _make_value(_core.LLVMConstBitCast(self.ptr, ty.ptr)) def select(self, true_const, false_const): - return _make_value(api.llvm.ConstantExpr.getSelect(self._ptr, - true_const._ptr, - false_const._ptr)) + check_is_constant(true_const) + check_is_constant(false_const) + return _make_value( + _core.LLVMConstSelect(self.ptr, true_const.ptr, false_const.ptr)) def extract_element(self, index): # note: self must be a _vector_ constant - return _make_value(api.llvm.ConstantExpr.getExtractElement(self._ptr, index._ptr)) + check_is_constant(index) + return _make_value( + _core.LLVMConstExtractElement(self.ptr, index.ptr)) def insert_element(self, value, index): - return _make_value(api.llvm.ConstantExpr.getExtractElement(self._ptr, - value._ptr, - index._ptr)) + # note: self must be a _vector_ constant + check_is_constant(value) + check_is_constant(index) + return _make_value( + _core.LLVMConstInsertElement(self.ptr, value.ptr, index.ptr)) def shuffle_vector(self, vector_b, mask): - return _make_value(api.llvm.ConstantExpr.getShuffleVector(self._ptr, - vector_b._ptr, - mask._ptr)) + # note: self must be a _vector_ constant + check_is_constant(vector_b) + # note: vector_b must be a _vector_ constant + check_is_constant(mask) + return _make_value( + _core.LLVMConstShuffleVector(self.ptr, vector_b.ptr, mask.ptr)) + class ConstantExpr(Constant): - _type_ = api.llvm.ConstantExpr - __slots__ = () - @property def opcode(self): - return self._ptr.getOpcode() + return _core.LLVMGetConstExprOpcode(self.ptr) @property def opcode_name(self): - return self._ptr.getOpcodeName() + return _core.LLVMGetConstExprOpcodeName(self.ptr) + class ConstantAggregateZero(Constant): - __slots__ = () + pass class ConstantDataArray(Constant): - __slots__ = () + pass class ConstantDataVector(Constant): - __slots__ = () - + pass class ConstantInt(Constant): - _type_ = api.llvm.ConstantInt - __slots__ = () - @property def z_ext_value(self): '''Obtain the zero extended value for an integer constant value.''' # Warning: assertion failure when value does not fit in 64 bits - return self._ptr.getZExtValue() + return _core.LLVMConstIntGetZExtValue(self.ptr) @property def s_ext_value(self): '''Obtain the sign extended value for an integer constant value.''' # Warning: assertion failure when value does not fit in 64 bits - return self._ptr.getSExtValue() + return _core.LLVMConstIntGetSExtValue(self.ptr) class ConstantFP(Constant): - __slots__ = () + pass class ConstantArray(Constant): - __slots__ = () + pass class ConstantStruct(Constant): - __slots__ = () + pass class ConstantVector(Constant): - __slots__ = () + pass class ConstantPointerNull(Constant): - __slots__ = () + pass class UndefValue(Constant): - __slots__ = () + pass class GlobalValue(Constant): - _type_ = api.llvm.GlobalValue - __slots__ = () + + def __init__(self, ptr): + Constant.__init__(self, ptr) + # Hang on to the module, don't let it die before we do. + # It is nice to have just a map of functions without + # retaining a ref to the owning module. + self._module_obj = self.module + + def _delete(self): + # Called in subclass delete() methods. + self._module_obj = None def _get_linkage(self): - return self._ptr.getLinkage() - + return _core.LLVMGetLinkage(self.ptr) def _set_linkage(self, value): - self._ptr.setLinkage(value) - + _core.LLVMSetLinkage(self.ptr, value) linkage = property(_get_linkage, _set_linkage) def _get_section(self): - return self._ptr.getSection() - + return _core.LLVMGetSection(self.ptr) def _set_section(self, value): - return self._ptr.setSection(value) - + return _core.LLVMSetSection(self.ptr, value) section = property(_get_section, _set_section) def _get_visibility(self): - return self._ptr.getVisibility() - + return _core.LLVMGetVisibility(self.ptr) def _set_visibility(self, value): - return self._ptr.setVisibility(value) - + return _core.LLVMSetVisibility(self.ptr, value) visibility = property(_get_visibility, _set_visibility) def _get_alignment(self): - return self._ptr.getAlignment() - + return _core.LLVMGetAlignment(self.ptr) def _set_alignment(self, value): - return self._ptr.setAlignment(value) - + return _core.LLVMSetAlignment(self.ptr, value) alignment = property(_get_alignment, _set_alignment) @property def is_declaration(self): - return self._ptr.isDeclaration() + return _core.LLVMIsDeclaration(self.ptr) != 0 @property def module(self): - return Module(self._ptr.getParent()) - - + return Module(_core.LLVMGetGlobalParent(self.ptr)) class GlobalVariable(GlobalValue): - _type_ = api.llvm.GlobalVariable - __slots__ = () @staticmethod def new(module, ty, name, addrspace=0): - linkage = api.llvm.GlobalValue.LinkageTypes - external_linkage = linkage.ExternalLinkage - tlmode = api.llvm.GlobalVariable.ThreadLocalMode - not_threadlocal = tlmode.NotThreadLocal - gv = api.llvm.GlobalVariable.new(module._ptr, - ty._ptr, - False, # is constant - external_linkage, - None, # initializer - name, - None, # insert before - not_threadlocal, - addrspace) - return _make_value(gv) + check_is_module(module) + check_is_type(ty) + return _make_value(_core.LLVMAddGlobalInAddressSpace(module.ptr, ty.ptr, name, addrspace)) @staticmethod def get(module, name): - gv = _make_value(module._ptr.getNamedGlobal(name)) - if not gv: - llvm.LLVMException("no global named `%s`" % name) - return gv + check_is_module(module) + ptr = _core.LLVMGetNamedGlobal(module.ptr, name) + if not ptr: + raise llvm.LLVMException("no global named `%s`" % name) + return _make_value(ptr) def delete(self): - _ValueFactory.delete(self._ptr) - self._ptr.eraseFromParent() + self._delete() + _core.LLVMDeleteGlobal(self.ptr) + self.forget() + self.ptr = None def _get_initializer(self): - if not self._ptr.hasInitializer(): + if _core.LLVMHasInitializer(self.ptr): + return _make_value(_core.LLVMGetInitializer(self.ptr)) + else: return None - return _make_value(self._ptr.getInitializer()) def _set_initializer(self, const): - self._ptr.setInitializer(const._ptr) + check_is_constant(const) + _core.LLVMSetInitializer(self.ptr, const.ptr) def _del_initializer(self): - self._ptr.setInitializer(None) + check_is_constant(const) initializer = property(_get_initializer, _set_initializer) def _get_is_global_constant(self): - return self._ptr.isConstant() + return _core.LLVMIsGlobalConstant(self.ptr) def _set_is_global_constant(self, value): - self._ptr.setConstant(value) + value = _to_int(value) + _core.LLVMSetGlobalConstant(self.ptr, value) - global_constant = property(_get_is_global_constant, - _set_is_global_constant) + global_constant = \ + property(_get_is_global_constant, _set_is_global_constant) def _get_thread_local(self): - return self._ptr.isThreadLocal() - + return bool(_core.LLVMIsThreadLocal(self.ptr)) def _set_thread_local(self, value): - return self._ptr.setThreadLocal(value) + value = _to_int(value) + _core.LLVMSetThreadLocal(self.ptr, value) thread_local = property(_get_thread_local, _set_thread_local) class Argument(Value): - __slots__ = () - _type_ = api.llvm.Argument - _valid_attrs = frozenset([ATTR_BY_VAL, ATTR_NEST, ATTR_NO_ALIAS, - ATTR_NO_CAPTURE, ATTR_STRUCT_RET]) - if llvm.version >= (3, 3): - def add_attribute(self, attr): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAttribute(attr) - attrs = api.llvm.AttributeSet.get(context, 0, attrbldr) - self._ptr.addAttr(attrs) + def add_attribute(self, attr): + _core.LLVMAddAttribute(self.ptr, attr) - if attr not in self: - raise ValueError("Attribute %r is not valid for arg %s" % - (attr, self)) + def remove_attribute(self, attr): + _core.LLVMRemoveAttribute(self.ptr, attr) - def remove_attribute(self, attr): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAttribute(attr) - attrs = api.llvm.AttributeSet.get(context, 0, attrbldr) - self._ptr.removeAttr(attrs) - - def _set_alignment(self, align): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAlignmentAttr(align) - attrs = api.llvm.AttributeSet.get(context, 0, attrbldr) - self._ptr.addAttr(attrs) - else: - def add_attribute(self, attr): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAttribute(attr) - attrs = api.llvm.Attributes.get(context, attrbldr) - self._ptr.addAttr(attrs) - if attr not in self: - raise ValueError("Attribute %r is not valid for arg %s" % - (attr, self)) - - def remove_attribute(self, attr): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAttribute(attr) - attrs = api.llvm.Attributes.get(context, attrbldr) - self._ptr.removeAttr(attrs) - - def _set_alignment(self, align): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAlignmentAttr(align) - attrs = api.llvm.Attributes.get(context, attrbldr) - self._ptr.addAttr(attrs) + def _set_alignment(self, align): + _core.LLVMSetParamAlignment(self.ptr, align) def _get_alignment(self): - return self._ptr.getParamAlignment() + return _core.LLVMGetParamAlignment(self.ptr) - alignment = property(_get_alignment, - _set_alignment) + alignment = \ + property(_get_alignment, _set_alignment) - @property - def attributes(self): - '''Returns a set of defined attributes. - ''' - return set(attr for attr in self._valid_attrs if attr in self) - - def __contains__(self, attr): - if attr == ATTR_BY_VAL: - return self.has_by_val() - elif attr == ATTR_NEST: - return self.has_nest() - elif attr == ATTR_NO_ALIAS: - return self.has_no_alias() - elif attr == ATTR_NO_CAPTURE: - return self.has_no_capture() - elif attr == ATTR_STRUCT_RET: - return self.has_struct_ret() - else: - raise ValueError('invalid attribute for argument') - - @property - def arg_no(self): - return self._ptr.getArgNo() - - def has_by_val(self): - return self._ptr.hasByValAttr() - - def has_nest(self): - return self._ptr.hasNestAttr() - - def has_no_alias(self): - return self._ptr.hasNoAliasAttr() - - def has_no_capture(self): - return self._ptr.hasNoCaptureAttr() - - def has_struct_ret(self): - return self._ptr.hasStructRetAttr() class Function(GlobalValue): - __slots__ = () - _type_ = api.llvm.Function @staticmethod def new(module, func_ty, name): - try: - fn = Function.get(module, name) - except llvm.LLVMException: - return Function.get_or_insert(module, func_ty, name) - else: - raise llvm.LLVMException("Duplicated function %s" % name) - + check_is_module(module) + check_is_type(func_ty) + return _make_value(_core.LLVMAddFunction(module.ptr, name, + func_ty.ptr)) @staticmethod def get_or_insert(module, func_ty, name): - constant = module._ptr.getOrInsertFunction(name, func_ty._ptr) - try: - fn = constant._downcast(api.llvm.Function) - except ValueError: - # bitcasted to function type - return _make_value(constant) - else: - return _make_value(fn) + check_is_module(module) + check_is_type(func_ty) + return _make_value(_core.LLVMModuleGetOrInsertFunction(module.ptr, + name, func_ty.ptr)) @staticmethod def get(module, name): - fn = module._ptr.getFunction(name) - if fn is None: + check_is_module(module) + ptr = _core.LLVMGetNamedFunction(module.ptr, name) + if not ptr: raise llvm.LLVMException("no function named `%s`" % name) - else: - return _make_value(fn) + return _make_value(ptr) @staticmethod def intrinsic(module, intrinsic_id, types): - fn = api.llvm.Intrinsic.getDeclaration(module._ptr, - intrinsic_id, - llvm._extract_ptrs(types)) - return _make_value(fn) + check_is_module(module) + ptrs = unpack_types(types) + return _make_value( + _core.LLVMGetIntrinsic(module.ptr, intrinsic_id, ptrs)) def delete(self): - _ValueFactory.delete(self._ptr) - self._ptr.eraseFromParent() + self._delete() + _core.LLVMDeleteFunction(self.ptr) + self.forget() + self.ptr = None @property def intrinsic_id(self): - self._ptr.getIntrinsicID() - - def _get_cc(self): - return self._ptr.getCallingConv() - - def _set_cc(self, value): - self._ptr.setCallingConv(value) + return _core.LLVMGetIntrinsicID(self.ptr) + def _get_cc(self): return _core.LLVMGetFunctionCallConv(self.ptr) + def _set_cc(self, value): _core.LLVMSetFunctionCallConv(self.ptr, value) calling_convention = property(_get_cc, _set_cc) - def _get_coll(self): - return self._ptr.getGC() - - def _set_coll(self, value): - return self._ptr.setGC(value) - + def _get_coll(self): return _core.LLVMGetGC(self.ptr) + def _set_coll(self, value): _core.LLVMSetGC(self.ptr, value) collector = property(_get_coll, _set_coll) # the nounwind attribute: - def _get_does_not_throw(self): - return self._ptr.doesNotThrow() - - def _set_does_not_throw(self,value): - assert value - self._ptr.setDoesNotThrow() - + def _get_does_not_throw(self): return _core.LLVMGetDoesNotThrow(self.ptr) + def _set_does_not_throw(self,value): _core.LLVMSetDoesNotThrow(self.ptr, value) does_not_throw = property(_get_does_not_throw, _set_does_not_throw) @property def args(self): - args = self._ptr.getArgumentList() - return list(map(_make_value, args)) + return _util.wrapiter(_core.LLVMGetFirstParam, + _core.LLVMGetNextParam, self.ptr, _make_value) @property def basic_block_count(self): - return len(self.basic_blocks) + return _core.LLVMCountBasicBlocks(self.ptr) @property def entry_basic_block(self): - assert self.basic_block_count - return _make_value(self._ptr.getEntryBlock()) + if self.basic_block_count == 0: + return None + return _make_value(_core.LLVMGetEntryBasicBlock(self.ptr)) def get_entry_basic_block(self): - "Deprecated. Use entry_basic_block instead" + """Deprecated, use entry_basic_block property.""" return self.entry_basic_block def append_basic_block(self, name): - context = api.llvm.getGlobalContext() - bb = api.llvm.BasicBlock.Create(context, name, self._ptr, None) - return _make_value(bb) + return _make_value(_core.LLVMAppendBasicBlock(self.ptr, name)) @property def basic_blocks(self): - return list(map(_make_value, self._ptr.getBasicBlockList())) + return _util.wrapiter(_core.LLVMGetFirstBasicBlock, + _core.LLVMGetNextBasicBlock, self.ptr, _make_value) def viewCFG(self): - return self._ptr.viewCFG() + return _core.LLVMViewFunctionCFG(self.ptr) def add_attribute(self, attr): - self._ptr.addFnAttr(attr) + _core.LLVMAddFunctionAttr(self.ptr, attr) def remove_attribute(self, attr): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAttribute(attr) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) - self._ptr.removeFnAttr(attrs) + _core.LLVMRemoveFunctionAttr(self.ptr, attr) def viewCFGOnly(self): - return self._ptr.viewCFGOnly() + return _core.LLVMViewFunctionCFGOnly(self.ptr) def verify(self): # Although we're just asking LLVM to return the success or @@ -1685,94 +1513,72 @@ class Function(GlobalValue): # Note: LLVM has a bug in preverifier that will always abort # the process upon failure. - actions = api.llvm.VerifierFailureAction - broken = api.llvm.verifyFunction(self._ptr, - actions.ReturnStatusAction) - if broken: - # If broken, then re-run to print the message - api.llvm.verifyFunction(self._ptr, actions.PrintMessageAction) - raise llvm.LLVMException("Function %s failed verification" % - self.name) + return _core.LLVMVerifyFunction(self.ptr) != 0 #===----------------------------------------------------------------------=== # InlineAsm #===----------------------------------------------------------------------=== class InlineAsm(Value): - __slots__ = () - _type_ = api.llvm.InlineAsm - @staticmethod def get(functype, asm, constrains, side_effect=False, - align_stack=False, dialect=api.llvm.InlineAsm.AsmDialect.AD_ATT): - ilasm = api.llvm.InlineAsm.get(functype._ptr, asm, constrains, - side_effect, align_stack, dialect) - return _make_value(ilasm) + align_stack=False, dialect=0): + assert dialect == 0, "LLVM 3.1 does not implement dialect selection" + check_is_type(functype) + pycap = _core.LLVMGetFunctionFromInlineAsm(functype.ptr, asm, + constrains, int(side_effect), + int(align_stack), dialect) + return _make_value(pycap) #===----------------------------------------------------------------------=== # MetaData #===----------------------------------------------------------------------=== class MetaData(Value): - __slots__ = () - _type_ = api.llvm.MDNode - @staticmethod def get(module, values): ''' values -- must be an iterable of Constant or None. None is treated as "null". ''' - context = api.llvm.getGlobalContext() - ptr = api.llvm.MDNode.get(context, llvm._extract_ptrs(values)) - return _make_value(ptr) + vs = unpack_values_or_none(values) + ptr = _core.LLVMMetaDataGet(module.ptr, vs) + return MetaData(ptr) @staticmethod def get_named_operands(module, name): - namedmd = module.get_named_metadata(name) - if not namedmd: - return [] - return [_make_value(namedmd._ptr.getOperand(i)) - for i in range(namedmd._ptr.getNumOperands())] + lst = _core.LLVMGetNamedMetadataOperands(module.ptr, name) + return [MetaData(ptr) for ptr in lst] @staticmethod def add_named_operand(module, name, operand): - namedmd = module.get_or_insert_named_metadata(name)._ptr - namedmd.addOperand(operand._ptr) + _core.LLVMAddNamedMetadataOperand(module.ptr, name, operand.ptr) @property def operand_count(self): - return self._ptr.getNumOperands() + return _core.LLVMMetaDataGetNumOperands(self.ptr) @property def operands(self): """Yields operands of this metadata.""" - res = [] - for i in range(self.operand_count): - op = self._ptr.getOperand(i) - if op is None: - res.append(None) - else: - res.append(_make_value(op)) - return res + return [self._get_operand(i) for i in range(self.operand_count)] + + def _get_operand(self, i): + val = _core.LLVMMetaDataGetOperand(self.ptr, i) + if val: # metadata operands can be None + return _make_value(val) class MetaDataString(Value): - _type_ = api.llvm.MDString - @staticmethod def get(module, s): - context = api.llvm.getGlobalContext() - ptr = api.llvm.MDString.get(context, s) - return _make_value(ptr) + ptr = _core.LLVMMetaDataStringGet(module.ptr, s) + return MetaDataString(ptr) @property def string(self): '''Same as MDString::getString''' - return self._ptr.getString() - - -class NamedMetaData(llvm.Wrapper): - __slots__ = () + return self.name +class NamedMetaData(llvm.Cacheable): @staticmethod def get_or_insert(mod, name): return mod.get_or_insert_named_metadata(name) @@ -1781,543 +1587,467 @@ class NamedMetaData(llvm.Wrapper): def get(mod, name): return mod.get_named_metadata(name) + def __init__(self, ptr): + self.ptr = ptr + def delete(self): - _ValueFactory.delete(self._ptr) - self._ptr.eraseFromParent() + _core.LLVMEraseNamedMetaData(self.ptr) @property def name(self): - return self._ptr.getName() + return _core.LLVMNamedMetaDataGetName(self.ptr) def __str__(self): - return str(self._ptr) + return _core.LLVMDumpNamedMDToString(self.ptr) def add(self, operand): - self._ptr.addOperand(operand._ptr) - + _core.LLVMNamedMetaDataAddOperand(self.ptr, operand.ptr) #===----------------------------------------------------------------------=== # Instruction #===----------------------------------------------------------------------=== class Instruction(User): - __slots__ = () - _type_ = api.llvm.Instruction @property def basic_block(self): - return _make_value(self._ptr.getParent()) + return _make_value(_core.LLVMGetInstructionParent(self.ptr)) @property def is_terminator(self): - return self._ptr.isTerminator() + return _core.LLVMInstIsTerminator(self.ptr) != 0 @property def is_binary_op(self): - return self._ptr.isBinaryOp() + return _core.LLVMInstIsBinaryOp(self.ptr) != 0 @property def is_shift(self): - return self._ptr.isShift() + return _core.LLVMInstIsShift(self.ptr) != 0 @property def is_cast(self): - return self._ptr.isCast() + return _core.LLVMInstIsCast(self.ptr) != 0 @property def is_logical_shift(self): - return self._ptr.isLogicalShift() + return _core.LLVMInstIsLogicalShift(self.ptr) != 0 @property def is_arithmetic_shift(self): - return self._ptr.isArithmeticShift() + return _core.LLVMInstIsArithmeticShift(self.ptr) != 0 @property def is_associative(self): - return self._ptr.isAssociative() + return _core.LLVMInstIsAssociative(self.ptr) != 0 @property def is_commutative(self): - return self._ptr.isCommutative() + return _core.LLVMInstIsCommutative(self.ptr) != 0 @property def is_volatile(self): """True if this is a volatile load or store.""" - if api.llvm.LoadInst.classof(self._ptr): - return self._ptr._downcast(api.llvm.LoadInst).isVolatile() - elif api.llvm.StoreInst.classof(self._ptr): - return self._ptr._downcast(api.llvm.StoreInst).isVolatile() - else: - return False + return _core.LLVMInstIsVolatile(self.ptr) != 0 def set_volatile(self, flag): - if api.llvm.LoadInst.classof(self._ptr): - return self._ptr._downcast(api.llvm.LoadInst).setVolatile(flag) - elif api.llvm.StoreInst.classof(self._ptr): - return self._ptr._downcast(api.llvm.StoreInst).setVolatile(flag) - else: - return False + return _core.LLVMSetVolatile(self.ptr, int(bool(flag))) def set_metadata(self, kind, metadata): - self._ptr.setMetadata(kind, metadata._ptr) - - def has_metadata(self): - return self._ptr.hasMetadata() - - def get_metadata(self, kind): - return self._ptr.getMetadata(kind) + return _core.LLVMInstSetMetaData(self.ptr, kind, metadata.ptr) @property def opcode(self): - return self._ptr.getOpcode() + return _core.LLVMInstGetOpcode(self.ptr) @property def opcode_name(self): - return self._ptr.getOpcodeName() + return _core.LLVMInstGetOpcodeName(self.ptr) def erase_from_parent(self): - return self._ptr.eraseFromParent() - - def replace_all_uses_with(self, inst): - self._ptr.replaceAllUsesWith(inst) - + return _core.LLVMInstructionEraseFromParent(self.ptr) class CallOrInvokeInstruction(Instruction): - __slots__ = () - _type_ = api.llvm.CallInst, api.llvm.InvokeInst - - def _get_cc(self): - return self._ptr.getCallingConv() - - def _set_cc(self, value): - return self._ptr.setCallingConv(value) + def _get_cc(self): return _core.LLVMGetInstructionCallConv(self.ptr) + def _set_cc(self, value): _core.LLVMSetInstructionCallConv(self.ptr, value) calling_convention = property(_get_cc, _set_cc) def add_parameter_attribute(self, idx, attr): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAttribute(attr) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) - - self._ptr.addAttribute(idx, attrs) + _core.LLVMAddInstrAttribute(self.ptr, idx, attr) def remove_parameter_attribute(self, idx, attr): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAttribute(attr) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) - - self._ptr.removeAttribute(idx, attrs) + _core.LLVMRemoveInstrAttribute(self.ptr, idx, attr) def set_parameter_alignment(self, idx, align): - context = api.llvm.getGlobalContext() - attrbldr = api.llvm.AttrBuilder.new() - attrbldr.addAlignmentAttr(align) - if llvm.version >= (3, 3): - attrs = api.llvm.Attribute.get(context, attrbldr) - else: - attrs = api.llvm.Attributes.get(context, attrbldr) - - self._ptr.addAttribute(idx, attrs) + _core.LLVMSetInstrParamAlignment(self.ptr, idx, align) def _get_called_function(self): - function = self._ptr.getCalledFunction() + function = _core.LLVMInstGetCalledFunction(self.ptr) if function: # Return value can be None on indirect call/invoke return _make_value(function) def _set_called_function(self, function): - self._ptr.setCalledFunction(function._ptr) + _core.LLVMInstSetCalledFunction(self.ptr, function.ptr) called_function = property(_get_called_function, _set_called_function) + # tail call is valid only for 'call', not 'invoke' + # disabled for now + #def _get_tc(self): return _core.LLVMIsTailCall(self.ptr) + #def _set_tc(self, value): _core.LLVMSetTailCall(self.ptr, value) + #tail_call = property(_get_tc, _set_tc) + class PHINode(Instruction): - __slots__ = () - _type_ = api.llvm.PHINode @property def incoming_count(self): - return self._ptr.getNumIncomingValues() + return _core.LLVMCountIncoming(self.ptr) def add_incoming(self, value, block): - self._ptr.addIncoming(value._ptr, block._ptr) + check_is_value(value) + check_is_basic_block(block) + _core.LLVMAddIncoming1(self.ptr, value.ptr, block.ptr) def get_incoming_value(self, idx): - return _make_value(self._ptr.getIncomingValue(idx)) + return _make_value(_core.LLVMGetIncomingValue(self.ptr, idx)) def get_incoming_block(self, idx): - return _make_value(self._ptr.getIncomingBlock(idx)) + return _make_value(_core.LLVMGetIncomingBlock(self.ptr, idx)) class SwitchInstruction(Instruction): - __slots__ = () - _type_ = api.llvm.SwitchInst def add_case(self, const, bblk): - self._ptr.addCase(const._ptr, bblk._ptr) + check_is_constant(const) # and has to be an int too + check_is_basic_block(bblk) + _core.LLVMAddCase(self.ptr, const.ptr, bblk.ptr) class CompareInstruction(Instruction): - __slots__ = () - _type_ = api.llvm.CmpInst @property def predicate(self): - n = self._ptr.getPredicate() - try: - return ICMPEnum.get(n) - except KeyError: - return FCMPEnum.get(n) + return _core.LLVMCmpInstGetPredicate(self.ptr) -class AllocaInstruction(Instruction): - __slots__ = () - _type_ = api.llvm.AllocaInst - - @property - def alignment(self): - return self._ptr.getAlignment() - - @alignment.setter - def alignment(self, n): - self._ptr.setAlignment(n) - - @property - def array_size(self): - return self._ptr.getArraySize() - - @array_size.setter - def array_size(self, value): - return self._ptr.setArraySize(value._ptr)._ptr - - @property - def is_array(self): - return self._ptr.isArrayAllocation() - - @property - def is_static(self): - return self._ptr.isStaticAlloca() - #===----------------------------------------------------------------------=== # Basic block #===----------------------------------------------------------------------=== class BasicBlock(Value): - __slots__ = () - _type_ = api.llvm.BasicBlock def insert_before(self, name): - context = api.llvm.getGlobalContext() - ptr = api.llvm.BasicBlock.Create(context, name, self.function._ptr, - self._ptr) - return _make_value(ptr) + return _make_value(_core.LLVMInsertBasicBlock(self.ptr, name)) def delete(self): - _ValueFactory.delete(self._ptr) - self._ptr.eraseFromParent() + _core.LLVMDeleteBasicBlock(self.ptr) + self.forget() + self.ptr = None @property def function(self): - return _make_value(self._ptr.getParent()) + func_ptr = _core.LLVMGetBasicBlockParent(self.ptr) + return _make_value(func_ptr) @property def instructions(self): - return list(map(_make_value, self._ptr.getInstList())) + return _util.wrapiter(_core.LLVMGetFirstInstruction, + _core.LLVMGetNextInstruction, self.ptr, _make_value) + #===----------------------------------------------------------------------=== # Value factory method #===----------------------------------------------------------------------=== - -class _ValueFactory(object): - __slots__ = () - cache = weakref.WeakValueDictionary() - - # value ID -> class map - class_for_valueid = { - VALUE_ARGUMENT : Argument, - VALUE_BASIC_BLOCK : BasicBlock, - VALUE_FUNCTION : Function, - VALUE_GLOBAL_ALIAS : GlobalValue, - VALUE_GLOBAL_VARIABLE : GlobalVariable, - VALUE_UNDEF_VALUE : UndefValue, - VALUE_CONSTANT_EXPR : ConstantExpr, - VALUE_CONSTANT_AGGREGATE_ZERO : ConstantAggregateZero, - VALUE_CONSTANT_DATA_ARRAY : ConstantDataArray, - VALUE_CONSTANT_DATA_VECTOR : ConstantDataVector, - VALUE_CONSTANT_INT : ConstantInt, - VALUE_CONSTANT_FP : ConstantFP, - VALUE_CONSTANT_ARRAY : ConstantArray, - VALUE_CONSTANT_STRUCT : ConstantStruct, - VALUE_CONSTANT_VECTOR : ConstantVector, - VALUE_CONSTANT_POINTER_NULL : ConstantPointerNull, - VALUE_MD_NODE : MetaData, - VALUE_MD_STRING : MetaDataString, - VALUE_INLINE_ASM : InlineAsm, - VALUE_INSTRUCTION + OPCODE_PHI : PHINode, - VALUE_INSTRUCTION + OPCODE_CALL : CallOrInvokeInstruction, - VALUE_INSTRUCTION + OPCODE_INVOKE : CallOrInvokeInstruction, - VALUE_INSTRUCTION + OPCODE_SWITCH : SwitchInstruction, - VALUE_INSTRUCTION + OPCODE_ICMP : CompareInstruction, - VALUE_INSTRUCTION + OPCODE_FCMP : CompareInstruction, - VALUE_INSTRUCTION + OPCODE_ALLOCA : AllocaInstruction, - } - - @classmethod - def build(cls, ptr): - # try to look in the cache - addr = ptr._capsule.pointer - id = ptr.getValueID() - key = id, addr - try: - obj = cls.cache[key] - return obj - except KeyError: - pass - # find class by value id - ctorcls = cls.class_for_valueid.get(id) - if not ctorcls: - if id > VALUE_INSTRUCTION: # "generic" instruction - ctorcls = Instruction - else: # "generic" value - ctorcls = Value - # cache the obj - obj = ctorcls(_ValueFactory, ptr) - cls.cache[key] = obj - return obj - - @classmethod - def delete(cls, ptr): - del cls.cache[(ptr.getValueID(), ptr._capsule.pointer)] +# value ID -> class map +__class_for_valueid = { + VALUE_ARGUMENT : Argument, + VALUE_BASIC_BLOCK : BasicBlock, + VALUE_FUNCTION : Function, + VALUE_GLOBAL_ALIAS : GlobalValue, + VALUE_GLOBAL_VARIABLE : GlobalVariable, + VALUE_UNDEF_VALUE : UndefValue, + VALUE_CONSTANT_EXPR : ConstantExpr, + VALUE_CONSTANT_AGGREGATE_ZERO : ConstantAggregateZero, + VALUE_CONSTANT_DATA_ARRAY : ConstantDataArray, + VALUE_CONSTANT_DATA_VECTOR : ConstantDataVector, + VALUE_CONSTANT_INT : ConstantInt, + VALUE_CONSTANT_FP : ConstantFP, + VALUE_CONSTANT_ARRAY : ConstantArray, + VALUE_CONSTANT_STRUCT : ConstantStruct, + VALUE_CONSTANT_VECTOR : ConstantVector, + VALUE_CONSTANT_POINTER_NULL : ConstantPointerNull, + VALUE_MD_NODE : MetaData, + VALUE_MD_STRING : MetaDataString, + VALUE_INLINE_ASM : InlineAsm, + VALUE_INSTRUCTION + OPCODE_PHI : PHINode, + VALUE_INSTRUCTION + OPCODE_CALL : CallOrInvokeInstruction, + VALUE_INSTRUCTION + OPCODE_INVOKE : CallOrInvokeInstruction, + VALUE_INSTRUCTION + OPCODE_SWITCH : SwitchInstruction, + VALUE_INSTRUCTION + OPCODE_ICMP : CompareInstruction, + VALUE_INSTRUCTION + OPCODE_FCMP : CompareInstruction +} def _make_value(ptr): - return _ValueFactory.build(ptr) + kind = _core.LLVMValueGetID(ptr) + # based on kind, create one of the Value subclasses + class_obj = __class_for_valueid.get(kind) + if class_obj: + return class_obj(ptr) + elif kind > VALUE_INSTRUCTION: + # "generic" instruction + return Instruction(ptr) + else: + # "generic" value + return Value(ptr) + #===----------------------------------------------------------------------=== # Builder #===----------------------------------------------------------------------=== -_atomic_orderings = { - 'unordered' : api.llvm.AtomicOrdering.Unordered, - 'monotonic' : api.llvm.AtomicOrdering.Monotonic, - 'acquire' : api.llvm.AtomicOrdering.Acquire, - 'release' : api.llvm.AtomicOrdering.Release, - 'acq_rel' : api.llvm.AtomicOrdering.AcquireRelease, - 'seq_cst' : api.llvm.AtomicOrdering.SequentiallyConsistent -} - -class Builder(llvm.Wrapper): - __slots__ = () +class Builder(object): @staticmethod def new(basic_block): - context = api.llvm.getGlobalContext() - ptr = api.llvm.IRBuilder.new(context) - ptr.SetInsertPoint(basic_block._ptr) - return Builder(ptr) + check_is_basic_block(basic_block) + b = Builder(_core.LLVMCreateBuilder()) + b.position_at_end(basic_block) + return b + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeBuilder(self.ptr) def position_at_beginning(self, bblk): """Position the builder at the beginning of the given block. Next instruction inserted will be first one in the block.""" - - # Instruction list won't be long anyway, - # Does not matter much to build a list of all instructions - instrs = bblk.instructions - if instrs: - self.position_before(instrs[0]) - else: - self.position_at_end(bblk) + check_is_basic_block(bblk) + # Avoids using "blk.instructions", which will fetch all the + # instructions into a list. Don't try this at home, though. + inst_ptr = _core.LLVMGetFirstInstruction(bblk.ptr) + if inst_ptr: + # Issue #10: inst_ptr can be None if b/b has no insts. + inst = _make_value(inst_ptr) + self.position_before(inst) def position_at_end(self, bblk): """Position the builder at the end of the given block. Next instruction inserted will be last one in the block.""" - - self._ptr.SetInsertPoint(bblk._ptr) + _core.LLVMPositionBuilderAtEnd(self.ptr, bblk.ptr) def position_before(self, instr): """Position the builder before the given instruction. - The instruction can belong to a basic block other than the - current one.""" - self._ptr.SetInsertPoint(instr._ptr) + The instruction can belong to a basic block other than the + current one.""" + _core.LLVMPositionBuilderBefore(self.ptr, instr.ptr) + + @property + def block(self): + """Deprecated, use basic_block property instead.""" + return _make_value(_core.LLVMGetInsertBlock(self.ptr)) @property def basic_block(self): """The basic block where the builder is positioned.""" - return _make_value(self._ptr.GetInsertBlock()) + return _make_value(_core.LLVMGetInsertBlock(self.ptr)) # terminator instructions - def _guard_terminators(self): - if __debug__: - import warnings - for instr in self.basic_block.instructions: - if instr.is_terminator: - warnings.warn("BasicBlock can only have one terminator") def ret_void(self): - self._guard_terminators() - return _make_value(self._ptr.CreateRetVoid()) + return _make_value(_core.LLVMBuildRetVoid(self.ptr)) def ret(self, value): - self._guard_terminators() - return _make_value(self._ptr.CreateRet(value._ptr)) + check_is_value(value) + return _make_value(_core.LLVMBuildRet(self.ptr, value.ptr)) def ret_many(self, values): - self._guard_terminators() - values = llvm._extract_ptrs(values) - return _make_value(self._ptr.CreateAggregateRet(values, len(values))) + vs = unpack_values(values) + return _make_value(_core.LLVMBuildRetMultiple(self.ptr, vs)) def branch(self, bblk): - self._guard_terminators() - return _make_value(self._ptr.CreateBr(bblk._ptr)) + check_is_basic_block(bblk) + if __debug__: + for instr in self.basic_block.instructions: + assert not instr.is_terminator, "BasicBlock can only have one terminator" + return _make_value(_core.LLVMBuildBr(self.ptr, bblk.ptr)) def cbranch(self, if_value, then_blk, else_blk): - self._guard_terminators() - return _make_value(self._ptr.CreateCondBr(if_value._ptr, - then_blk._ptr, - else_blk._ptr)) + check_is_value(if_value) + check_is_basic_block(then_blk) + check_is_basic_block(else_blk) + return _make_value( + _core.LLVMBuildCondBr(self.ptr, + if_value.ptr, then_blk.ptr, else_blk.ptr)) def switch(self, value, else_blk, n=10): - self._guard_terminators() - return _make_value(self._ptr.CreateSwitch(value._ptr, - else_blk._ptr, - n)) + check_is_value(value) # value has to be of any 'int' type + check_is_basic_block(else_blk) + return _make_value( + _core.LLVMBuildSwitch(self.ptr, value.ptr, else_blk.ptr, n)) def invoke(self, func, args, then_blk, catch_blk, name=""): - self._guard_terminators() - return _make_value(self._ptr.CreateInvoke(func._ptr, - then_blk._ptr, - catch_blk._ptr, - llvm._extract_ptrs(args))) + check_is_callable(func) + check_is_basic_block(then_blk) + check_is_basic_block(catch_blk) + args2 = unpack_values(args) + return _make_value( + _core.LLVMBuildInvoke(self.ptr, func.ptr, args2, + then_blk.ptr, catch_blk.ptr, name)) def unreachable(self): - self._guard_terminators() - return _make_value(self._ptr.CreateUnreachable()) + return _make_value(_core.LLVMBuildUnreachable(self.ptr)) # arithmethic, bitwise and logical - def add(self, lhs, rhs, name="", nuw=False, nsw=False): - return _make_value(self._ptr.CreateAdd(lhs._ptr, rhs._ptr, name, - nuw, nsw)) + def add(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value(_core.LLVMBuildAdd(self.ptr, lhs.ptr, rhs.ptr, name)) def fadd(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateFAdd(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value(_core.LLVMBuildFAdd(self.ptr, lhs.ptr, rhs.ptr, name)) - def sub(self, lhs, rhs, name="", nuw=False, nsw=False): - return _make_value(self._ptr.CreateSub(lhs._ptr, rhs._ptr, name, - nuw, nsw)) + def sub(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value(_core.LLVMBuildSub(self.ptr, lhs.ptr, rhs.ptr, name)) def fsub(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateFSub(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value(_core.LLVMBuildFSub(self.ptr, lhs.ptr, rhs.ptr, name)) - def mul(self, lhs, rhs, name="", nuw=False, nsw=False): - return _make_value(self._ptr.CreateMul(lhs._ptr, rhs._ptr, name, - nuw, nsw)) + def mul(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value(_core.LLVMBuildMul(self.ptr, lhs.ptr, rhs.ptr, name)) def fmul(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateFMul(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value(_core.LLVMBuildFMul(self.ptr, lhs.ptr, rhs.ptr, name)) - def udiv(self, lhs, rhs, name="", exact=False): - return _make_value(self._ptr.CreateUDiv(lhs._ptr, rhs._ptr, name, - exact)) + def udiv(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildUDiv(self.ptr, lhs.ptr, rhs.ptr, name)) - def sdiv(self, lhs, rhs, name="", exact=False): - return _make_value(self._ptr.CreateSDiv(lhs._ptr, rhs._ptr, name, - exact)) + def sdiv(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildSDiv(self.ptr, lhs.ptr, rhs.ptr, name)) def fdiv(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateFDiv(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildFDiv(self.ptr, lhs.ptr, rhs.ptr, name)) def urem(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateURem(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildURem(self.ptr, lhs.ptr, rhs.ptr, name)) def srem(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateSRem(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildSRem(self.ptr, lhs.ptr, rhs.ptr, name)) def frem(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateFRem(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildFRem(self.ptr, lhs.ptr, rhs.ptr, name)) - def shl(self, lhs, rhs, name="", nuw=False, nsw=False): - return _make_value(self._ptr.CreateShl(lhs._ptr, rhs._ptr, name, - nuw, nsw)) + def shl(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildShl(self.ptr, lhs.ptr, rhs.ptr, name)) - def lshr(self, lhs, rhs, name="", exact=False): - return _make_value(self._ptr.CreateLShr(lhs._ptr, rhs._ptr, name, - exact)) + def lshr(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildLShr(self.ptr, lhs.ptr, rhs.ptr, name)) - def ashr(self, lhs, rhs, name="", exact=False): - return _make_value(self._ptr.CreateAShr(lhs._ptr, rhs._ptr, name, - exact)) + def ashr(self, lhs, rhs, name=""): + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildAShr(self.ptr, lhs.ptr, rhs.ptr, name)) def and_(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateAnd(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildAnd(self.ptr, lhs.ptr, rhs.ptr, name)) def or_(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateOr(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildOr(self.ptr, lhs.ptr, rhs.ptr, name)) def xor(self, lhs, rhs, name=""): - return _make_value(self._ptr.CreateXor(lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildXor(self.ptr, lhs.ptr, rhs.ptr, name)) - def neg(self, val, name="", nuw=False, nsw=False): - return _make_value(self._ptr.CreateNeg(val._ptr, name, nuw, nsw)) + def neg(self, val, name=""): + check_is_value(val) + return _make_value(_core.LLVMBuildNeg(self.ptr, val.ptr, name)) def not_(self, val, name=""): - return _make_value(self._ptr.CreateNot(val._ptr, name)) + check_is_value(val) + return _make_value(_core.LLVMBuildNot(self.ptr, val.ptr, name)) # memory def malloc(self, ty, name=""): - allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) - ity = allocsz.getType() - malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, - ity, - ty._ptr, - allocsz, - None, - None, - "") - inst = self._ptr.Insert(malloc, name) - return _make_value(inst) + check_is_type(ty) + return _make_value(_core.LLVMBuildMalloc(self.ptr, ty.ptr, name)) def malloc_array(self, ty, size, name=""): - allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) - ity = allocsz.getType() - malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, - ity, - ty._ptr, - allocsz, - size._ptr, - None, - "") - inst = self._ptr.Insert(malloc, name) - return _make_value(inst) + check_is_type(ty) + check_is_value(size) + return _make_value( + _core.LLVMBuildArrayMalloc(self.ptr, ty.ptr, size.ptr, name)) - def alloca(self, ty, size=None, name=""): - sizeptr = size._ptr if size else None - return _make_value(self._ptr.CreateAlloca(ty._ptr, sizeptr, name)) + def alloca(self, ty, name=""): + check_is_type(ty) + return _make_value(_core.LLVMBuildAlloca(self.ptr, ty.ptr, name)) - @deprecated def alloca_array(self, ty, size, name=""): - return self.alloca(ty, size, name=name) + check_is_type(ty) + check_is_value(size) + return _make_value( + _core.LLVMBuildArrayAlloca(self.ptr, ty.ptr, size.ptr, name)) def free(self, ptr): - free = api.llvm.CallInst.CreateFree(ptr._ptr, self.basic_block._ptr) - inst = self._ptr.Insert(free) - return _make_value(inst) + check_is_value(ptr) + return _make_value(_core.LLVMBuildFree(self.ptr, ptr.ptr)) def load(self, ptr, name="", align=0, volatile=False, invariant=False): - inst = _make_value(self._ptr.CreateLoad(ptr._ptr, name)) + check_is_value(ptr) + inst = _make_value(_core.LLVMBuildLoad(self.ptr, ptr.ptr, name)) if align: - inst._ptr.setAlignment(align) + _core.LLVMLdSetAlignment(inst.ptr, align) if volatile: inst.set_volatile(volatile) if invariant: @@ -2327,141 +2057,198 @@ class Builder(llvm.Wrapper): return inst def store(self, value, ptr, align=0, volatile=False): - inst = _make_value(self._ptr.CreateStore(value._ptr, ptr._ptr)) + check_is_value(value) + check_is_value(ptr) + inst = _make_value(_core.LLVMBuildStore(self.ptr, value.ptr, ptr.ptr)) if align: - inst._ptr.setAlignment(align) + _core.LLVMStSetAlignment(inst.ptr, align) if volatile: inst.set_volatile(volatile) return inst def gep(self, ptr, indices, name="", inbounds=False): + check_is_value(ptr) + index_ptrs = unpack_values(indices) if inbounds: - ret = self._ptr.CreateInBoundsGEP(ptr._ptr, - llvm._extract_ptrs(indices), - name) + ret = _core.LLVMBuildInBoundsGEP(self.ptr, ptr.ptr, index_ptrs, name) else: - ret = self._ptr.CreateGEP(ptr._ptr, - llvm._extract_ptrs(indices), - name) + ret = _core.LLVMBuildGEP(self.ptr, ptr.ptr, index_ptrs, name) return _make_value(ret) # casts and extensions def trunc(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateTrunc(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) def zext(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateZExt(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildZExt(self.ptr, value.ptr, dest_ty.ptr, name)) def sext(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateSExt(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildSExt(self.ptr, value.ptr, dest_ty.ptr, name)) def fptoui(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateFPToUI(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildFPToUI(self.ptr, value.ptr, dest_ty.ptr, name)) def fptosi(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateFPToSI(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildFPToSI(self.ptr, value.ptr, dest_ty.ptr, name)) def uitofp(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateUIToFP(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildUIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) def sitofp(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateSIToFP(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildSIToFP(self.ptr, value.ptr, dest_ty.ptr, name)) def fptrunc(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateFPTrunc(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildFPTrunc(self.ptr, value.ptr, dest_ty.ptr, name)) def fpext(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateFPExt(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildFPExt(self.ptr, value.ptr, dest_ty.ptr, name)) def ptrtoint(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreatePtrToInt(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildPtrToInt(self.ptr, value.ptr, dest_ty.ptr, name)) def inttoptr(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateIntToPtr(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildIntToPtr(self.ptr, value.ptr, dest_ty.ptr, name)) def bitcast(self, value, dest_ty, name=""): - return _make_value(self._ptr.CreateBitCast(value._ptr, dest_ty._ptr, name)) + check_is_value(value) + check_is_type(dest_ty) + return _make_value( + _core.LLVMBuildBitCast(self.ptr, value.ptr, dest_ty.ptr, name)) # comparisons def icmp(self, ipred, lhs, rhs, name=""): - return _make_value(self._ptr.CreateICmp(ipred, lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildICmp(self.ptr, ipred, lhs.ptr, rhs.ptr, name)) def fcmp(self, rpred, lhs, rhs, name=""): - return _make_value(self._ptr.CreateFCmp(rpred, lhs._ptr, rhs._ptr, name)) + check_is_value(lhs) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildFCmp(self.ptr, rpred, lhs.ptr, rhs.ptr, name)) # misc def extract_value(self, retval, idx, name=""): - if not isinstance(idx, (tuple, list)): - idx = [idx] - return _make_value(self._ptr.CreateExtractValue(retval._ptr, idx, - name)) + check_is_value(retval) + return _make_value( + _core.LLVMBuildGetResult(self.ptr, retval.ptr, idx, name)) # obsolete synonym for extract_value getresult = extract_value def insert_value(self, retval, rhs, idx, name=""): - if not isinstance(idx, (tuple, list)): - idx = [idx] - return _make_value(self._ptr.CreateInsertValue(retval._ptr, - rhs._ptr, - idx, - name)) + check_is_value(retval) + check_is_value(rhs) + return _make_value( + _core.LLVMBuildInsertValue(self.ptr, retval.ptr, rhs.ptr, idx, + name)) def phi(self, ty, name=""): - return _make_value(self._ptr.CreatePHI(ty._ptr, 2, name)) + check_is_type(ty) + return _make_value(_core.LLVMBuildPhi(self.ptr, ty.ptr, name)) def call(self, fn, args, name=""): - err_template = 'Argument type mismatch: expected %s but got %s' + check_is_callable(fn) + err_template = 'Argument type mismatch: expected %s but got %s' for i, (t, v) in enumerate(zip(fn.type.pointee.args, args)): if t != v.type: raise TypeError(err_template % (t, v.type)) - arg_ptrs = llvm._extract_ptrs(args) - return _make_value(self._ptr.CreateCall(fn._ptr, arg_ptrs, name)) + arg_ptrs = unpack_values(args) + return _make_value( + _core.LLVMBuildCall(self.ptr, fn.ptr, arg_ptrs, name)) def select(self, cond, then_value, else_value, name=""): - return _make_value(self._ptr.CreateSelect(cond._ptr, then_value._ptr, - else_value._ptr, name)) + check_is_value(cond) + check_is_value(then_value) + check_is_value(else_value) + return _make_value( + _core.LLVMBuildSelect(self.ptr, cond.ptr, + then_value.ptr, else_value.ptr, name)) def vaarg(self, list_val, ty, name=""): - return _make_value(self._ptr.CreateVAArg(list_val._ptr, ty._ptr, name)) + check_is_value(list_val) + check_is_type(ty) + return _make_value( + _core.LLVMBuildVAArg(self.ptr, list_val.ptr, ty.ptr, name)) def extract_element(self, vec_val, idx_val, name=""): - return _make_value(self._ptr.CreateExtractElement(vec_val._ptr, - idx_val._ptr, - name)) - + check_is_value(vec_val) + check_is_value(idx_val) + return _make_value( + _core.LLVMBuildExtractElement(self.ptr, vec_val.ptr, + idx_val.ptr, name)) def insert_element(self, vec_val, elt_val, idx_val, name=""): - return _make_value(self._ptr.CreateInsertElement(vec_val._ptr, - elt_val._ptr, - idx_val._ptr, - name)) + check_is_value(vec_val) + check_is_value(elt_val) + check_is_value(idx_val) + return _make_value( + _core.LLVMBuildInsertElement(self.ptr, vec_val.ptr, + elt_val.ptr, idx_val.ptr, name)) def shuffle_vector(self, vecA, vecB, mask, name=""): - return _make_value(self._ptr.CreateShuffleVector(vecA._ptr, - vecB._ptr, - mask._ptr, - name)) + check_is_value(vecA) + check_is_value(vecB) + check_is_value(mask) + return _make_value( + _core.LLVMBuildShuffleVector(self.ptr, + vecA.ptr, vecB.ptr, mask.ptr, name)) + # atomics def atomic_cmpxchg(self, ptr, old, new, ordering, crossthread=True): - return _make_value(self._ptr.CreateAtomicCmpXchg(ptr._ptr, - old._ptr, - new._ptr, - _atomic_orderings[ordering], - _sync_scope(crossthread))) + check_is_value(ptr) + check_is_value(old) + check_is_value(new) + inst = _core.LLVMBuildAtomicCmpXchg(self.ptr, ptr.ptr, old.ptr, new.ptr, + ordering.lower(), + int(bool(crossthread))) + return _make_value(inst) def atomic_rmw(self, op, ptr, val, ordering, crossthread=True): - op_dict = dict((k.lower(), v) - for k, v in vars(api.llvm.AtomicRMWInst.BinOp).items()) - op = op_dict[op] - return _make_value(self._ptr.CreateAtomicRMW(op, ptr._ptr, val._ptr, - _atomic_orderings[ordering], - _sync_scope(crossthread))) + check_is_value(ptr) + check_is_value(val) + inst = _core.LLVMBuildAtomicRMW(self.ptr, op.lower(), ptr.ptr, val.ptr, + ordering.lower(), int(bool(crossthread))) + return _make_value(inst) def atomic_xchg(self, *args, **kwargs): return self.atomic_rmw('xchg', *args, **kwargs) @@ -2496,31 +2283,69 @@ class Builder(llvm.Wrapper): def atomic_umin(self, *args, **kwargs): return self.atomic_rmw('umin', *args, **kwargs) + def atomic_load(self, ptr, ordering, align=1, crossthread=True, volatile=False, name=""): - inst = self.load(ptr, align=align, volatile=volatile, name=name) - inst._ptr.setAtomic(_atomic_orderings[ordering], - _sync_scope(crossthread)) + check_is_value(ptr) + inst = _make_value(_core.LLVMBuildAtomicLoad( + self.ptr, ptr.ptr, int(align), + ordering.lower(), int(bool(crossthread)))) + if volatile: + inst.set_volatile(volatile) + if inst: + inst.name = name return inst def atomic_store(self, value, ptr, ordering, align=1, crossthread=True, volatile=False): - inst = self.store(value, ptr, align=align, volatile=volatile) - inst._ptr.setAtomic(_atomic_orderings[ordering], - _sync_scope(crossthread)) + check_is_value(value) + check_is_value(ptr) + inst = _make_value(_core.LLVMBuildAtomicStore( + self.ptr, ptr.ptr, value.ptr, int(align), + ordering.lower(), int(bool(crossthread)))) + if volatile: + inst.set_volatile(volatile) return inst - def fence(self, ordering, crossthread=True): - return _make_value(self._ptr.CreateFence(_atomic_orderings[ordering], - _sync_scope(crossthread))) + inst = _make_value(_core.LLVMBuildFence(self.ptr, ordering.lower(), + int(bool(crossthread)))) + return inst -def _sync_scope(crossthread): - if crossthread: - scope = api.llvm.SynchronizationScope.CrossThread - else: - scope = api.llvm.SynchronizationScope.SingleThread - return scope +#===----------------------------------------------------------------------=== +# Memory buffer +#===----------------------------------------------------------------------=== + +class MemoryBuffer(object): + + @staticmethod + def from_file(fname): + ret = _core.LLVMCreateMemoryBufferWithContentsOfFile(fname) + if isinstance(ret, str): + return (None, ret) + else: + obj = MemoryBuffer(ret) + return (obj, "") + + @staticmethod + def from_stdin(): + ret = _core.LLVMCreateMemoryBufferWithSTDIN() + if isinstance(ret, str): + return (None, ret) + else: + obj = MemoryBuffer(ret) + return (obj, "") + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeMemoryBuffer(self.ptr) + + +#===----------------------------------------------------------------------=== +# Misc +#===----------------------------------------------------------------------=== def load_library_permanently(filename): """Load a shared library. @@ -2528,27 +2353,45 @@ def load_library_permanently(filename): Load the given shared library (filename argument specifies the full path of the .so file) using LLVM. Symbols from these are available from the execution engine thereafter.""" - with contextlib.closing(BytesIO()) as errmsg: - failed = api.llvm.sys.DynamicLibrary.LoadPermanentLibrary(filename, - errmsg) - if failed: - raise llvm.LLVMException(errmsg.getvalue()) + + ret = _core.LLVMLoadLibraryPermanently(filename) + if isinstance(ret, str): + raise llvm.LLVMException(ret) def inline_function(call): - info = api.llvm.InlineFunctionInfo.new() - return api.llvm.InlineFunction(call._ptr, info) + check_is_value(call) + return bool(_core.LLVMInlineFunction(call.ptr)) def parse_environment_options(progname, envname): - api.llvm.cl.ParseEnvironmentOptions(progname, envname) + _core.LLVMParseEnvOpts(progname, envname) -if api.llvm.InitializeNativeTarget(): +#===----------------------------------------------------------------------=== +# Initialization +#===----------------------------------------------------------------------=== +if _core.LLVMInitializeNativeTarget(): raise llvm.LLVMException("No native target!?") -if api.llvm.InitializeNativeTargetAsmPrinter(): +if _core.LLVMInitializeNativeTargetAsmPrinter(): # should this be an optional feature? # should user trigger the initialization? raise llvm.LLVMException("No native asm printer!?") -if api.llvm.InitializeNativeTargetAsmParser(): - # required by MCJIT? - # should this be an optional feature? - # should user trigger the initialization? - raise llvm.LLVMException("No native asm parser!?") + + +HAS_PTX = HAS_NVPTX = False +if True: # use PTX? + try: + _core.LLVMInitializePTXTarget() + _core.LLVMInitializePTXTargetInfo() + _core.LLVMInitializePTXTargetMC() + _core.LLVMInitializePTXAsmPrinter() + HAS_PTX = True + except AttributeError: + try: + _core.LLVMInitializeNVPTXTarget() + _core.LLVMInitializeNVPTXTargetInfo() + _core.LLVMInitializeNVPTXTargetMC() + _core.LLVMInitializeNVPTXAsmPrinter() + HAS_NVPTX = True + except AttributeError: + pass + + diff --git a/llvm/debuginfo.py b/llvm/debuginfo.py new file mode 100644 index 0000000..0f18b33 --- /dev/null +++ b/llvm/debuginfo.py @@ -0,0 +1,398 @@ +""" +Support for debug info metadata. +""" + +import functools + +import llvm.core +from llvm import _dwarf + +#---------------------------------------------------------------------------- +# Some types and type checking functions +#---------------------------------------------------------------------------- + +int32_t = llvm.core.Type.int(32) +bool_t = llvm.core.Type.int(1) +p_int32_t = llvm.core.Type.pointer(int32_t) +null = llvm.core.Constant.null(p_int32_t) + +i32 = functools.partial(llvm.core.Constant.int, int32_t) +i1 = functools.partial(llvm.core.Constant.int, bool_t) + +def is_md(value): + return isinstance(value, (llvm.core.MetaData, llvm.core.NamedMetaData, + llvm.core.Value)) + +def is_mdstr(value): + return isinstance(value, (llvm.core.MetaDataString, llvm.core.Value)) + +#---------------------------------------------------------------------------- +# Callbacks for debug type descriptors +#---------------------------------------------------------------------------- + +def get_i32(llvm_module, value): + return i32(value) + +def get_i1(llvm_module, value): + return i1(value) + +def get_md(llvm_module, value): + if is_md(value): + return value + return value.get_metadata(llvm_module) + +def get_mdstr(llvm_module, value): + if is_mdstr(value): + return value + return llvm.core.MetaDataString.get(llvm_module, value) + +def get_mdlist(llvm_module, value): + if isinstance(value, list): + value = MDList([value]) + return get_md(llvm_module, value) + +def get_lfunc(llvm_module, lfunc): + assert lfunc.module is llvm_module + return lfunc + +#---------------------------------------------------------------------------- +# Debug descriptors that generate LLVM Metadata +#---------------------------------------------------------------------------- + +class desc(object): + """ + Descriptor of a debug field. + + field_name: + name of the field (keyword argument name) + build_metadata: + metadata callback :: (llvm_module, Python value) -> LLVM Value + default: + default value for this field + """ + + def __init__(self, field_name, build_metadata, default=None): + self.field_name = field_name + self.build_metadata = build_metadata + self.default = default + + +def build_operand_list(type_descriptors, idx2name, operands, kwargs): + """ + Build the list of operands from the positional and keyword arguments + to a DebugInfoDescriptor. + + E.g. FileDescriptor("foo.c", "/path/to/file", compile_unit=compile_unit) + + idx2name: {0 : 'source_filename', + 1 : 'source_filedir', + 2 : 'compile_unit' } + operands: ["foo.c", "/path/to/file"] + kwargs: { 'compile_unit' : compile_unit } + """ + for i in range(len(operands), len(type_descriptors)): + name = idx2name[i] + if name in kwargs: + op = kwargs[name] + else: + typedesc = type_descriptors[i] + assert typedesc.default is not None, ( + "No value found for field %s" % typedesc.field_name) + op = typedesc.default + + operands.append(op) + + return operands + + +class DebugInfoDescriptor(object): + """ + Base class to describe a debug info descriptor. + + See http://llvm.org/docs/SourceLevelDebugging.html + """ + + type_descriptors = None # [desc(...)] + idx2name = None # { "field_idx" : field_name } + name2idx = None # { "field_name" : field_idx } + + # Whether the debug descriptor is allowed to be incomplete + # The policy seems unclear ? + accept_optional_data = False + + def __init__(self, *args, **kwargs): + self.class_init() + self.metadata_cache = {} + + operands = list(args) + if kwargs or not self.accept_optional_data: + operands = build_operand_list(self.type_descriptors, + self.idx2name, operands, kwargs) + + self.operands = operands + self.operands_dict = dict( + (typedesc.field_name, operand) + for typedesc, operand in zip(self.type_descriptors, operands)) + + @classmethod + def class_init(cls): + if cls.idx2name is None and cls.type_descriptors is not None: + cls.name2idx = {} + cls.idx2name = {} + + for i, typedesc in enumerate(cls.type_descriptors): + cls.name2idx[typedesc.field_name] = i + cls.idx2name[i] = typedesc.field_name + + def add_metadata(self, metadata_name, metadata): + """ + Replace a metadata value in the operand list. + """ + idx = self.name2idx[metadata_name] + self.operands[idx] = metadata + + #------------------------------------------------------------------------ + # Define metadata in a module + #------------------------------------------------------------------------ + + def get_metadata(self, llvm_module): + """ + Get an existing metadata node for the given LLVM module, or build + one from this instance. + """ + if llvm_module in self.metadata_cache: + node = self.metadata_cache[llvm_module] + else: + node = self.build_metadata(llvm_module) + self.metadata_cache[llvm_module] = node + + return node + + def build_metadata(self, llvm_module): + "Build a metadata node for the given LLVM module" + mdops = [] + for type_desc, operand in zip(self.type_descriptors, self.operands): + try: + field_value = type_desc.build_metadata(llvm_module, operand) + except Exception, e: + if type_desc.build_metadata is get_md: + raise + + raise ValueError("Invalid value for field %r: %s" % ( + type_desc.field_name, e)) + + mdops.append(field_value) + + return llvm.core.MetaData.get(llvm_module, mdops) + + def define(self, llvm_module): + """ + Define this debug descriptor as named debug metadata for the module. + """ + md = self.get_metadata(llvm_module) + llvm.core.MetaData.add_named_operand(llvm_module, "dbg", md) + +#---------------------------------------------------------------------------- +# Convenience descriptors +#---------------------------------------------------------------------------- + +class MDList(DebugInfoDescriptor): + """ + [MetaData] + """ + + def __init__(self, operands): + self.type_descriptors = [desc("op", get_md)] * len(operands) + super(MDList, self).__init__(*operands) + +empty = MDList([]) + +#---------------------------------------------------------------------------- +# Dwarf Debug descriptors +#---------------------------------------------------------------------------- + +class CompileUnitDescriptor(DebugInfoDescriptor): + """ + !0 = metadata !{ + i32, ;; Tag = 17 + LLVMDebugVersion (DW_TAG_compile_unit) + i32, ;; Unused field. + i32, ;; DWARF language identifier (ex. DW_LANG_C89) + metadata, ;; Source file name + metadata, ;; Source file directory (includes trailing slash) + metadata ;; Producer (ex. "4.0.1 LLVM (LLVM research group)") + i1, ;; True if this is a main compile unit. + i1, ;; True if this is optimized. + metadata, ;; Flags + i32 ;; Runtime version + metadata ;; List of enums types + metadata ;; List of retained types + metadata ;; List of subprograms + metadata ;; List of global variables + } + """ + + accept_optional_data = True + + type_descriptors = [ + desc("tag", get_i32), + desc("unused", get_i32), + + # Positional argument list starts here: + desc("langid", get_i32), + desc("source_filename", get_mdstr), + desc("source_filedir", get_mdstr), + desc("producer", get_mdstr), + desc("is_main", get_i1, default=False), + desc("is_optimized", get_i1, default=False), + desc("compile_flags", get_mdstr, default=""), + desc("runtime_version", get_i32, default=0), + desc("enum_types", get_mdlist, default=empty), + desc("retained_types", get_mdlist, default=empty), + desc("subprograms", get_mdlist, default=empty), + desc("global_vars", get_mdlist, default=empty), + ] + + def __init__(self, *args, **kwargs): + super(CompileUnitDescriptor, self).__init__( + _dwarf.DW_TAG_compile_unit + _dwarf.LLVMDebugVersion, # tag + 0, # unused + *args, **kwargs) + + def define(self, llvm_module): + """ + Define this debug descriptor as named debug metadata for the module. + """ + md = self.get_metadata(llvm_module) + llvm.core.MetaData.add_named_operand(llvm_module, "llvm.dbg.cu", md) + + +class FileDescriptor(DebugInfoDescriptor): + """ + !0 = metadata !{ + i32, ;; Tag = 41 + LLVMDebugVersion (DW_TAG_file_type) + metadata, ;; Source file name + metadata, ;; Source file directory (includes trailing slash) + metadata ;; Unused + } + """ + + type_descriptors = [ + desc("tag", get_i32), + + # Positional argument list starts here: + desc("source_filename", get_mdstr), + desc("source_filedir", get_mdstr), + desc("compile_unit", get_md, default=null), + ] + + def __init__(self, *args, **kwargs): + super(FileDescriptor, self).__init__( + _dwarf.DW_TAG_file_type + _dwarf.LLVMDebugVersion, # Tag + *args, **kwargs) + + @classmethod + def from_compileunit(cls, compile_unit_descriptor): + return cls(compile_unit_descriptor.operands_dict["source_filename"], + compile_unit_descriptor.operands_dict["source_filedir"], + compile_unit_descriptor) + + +class SubprogramDescriptor(DebugInfoDescriptor): + """ + !2 = metadata !{ + i32, ;; Tag = 46 + LLVMDebugVersion (DW_TAG_subprogram) + i32, ;; Unused field. + metadata, ;; Reference to context descriptor + metadata, ;; Name + metadata, ;; Display name (fully qualified C++ name) + metadata, ;; MIPS linkage name (for C++) + metadata, ;; Reference to file where defined + i32, ;; Line number where defined + metadata, ;; Reference to type descriptor + i1, ;; True if the global is local to compile unit (static) + i1, ;; True if the global is defined in the compile unit (not extern) + i32, ;; Line number where the scope of the subprogram begins + i32, ;; Virtuality, e.g. dwarf::DW_VIRTUALITY__virtual + i32, ;; Index into a virtual function + metadata, ;; indicates which base type contains the vtable pointer for the + ;; derived class + i32, ;; Flags - Artifical, Private, Protected, Explicit, Prototyped. + i1, ;; isOptimized + Function * , ;; Pointer to LLVM function + metadata, ;; Lists function template parameters + metadata, ;; Function declaration descriptor + metadata ;; List of function variables + } + """ + + accept_optional_data = True + + type_descriptors = [ + desc("tag", get_i32), + desc("unused", get_i32), + + # Positional argument list starts here: + desc("file_desc", get_md), + desc("name", get_mdstr), + desc("display_name", get_mdstr), + desc("mips_linkage_name", get_mdstr), + desc("source_file_ref", get_md), + desc("line_number", get_i32), + desc("signature", get_md), + desc("is_local", get_i1, default=False), + desc("is_definition", get_i1, default=True), + desc("virtual_attribute", get_i32, default=0), + desc("virtual_index", get_i32, default=0), + desc("virttab", get_i32, default=0), + desc("flags", get_i32, default=0), + desc("is_optimized", get_i1, default=False), + desc("llvm_func", get_lfunc), + # Template params + # Func decl + # Func vars + ] + + def __init__(self, *args, **kwargs): + super(SubprogramDescriptor, self).__init__( + _dwarf.DW_TAG_subprogram + _dwarf.LLVMDebugVersion, # Tag + 0, # Unused + *args, **kwargs) + +class BlockDescriptor(DebugInfoDescriptor): + """ + !3 = metadata !{ + i32, ;; Tag = 11 + LLVMDebugVersion (DW_TAG_lexical_block) + metadata,;; Reference to context descriptor + i32, ;; Line number + i32 ;; Column number + } + """ + + type_descriptors = [ + desc("tag", get_i32), + + # Positional argument list starts here: + desc("context_descr", get_md), # FileDescr | BlockDescr | + # SubprogDescr | ComputeUnit + desc("line_number", get_i32), + desc("col_number", get_i32), + ] + + def __init__(self, *args, **kwargs): + super(BlockDescriptor, self).__init__( + _dwarf.DW_TAG_lexical_block + _dwarf.LLVMDebugVersion, + *args, **kwargs) + +class PositionInfoDescriptor(DebugInfoDescriptor): + """ + line number, column number, scope, and original scope + """ + + type_descriptors = [ + desc("line_number", get_i32), + desc("col_number", get_i32), + desc("context_descr", get_md), # Scope of instruction + # (FileDescr etc) + desc("original_context_descr", get_md, # The original scope if inlined + default=null), + ] diff --git a/llvm/deprecated.py b/llvm/deprecated.py deleted file mode 100644 index 6db5fe7..0000000 --- a/llvm/deprecated.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -Shameless borrowed from Smart_deprecation_warnings -https://wiki.python.org/moin/PythonDecoratorLibrary -""" - -import warnings -import functools - - -def deprecated(func): - """This is a decorator which can be used to mark functions - as deprecated. It will result in a warning being emitted - when the function is used.""" - - @functools.wraps(func) - def new_func(*args, **kwargs): - warnings.warn_explicit( - "Call to deprecated function %s." % (func.__name__,), - category=DeprecationWarning, - filename=func.func_code.co_filename, - lineno=func.func_code.co_firstlineno + 1 - ) - return func(*args, **kwargs) - - return new_func diff --git a/llvm/ee.py b/llvm/ee.py index f615b61..e5d6ef1 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -28,54 +28,85 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -"Execution Engine and related classes." +"""Execution Engine and related classes. -import sys +""" -import llvm -from llvm import core -from llvm.passes import TargetData, TargetTransformInfo -from llvmpy import api, extra +import llvm # top-level, for common stuff +import llvm.core as core # module, function etc. +import llvm._core as _core # C wrappers +import llvm._util as _util # utility functions +import logging +import os + +logger = logging.getLogger(__name__) + + +# re-export TargetData for backward compatibility. +from llvm.passes import TargetData + +def _detect_avx_support(): + '''FIXME: This is a workaround for AVX support. + ''' + disable_avx_detect = int(os.environ.get('LLVMPY_DISABLE_AVX_DETECT', 0)) + if disable_avx_detect: + return False # enable AVX if user disable AVX detect + force_disable_avx = int(os.environ.get('LLVMPY_FORCE_DISABLE_AVX', 0)) + if force_disable_avx: + return True # force disable AVX + # auto-detect avx + try: + for line in open('/proc/cpuinfo'): + if line.lstrip().startswith('flags') and 'avx' in line.split(): + # enable AVX if flags contain AVX + return False + except IOError: + pass # disable AVX if no /proc/cpuinfo is found + return True # disable AVX if flags does not have AVX + +FORCE_DISABLE_AVX = _detect_avx_support() #===----------------------------------------------------------------------=== -# import items which were moved to target module +# Enumerations #===----------------------------------------------------------------------=== -from llvm.target import (initialize_all, initialize_target, - print_registered_targets, get_host_cpu_name, get_default_triple, - TargetMachine, - BO_BIG_ENDIAN, BO_LITTLE_ENDIAN, - CM_DEFAULT, CM_JITDEFAULT, CM_SMALL, CM_KERNEL, CM_MEDIUM, CM_LARGE, - RELOC_DEFAULT, RELOC_STATIC, RELOC_PIC, RELOC_DYNAMIC_NO_PIC) +BO_BIG_ENDIAN = 0 +BO_LITTLE_ENDIAN = 1 + +# CodeModel +CM_DEFAULT = 0 +CM_JITDEFAULT = 1 +CM_SMALL = 2 +CM_KERNEL = 3 +CM_MEDIUM = 4 +CM_LARGE = 5 #===----------------------------------------------------------------------=== # Generic value #===----------------------------------------------------------------------=== -class GenericValue(llvm.Wrapper): +class GenericValue(object): @staticmethod def int(ty, intval): - ptr = api.llvm.GenericValue.CreateInt(ty._ptr, int(intval), False) + core.check_is_type(ty) + ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 0) return GenericValue(ptr) @staticmethod def int_signed(ty, intval): - ptr = api.llvm.GenericValue.CreateInt(ty._ptr, int(intval), True) + core.check_is_type(ty) + ptr = _core.LLVMCreateGenericValueOfInt(ty.ptr, intval, 1) return GenericValue(ptr) @staticmethod def real(ty, floatval): - if str(ty) == 'float': - ptr = api.llvm.GenericValue.CreateFloat(float(floatval)) - elif str(ty) == 'double': - ptr = api.llvm.GenericValue.CreateDouble(float(floatval)) - else: - raise Exception('Unreachable') + core.check_is_type(ty) # only float or double + ptr = _core.LLVMCreateGenericValueOfFloat(ty.ptr, floatval) return GenericValue(ptr) @staticmethod - def pointer(addr): + def pointer(*args): ''' One argument version takes (addr). Two argument version takes (ty, addr). [Deprecated] @@ -83,46 +114,79 @@ class GenericValue(llvm.Wrapper): `ty` is unused. `addr` is an integer representing an address. + TODO: remove two argument version. ''' - ptr = api.llvm.GenericValue.CreatePointer(int(addr)) + if len(args)==2: + logger.warning("Deprecated: Two argument version of " + "GenericValue.pointer() is deprecated.") + addr = args[1] + elif len(args)!=1: + raise TypeError("pointer() takes 1 or 2 arguments.") + else: + addr = args[0] + ptr = _core.LLVMCreateGenericValueOfPointer(addr) return GenericValue(ptr) + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeGenericValue(self.ptr) + def as_int(self): - return self._ptr.toUnsignedInt() + return _core.LLVMGenericValueToInt(self.ptr, 0) def as_int_signed(self): - return self._ptr.toSignedInt() + return _core.LLVMGenericValueToInt(self.ptr, 1) def as_real(self, ty): - return self._ptr.toFloat(ty._ptr) + core.check_is_type(ty) # only float or double + return _core.LLVMGenericValueToFloat(ty.ptr, self.ptr) def as_pointer(self): - return self._ptr.toPointer() + return _core.LLVMGenericValueToPointer(self.ptr) + + +# helper functions for generic value objects +def check_is_generic_value(obj): _util.check_gen(obj, GenericValue) +def _unpack_generic_values(objlist): + return _util.unpack_gen(objlist, check_is_generic_value) + #===----------------------------------------------------------------------=== # Engine builder #===----------------------------------------------------------------------=== -class EngineBuilder(llvm.Wrapper): +class EngineBuilder(object): @staticmethod def new(module): - ptr = api.llvm.EngineBuilder.new(module._ptr) - return EngineBuilder(ptr) + core.check_is_module(module) + _util.check_is_unowned(module) + obj = _core.LLVMCreateEngineBuilder(module.ptr) + return EngineBuilder(obj, module) + + def __init__(self, ptr, module): + self.ptr = ptr + self._module = module + self.__has_mattrs = False + + def __del__(self): + _core.LLVMDisposeEngineBuilder(self.ptr) def force_jit(self): - self._ptr.setEngineKind(api.llvm.EngineKind.Kind.JIT) + _core.LLVMEngineBuilderForceJIT(self.ptr) return self def force_interpreter(self): - self._ptr.setEngineKind(api.llvm.EngineKind.Kind.Interpreter) + _core.LLVMEngineBuilderForceInterpreter(self.ptr) return self def opt(self, level): ''' level valid [0, 1, 2, 3] -- [None, Less, Default, Aggressive] ''' - assert 0 <= level <= 3 - self._ptr.setOptLevel(level) + assert level in range(4) + _core.LLVMEngineBuilderSetOptLevel(self.ptr, level) return self def mattrs(self, string): @@ -130,53 +194,45 @@ class EngineBuilder(llvm.Wrapper): e.g: +sse,-3dnow ''' - self._ptr.setMAttrs(string.split(',')) + self.__has_mattrs = True + if FORCE_DISABLE_AVX: + if 'avx' not in map(lambda x: x.strip(), string.split(',')): + # User did not override + string += ',-avx' + _core.LLVMEngineBuilderSetMAttrs(self.ptr, string.replace(',', ' ')) return self def create(self, tm=None): ''' tm --- Optional. Provide a TargetMachine. Ownership is transfered - to the returned execution engine. + to the returned execution engine. ''' - if tm is not None: - engine = self._ptr.create(tm._ptr) - elif (sys.platform.startswith('win32') and - getattr(self, '_use_mcjit', False)): - # force ELF generation on MCJIT on win32 - triple = get_default_triple() - tm = TargetMachine.new('%s-elf' % triple) - engine = self._ptr.create(tm._ptr) - else: - engine = self._ptr.create() - ee = ExecutionEngine(engine) - ee.finalize_object() # no effect for legacy JIT - return ee + if not self.__has_mattrs and FORCE_DISABLE_AVX: + self.mattrs('-avx') - def select_target(self, *args): + if tm: + _util.check_is_unowned(tm) + ret = _core.LLVMEngineBuilderCreateTM(self.ptr, tm.ptr) + else: + ret = _core.LLVMEngineBuilderCreate(self.ptr) + if isinstance(ret, str): + raise llvm.LLVMException(ret) + engine = ExecutionEngine(ret, self._module) + if tm: + tm._own(owner=llvm.DummyOwner) + return engine + + def select_target(self): '''get the corresponding target machine - - Accept no arguments or (triple, march, mcpu, mattrs) ''' - if args: - triple, march, mcpu, mattrs = args - ptr = self._ptr.selectTarget(triple, march, mcpu, - mattrs.split(',')) - else: - ptr = self._ptr.selectTarget() + ptr = _core.LLVMTargetMachineFromEngineBuilder(self.ptr) return TargetMachine(ptr) - def mcjit(self, enable): - '''Enable/disable MCJIT - ''' - self._ptr.setUseMCJIT(enable) - self._use_mcjit = True - return self - #===----------------------------------------------------------------------=== # Execution engine #===----------------------------------------------------------------------=== -class ExecutionEngine(llvm.Wrapper): +class ExecutionEngine(object): @staticmethod def new(module, force_interpreter=False): @@ -185,80 +241,152 @@ class ExecutionEngine(llvm.Wrapper): eb.force_interpreter() return eb.create() + def __init__(self, ptr, module): + self.ptr = ptr + module._own(self) + + def __del__(self): + _core.LLVMDisposeExecutionEngine(self.ptr) + def disable_lazy_compilation(self, disabled=True): - self._ptr.DisableLazyCompilation(disabled) + _core.LLVMExecutionEngineDisableLazyCompilation(self.ptr, + int(bool(disabled))) def run_function(self, fn, args): - ptr = self._ptr.runFunction(fn._ptr, list(map(lambda x: x._ptr, args))) - return GenericValue(ptr) - - def get_pointer_to_named_function(self, name, abort=True): - return self._ptr.getPointerToNamedFunction(name, abort) + core.check_is_function(fn) + ptrs = _unpack_generic_values(args) + gvptr = _core.LLVMRunFunction2(self.ptr, fn.ptr, ptrs) + return GenericValue(gvptr) def get_pointer_to_function(self, fn): - return self._ptr.getPointerToFunction(fn._ptr) + core.check_is_function(fn) + return _core.LLVMGetPointerToFunction(self.ptr,fn.ptr) def get_pointer_to_global(self, val): - return self._ptr.getPointerToGlobal(val._ptr) + core.check_is_global_value(val) + return _core.LLVMGetPointerToGlobal(self.ptr, val.ptr) def add_global_mapping(self, gvar, addr): assert addr >= 0, "Address cannot not be negative" - self._ptr.addGlobalMapping(gvar._ptr, addr) + _core.LLVMAddGlobalMapping(self.ptr, gvar.ptr, addr) def run_static_ctors(self): - self._ptr.runStaticConstructorsDestructors(False) + _core.LLVMRunStaticConstructors(self.ptr) def run_static_dtors(self): - self._ptr.runStaticConstructorsDestructors(True) + _core.LLVMRunStaticDestructors(self.ptr) def free_machine_code_for(self, fn): - self._ptr.freeMachineCodeForFunction(fn._ptr) + core.check_is_function(fn) + _core.LLVMFreeMachineCodeForFunction(self.ptr, fn.ptr) def add_module(self, module): - self._ptr.addModule(module._ptr) + core.check_is_module(module) + _core.LLVMAddModule(self.ptr, module.ptr) + module._own(self) def remove_module(self, module): - return self._ptr.removeModule(module._ptr) - - def finalize_object(self): - return self._ptr.finalizeObject() + core.check_is_module(module) + if module.owner != self: + raise llvm.LLVMException("module is not owned by self") + ret = _core.LLVMRemoveModule2(self.ptr, module.ptr) + if isinstance(ret, str): + raise llvm.LLVMException(ret) + return core.Module(ret) @property def target_data(self): - ptr = self._ptr.getDataLayout() - return TargetData(ptr) + td = TargetData(_core.LLVMGetExecutionEngineTargetData(self.ptr)) + td._own(self) + return td #===----------------------------------------------------------------------=== -# Dynamic Library +# Target machine #===----------------------------------------------------------------------=== -def dylib_add_symbol(name, ptr): - api.llvm.sys.DynamicLibrary.AddSymbol(name, ptr) +def print_registered_targets(): + ''' + Note: print directly to stdout + ''' + _core.LLVMPrintRegisteredTargetsForVersion() -def dylib_address_of_symbol(name): - return api.llvm.sys.DynamicLibrary.SearchForAddressOfSymbol(name) +def get_host_cpu_name(): + '''return the string name of the host CPU + ''' + return _core.LLVMGetHostCPUName() -def dylib_import_library(filename): - """Permanently import a dynamic library. - - Returns a DynamicLibrary object - - Raises RuntimeError - """ - return DynamicLibrary(filename) +def get_default_triple(): + '''return the target triple of the host in str-rep + ''' + return _core.LLVMDefaultTargetTriple() -class DynamicLibrary(object): - def __init__(self, filename): - """ - Raises RuntimeError - """ - self._ptr = api.llvm.sys.DynamicLibrary.getPermanentLibrary( - filename) +class TargetMachine(llvm.Ownable): + + @staticmethod + def new(triple='', cpu='', features='', opt=2, cm=CM_DEFAULT): + if not triple and not cpu: + triple = get_default_triple() + cpu = get_host_cpu_name() + ptr = _core.LLVMCreateTargetMachine(triple, cpu, features, opt, cm) + return TargetMachine(ptr) + + @staticmethod + def lookup(arch, cpu='', features='', opt=2, cm=CM_DEFAULT): + '''create a targetmachine given an architecture name + + For a list of architectures, + use: `llc -help` + + For a list of available CPUs, + use: `llvm-as < /dev/null | llc -march=xyz -mcpu=help` + + For a list of available attributes (features), + use: `llvm-as < /dev/null | llc -march=xyz -mattr=help` + ''' + ptr = _core.LLVMTargetMachineLookup(arch, cpu, features, opt, cm) + return TargetMachine(ptr) + + def __init__(self, ptr): + llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeTargetMachine) + + def emit_assembly(self, module): + '''returns byte string of the module as assembly code of the target machine + ''' + return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, True) + + def emit_object(self, module): + '''returns byte string of the module as native code of the target machine + ''' + return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, False) + + @property + def target_data(self): + '''get target data of this machine + ''' + ptr = _core.LLVMTargetMachineGetTargetData(self.ptr) + td = TargetData(ptr) + td._own(self) + return td + + @property + def target_name(self): + return _core.LLVMTargetMachineGetTargetName(self.ptr) + + @property + def target_short_description(self): + return _core.LLVMTargetMachineGetTargetShortDescription(self.ptr) + + @property + def triple(self): + return _core.LLVMTargetMachineGetTriple(self.ptr) + + @property + def cpu(self): + return _core.LLVMTargetMachineGetCPU(self.ptr) + + @property + def feature_string(self): + return _core.LLVMTargetMachineGetFS(self.ptr) - def get_address_of_symbol(self, symbol): - """ - Get the address of `symbol` (str) as integer - """ - return self._ptr.getAddressOfSymbol(symbol) diff --git a/llvm/extra.cpp b/llvm/extra.cpp new file mode 100644 index 0000000..7b6c064 --- /dev/null +++ b/llvm/extra.cpp @@ -0,0 +1,1361 @@ +/* + * Copyright (c) 2008-10, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * These are some "extra" functions not available in the standard LLVM-C + * bindings, but are required / good-to-have inorder to implement the + * Python bindings. + */ + +// standard includes +#include +#include +#include +#include +#include + +// LLVM includes +#include "llvm/LLVMContext.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Casting.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" +//#include "llvm/TypeSymbolTable.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/CallSite.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/Host.h" + +#include "llvm/IntrinsicInst.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Assembly/Parser.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/PassManager.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/DomPrinter.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" +#include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Linker.h" +#include "llvm/Support/SourceMgr.h" +#include +#include +#include + + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 + #include "llvm/DataLayout.h" +#else + #include "llvm/Target/TargetData.h" +#endif + +// LLVM-C includes +#include "llvm-c/Core.h" +#include "llvm-c/ExecutionEngine.h" + +// our includes +#include "extra.h" +#include "llvm_c_extra.h" + +namespace llvm{ +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(NamedMDNode, LLVMNamedMDRef) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Pass, LLVMPassRef) + +template +inline T **unwrap(LLVMTypeRef *Tys, unsigned Length) { + (void)Length; + return reinterpret_cast(Tys); +} + +} + +/* + * For use in LLVMDumpPasses to dump passes. + */ +class PassRegistryPrinter : public llvm::PassRegistrationListener{ +public: + std::ostringstream stringstream; + + inline virtual void passEnumerate(const llvm::PassInfo * pass_info){ + stringstream << pass_info->getPassArgument() + << "\t" + << pass_info->getPassName() + << "\n"; + } +}; + + +/* Helper method for LLVMDumpXXXToString() methods. */ +template +char *do_print(W obj) +{ + std::string s; + llvm::raw_string_ostream buf(s); + UW *p = llvm::unwrap(obj); + assert(p); + p->print(buf); + return strdup(buf.str().c_str()); +} + +namespace { +using namespace llvm; +const CodeGenOpt::Level OptLevelMap[] = { + CodeGenOpt::None, + CodeGenOpt::Less, + CodeGenOpt::Default, + CodeGenOpt::Aggressive, +}; + +const CodeModel::Model CodeModelMap[] = { + CodeModel::Default, + CodeModel::JITDefault, + CodeModel::Small, + CodeModel::Kernel, + CodeModel::Medium, + CodeModel::Large, +}; + + +} // end anony namespace + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 +LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref){ + using namespace llvm; + TargetMachine * tm = unwrap(tmref); + Pass * tti = new TargetTransformInfo(tm->getScalarTargetTransformInfo(), + tm->getVectorTargetTransformInfo()); + return wrap(tti); +} +#endif + +LLVMPassRef LLVMCreateTargetLibraryInfo(const char * triple){ + using namespace llvm; + Pass * tli = new TargetLibraryInfo(Triple(triple)); + return wrap(tli); +} + +const char * LLVMDefaultTargetTriple(){ + return strdup(llvm::sys::getDefaultTargetTriple().c_str()); +} + +LLVMPassRef LLVMCreatePassByName(const char *name){ + using namespace llvm; + const PassInfo * pi = Pass::lookupPassInfo(StringRef(name)); + if (pi) { + return wrap(pi->createPass()); + } else { // cannot find pass + return NULL; + } +} + +void LLVMDisposePass(LLVMPassRef passref){ + using namespace llvm; + delete unwrap(passref); +} + +const char * LLVMGetPassName(LLVMPassRef passref){ + using namespace llvm; + return unwrap(passref)->getPassName(); +} + +void LLVMPassDump(LLVMPassRef passref){ + using namespace llvm; + return unwrap(passref)->dump(); +} + +void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref){ + using namespace llvm; + unwrap(pmref)->add(unwrap(passref)); +} + +LLVMValueRef LLVMGetFunctionFromInlineAsm(LLVMTypeRef funcType, + const char inlineAsm[], + const char constrains[], + bool hasSideEffect, + bool isAlignStack, + int asmDialect) +{ + using namespace llvm; + FunctionType *fnty = unwrap(funcType); + // asmDialect does not exist for LLVM 3.1 + InlineAsm *inlineasmobj = InlineAsm::get(fnty, inlineAsm, constrains, + hasSideEffect, isAlignStack); + return wrap(inlineasmobj); +} + +LLVMModuleRef LLVMCloneModule(LLVMModuleRef mod) +{ + using namespace llvm; + return wrap(CloneModule(unwrap(mod))); +} + +const char * LLVMDumpNamedMDToString(LLVMNamedMDRef nmd) +{ + using namespace llvm; + std::string s; + llvm::raw_string_ostream buf(s); + unwrap(nmd)->print(buf, NULL); + return strdup(buf.str().c_str()); +} + +const char * LLVMNamedMetaDataGetName(LLVMNamedMDRef nmd) +{ + using namespace llvm; + return unwrap(nmd)->getName().data(); +} + +void LLVMNamedMetaDataAddOperand(LLVMNamedMDRef nmd, LLVMValueRef md) +{ + using namespace llvm; + unwrap(nmd)->addOperand(unwrap(md)); +} + +void LLVMEraseNamedMetaData(LLVMNamedMDRef nmd) +{ + using namespace llvm; + unwrap(nmd)->eraseFromParent(); +} + +LLVMNamedMDRef LLVMModuleGetOrInsertNamedMetaData(LLVMModuleRef mod, const char *name) +{ + using namespace llvm; + return wrap(unwrap(mod)->getOrInsertNamedMetadata(name)); +} + +LLVMNamedMDRef LLVMModuleGetNamedMetaData(LLVMModuleRef mod, const char *name) +{ + using namespace llvm; + return wrap(unwrap(mod)->getNamedMetadata(name)); +} + +void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind, + LLVMValueRef metaref) +{ + using namespace llvm; + unwrap(instref)->setMetadata(mdkind, unwrap(metaref)); +} + +LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs, + unsigned valct) +{ + using namespace llvm; + LLVMContext & context = unwrap(modref)->getContext(); + MDNode * const node = MDNode::get( + context, + makeArrayRef(unwrap(valrefs, valct), valct)); + return wrap(node); +} + +LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index) +{ + return wrap(llvm::unwrap(mdref)->getOperand(index)); +} + +unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref) +{ + return llvm::unwrap(mdref)->getNumOperands(); +} + +LLVMValueRef LLVMMetaDataStringGet(LLVMModuleRef modref, const char *s) +{ + LLVMContext & context = unwrap(modref)->getContext(); + MDString * const mdstring = MDString::get(context, s); + return wrap(mdstring); +} + +const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst) +{ + return llvm::unwrap(inst)->getOpcodeName(); +} + +unsigned LLVMGetConstExprOpcode(LLVMValueRef inst) +{ + return llvm::unwrap(inst)->getOpcode(); +} + +void LLVMLdSetAlignment(LLVMValueRef inst, unsigned align) +{ + return llvm::unwrap(inst)->setAlignment(align); +} + +void LLVMStSetAlignment(LLVMValueRef inst, unsigned align) +{ + return llvm::unwrap(inst)->setAlignment(align); +} + +const char * LLVMGetHostCPUName() +{ + return strdup(llvm::sys::getHostCPUName().c_str()); +} + +const char * LLVMGetHostCPUFeatures() +{ + // placeholder + // TODO not implemented even in LLVM3.2svn + // llvm::sys::getHostCPUFeatures + return NULL; +} + +int LLVMInitializeNativeTargetAsmPrinter() +{ + return llvm::InitializeNativeTargetAsmPrinter(); +} + + +LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, + const char *features, int opt, + int codemodel, + std::string &error) +{ + using namespace llvm; + Triple TheTriple; + + // begin borrow from LLVM 3.2 code + // because we don't have 3 argument version of lookup() in 3.1 + const Target * TheTarget = NULL; + + const std::string ArchName(arch); + for (TargetRegistry::iterator it = TargetRegistry::begin(), + ie = TargetRegistry::end(); it != ie; ++it) { + if (ArchName == it->getName()) { + TheTarget = &*it; + break; + } + } + + if (!TheTarget) { + error = "Unknown arch"; + return NULL; + } + + Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName); + + if (Type != Triple::UnknownArch){ + TheTriple.setArch(Type); + } + // end borrow from LLVM 3.2 code + + if (!TheTarget->hasTargetMachine()){ + error = "No target machine for the arch"; + return NULL; + } + + TargetOptions no_target_options; + TargetMachine * tm = TheTarget->createTargetMachine(TheTriple.str(), cpu, + features, + no_target_options, + Reloc::Default, + CodeModelMap[codemodel], + OptLevelMap[opt]); + + if (!tm){ + error = "Cannot create target machine"; + return NULL; + } + return wrap(tm); +} + +LLVMTargetMachineRef LLVMCreateTargetMachine(const char *triple, + const char *cpu, + const char *features, + int opt, + int codemodel, + std::string &error) +{ + using namespace llvm; + + std::string TheTriple = triple; + const Target * TheTarget = TargetRegistry::lookupTarget(TheTriple, error); + if (!TheTarget) return NULL; + + TargetOptions no_target_options; + TargetMachine * tm = TheTarget->createTargetMachine(TheTriple, cpu, features, + no_target_options, + Reloc::Default, + CodeModelMap[codemodel], + OptLevelMap[opt]); + if (!tm) { + error = "Cannot create target machine"; + return NULL; + } + return wrap(tm); +} + +LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb) +{ + using namespace llvm; + TargetMachine * tm = unwrap(eb)->selectTarget(); + return wrap(tm); +} + +void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm){ + delete llvm::unwrap(tm); +} + + +unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, + LLVMModuleRef modref, + int assembly, size_t * lenp, + std::string &error) +{ + using namespace llvm; + assert(lenp); + + Module *modulep = unwrap(modref); + assert(modulep); + + // get objectcode into a string + std::string s; + raw_string_ostream buf(s); + + formatted_raw_ostream fso(buf); + + TargetMachine * tm = unwrap(tmref); + + PassManager pm; +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 + if (!tm->getDataLayout()){ + error = "No target data in target machine"; + return NULL; + } + pm.add(new DataLayout(*tm->getDataLayout())); +#else + if (!tm->getTargetData()){ + error = "No target data in target machine"; + return NULL; + } + pm.add(new TargetData(*tm->getTargetData())); +#endif + + + + bool failed; + if( assembly ) { + failed = tm->addPassesToEmitFile(pm, fso, TargetMachine::CGFT_AssemblyFile); + } else { + failed = tm->addPassesToEmitFile(pm, fso, TargetMachine::CGFT_ObjectFile); + } + + if ( failed ) { + error = "No support for emit file"; + return NULL; + } + + pm.run(*modulep); + + // flush all streams + fso.flush(); + buf.flush(); + + const std::string& bc = buf.str(); + + // and then into a new buffer + size_t bclen = bc.size(); + unsigned char *bytes = new unsigned char[bclen]; + memcpy(bytes, bc.data(), bclen); + + /* return */ + *lenp = bclen; + return bytes; +} + +const char* LLVMTargetMachineGetTargetName(LLVMTargetMachineRef tm) +{ + return strdup(llvm::unwrap(tm)->getTarget().getName()); +} + +const char* LLVMTargetMachineGetTargetShortDescription(LLVMTargetMachineRef tm) +{ + return strdup(llvm::unwrap(tm)->getTarget().getShortDescription()); +} + +const char* LLVMTargetMachineGetTriple(LLVMTargetMachineRef tm) +{ + return strdup(llvm::unwrap(tm)->getTargetTriple().str().c_str()); +} + +const char* LLVMTargetMachineGetCPU(LLVMTargetMachineRef tm) +{ + return strdup(llvm::unwrap(tm)->getTargetCPU().str().c_str()); +} + +const char* LLVMTargetMachineGetFS(LLVMTargetMachineRef tm) +{ + return strdup(llvm::unwrap(tm)->getTargetFeatureString().str().c_str()); +} + +void LLVMPrintRegisteredTargetsForVersion(){ + llvm::TargetRegistry::printRegisteredTargetsForVersion(); +} + + + +LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm) +{ + using namespace llvm; +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 + return wrap(new DataLayout(*unwrap(tm)->getDataLayout())); +#else + return wrap(new TargetData(*unwrap(tm)->getTargetData())); +#endif +} + +unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, + size_t * lenp, std::string &error) +{ + using namespace llvm; + assert(lenp); + + Module *modulep = unwrap(module); + assert(modulep); + + // select native default machine + TargetMachine * tm = EngineBuilder(modulep).selectTarget(); + + return LLVMTargetMachineEmitFile(wrap(tm), module, assembly, lenp, error); +} + +static +llvm::AtomicOrdering atomic_ordering_from_string(const char * ordering) +{ + using namespace llvm; + + if ( strcmp(ordering, "unordered") == 0 ) + return Unordered; + else if ( strcmp(ordering, "monotonic") == 0 ) + return Monotonic; + else if ( strcmp(ordering, "acquire") == 0 ) + return Acquire; + else if ( strcmp(ordering, "release") == 0 ) + return Release; + else if ( strcmp(ordering, "acq_rel") == 0 ) + return AcquireRelease; + else if ( strcmp(ordering, "seq_cst") == 0 ) + return SequentiallyConsistent; + else + return NotAtomic; +} + +static +llvm::SynchronizationScope sync_scope_from_int(int crossthread) +{ + if( crossthread ) + return llvm::CrossThread; + else + return llvm::SingleThread; +} + +LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering, + int crossthread) +{ + using namespace llvm; + AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); + SynchronizationScope sync_scope = sync_scope_from_int(crossthread); + + Value * inst = unwrap(builder)->CreateFence(atomic_order, sync_scope); + return wrap(inst); +} + +LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * opname, + LLVMValueRef ptr, LLVMValueRef val, + const char* ordering, int crossthread) +{ + using namespace llvm; + + AtomicRMWInst::BinOp op; + + if( strcmp(opname, "xchg") == 0 ) + op = AtomicRMWInst::Xchg; + else if( strcmp(opname, "add") == 0 ) + op = AtomicRMWInst::Add; + else if( strcmp(opname, "sub") == 0 ) + op = AtomicRMWInst::Sub; + else if( strcmp(opname, "and") == 0 ) + op = AtomicRMWInst::And; + else if( strcmp(opname, "nand") == 0 ) + op = AtomicRMWInst::Nand; + else if( strcmp(opname, "or") == 0 ) + op = AtomicRMWInst::Or; + else if( strcmp(opname, "xor") == 0 ) + op = AtomicRMWInst::Xor; + else if( strcmp(opname, "max") == 0 ) + op = AtomicRMWInst::Max; + else if( strcmp(opname, "min") == 0 ) + op = AtomicRMWInst::Min; + else if( strcmp(opname, "umax") == 0 ) + op = AtomicRMWInst::UMax; + else if( strcmp(opname, "umin") == 0 ) + op = AtomicRMWInst::UMin; + else + op = AtomicRMWInst::BAD_BINOP; + + AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); + SynchronizationScope sync_scope = sync_scope_from_int(crossthread); + + Value * inst = unwrap(builder)->CreateAtomicRMW(op, unwrap(ptr), unwrap(val), + atomic_order, sync_scope); + return wrap(inst); +} + +LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, + unsigned align, const char* ordering, + int crossthread) +{ + using namespace llvm; + AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); + SynchronizationScope sync_scope = sync_scope_from_int(crossthread); + + LoadInst * inst = unwrap(builder)->CreateLoad(unwrap(ptr)); + + inst->setAtomic(atomic_order, sync_scope); + inst->setAlignment(align); + + return wrap(inst); +} + +LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, + LLVMValueRef ptr, LLVMValueRef val, + unsigned align, const char* ordering, + int crossthread) +{ + using namespace llvm; + AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); + SynchronizationScope sync_scope = sync_scope_from_int(crossthread); + + StoreInst * inst = unwrap(builder)->CreateStore(unwrap(val), unwrap(ptr)); + + inst->setAtomic(atomic_order, sync_scope); + inst->setAlignment(align); + + return wrap(inst); +} + +LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, + LLVMValueRef cmp, LLVMValueRef val, + const char* ordering, int crossthread) +{ + using namespace llvm; + + AtomicOrdering atomic_order = atomic_ordering_from_string(ordering); + SynchronizationScope sync_scope = sync_scope_from_int(crossthread); + + Value * inst = unwrap(builder)->CreateAtomicCmpXchg( + unwrap(ptr), unwrap(cmp), unwrap(val), + atomic_order, sync_scope); + return wrap(inst); +} + +LLVMEngineBuilderRef LLVMCreateEngineBuilder(LLVMModuleRef mod) +{ + return llvm::wrap(new EngineBuilder(unwrap(mod))); +} + +void LLVMDisposeEngineBuilder(LLVMEngineBuilderRef eb) +{ + delete llvm::unwrap(eb); +} + +void LLVMEngineBuilderForceJIT(LLVMEngineBuilderRef eb) +{ + using namespace llvm; + unwrap(eb)->setEngineKind(EngineKind::JIT); +} + +void LLVMEngineBuilderForceInterpreter(LLVMEngineBuilderRef eb) +{ + using namespace llvm; + unwrap(eb)->setEngineKind(EngineKind::Interpreter); +} + +void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level) +{ + unwrap(eb)->setOptLevel(OptLevelMap[level]); +} + +void LLVMEngineBuilderSetMCPU(LLVMEngineBuilderRef eb, const char * mcpu) +{ // TODO add test when llvm3.2 releases + unwrap(eb)->setMCPU(mcpu); // does not work in llvm3.1 +} + +void LLVMEngineBuilderSetMAttrs(LLVMEngineBuilderRef eb, const char * mattrs) +{ // TODO add test when llvm3.2 releases + std::vector tokenized; + std::istringstream iss(mattrs); + std::string buf; + while ( iss >> buf ){ + tokenized.push_back(buf); + } + unwrap(eb)->setMAttrs(tokenized); // does not work in llvm3.1 +} + +LLVMExecutionEngineRef LLVMEngineBuilderCreate(LLVMEngineBuilderRef eb, std::string & error) +{ + using namespace llvm; + LLVMExecutionEngineRef ret; + + ret = wrap(unwrap(eb)->setErrorStr(&error).create()); + + if ( !error.empty() ) { // error string is set + return NULL; + } else { + return ret; + } +} + +LLVMExecutionEngineRef LLVMEngineBuilderCreateTM(LLVMEngineBuilderRef eb, + LLVMTargetMachineRef tm, + std::string & error) +{ + using namespace llvm; + LLVMExecutionEngineRef ret; + + ret = wrap(unwrap(eb)->setErrorStr(&error).create(unwrap(tm))); + + if ( !error.empty() ) { // error string is set + return NULL; + } else { + return ret; + } +} + +int LLVMPassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef pmb) +{ + return llvm::unwrap(pmb)->OptLevel; +} + +int LLVMPassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef pmb) +{ + return llvm::unwrap(pmb)->SizeLevel; +} + +void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag) +{ + llvm::unwrap(pmb)->Vectorize = flag; +} + +int LLVMPassManagerBuilderGetVectorize(LLVMPassManagerBuilderRef pmb){ + return llvm::unwrap(pmb)->Vectorize; +} + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 +void LLVMPassManagerBuilderSetLoopVectorize(LLVMPassManagerBuilderRef pmb, + int flag) +{ + llvm::unwrap(pmb)->LoopVectorize = flag; +} + +int LLVMPassManagerBuilderGetLoopVectorize(LLVMPassManagerBuilderRef pmb){ + return llvm::unwrap(pmb)->LoopVectorize; +} +#endif // llvm-3.2 + + +int LLVMPassManagerBuilderGetDisableUnitAtATime(LLVMPassManagerBuilderRef pmb) +{ + return llvm::unwrap(pmb)->DisableUnitAtATime; +} + +int LLVMPassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef pmb) +{ + return llvm::unwrap(pmb)->DisableUnrollLoops; +} + +int LLVMPassManagerBuilderGetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef pmb) +{ + return llvm::unwrap(pmb)->DisableSimplifyLibCalls; +} + + +int LLVMAddPassByName(LLVMPassManagerRef pm, const char * name) +{ + using namespace llvm; + const PassInfo * pi = Pass::lookupPassInfo(StringRef(name)); + if (pi){ + unwrap(pm)->add(pi->createPass()); + return 1; // success + } else { + return 0; // fail -- cannot find pass + } +} + +void LLVMInitializePasses(){ + using namespace llvm; + PassRegistry ®istry = *PassRegistry::getPassRegistry(); + initializeCore(registry); + initializeScalarOpts(registry); + initializeVectorization(registry); + initializeIPO(registry); + initializeAnalysis(registry); + initializeIPA(registry); + initializeTransformUtils(registry); + initializeInstCombine(registry); + initializeInstrumentation(registry); + initializeTarget(registry); +} + +const char * LLVMDumpPasses() +{ + using namespace llvm; + PassRegistry ®istry = *PassRegistry::getPassRegistry(); + PassRegistryPrinter prp; + registry.enumerateWith(&prp); + return strdup(prp.stringstream.str().c_str()); +} + + +int LLVMIsLiteralStruct(LLVMTypeRef type) +{ + return llvm::unwrap(type)->isLiteral(); +} + +LLVMTypeRef LLVMStructTypeIdentified(const char * name) +{ + using namespace llvm; + return wrap(StructType::create(getGlobalContext(), name)); +} + +void LLVMSetStructBody(LLVMTypeRef type, LLVMTypeRef* elemtys, + unsigned elemct, int is_packed) +{ + using namespace llvm; + ArrayRef elemtys_aryref(unwrap(elemtys), elemct); + unwrap(type)->setBody(elemtys_aryref, is_packed); +} + +void LLVMSetStructName(LLVMTypeRef type, const char * name) +{ + llvm::StructType *st = llvm::unwrap(type); + st->setName(name); +} + +char *LLVMGetModuleIdentifier(LLVMModuleRef module) +{ + return strdup(llvm::unwrap(module)->getModuleIdentifier().c_str()); +} + +void LLVMSetModuleIdentifier(LLVMModuleRef module, const char * name) +{ + llvm::unwrap(module)->setModuleIdentifier(name); +} + +char *LLVMDumpModuleToString(LLVMModuleRef module) +{ + std::string s; + llvm::raw_string_ostream buf(s); + llvm::Module *p = llvm::unwrap(module); + assert(p); + p->print(buf, NULL); + return strdup(buf.str().c_str()); +} + +void LLVMModuleAddLibrary(LLVMModuleRef module, const char *name) +{ + llvm::Module *M = llvm::unwrap(module); + llvm::StringRef namestr = llvm::StringRef(name); + M->addLibrary(namestr); + return; +} + +char *LLVMDumpTypeToString(LLVMTypeRef type) +{ + return do_print(type); +} + +char *LLVMDumpValueToString(LLVMValueRef value) +{ + return do_print(value); +} + +unsigned LLVMModuleGetPointerSize(LLVMModuleRef module) +{ + llvm::Module *modulep = llvm::unwrap(module); + assert(modulep); + + llvm::Module::PointerSize p = modulep->getPointerSize(); + if (p == llvm::Module::Pointer32) + return 32; + else if (p == llvm::Module::Pointer64) + return 64; + return 0; +} + +LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module, + const char *name, LLVMTypeRef function_type) +{ + assert(name); + + llvm::Module *modulep = llvm::unwrap(module); + assert(modulep); + + llvm::FunctionType *ftp = llvm::unwrap(function_type); + assert(ftp); + + llvm::Constant *f = modulep->getOrInsertFunction(name, ftp); + return wrap(f); +} + +int LLVMHasInitializer(LLVMValueRef global_var) +{ + llvm::GlobalVariable *gvp = llvm::unwrap(global_var); + assert(gvp); + + return gvp->hasInitializer(); +} + +#define inst_checkfn(ourfn, llvmfn) \ +unsigned ourfn (LLVMValueRef v) { \ + llvm::Instruction *ip = llvm::unwrap(v); \ + assert(ip); \ + return ip-> llvmfn () ? 1 : 0; \ +} + +inst_checkfn(LLVMInstIsTerminator, isTerminator) +inst_checkfn(LLVMInstIsBinaryOp, isBinaryOp) +inst_checkfn(LLVMInstIsShift, isShift) +inst_checkfn(LLVMInstIsCast, isCast) +inst_checkfn(LLVMInstIsLogicalShift, isLogicalShift) +inst_checkfn(LLVMInstIsArithmeticShift, isArithmeticShift) +inst_checkfn(LLVMInstIsAssociative, isAssociative) +inst_checkfn(LLVMInstIsCommutative, isCommutative) + +unsigned LLVMInstIsVolatile(LLVMValueRef v) +{ + using namespace llvm; + Instruction *ip = unwrap(v); + assert(ip); + return ((isa(*ip) && cast(*ip).isVolatile()) || + (isa(*ip) && cast(*ip).isVolatile()) ); +} + +const char *LLVMInstGetOpcodeName(LLVMValueRef inst) +{ + llvm::Instruction *instp = llvm::unwrap(inst); + assert(instp); + return instp->getOpcodeName(); +} + +unsigned LLVMInstGetOpcode(LLVMValueRef inst) +{ + llvm::Instruction *instp = llvm::unwrap(inst); + assert(instp); + return instp->getOpcode(); +} + +unsigned LLVMCmpInstGetPredicate(LLVMValueRef cmpinst) +{ + llvm::CmpInst *instp = llvm::unwrap(cmpinst); + assert(instp); + return instp->getPredicate(); +} + +LLVMValueRef LLVMInstGetCalledFunction(LLVMValueRef inst) +{ + llvm::Instruction *instp = llvm::unwrap(inst); + return llvm::wrap(CallSite(instp).getCalledFunction()); +} + +void LLVMInstSetCalledFunction(LLVMValueRef inst, LLVMValueRef fn) +{ + using namespace llvm; + Instruction *instp = unwrap(inst); + CallSite(instp).setCalledFunction(unwrap(fn)); +} + +///* llvm::unwrap a set of `n' wrapped objects starting at `values', +// * into a vector of pointers to llvm::unwrapped objects `out'. */ +//template +//void unwrap_vec(W *values, unsigned n, std::vector& out) +//{ +// out.clear(); +// out.reserve(n); +// while (n--) { +// UW *p = llvm::unwrap(*values); +// assert(p); +// out.push_back(p); +// ++values; +// } +//} + +///* Same as llvm::unwrap_vec, but use a vector of const pointers. */ +//template +//void unwrap_cvec(W *values, unsigned n, std::vector& out) +//{ +// out.clear(); + +// while (n--) { +// UW *p = llvm::unwrap(*values); +// assert(p); +// out.push_back(p); +// ++values; +// } +//} + + +LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef builder, + LLVMValueRef *values, unsigned n_values) +{ + using namespace llvm; + assert(values); + + IRBuilder<> *builderp = unwrap(builder); + assert(builderp); + + return wrap(builderp->CreateAggregateRet(unwrap(values, n_values), n_values)); +} + +LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, + LLVMValueRef value, unsigned index, const char *name) +{ + assert(name); + + llvm::IRBuilder<> *builderp = llvm::unwrap(builder); + assert(builderp); + + return llvm::wrap(builderp->CreateExtractValue(llvm::unwrap(value), index, name)); +} + +unsigned LLVMValueGetID(LLVMValueRef value) +{ + llvm::Value *valuep = llvm::unwrap(value); + assert(valuep); + + return valuep->getValueID(); +} + + +unsigned LLVMValueGetNumUses(LLVMValueRef value) +{ + llvm::Value *valuep = llvm::unwrap(value); + assert(valuep); + + return valuep->getNumUses(); +} + + +unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs) +{ + llvm::Value *valuep = llvm::unwrap(value); + assert(valuep); + + unsigned n = valuep->getNumUses(); + if (n == 0) + return 0; + + assert(refs); + LLVMValueRef *out = new LLVMValueRef[n]; + if (!out) + return 0; + *refs = out; + + memset(out, 0, sizeof(LLVMValueRef) * n); + llvm::Value::use_iterator it = valuep->use_begin(); + while (it != valuep->use_end()) { + *out++ = llvm::wrap(*it); + ++it; + } + + return n; +} + +void LLVMDisposeValueRefArray(LLVMValueRef *refs) +{ + assert(refs); + delete [] refs; +} + +unsigned LLVMUserGetNumOperands(LLVMValueRef user) +{ + llvm::User *userp = llvm::unwrap(user); + assert(userp); + return userp->getNumOperands(); +} + +LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx) +{ + llvm::User *userp = llvm::unwrap(user); + assert(userp); + llvm::Value *operand = userp->getOperand(idx); + return llvm::wrap(operand); +} + +unsigned LLVMGetDoesNotThrow(LLVMValueRef fn) +{ + llvm::Function *fnp = llvm::unwrap(fn); + assert(fnp); + + return fnp->doesNotThrow(); +} + +void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow) +{ + llvm::Function *fnp = llvm::unwrap(fn); + assert(fnp); + + if ((bool)DoesNotThrow) + fnp->setDoesNotThrow(); +} + + +LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id, + LLVMTypeRef *types, unsigned n_types) +{ + using namespace llvm; + assert(types); + + Module *modulep = unwrap(module); + assert(modulep); + + Function *intfunc = Intrinsic::getDeclaration(modulep, Intrinsic::ID(id), + makeArrayRef(unwrap(types, n_types), + n_types)); + + return wrap(intfunc); +} + +LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtext, char **out) +{ + assert(asmtext); + assert(out); + + llvm::Module *modulep; + llvm::SMDiagnostic error; + if (!(modulep = llvm::ParseAssemblyString(asmtext, NULL, error, + llvm::getGlobalContext()))) { + std::string s; + llvm::raw_string_ostream buf(s); + error.print("llvm-py", buf); + *out = strdup(buf.str().c_str()); + return NULL; + } + + return wrap(modulep); +} + +LLVMModuleRef LLVMGetModuleFromBitcode(const char *bitcode, unsigned bclen, + char **out) +{ + assert(bitcode); + assert(out); + + llvm::StringRef as_str(bitcode, bclen); + + llvm::MemoryBuffer *mbp; + if (!(mbp = llvm::MemoryBuffer::getMemBufferCopy(as_str))) + return NULL; + + std::string msg; + llvm::Module *modulep; + if (!(modulep = llvm::ParseBitcodeFile(mbp, llvm::getGlobalContext(), + &msg))) + *out = strdup(msg.c_str()); + + delete mbp; + return wrap(modulep); +} + +#if LLVM_VERSION_MAJOR <= 3 && LLVM_VERSION_MINOR < 2 +// Shamelessly copy from LLVM-3.2 +unsigned LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src, + int Mode, char **OutMessages) { + std::string Messages; + unsigned Result = Linker::LinkModules(unwrap(Dest), unwrap(Src), Mode, + OutMessages? &Messages : 0); + if (OutMessages) + *OutMessages = strdup(Messages.c_str()); + return Result; +} +#endif + +unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, size_t *lenp) +{ + assert(lenp); + + llvm::Module *modulep = llvm::unwrap(module); + assert(modulep); + + /* get bc into a string */ + std::string s; + llvm::raw_string_ostream buf(s); + llvm::WriteBitcodeToFile(modulep, buf); + const std::string& bc = buf.str(); + + /* and then into a new()-ed block */ + size_t bclen = bc.size(); + unsigned char *bytes = new unsigned char[bclen]; + memcpy(bytes, bc.data(), bclen); + + /* return */ + *lenp = bclen; + return bytes; +} + +/* Return 0 on failure (with errmsg filled in), 1 on success. */ +unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg) +{ + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@1"); + assert(filename); + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2"); + assert(errmsg); + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3"); + + /* Note: the LLVM API returns true on failure. Don't ask why. */ + std::string msg; + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4"); + if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) { + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@5"); + *errmsg = strdup(msg.c_str()); + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@6"); + return 0; + } + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@7"); + return 1; +} + +void LLVMExecutionEngineDisableLazyCompilation(LLVMExecutionEngineRef ee, int flag) +{ + llvm::unwrap(ee)->DisableLazyCompilation(flag); +} + +void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn) +{ + llvm::ExecutionEngine *eep = llvm::unwrap(ee); + assert(eep); + + llvm::Function *fnp = llvm::unwrap(fn); + assert(fnp); + + return eep->getPointerToFunction(fnp); +} + + +int LLVMInlineFunction(LLVMValueRef call) +{ + llvm::Value *callp = llvm::unwrap(call); + assert(callp); + + llvm::InlineFunctionInfo unused; + + llvm::Instruction *II = llvm::dyn_cast(callp); + if (II->getOpcode() == llvm::Instruction::Call) + return llvm::InlineFunction(static_cast(II), unused); + else if (II->getOpcode() == llvm::Instruction::Invoke) + return llvm::InlineFunction(static_cast(II), unused); + else + return 0; +} + +unsigned LLVMGetParamAlignment(LLVMValueRef arg) +{ + llvm::Argument *argp = llvm::unwrap(arg); + assert(argp); + + unsigned argno = argp->getArgNo(); + + return argp->getParent()->getParamAlignment(argno + 1); +} + + +/* Passes. A few passes (listed below) are used directly from LLVM-C, + * rest are defined here. + */ +/* +#define define_pass(P) \ +void LLVMAdd ## P ## Pass (LLVMPassManagerRef passmgr) { \ + using namespace llvm; \ + llvm::PassManagerBase *pmp = llvm::unwrap(passmgr); \ + assert(pmp); \ + pmp->add( create ## P ## Pass ()); \ +} + +define_pass( AAEval ) +define_pass( AliasAnalysisCounter ) +//define_pass( AlwaysInliner ) +//define_pass( BasicAliasAnalysis ) +define_pass( BlockPlacement ) +define_pass( BreakCriticalEdges ) +define_pass( CodeGenPrepare ) +define_pass( DbgInfoPrinter ) +define_pass( DeadCodeElimination ) +define_pass( DeadInstElimination ) +define_pass( DemoteRegisterToMemory ) +define_pass( DomOnlyPrinter ) +define_pass( DomOnlyViewer ) +define_pass( DomPrinter ) +define_pass( DomViewer ) +define_pass( EdgeProfiler ) +//define_pass( GEPSplitter ) +define_pass( GlobalsModRef ) +define_pass( InstCount ) +define_pass( InstructionNamer ) +define_pass( LazyValueInfo ) +define_pass( LCSSA ) +//define_pass( LiveValues ) +define_pass( LoopDependenceAnalysis ) +define_pass( LoopExtractor ) +define_pass( LoopSimplify ) +define_pass( LoopStrengthReduce ) +define_pass( LowerInvoke ) +define_pass( LowerSwitch ) +define_pass( MergeFunctions ) +define_pass( NoAA ) +define_pass( NoProfileInfo ) +define_pass( OptimalEdgeProfiler ) +define_pass( PartialInlining ) +//define_pass( PartialSpecialization ) +define_pass( PostDomOnlyPrinter ) +define_pass( PostDomOnlyViewer ) +define_pass( PostDomPrinter ) +define_pass( PostDomViewer ) +define_pass( ProfileEstimator ) +define_pass( ProfileLoader ) +define_pass( ProfileVerifier ) +define_pass( ScalarEvolutionAliasAnalysis ) +//define_pass( SimplifyHalfPowrLibCalls ) +define_pass( SingleLoopExtractor ) +define_pass( StripNonDebugSymbols ) +//define_pass( StructRetPromotion ) +//define_pass( TailDuplication ) +define_pass( UnifyFunctionExitNodes ) +*/ +/* we support only internalize(true) */ +/* +llvm::ModulePass *createInternalize2Pass() { return llvm::createInternalizePass(true); } +define_pass( Internalize2 ) +*/ diff --git a/llvm/extra.h b/llvm/extra.h new file mode 100644 index 0000000..b734f1b --- /dev/null +++ b/llvm/extra.h @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2008-10, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * These are some "extra" functions not available in the standard LLVM-C + * bindings, but are required / good-to-have inorder to implement the + * Python bindings. + */ + +#ifndef LLVM_PY_EXTRA_H +#define LLVM_PY_EXTRA_H + +// select PTX or NVPTX + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 + #define LLVM_HAS_NVPTX 1 +#else + #define LLVM_HAS_NVPTX 0 +#endif + +#include "llvm-c/Transforms/PassManagerBuilder.h" +#include "llvm_c_extra.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 +/* + * Wraps new TargetTransformInfo( + * TargetMachine::getScalarTargetTransformInfo, + * TargetMachine::getVectorTargetTransformInfo) + */ +LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref); +#endif + +/* + * Wraps new TargetLibraryInfo + */ +LLVMPassRef LLVMCreateTargetLibraryInfo(const char * triple); + +/* + * Wraps llvm::getDefaultTargetTriple + */ +const char * LLVMDefaultTargetTriple(); + +/* + * Wraps Pass::lookupPassInfo and PassInfo::createPass + */ +LLVMPassRef LLVMCreatePassByName(const char *name); + +/* + * Wraps operator delete (Pass*) + */ +void LLVMDisposePass(LLVMPassRef passref); + +/* + * Wraps Pass::getPassName + */ +const char * LLVMGetPassName(LLVMPassRef passref); + +/* + * Wraps PassManager::add + */ +void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref); + +/* + * Wraps Pass::dump + */ +void LLVMPassDump(LLVMPassRef passref); + +/* + * Wraps llvm:InlineAsm::get + */ +LLVMValueRef LLVMGetFunctionFromInlineAsm(LLVMTypeRef funcType, + const char inlineAsm[], + const char constrains[], + bool hasSideEffect, + bool isAlignStack, + int asmDialect); + +/* + * Wraps llvm::CloneModule + */ +LLVMModuleRef LLVMCloneModule(LLVMModuleRef mod); + + +/* + * Wraps NamedMDNode::print() + */ +const char * LLVMDumpNamedMDToString(LLVMNamedMDRef nmd); + +/* + * Wraps NamedMDNode::getName() + */ +const char * LLVMNamedMetaDataGetName(LLVMNamedMDRef nmd); + +/* + * Wraps NamedMDNode::addOperand() + */ +void LLVMNamedMetaDataAddOperand(LLVMNamedMDRef nmd, LLVMValueRef md); + +/* + * Wraps NamedMDNode::eraseFromParent() + */ +void LLVMEraseNamedMetaData(LLVMNamedMDRef nmd); + +/* + * Wraps Module::getOrInsertNamedMetadata + */ +LLVMNamedMDRef LLVMModuleGetOrInsertNamedMetaData(LLVMModuleRef mod, const char *name); + +/* + * Wraps Module::getNamedMetadata + */ +LLVMNamedMDRef LLVMModuleGetNamedMetaData(LLVMModuleRef mod, const char *name); + +/* + * Wraps Instruction::setMetadata() + */ +void LLVMInstSetMetaData(LLVMValueRef instref, const char* mdkind, + LLVMValueRef metaref); + +/* + * Wraps MDNode::get() + */ +LLVMValueRef LLVMMetaDataGet(LLVMModuleRef modref, LLVMValueRef * valrefs, + unsigned valct); + +/* + * Wraps MDNode::getOperand() + */ +LLVMValueRef LLVMMetaDataGetOperand(LLVMValueRef mdref, unsigned index); + +/* + * Wraps MDNode::getNumOperands() + */ +unsigned LLVMMetaDataGetNumOperands(LLVMValueRef mdref); + +/* + * Wraps MDString::get() + */ +LLVMValueRef LLVMMetaDataStringGet(LLVMModuleRef modref, const char *s); + +/* + * Wraps ConstantExpr::getOpcodeName() + */ +const char *LLVMGetConstExprOpcodeName(LLVMValueRef inst); + +/* + * Wraps ConstantExpr::getOpcode() + */ +unsigned LLVMGetConstExprOpcode(LLVMValueRef inst); + +/* + * Wraps LoadInst::SetAlignment + */ +void LLVMLdSetAlignment(LLVMValueRef inst, unsigned align); + +/* + * Wraps StoreInst::SetAlignment + */ +void LLVMStSetAlignment(LLVMValueRef inst, unsigned align); + +const char * LLVMGetHostCPUName(); + +int LLVMInitializeNativeTargetAsmPrinter(); + + +LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, + const char *features, int opt, + int codemodel, std::string &error); + +LLVMTargetMachineRef LLVMCreateTargetMachine(const char *arch, const char *cpu, + const char *features, int opt, + int codemodel, + std::string &error); + +/* + * Wraps EngineBuilder::selectTarget + */ +LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb); + +/* + * Wraps operator delete + */ +void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm); + +/* + * Wraps TargetMachine::addPassesToEmitFile + */ +unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, + LLVMModuleRef modref, + int assembly, size_t * lenp, + std::string &error); + +/* + * Wraps TargetMachine::getTargetData + */ +LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm); + +/* + * Wraps TargetMachine::getTarget().getName() + */ +const char* LLVMTargetMachineGetTargetName(LLVMTargetMachineRef tm); + +/* + * Wraps TargetMachine::getTarget().getShortDescription() + */ +const char* LLVMTargetMachineGetTargetShortDescription(LLVMTargetMachineRef tm); + +/* + * Wraps TargetMachine::getTargetTriple + */ +const char * LLVMTargetMachineGetTriple(LLVMTargetMachineRef tm); + +/* + * Wraps TargetMachine::getTargetCPU + */ +const char * LLVMTargetMachineGetCPU(LLVMTargetMachineRef tm); + +/* + * Wraps TargetMachine::getTargetFeatureString + */ +const char * LLVMTargetMachineGetFS(LLVMTargetMachineRef tm); + +/* + * Wraps TargetRegister::printRegisteredTargetsForVersion + */ +void LLVMPrintRegisteredTargetsForVersion(); + +/* + * Wraps TargetMachine::addPassesToEmitFile + */ +unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, + size_t * lenp, std::string &error); + +/* + * Wraps IRBuilder::CreateFence + */ +LLVMValueRef LLVMBuildFence(LLVMBuilderRef builder, const char* ordering, + int crossthread); + +/* + * Wraps IRBuilder::CreateLoad, LoadInst::setAtomic + */ +LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef builder, LLVMValueRef ptr, + unsigned align, const char* ordering, + int crossthread); +/* + * Wraps IRBuilder::CreateStore, StoreInst::setAtomic + */ +LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef builder, + LLVMValueRef ptr, LLVMValueRef val, + unsigned align, const char* ordering, + int crossthread); + +/* + * Wraps IRBuilder::CreateAtomicRMW + */ +LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * op, + LLVMValueRef ptr, LLVMValueRef val, + const char* ordering, int crossthread); + +/* + * Wraps IRBuilder::CreateAtomicCmpXchg + */ +LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, + LLVMValueRef cmp, LLVMValueRef val, + const char* ordering, int crossthread); + +/* + * Wraps new EngineBuilder + */ +LLVMEngineBuilderRef LLVMCreateEngineBuilder(LLVMModuleRef mod); + +/* + * Wraps delete EngineBuilder + */ +void LLVMDisposeEngineBuilder(LLVMEngineBuilderRef eb); + + +/* + * Wraps EngineBuilder::setEngineKind(EngineKind::JIT) + */ +void LLVMEngineBuilderForceJIT(LLVMEngineBuilderRef eb); + +/* + * Wraps EngineBuilder::setEngineKind(EngineKind::Interpreter) + */ +void LLVMEngineBuilderForceInterpreter(LLVMEngineBuilderRef eb); + + +/* + * Wraps EngineBuilder::setOptLevel + */ +void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level); + +/* + * Wraps EngineBuilder::setMCPU + */ +void LLVMEngineBuilderSetMCPU(LLVMEngineBuilderRef eb, const char * mcpu); + +/* + * Wraps EngineBuilder::setMAttrs + */ +void LLVMEngineBuilderSetMAttrs(LLVMEngineBuilderRef eb, const char * mattrs); + +/* + * Wraps EngineBuilder::setErrorStr and EngineBuilder::create + */ +LLVMExecutionEngineRef LLVMEngineBuilderCreate(LLVMEngineBuilderRef eb, + std::string &error); + +/* + * Wraps EngineBuilder::create(TargetMachine*) + */ +LLVMExecutionEngineRef LLVMEngineBuilderCreateTM(LLVMEngineBuilderRef ebref, + LLVMTargetMachineRef tmref, + std::string & error); + + +/* + * Wraps PassManagerBuilder::OptLevel + */ +int LLVMPassManagerBuilderGetOptLevel(LLVMPassManagerBuilderRef pmb); + +/* + * Wraps PassManagerBuilder::SizeLevel + */ +int LLVMPassManagerBuilderGetSizeLevel(LLVMPassManagerBuilderRef pmb); + +/* + * Wraps PassManagerBuilder::Vectorize + */ +void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag); + +/* + * Wraps PassManagerBuilder::Vectorize + */ +int LLVMPassManagerBuilderGetVectorize(LLVMPassManagerBuilderRef pmb); + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 +/* + * Wraps PassManagerBuilder::LoopVectorize + */ +void LLVMPassManagerBuilderSetLoopVectorize(LLVMPassManagerBuilderRef pmb, + int flag); + +/* + * Wraps PassManagerBuilder::LoopVectorize + */ +int LLVMPassManagerBuilderGetLoopVectorize(LLVMPassManagerBuilderRef pmb); +#endif // llvm-3.2 + +/* + * Wraps PassManagerBuilder::DisableUnitAtATime + */ +int LLVMPassManagerBuilderGetDisableUnitAtATime(LLVMPassManagerBuilderRef pmb); + +/* + * Wraps PassManagerBuilder::DisableUnrollLoops + */ +int LLVMPassManagerBuilderGetDisableUnrollLoops(LLVMPassManagerBuilderRef pmb); + +/* + * Wraps PassManagerBuilder::DisableSimplifyLibCalls + */ +int LLVMPassManagerBuilderGetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef pmb); + +/* + * Wraps PassManager::add + */ +int LLVMAddPassByName(LLVMPassManagerRef pm, const char * name); + +/* + * Wraps initialize* + */ +void LLVMInitializePasses(void); + +/* + * Wraps PassRegistry::enumerateWith() + * Returns a '\n' separated string of all passes available to `opt`. + */ +const char * LLVMDumpPasses(void); + +/* + * Wraps StructType::isLiteral() + */ +int LLVMIsLiteralStruct(LLVMTypeRef type); + +/* + * Wraps StructType::create() + */ +LLVMTypeRef LLVMStructTypeIdentified(const char * name); + +/* + * StructType::setBody() + */ +void LLVMSetStructBody(LLVMTypeRef type, LLVMTypeRef* elemtys, unsigned elemct, int is_packed); + +/* + * Wraps llvm::StructType::setName() + */ +void LLVMSetStructName(LLVMTypeRef type, const char * name); + + +/* + * Wraps llvm::Module::getModuleIdentifier() + */ +char *LLVMGetModuleIdentifier(LLVMModuleRef module); + +/* + * Wraps llvm::Module::setModuleIdentifier() + */ +void LLVMSetModuleIdentifier(LLVMModuleRef module, const char * name); + +/* Notes: + * - Some returned strings must be disposed of by LLVMDisposeMessage. These are + * indicated in the comments. Where it is not indicated, DO NOT call dispose. + */ + +/* Wraps llvm::Module::print(). Dispose the returned string after use, via + * LLVMDisposeMessage(). */ +char *LLVMDumpModuleToString(LLVMModuleRef module); + +/* Wraps llvm::Module::addLibrary(name). */ +void LLVMModuleAddLibrary(LLVMModuleRef module, const char *name); + +/* Wraps llvm::Type::print(). Dispose the returned string after use, via + * LLVMDisposeMessage(). */ +char *LLVMDumpTypeToString(LLVMTypeRef type); + +/* Wraps llvm::Value::print(). Dispose the returned string after use, via + * LLVMDisposeMessage(). */ +char *LLVMDumpValueToString(LLVMValueRef Val); + +/* Wraps llvm::IRBuilder::CreateRet(). */ +LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef bulder, LLVMValueRef *values, + unsigned n_values); + +/* Wraps llvm::IRBuilder::CreateGetResult(). */ +LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value, + unsigned index, const char *name); + +/* Wraps llvm::Value::getValueID(). */ +unsigned LLVMValueGetID(LLVMValueRef value); + +/* Wraps llvm::Value::getNumUses(). */ +unsigned LLVMValueGetNumUses(LLVMValueRef value); + +/* Wraps llvm::Value::use_{begin,end}. Allocates LLVMValueRef's as + * required. Number of objects are returned as return value. If that is + * greater than zero, the pointer given out must be freed by a + * subsequent call to LLVMDisposeValueRefArray(). */ +unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs); + +/* See above. */ +void LLVMDisposeValueRefArray(LLVMValueRef *refs); + +/* Wraps llvm:User::getNumOperands(). */ +unsigned LLVMUserGetNumOperands(LLVMValueRef user); + +/* Wraps llvm:User::getOperand(). */ +LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx); + +/* Wraps llvm::ConstantExpr::getVICmp(). */ +LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs, + LLVMValueRef rhs); + +/* Wraps llvm::ConstantExpr::getVFCmp(). */ +LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate predicate, LLVMValueRef lhs, + LLVMValueRef rhs); + +/* Wraps llvm::IRBuilder::CreateVICmp(). */ +LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef builder, LLVMIntPredicate predicate, + LLVMValueRef lhs, LLVMValueRef rhs, const char *name); + +/* Wraps llvm::IRBuilder::CreateVFCmp(). */ +LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef builder, LLVMRealPredicate predicate, + LLVMValueRef lhs, LLVMValueRef rhs, const char *name); + +/* Wraps llvm::Intrinsic::getDeclaration(). */ +LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef builder, int id, + LLVMTypeRef *types, unsigned n_types); + +/* Wraps llvm::Function::doesNotThrow(). */ +unsigned LLVMGetDoesNotThrow(LLVMValueRef fn); + +/* Wraps llvm::Function::setDoesNotThrow(). */ +void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow); + +/* Wraps llvm::Module::getPointerSize(). */ +unsigned LLVMModuleGetPointerSize(LLVMModuleRef module); + +/* Wraps llvm::Module::getOrInsertFunction(). */ +LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module, + const char *name, LLVMTypeRef function_type); + +/* Wraps llvm::GlobalVariable::hasInitializer(). */ +int LLVMHasInitializer(LLVMValueRef global_var); + +/* The following functions wrap various llvm::Instruction::isXXX() functions. + * All of them take an instruction and return 0 (isXXX returned false) or 1 + * (isXXX returned false). */ +unsigned LLVMInstIsTerminator (LLVMValueRef inst); +unsigned LLVMInstIsBinaryOp (LLVMValueRef inst); +unsigned LLVMInstIsShift (LLVMValueRef inst); +unsigned LLVMInstIsCast (LLVMValueRef inst); +unsigned LLVMInstIsLogicalShift (LLVMValueRef inst); +unsigned LLVMInstIsArithmeticShift (LLVMValueRef inst); +unsigned LLVMInstIsAssociative (LLVMValueRef inst); +unsigned LLVMInstIsCommutative (LLVMValueRef inst); +unsigned LLVMInstIsTrapping (LLVMValueRef inst); + +/* As above, but these are wrap methods from subclasses of Instruction. */ +unsigned LLVMInstIsVolatile (LLVMValueRef inst); + +/* Wraps llvm::Instruction::getOpcodeName(). */ +const char *LLVMInstGetOpcodeName(LLVMValueRef inst); + +/* Wraps llvm::Instruction::getOpcode(). */ +unsigned LLVMInstGetOpcode(LLVMValueRef inst); + +/* Wraps llvm::CmpInst::getPredicate(). */ +unsigned LLVMCmpInstGetPredicate(LLVMValueRef cmpinst); + +/* Wraps llvm::CallSite::getCalledFunction. + */ +LLVMValueRef LLVMInstGetCalledFunction(LLVMValueRef inst); + +/* Wraps llvm::CallSite::setCalledFunction. + */ +void LLVMInstSetCalledFunction(LLVMValueRef inst, LLVMValueRef fn); + +/* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with + * `out' pointing to an error message). Dispose error message after use, via + * LLVMDisposeMessage(). */ +LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtxt, char **out); + +/* Wraps llvm::ParseBitcodeFile(). Returns a module reference or NULL (with + * `out' pointing to an error message). Dispose error message after use, via + * LLVMDisposeMessage(). */ +LLVMModuleRef LLVMGetModuleFromBitcode(const char *bc, unsigned bclen, + char **out); + +#if LLVM_VERSION_MAJOR <= 3 && LLVM_VERSION_MINOR < 2 +/* Wraps llvm::Linker::LinkModules(). Returns 0 on failure (with errmsg + * filled in) and 1 on success. Dispose error message after use with + * LLVMDisposeMessage(). */ +unsigned LLVMLinkModules(LLVMModuleRef dest, LLVMModuleRef src, int mode, + char **errmsg); +#endif +/* Returns pointer to a heap-allocated block of `*len' bytes containing bit code + * for the given module. NULL on error. */ +unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, size_t *len); + +/* Wraps llvm::sys::DynamicLibrary::LoadLibraryPermanently(). Returns 0 on + * failure (with errmsg filled in) and 1 on success. Dispose error message after + * use, via LLVMDisposeMessage(). */ +unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg); + +/* Wraps llvm::ExecutionEngine::DisableLazyCompilation(bool) + */ +void LLVMExecutionEngineDisableLazyCompilation(LLVMExecutionEngineRef ee, + int flag); + +/* Wraps llvm::ExecutionEngine::getPointerToFunction(). Returns a pointer + * to the JITted function. */ +void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn); + +/* Wraps llvm::InlineFunction(). Inlines a function. C is the call + * instruction, created by LLVMBuildCall. Even if it fails, the Function + * containing the call is still in a proper state (not changed). + */ +int LLVMInlineFunction(LLVMValueRef call); + +/* Wraps llvm::getAlignmentFromAttrs from Attributes.h. Compliments the + * already available LLVMSetParamAlignment(). */ +unsigned LLVMGetParamAlignment(LLVMValueRef arg); + +/* Passes. Some passes are used directly from LLVM-C, rest are declared + * here. */ + +/* +#define declare_pass(P) \ + void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM); + +declare_pass( AAEval ) +declare_pass( AliasAnalysisCounter ) +declare_pass( AlwaysInliner ) +declare_pass( BasicAliasAnalysis ) +declare_pass( BlockPlacement ) +declare_pass( BreakCriticalEdges ) +declare_pass( CodeGenPrepare ) +declare_pass( DbgInfoPrinter ) +declare_pass( DeadCodeElimination ) +declare_pass( DeadInstElimination ) +declare_pass( DemoteRegisterToMemory ) +declare_pass( DomOnlyPrinter ) +declare_pass( DomOnlyViewer ) +declare_pass( DomPrinter ) +declare_pass( DomViewer ) +declare_pass( EdgeProfiler ) +//declare_pass( GEPSplitter ) +declare_pass( GlobalsModRef ) +declare_pass( InstCount ) +declare_pass( InstructionNamer ) +declare_pass( LazyValueInfo ) +declare_pass( LCSSA ) +//declare_pass( LiveValues ) +declare_pass( LoopDependenceAnalysis ) +declare_pass( LoopExtractor ) +declare_pass( LoopSimplify ) +declare_pass( LoopStrengthReduce ) +declare_pass( LowerInvoke ) +declare_pass( LowerSwitch ) +declare_pass( MergeFunctions ) +declare_pass( NoAA ) +declare_pass( NoProfileInfo ) +declare_pass( OptimalEdgeProfiler ) +declare_pass( PartialInlining ) +//declare_pass( PartialSpecialization ) +declare_pass( PostDomOnlyPrinter ) +declare_pass( PostDomOnlyViewer ) +declare_pass( PostDomPrinter ) +declare_pass( PostDomViewer ) +declare_pass( ProfileEstimator ) +declare_pass( ProfileLoader ) +declare_pass( ProfileVerifier ) +declare_pass( ScalarEvolutionAliasAnalysis ) +declare_pass( SimplifyHalfPowrLibCalls ) +declare_pass( SingleLoopExtractor ) +declare_pass( StripNonDebugSymbols ) +declare_pass( StructRetPromotion ) +declare_pass( TailDuplication ) +declare_pass( UnifyFunctionExitNodes ) + +declare_pass( Internalize2 ) +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LLVM_PY_EXTRA_H */ + diff --git a/llvm/llrt.py b/llvm/llrt.py deleted file mode 100644 index c704a66..0000000 --- a/llvm/llrt.py +++ /dev/null @@ -1,79 +0,0 @@ -import os -import llvm.core as lc -import llvm.passes as lp -import llvm.ee as le - -def replace_divmod64(lfunc): - '''Replaces all 64-bit integer division (sdiv, udiv) and modulo (srem, urem) - ''' - int64 = lc.Type.int(64) - int64ptr = lc.Type.pointer(lc.Type.int(64)) - - functy = lc.Type.function(int64, [int64, int64]) - udiv64 = lfunc.module.get_or_insert_function(functy, '__llrt_udiv64') - sdiv64 = lfunc.module.get_or_insert_function(functy, '__llrt_sdiv64') - umod64 = lfunc.module.get_or_insert_function(functy, '__llrt_umod64') - smod64 = lfunc.module.get_or_insert_function(functy, '__llrt_smod64') - - builder = lc.Builder.new(lfunc.entry_basic_block) - for bb in lfunc.basic_blocks: - for inst in bb.instructions: - if inst.opcode_name == 'sdiv' and inst.type == int64: - _replace_with(builder, inst, sdiv64) - elif inst.opcode_name == 'udiv' and inst.type == int64: - _replace_with(builder, inst, udiv64) - elif inst.opcode_name == 'srem' and inst.type == int64: - _replace_with(builder, inst, smod64) - elif inst.opcode_name == 'urem' and inst.type == int64: - _replace_with(builder, inst, umod64) - -def _replace_with(builder, inst, func): - '''Replace instruction with a call to the function with the same operands - as arguments. - ''' - builder.position_before(inst) - replacement = builder.call(func, inst.operands) - inst.replace_all_uses_with(replacement._ptr) - inst.erase_from_parent() - -def load(arch): - '''Load the LLRT module corresponding to the given architecture - Creates a new module and optimizes it using the information from - the host machine. - ''' - if arch != 'x86_64': - arch = 'x86' - path = os.path.join(os.path.dirname(__file__), 'llrt', 'llrt_%s.ll' % arch) - with open(path) as fin: - lib = lc.Module.from_assembly(fin) - - # run passes to optimize - tm = le.TargetMachine.new() - pms = lp.build_pass_managers(tm, opt=3, fpm=False) - pms.pm.run(lib) - return lib - -class LLRT(object): - def __init__(self): - arch = le.get_default_triple().split('-', 1)[0] - self.module = load(arch) - self.engine = le.EngineBuilder.new(self.module).opt(3).create() - self.installed_symbols = set() - - def install_symbols(self): - '''Bind all the external symbols to the global symbol map. - Any future reference to these symbols will be automatically resolved - by LLVM. - ''' - for lfunc in self.module.functions: - if lfunc.linkage == lc.LINKAGE_EXTERNAL: - mangled = '__llrt_' + lfunc.name - self.installed_symbols.add(mangled) - ptr = self.engine.get_pointer_to_function(lfunc) - le.dylib_add_symbol(mangled, ptr) - - def uninstall_symbols(self): - for sym in self.installed_symbols: - le.dylib_add_symbol(sym, 0) - - diff --git a/llvm/llrt/llrt_x86.ll b/llvm/llrt/llrt_x86.ll deleted file mode 100644 index 5096214..0000000 --- a/llvm/llrt/llrt_x86.ll +++ /dev/null @@ -1,371 +0,0 @@ -; ModuleID = 'udivmod64_x86.bc' -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128" - -%struct.div_state_ = type { i64, i64 } - -define i64 @udivmod64(i64 %dividend, i64 %divisor, i64* %remainder) nounwind ssp { - %1 = alloca i64, align 4 - %2 = alloca i64, align 8 - %3 = alloca i64, align 8 - %4 = alloca i64*, align 4 - %state = alloca %struct.div_state_, align 4 - %quotient = alloca i64, align 8 - %i = alloca i32, align 4 - %skipahead = alloca i32, align 4 - store i64 %dividend, i64* %2, align 8 - store i64 %divisor, i64* %3, align 8 - store i64* %remainder, i64** %4, align 4 - %5 = getelementptr inbounds %struct.div_state_* %state, i32 0, i32 0 - store i64 0, i64* %5, align 4 - %6 = getelementptr inbounds %struct.div_state_* %state, i32 0, i32 1 - %7 = load i64* %2, align 8 - store i64 %7, i64* %6, align 4 - store i64 0, i64* %quotient, align 8 - %8 = load i64* %3, align 8 - %9 = icmp eq i64 %8, 0 - br i1 %9, label %10, label %11 - -;