diff --git a/CHANGELOG b/CHANGELOG index 45d6a5f..5af6169 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,40 +1,3 @@ -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 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..0fbcd24 100644 --- a/README.rst +++ b/README.rst @@ -30,13 +30,10 @@ Quickstart 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. +3. Run ``REQUIRES_RTTI=1 make`` to build. **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:: 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/source/index.rst b/docs/source/index.rst index fbf5c8b..7798b77 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..acd5a41 100644 --- a/llpython/byte_control.py +++ b/llpython/byte_control.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import opcode diff --git a/llpython/byte_flow.py b/llpython/byte_flow.py index 197c839..2201791 100644 --- a/llpython/byte_flow.py +++ b/llpython/byte_flow.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import dis diff --git a/llpython/byte_translator.py b/llpython/byte_translator.py index a6e5864..9b6d2de 100644 --- a/llpython/byte_translator.py +++ b/llpython/byte_translator.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ '''Defines a bytecode based LLVM translator for llpython code. ''' diff --git a/llpython/bytecode_visitor.py b/llpython/bytecode_visitor.py index 3fa3f48..009d1a0 100644 --- a/llpython/bytecode_visitor.py +++ b/llpython/bytecode_visitor.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import itertools 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..b29bc56 100644 --- a/llpython/gen_bytecode_visitor.py +++ b/llpython/gen_bytecode_visitor.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import from . import opcode_util diff --git a/llpython/nobitey.py b/llpython/nobitey.py index 4236d29..68bde5f 100644 --- a/llpython/nobitey.py +++ b/llpython/nobitey.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from __future__ import absolute_import import sys diff --git a/llpython/opcode_util.py b/llpython/opcode_util.py index 7a1972b..efd0c5c 100644 --- a/llpython/opcode_util.py +++ b/llpython/opcode_util.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ import dis diff --git a/llpython/phi_injector.py b/llpython/phi_injector.py index dfa1061..ee28ab5 100644 --- a/llpython/phi_injector.py +++ b/llpython/phi_injector.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python # ______________________________________________________________________ from .bytecode_visitor import BytecodeFlowVisitor, BenignBytecodeVisitorMixin 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..05fc94f 100644 --- a/llvm-config-win32.py +++ b/llvm-config-win32.py @@ -2,7 +2,6 @@ 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 @@ -40,17 +39,55 @@ def libs_options(): # NOTE: instead of actually looking at the components requested, # we just print 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 +LLVMX86Disassembler +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) + if isfile(join(find_llvm_prefix(), 'lib', 'LLVMPTXCodeGen.lib')): + print('-lLLVMPTXAsmPrinter') + print('-lLLVMPTXCodeGen') + print('-lLLVMPTXDesc') + print('-lLLVMPTXInfo') + + elif isfile(join(find_llvm_prefix(), 'lib', 'LLVMNVPTXCodeGen.lib')): + print('-lLLVMNVPTXAsmPrinter') + print('-lLLVMNVPTXCodeGen') + print('-lLLVMNVPTXDesc') + print('-lLLVMNVPTXInfo') + def main(): try: @@ -61,15 +98,12 @@ def main(): 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')) + ensure_file(join(incdir, 'llvm' , 'BasicBlock.h')) print(incdir) elif option == '--libdir': diff --git a/llvm/__init__.py b/llvm/__init__.py index 9b24112..8f71446 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -4,13 +4,10 @@ del get_versions from llvmpy import extra - version = extra.get_llvm_version() del extra class Wrapper(object): - __slots__ = '__ptr' - def __init__(self, ptr): assert ptr self.__ptr = ptr @@ -34,14 +31,14 @@ def _extract_ptrs(objs): class LLVMException(Exception): pass -def test(verbosity=3, run_isolated=True): +def test(verbosity=1): """test(verbosity=1) -> TextTestResult Run self-test, and return the number of failures + errors """ - from llvm.tests import run + from llvm.test_llvmpy import run - result = run(verbosity=verbosity, run_isolated=run_isolated) - errct = len(result.failures) + len(result.errors) + result = run(verbosity=verbosity) + + return len(result.failures) + len(result.errors) - return errct diff --git a/llvm/core.py b/llvm/core.py index 4db8135..478728b 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -41,203 +41,150 @@ import contextlib, weakref 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_VOID = api.llvm.Type.TypeID.VoidTyID +TYPE_HALF = api.llvm.Type.TypeID.HalfTyID +TYPE_FLOAT = api.llvm.Type.TypeID.FloatTyID +TYPE_DOUBLE = api.llvm.Type.TypeID.DoubleTyID +TYPE_X86_FP80 = api.llvm.Type.TypeID.X86_FP80TyID +TYPE_FP128 = api.llvm.Type.TypeID.FP128TyID +TYPE_PPC_FP128 = api.llvm.Type.TypeID.PPC_FP128TyID +TYPE_LABEL = api.llvm.Type.TypeID.LabelTyID +TYPE_INTEGER = api.llvm.Type.TypeID.IntegerTyID +TYPE_FUNCTION = api.llvm.Type.TypeID.FunctionTyID +TYPE_STRUCT = api.llvm.Type.TypeID.StructTyID +TYPE_ARRAY = api.llvm.Type.TypeID.ArrayTyID +TYPE_POINTER = api.llvm.Type.TypeID.PointerTyID +TYPE_VECTOR = api.llvm.Type.TypeID.VectorTyID +TYPE_METADATA = api.llvm.Type.TypeID.MetadataTyID +TYPE_X86_MMX = api.llvm.Type.TypeID.X86_MMXTyID # 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 = api.llvm.Value.ValueTy.ArgumentVal +VALUE_BASIC_BLOCK = api.llvm.Value.ValueTy.BasicBlockVal +VALUE_FUNCTION = api.llvm.Value.ValueTy.FunctionVal +VALUE_GLOBAL_ALIAS = api.llvm.Value.ValueTy.GlobalAliasVal +VALUE_GLOBAL_VARIABLE = api.llvm.Value.ValueTy.GlobalVariableVal +VALUE_UNDEF_VALUE = api.llvm.Value.ValueTy.UndefValueVal +VALUE_BLOCK_ADDRESS = api.llvm.Value.ValueTy.BlockAddressVal +VALUE_CONSTANT_EXPR = api.llvm.Value.ValueTy.ConstantExprVal +VALUE_CONSTANT_AGGREGATE_ZERO = api.llvm.Value.ValueTy.ConstantAggregateZeroVal +VALUE_CONSTANT_DATA_ARRAY = api.llvm.Value.ValueTy.ConstantDataArrayVal +VALUE_CONSTANT_DATA_VECTOR = api.llvm.Value.ValueTy.ConstantDataVectorVal +VALUE_CONSTANT_INT = api.llvm.Value.ValueTy.ConstantIntVal +VALUE_CONSTANT_FP = api.llvm.Value.ValueTy.ConstantFPVal +VALUE_CONSTANT_ARRAY = api.llvm.Value.ValueTy.ConstantArrayVal +VALUE_CONSTANT_STRUCT = api.llvm.Value.ValueTy.ConstantStructVal +VALUE_CONSTANT_VECTOR = api.llvm.Value.ValueTy.ConstantVectorVal +VALUE_CONSTANT_POINTER_NULL = api.llvm.Value.ValueTy.ConstantPointerNullVal +VALUE_MD_NODE = api.llvm.Value.ValueTy.MDNodeVal +VALUE_MD_STRING = api.llvm.Value.ValueTy.MDStringVal +VALUE_INLINE_ASM = api.llvm.Value.ValueTy.InlineAsmVal +VALUE_PSEUDO_SOURCE_VALUE = api.llvm.Value.ValueTy.PseudoSourceValueVal +VALUE_FIXED_STACK_PSEUDO_SOURCE_VALUE = api.llvm.Value.ValueTy.FixedStackPseudoSourceValueVal +VALUE_INSTRUCTION = api.llvm.Value.ValueTy.InstructionVal # 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 = api.llvm.CallingConv.ID.C +CC_FASTCALL = api.llvm.CallingConv.ID.Fast +CC_COLDCALL = api.llvm.CallingConv.ID.Cold +CC_GHC = api.llvm.CallingConv.ID.GHC +CC_X86_STDCALL = api.llvm.CallingConv.ID.X86_StdCall +CC_X86_FASTCALL = api.llvm.CallingConv.ID.X86_FastCall +CC_ARM_APCS = api.llvm.CallingConv.ID.ARM_APCS +CC_ARM_AAPCS = api.llvm.CallingConv.ID.ARM_AAPCS +CC_ARM_AAPCS_VFP = api.llvm.CallingConv.ID.ARM_AAPCS_VFP +CC_MSP430_INTR = api.llvm.CallingConv.ID.MSP430_INTR +CC_X86_THISCALL = api.llvm.CallingConv.ID.X86_ThisCall +CC_PTX_KERNEL = api.llvm.CallingConv.ID.PTX_Kernel +CC_PTX_DEVICE = api.llvm.CallingConv.ID.PTX_Device +CC_MBLAZE_INTR = api.llvm.CallingConv.ID.MBLAZE_INTR +CC_MBLAZE_SVOL = api.llvm.CallingConv.ID.MBLAZE_SVOL -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 = api.llvm.CmpInst.Predicate.ICMP_EQ +ICMP_NE = api.llvm.CmpInst.Predicate.ICMP_NE +ICMP_UGT = api.llvm.CmpInst.Predicate.ICMP_UGT +ICMP_UGE = api.llvm.CmpInst.Predicate.ICMP_UGE +ICMP_ULT = api.llvm.CmpInst.Predicate.ICMP_ULT +ICMP_ULE = api.llvm.CmpInst.Predicate.ICMP_ULE +ICMP_SGT = api.llvm.CmpInst.Predicate.ICMP_SGT +ICMP_SGE = api.llvm.CmpInst.Predicate.ICMP_SGE +ICMP_SLT = api.llvm.CmpInst.Predicate.ICMP_SLT +ICMP_SLE = api.llvm.CmpInst.Predicate.ICMP_SLE - 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 +197,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 = api.llvm.CmpInst.Predicate.FCMP_FALSE +FCMP_OEQ = api.llvm.CmpInst.Predicate.FCMP_OEQ +FCMP_OGT = api.llvm.CmpInst.Predicate.FCMP_OGT +FCMP_OGE = api.llvm.CmpInst.Predicate.FCMP_OGE +FCMP_OLT = api.llvm.CmpInst.Predicate.FCMP_OLT +FCMP_OLE = api.llvm.CmpInst.Predicate.FCMP_OLE +FCMP_ONE = api.llvm.CmpInst.Predicate.FCMP_ONE +FCMP_ORD = api.llvm.CmpInst.Predicate.FCMP_ORD +FCMP_UNO = api.llvm.CmpInst.Predicate.FCMP_UNO +FCMP_UEQ = api.llvm.CmpInst.Predicate.FCMP_UEQ +FCMP_UGT = api.llvm.CmpInst.Predicate.FCMP_UGT +FCMP_UGE = api.llvm.CmpInst.Predicate.FCMP_UGE +FCMP_ULT = api.llvm.CmpInst.Predicate.FCMP_ULT +FCMP_ULE = api.llvm.CmpInst.Predicate.FCMP_ULE +FCMP_UNE = api.llvm.CmpInst.Predicate.FCMP_UNE +FCMP_TRUE = api.llvm.CmpInst.Predicate.FCMP_TRUE # real predicates - RPRED_FALSE = FCMP_FALSE RPRED_OEQ = FCMP_OEQ RPRED_OGT = FCMP_OGT @@ -295,75 +233,68 @@ 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() +LINKAGE_EXTERNAL = \ + api.llvm.GlobalValue.LinkageTypes.ExternalLinkage +LINKAGE_AVAILABLE_EXTERNALLY = \ + api.llvm.GlobalValue.LinkageTypes.AvailableExternallyLinkage +LINKAGE_LINKONCE_ANY = \ + api.llvm.GlobalValue.LinkageTypes.LinkOnceAnyLinkage +LINKAGE_LINKONCE_ODR = \ + api.llvm.GlobalValue.LinkageTypes.LinkOnceODRLinkage +LINKAGE_WEAK_ANY = \ + api.llvm.GlobalValue.LinkageTypes.WeakAnyLinkage +LINKAGE_WEAK_ODR = \ + api.llvm.GlobalValue.LinkageTypes.WeakODRLinkage +LINKAGE_APPENDING = \ + api.llvm.GlobalValue.LinkageTypes.AppendingLinkage +LINKAGE_INTERNAL = \ + api.llvm.GlobalValue.LinkageTypes.InternalLinkage +LINKAGE_PRIVATE = \ + api.llvm.GlobalValue.LinkageTypes.PrivateLinkage +LINKAGE_DLLIMPORT = \ + api.llvm.GlobalValue.LinkageTypes.DLLImportLinkage +LINKAGE_DLLEXPORT = \ + api.llvm.GlobalValue.LinkageTypes.DLLExportLinkage +LINKAGE_EXTERNAL_WEAK = \ + api.llvm.GlobalValue.LinkageTypes.ExternalWeakLinkage +LINKAGE_COMMON = \ + api.llvm.GlobalValue.LinkageTypes.CommonLinkage +LINKAGE_LINKER_PRIVATE = \ + api.llvm.GlobalValue.LinkageTypes.LinkerPrivateLinkage +LINKAGE_LINKER_PRIVATE_WEAK = \ + api.llvm.GlobalValue.LinkageTypes.LinkerPrivateWeakLinkage # visibility (see llvm/GlobalValue.h) -class VisibilityEnum(Enum): - prefix = 'VISIBILITY_' +VISIBILITY_DEFAULT = api.llvm.GlobalValue.VisibilityTypes.DefaultVisibility +VISIBILITY_HIDDEN = api.llvm.GlobalValue.VisibilityTypes.HiddenVisibility +VISIBILITY_PROTECTED = api.llvm.GlobalValue.VisibilityTypes.ProtectedVisibility - VISIBILITY_DEFAULT = api.llvm.GlobalValue.VisibilityTypes.DefaultVisibility - VISIBILITY_HIDDEN = api.llvm.GlobalValue.VisibilityTypes.HiddenVisibility - VISIBILITY_PROTECTED = api.llvm.GlobalValue.VisibilityTypes.ProtectedVisibility +# parameter attributes llvm::Attributes::AttrVal (see llvm/Attributes.h) +ATTR_NONE = api.llvm.Attributes.AttrVal.None_ +ATTR_ZEXT = api.llvm.Attributes.AttrVal.ZExt +ATTR_SEXT = api.llvm.Attributes.AttrVal.SExt +ATTR_NO_RETURN = api.llvm.Attributes.AttrVal.NoReturn +ATTR_IN_REG = api.llvm.Attributes.AttrVal.InReg +ATTR_STRUCT_RET = api.llvm.Attributes.AttrVal.StructRet +ATTR_NO_UNWIND = api.llvm.Attributes.AttrVal.NoUnwind +ATTR_NO_ALIAS = api.llvm.Attributes.AttrVal.NoAlias +ATTR_BY_VAL = api.llvm.Attributes.AttrVal.ByVal +ATTR_NEST = api.llvm.Attributes.AttrVal.Nest +ATTR_READ_NONE = api.llvm.Attributes.AttrVal.ReadNone +ATTR_READONLY = api.llvm.Attributes.AttrVal.ReadOnly +ATTR_NO_INLINE = api.llvm.Attributes.AttrVal.NoInline +ATTR_ALWAYS_INLINE = api.llvm.Attributes.AttrVal.AlwaysInline +ATTR_OPTIMIZE_FOR_SIZE = api.llvm.Attributes.AttrVal.OptimizeForSize +ATTR_STACK_PROTECT = api.llvm.Attributes.AttrVal.StackProtect +ATTR_STACK_PROTECT_REQ = api.llvm.Attributes.AttrVal.StackProtectReq +ATTR_ALIGNMENT = api.llvm.Attributes.AttrVal.Alignment +ATTR_NO_CAPTURE = api.llvm.Attributes.AttrVal.NoCapture +ATTR_NO_REDZONE = api.llvm.Attributes.AttrVal.NoRedZone +ATTR_NO_IMPLICIT_FLOAT = api.llvm.Attributes.AttrVal.NoImplicitFloat +ATTR_NAKED = api.llvm.Attributes.AttrVal.Naked +ATTR_INLINE_HINT = api.llvm.Attributes.AttrVal.InlineHint +ATTR_STACK_ALIGNMENT = api.llvm.Attributes.AttrVal.StackAlignment -VisibilityEnum.declare() - -# 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 - else: - AttrVal = api.llvm.Attributes.AttrVal - - 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() class Module(llvm.Wrapper): """A Module instance stores all the information related to an LLVM module. @@ -379,7 +310,6 @@ class Module(llvm.Wrapper): module_obj = Module.new('my_module') """ - __slots__ = '__weakref__' __cache = weakref.WeakValueDictionary() def __new__(cls, ptr): @@ -452,12 +382,12 @@ class Module(llvm.Wrapper): """ return str(self._ptr) - def __hash__(self): - return id(self._ptr) - def __eq__(self, rhs): + assert isinstance(rhs, Module), type(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) @@ -513,7 +443,7 @@ class Module(llvm.Wrapper): mode, errmsg) if failed: - raise llvm.LLVMException(errmsg.getvalue()) + raise llvm.LLVMException(errmsg) def get_type_named(self, name): typ = self._ptr.getTypeByName(name) @@ -605,7 +535,7 @@ class Module(llvm.Wrapper): ret = False if fileobj is None: ret = True - fileobj = BytesIO() + fileobj = BytesIO api.llvm.WriteBitcodeToFile(self._ptr, fileobj) if ret: return fileobj.getvalue() @@ -689,7 +619,6 @@ class Type(llvm.Wrapper): Use one of the static methods to create an instance. Example: ty = Type.double() """ - __slots__ = '__name__' _type_ = api.llvm.Type def __init__(self, ptr): @@ -871,9 +800,6 @@ class Type(llvm.Wrapper): def __str__(self): return str(self._ptr) - def __hash__(self): - return hash(self._ptr) - def __eq__(self, rhs): return self._ptr is rhs._ptr @@ -882,7 +808,6 @@ class Type(llvm.Wrapper): class IntegerType(Type): """Represents an integer type.""" - __slots__ = () _type_ = api.llvm.IntegerType @property @@ -892,7 +817,6 @@ class IntegerType(Type): class FunctionType(Type): """Represents a function type.""" - __slots__ = () _type_ = api.llvm.FunctionType @property @@ -922,7 +846,6 @@ class FunctionType(Type): class StructType(Type): """Represents a structure type.""" _type_ = api.llvm.StructType - __slots__ = () @property def element_count(self): @@ -956,10 +879,7 @@ class StructType(Type): self._ptr.setName(name) def _get_name(self): - if self._ptr.isLiteral(): - return "" - else: - return self._ptr.getName() + return self._ptr.getName() name = property(_get_name, _set_name) @@ -978,10 +898,10 @@ class StructType(Type): def is_layout_identical(self, other): return self._ptr.isLayoutIdentical(other._ptr) + class ArrayType(Type): """Represents an array type.""" _type_ = api.llvm.ArrayType - __slots__ = () @property def element(self): @@ -993,7 +913,6 @@ class ArrayType(Type): class PointerType(Type): _type_ = api.llvm.PointerType - __slots__ = () @property def pointee(self): @@ -1005,7 +924,6 @@ class PointerType(Type): class VectorType(Type): _type_ = api.llvm.VectorType - __slots__ = () @property def element(self): @@ -1017,7 +935,6 @@ class VectorType(Type): class Value(llvm.Wrapper): _type_ = api.llvm.Value - __slots__ = '__weakref__' def __init__(self, builder, ptr): assert builder is _ValueFactory @@ -1048,9 +965,6 @@ class Value(llvm.Wrapper): def __str__(self): return str(self._ptr) - def __hash__(self): - return hash(self._ptr) - def __eq__(self, rhs): if isinstance(rhs, Value): return str(self) == str(rhs) @@ -1086,7 +1000,6 @@ class Value(llvm.Wrapper): class User(Value): _type_ = api.llvm.User - __slots__ = () @property def operand_count(self): @@ -1101,7 +1014,6 @@ class User(Value): class Constant(User): _type_ = api.llvm.Constant - __slots__ = () @staticmethod def null(ty): @@ -1287,7 +1199,6 @@ class Constant(User): class ConstantExpr(Constant): _type_ = api.llvm.ConstantExpr - __slots__ = () @property def opcode(self): @@ -1298,20 +1209,19 @@ class ConstantExpr(Constant): return self._ptr.getOpcodeName() 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): @@ -1327,32 +1237,30 @@ class ConstantInt(Constant): 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 _get_linkage(self): return self._ptr.getLinkage() @@ -1398,7 +1306,6 @@ class GlobalValue(Constant): class GlobalVariable(GlobalValue): _type_ = api.llvm.GlobalVariable - __slots__ = () @staticmethod def new(module, ty, name, addrspace=0): @@ -1459,60 +1366,28 @@ class GlobalVariable(GlobalValue): 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): + 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 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): + context = api.llvm.getGlobalContext() + attrbldr = api.llvm.AttrBuilder.new() + attrbldr.addAlignmentAttr(align) + attrs = api.llvm.Attributes.get(context, attrbldr) + self._ptr.addAttr(attrs) def _get_alignment(self): return self._ptr.getParamAlignment() @@ -1520,47 +1395,7 @@ class Argument(Value): 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 @@ -1670,10 +1505,7 @@ class Function(GlobalValue): 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) + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.removeFnAttr(attrs) def viewCFGOnly(self): @@ -1699,7 +1531,6 @@ class Function(GlobalValue): #===----------------------------------------------------------------------=== class InlineAsm(Value): - __slots__ = () _type_ = api.llvm.InlineAsm @staticmethod @@ -1714,7 +1545,6 @@ class InlineAsm(Value): #===----------------------------------------------------------------------=== class MetaData(Value): - __slots__ = () _type_ = api.llvm.MDNode @staticmethod @@ -1771,7 +1601,6 @@ class MetaDataString(Value): class NamedMetaData(llvm.Wrapper): - __slots__ = () @staticmethod def get_or_insert(mod, name): @@ -1801,7 +1630,6 @@ class NamedMetaData(llvm.Wrapper): #===----------------------------------------------------------------------=== class Instruction(User): - __slots__ = () _type_ = api.llvm.Instruction @property @@ -1878,12 +1706,8 @@ class Instruction(User): def erase_from_parent(self): return self._ptr.eraseFromParent() - def replace_all_uses_with(self, inst): - self._ptr.replaceAllUsesWith(inst) - class CallOrInvokeInstruction(Instruction): - __slots__ = () _type_ = api.llvm.CallInst, api.llvm.InvokeInst def _get_cc(self): @@ -1898,33 +1722,21 @@ class CallOrInvokeInstruction(Instruction): 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) - + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.addAttribute(idx, attrs) 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) - + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.removeAttribute(idx, attrs) 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) - + attrs = api.llvm.Attributes.get(context, attrbldr) self._ptr.addAttribute(idx, attrs) def _get_called_function(self): @@ -1939,7 +1751,6 @@ class CallOrInvokeInstruction(Instruction): class PHINode(Instruction): - __slots__ = () _type_ = api.llvm.PHINode @property @@ -1957,60 +1768,21 @@ class PHINode(Instruction): class SwitchInstruction(Instruction): - __slots__ = () - _type_ = api.llvm.SwitchInst def add_case(self, const, bblk): self._ptr.addCase(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) - - -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() - + return self._ptr.getPredicate() #===----------------------------------------------------------------------=== # Basic block #===----------------------------------------------------------------------=== class BasicBlock(Value): - __slots__ = () _type_ = api.llvm.BasicBlock def insert_before(self, name): @@ -2037,7 +1809,6 @@ class BasicBlock(Value): class _ValueFactory(object): - __slots__ = () cache = weakref.WeakValueDictionary() # value ID -> class map @@ -2066,8 +1837,7 @@ class _ValueFactory(object): 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, + VALUE_INSTRUCTION + OPCODE_FCMP : CompareInstruction } @classmethod @@ -2114,7 +1884,6 @@ _atomic_orderings = { } class Builder(llvm.Wrapper): - __slots__ = () @staticmethod def new(basic_block): @@ -2205,34 +1974,29 @@ class Builder(llvm.Wrapper): # 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=""): + return _make_value(self._ptr.CreateAdd(lhs._ptr, rhs._ptr, name)) def fadd(self, lhs, rhs, name=""): return _make_value(self._ptr.CreateFAdd(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=""): + return _make_value(self._ptr.CreateSub(lhs._ptr, rhs._ptr, name)) def fsub(self, lhs, rhs, name=""): return _make_value(self._ptr.CreateFSub(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=""): + return _make_value(self._ptr.CreateMul(lhs._ptr, rhs._ptr, name)) def fmul(self, lhs, rhs, name=""): return _make_value(self._ptr.CreateFMul(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=""): + return _make_value(self._ptr.CreateUDiv(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=""): + return _make_value(self._ptr.CreateSDiv(lhs._ptr, rhs._ptr, name)) def fdiv(self, lhs, rhs, name=""): return _make_value(self._ptr.CreateFDiv(lhs._ptr, rhs._ptr, name)) @@ -2246,17 +2010,14 @@ class Builder(llvm.Wrapper): def frem(self, lhs, rhs, name=""): return _make_value(self._ptr.CreateFRem(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=""): + return _make_value(self._ptr.CreateShl(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=""): + return _make_value(self._ptr.CreateLShr(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=""): + return _make_value(self._ptr.CreateAShr(lhs._ptr, rhs._ptr, name)) def and_(self, lhs, rhs, name=""): return _make_value(self._ptr.CreateAnd(lhs._ptr, rhs._ptr, name)) @@ -2267,8 +2028,8 @@ class Builder(llvm.Wrapper): def xor(self, lhs, rhs, name=""): return _make_value(self._ptr.CreateXor(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=""): + return _make_value(self._ptr.CreateNeg(val._ptr, name)) def not_(self, val, name=""): return _make_value(self._ptr.CreateNot(val._ptr, name)) @@ -2276,6 +2037,7 @@ class Builder(llvm.Wrapper): # memory def malloc(self, ty, name=""): + context = api.llvm.getGlobalContext() allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) ity = allocsz.getType() malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, @@ -2289,6 +2051,7 @@ class Builder(llvm.Wrapper): return _make_value(inst) def malloc_array(self, ty, size, name=""): + context = api.llvm.getGlobalContext() allocsz = api.llvm.ConstantExpr.getSizeOf(ty._ptr) ity = allocsz.getType() malloc = api.llvm.CallInst.CreateMalloc(self.basic_block._ptr, @@ -2301,13 +2064,12 @@ class Builder(llvm.Wrapper): inst = self._ptr.Insert(malloc, name) return _make_value(inst) - 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=""): + intty = Type.int() + return _make_value(self._ptr.CreateAlloca(ty._ptr, None, name)) - @deprecated def alloca_array(self, ty, size, name=""): - return self.alloca(ty, size, name=name) + return _make_value(self._ptr.CreateAlloca(ty._ptr, size._ptr, name)) def free(self, ptr): free = api.llvm.CallInst.CreateFree(ptr._ptr, self.basic_block._ptr) @@ -2394,20 +2156,15 @@ class Builder(llvm.Wrapper): # 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)) + return _make_value(self._ptr.CreateExtractValue(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, + [idx], name)) def phi(self, ty, name=""): @@ -2547,8 +2304,4 @@ if api.llvm.InitializeNativeTargetAsmPrinter(): # 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!?") + 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..e4ee4bc 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -30,23 +30,33 @@ "Execution Engine and related classes." -import sys +from io import BytesIO +import contextlib import llvm from llvm import core from llvm.passes import TargetData, TargetTransformInfo from llvmpy import api, extra - #===----------------------------------------------------------------------=== -# 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 = api.llvm.CodeModel.Model.Default +CM_JITDEFAULT = api.llvm.CodeModel.Model.JITDefault +CM_SMALL = api.llvm.CodeModel.Model.Small +CM_KERNEL = api.llvm.CodeModel.Model.Kernel +CM_MEDIUM = api.llvm.CodeModel.Model.Medium +CM_LARGE = api.llvm.CodeModel.Model.Large + +# Reloc +RELOC_DEFAULT = api.llvm.Reloc.Model.Default +RELOC_STATIC = api.llvm.Reloc.Model.Static +RELOC_PIC = api.llvm.Reloc.Model.PIC_ +RELOC_DYNAMIC_NO_PIC = api.llvm.Reloc.Model.DynamicNoPIC #===----------------------------------------------------------------------=== # Generic value @@ -140,17 +150,9 @@ class EngineBuilder(llvm.Wrapper): ''' 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 + return ExecutionEngine(engine) def select_target(self, *args): '''get the corresponding target machine @@ -165,12 +167,6 @@ class EngineBuilder(llvm.Wrapper): ptr = self._ptr.selectTarget() return TargetMachine(ptr) - def mcjit(self, enable): - '''Enable/disable MCJIT - ''' - self._ptr.setUseMCJIT(enable) - self._use_mcjit = True - return self #===----------------------------------------------------------------------=== # Execution engine @@ -192,9 +188,6 @@ class ExecutionEngine(llvm.Wrapper): 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) - def get_pointer_to_function(self, fn): return self._ptr.getPointerToFunction(fn._ptr) @@ -220,45 +213,151 @@ class ExecutionEngine(llvm.Wrapper): def remove_module(self, module): return self._ptr.removeModule(module._ptr) - def finalize_object(self): - return self._ptr.finalizeObject() - @property def target_data(self): ptr = self._ptr.getDataLayout() return TargetData(ptr) - #===----------------------------------------------------------------------=== -# Dynamic Library +# Target machine #===----------------------------------------------------------------------=== -def dylib_add_symbol(name, ptr): - api.llvm.sys.DynamicLibrary.AddSymbol(name, ptr) - -def dylib_address_of_symbol(name): - return api.llvm.sys.DynamicLibrary.SearchForAddressOfSymbol(name) - -def dylib_import_library(filename): - """Permanently import a dynamic library. - - Returns a DynamicLibrary object - - Raises RuntimeError +def initialize_target(target, noraise=False): + """Initialize target by name. + It is safe to initialize the same target multiple times. """ - return DynamicLibrary(filename) + prefix = 'LLVMInitialize' + postfixes = ['Target', 'TargetInfo', 'TargetMC', 'AsmPrinter'] + try: + for postfix in postfixes: + getattr(api, '%s%s%s' % (prefix, target, postfix))() + except AttributeError: + if noraise: + return False + else: + raise + else: + return True -class DynamicLibrary(object): - def __init__(self, filename): - """ - Raises RuntimeError - """ - self._ptr = api.llvm.sys.DynamicLibrary.getPermanentLibrary( - filename) +def print_registered_targets(): + ''' + Note: print directly to stdout + ''' + api.llvm.TargetRegistry.printRegisteredTargetsForVersion() + +def get_host_cpu_name(): + '''return the string name of the host CPU + ''' + return api.llvm.sys.getHostCPUName() + +def get_default_triple(): + '''return the target triple of the host in str-rep + ''' + return api.llvm.sys.getDefaultTargetTriple() + + +class TargetMachine(llvm.Wrapper): + + @staticmethod + def new(triple='', cpu='', features='', opt=2, cm=CM_DEFAULT, + reloc=RELOC_DEFAULT): + if not triple: + triple = get_default_triple() + if not cpu: + cpu = get_host_cpu_name() + with contextlib.closing(BytesIO()) as error: + target = api.llvm.TargetRegistry.lookupTarget(triple, error) + if not target: + raise llvm.LLVMException(error) + if not target.hasTargetMachine(): + raise llvm.LLVMException(target, "No target machine.") + target_options = api.llvm.TargetOptions.new() + tm = target.createTargetMachine(triple, cpu, features, + target_options, + reloc, cm, opt) + if not tm: + raise llvm.LLVMException("Cannot create target machine") + return TargetMachine(tm) + + @staticmethod + def lookup(arch, cpu='', features='', opt=2, cm=CM_DEFAULT, + reloc=RELOC_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` + ''' + triple = api.llvm.Triple.new() + with contextlib.closing(BytesIO()) as error: + target = api.llvm.TargetRegistry.lookupTarget(arch, triple, error) + if not target: + raise llvm.LLVMException(error.getvalue()) + if not target.hasTargetMachine(): + raise llvm.LLVMException(target, "No target machine.") + target_options = api.llvm.TargetOptions.new() + tm = target.createTargetMachine(str(triple), cpu, features, + target_options, + reloc, cm, opt) + if not tm: + raise llvm.LLVMException("Cannot create target machine") + return TargetMachine(tm) + + def _emit_file(self, module, cgft): + pm = api.llvm.PassManager.new() + os = extra.make_raw_ostream_for_printing() + pm.add(api.llvm.DataLayout.new(str(self.target_data))) + failed = self._ptr.addPassesToEmitFile(pm, os, cgft) + pm.run(module) + + + CGFT = api.llvm.TargetMachine.CodeGenFileType + if cgft == CGFT.CGFT_ObjectFile: + return os.bytes() + else: + return os.str() + + def emit_assembly(self, module): + '''returns byte string of the module as assembly code of the target machine + ''' + CGFT = api.llvm.TargetMachine.CodeGenFileType + return self._emit_file(module._ptr, CGFT.CGFT_AssemblyFile) + + def emit_object(self, module): + '''returns byte string of the module as native code of the target machine + ''' + CGFT = api.llvm.TargetMachine.CodeGenFileType + return self._emit_file(module._ptr, CGFT.CGFT_ObjectFile) + + @property + def target_data(self): + '''get target data of this machine + ''' + return TargetData(self._ptr.getDataLayout()) + + @property + def target_name(self): + return self._ptr.getTarget().getName() + + @property + def target_short_description(self): + return self._ptr.getTarget().getShortDescription() + + @property + def triple(self): + return self._ptr.getTargetTriple() + + @property + def cpu(self): + return self._ptr.getTargetCPU() + + @property + def feature_string(self): + return self._ptr.getTargetFeatureString() - def get_address_of_symbol(self, symbol): - """ - Get the address of `symbol` (str) as integer - """ - return self._ptr.getAddressOfSymbol(symbol) 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 - -;