From 7adecd8f5dc3861bd1c6f8b9d412b866fe8473db Mon Sep 17 00:00:00 2001 From: "Travis E. Oliphant" Date: Sun, 11 Nov 2012 01:43:47 -0600 Subject: [PATCH 001/414] master is now 0.9.1 --- llvm/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/__init__.py b/llvm/__init__.py index 1145d74..c800500 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -2,7 +2,7 @@ Common classes related to LLVM. """ -__version__ = '0.9' +__version__ = '0.9.1' from weakref import WeakValueDictionary From 52d7b8b6f5857fa994d1bea61a65a0775c71f421 Mon Sep 17 00:00:00 2001 From: Maggie Mari Date: Fri, 24 Aug 2012 16:02:38 -0500 Subject: [PATCH 002/414] Adding reference pages to toctree. --- docs/source/doc/core.rst | 9 +++++++++ docs/source/doc/llvmcore.rst | 9 +++++++++ docs/source/doc/llvmee.rst | 9 +++++++++ docs/source/doc/llvmpasses.rst | 9 +++++++++ docs/source/index.rst | 3 +++ 5 files changed, 39 insertions(+) create mode 100644 docs/source/doc/core.rst create mode 100644 docs/source/doc/llvmcore.rst create mode 100644 docs/source/doc/llvmee.rst create mode 100644 docs/source/doc/llvmpasses.rst diff --git a/docs/source/doc/core.rst b/docs/source/doc/core.rst new file mode 100644 index 0000000..a3b94b6 --- /dev/null +++ b/docs/source/doc/core.rst @@ -0,0 +1,9 @@ +******************************** +llvm.core +******************************** + +.. toctree:: + :titlesonly: + :glob: + + llvm.core.* \ No newline at end of file diff --git a/docs/source/doc/llvmcore.rst b/docs/source/doc/llvmcore.rst new file mode 100644 index 0000000..a3b94b6 --- /dev/null +++ b/docs/source/doc/llvmcore.rst @@ -0,0 +1,9 @@ +******************************** +llvm.core +******************************** + +.. toctree:: + :titlesonly: + :glob: + + llvm.core.* \ No newline at end of file diff --git a/docs/source/doc/llvmee.rst b/docs/source/doc/llvmee.rst new file mode 100644 index 0000000..2145502 --- /dev/null +++ b/docs/source/doc/llvmee.rst @@ -0,0 +1,9 @@ +******************************** +llvm.ee +******************************** + +.. toctree:: + :titlesonly: + :glob: + + llvm.ee.* \ No newline at end of file diff --git a/docs/source/doc/llvmpasses.rst b/docs/source/doc/llvmpasses.rst new file mode 100644 index 0000000..0931467 --- /dev/null +++ b/docs/source/doc/llvmpasses.rst @@ -0,0 +1,9 @@ +******************************** +llvm.passes +******************************** + +.. toctree:: + :titlesonly: + :glob: + + llvm.passes.* \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index f8b8a31..9f86b32 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,6 +16,9 @@ Contents: doc/llvm_cbuilder.rst doc/llpython/index.rst doc/examples.rst + doc/llvmcore.rst + doc/llvmee.rst + doc/llvmpasses.rst Indices and tables From 425e382368a1aef491a7ea192b800058460a22e2 Mon Sep 17 00:00:00 2001 From: Maggie Mari Date: Mon, 12 Nov 2012 10:51:30 -0600 Subject: [PATCH 003/414] Fixed broken link in llvmpy docs. --- docs/source/doc/getting_started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/doc/getting_started.rst b/docs/source/doc/getting_started.rst index f13c616..f9b9c56 100644 --- a/docs/source/doc/getting_started.rst +++ b/docs/source/doc/getting_started.rst @@ -26,7 +26,7 @@ Both LLVM and llvmpy are distributed under (different) permissive open source licenses. llvmpy uses the `new BSD license `_. More information is available -`here `_. +`here `_. Platforms --------- From d491d91dd27849eac3bd070f2069fe25fa98e398 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Thu, 29 Nov 2012 12:36:54 -0600 Subject: [PATCH 004/414] Add TBAA Builder --- llvm/tbaa.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/tbaa.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 llvm/tbaa.py create mode 100644 test/tbaa.py diff --git a/llvm/tbaa.py b/llvm/tbaa.py new file mode 100644 index 0000000..d8e0074 --- /dev/null +++ b/llvm/tbaa.py @@ -0,0 +1,51 @@ +from llvm.core import * + +class TBAABuilder(object): + '''Simplify creation of TBAA metadata. + + Each TBAABuidler object operates on a module. + User can create multiple TBAABuilder on a module + ''' + + def __init__(self, module, rootid): + ''' + module --- the module to use. + root --- string name to identify the TBAA root. + ''' + self.__module = module + self.__rootid = rootid + self.__rootmd = self.__new_md(rootid) + + @classmethod + def new(cls, module, rootid): + return cls(module, rootid) + + def get_node(self, name, parent=None, const=False): + '''Returns a MetaData object representing a TBAA node. + + Use loadstore_instruction.set_metadata('tbaa', node) to + bind a type to a memory. + ''' + parent = parent or self.root + const = Constant.int(Type.int(), int(bool(const))) + return self.__new_md(name, parent, const) + + @property + def module(self): + return self.__module + + @property + def root(self): + return self.__rootmd + + @property + def root_name(self): + return self.__rootid + + def __new_md(self, *args): + contents = list(args) + for i, v in enumerate(contents): + if isinstance(v, str): + contents[i] = MetaDataString.get(self.module, v) + return MetaData.get(self.module, contents) + diff --git a/test/tbaa.py b/test/tbaa.py new file mode 100644 index 0000000..d775a53 --- /dev/null +++ b/test/tbaa.py @@ -0,0 +1,34 @@ +from llvm.core import * +from llvm.tbaa import * +import unittest + +class TestTBAABuilder(unittest.TestCase): + def test_tbaa_builder(self): + mod = Module.new('test_tbaa_builder') + fty = Type.function(Type.void(), [Type.pointer(Type.float())]) + foo = mod.add_function(fty, 'foo') + bb = foo.append_basic_block('entry') + bldr = Builder.new(bb) + + tbaa = TBAABuilder.new(mod, "tbaa.root") + float = tbaa.get_node('float', const=False) + const_float = tbaa.get_node('const float', float, const=True) + + + tbaa = TBAABuilder.new(mod, "tbaa.root") + old_const_float = const_float + del const_float + + const_float = tbaa.get_node('const float', float, const=True) + + self.assertIs(old_const_float, const_float) + + ptr = bldr.load(foo.args[0]) + ptr.set_metadata('tbaa', const_float) + + + bldr.ret_void() + print mod + +if __name__ == '__main__': + unittest.main() From f9376bf2d0d8c969eed58cec68b7b782b2642827 Mon Sep 17 00:00:00 2001 From: John Szakmeister Date: Fri, 30 Nov 2012 03:29:40 -0500 Subject: [PATCH 005/414] Fix an error in the full listing for the kaleidoscope lexer. --- docs/source/doc/kaleidoscope/PythonLangImpl2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl2.rst b/docs/source/doc/kaleidoscope/PythonLangImpl2.rst index 8c915db..d5d6efc 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl2.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl2.rst @@ -811,7 +811,7 @@ Lexer yield CharacterToken(string[0]) string = string[1:] - yield EOFToken() + yield EOFToken() From 7c7c198953b851711a99928303acd5165f2f6f30 Mon Sep 17 00:00:00 2001 From: John Szakmeister Date: Fri, 30 Nov 2012 04:01:04 -0500 Subject: [PATCH 006/414] Mark a block of code as text, and remove the python-isms. The kaleidoscope language being implemented looks similar to Python, but is not the same. --- docs/source/doc/kaleidoscope/PythonLangImpl1.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl1.rst b/docs/source/doc/kaleidoscope/PythonLangImpl1.rst index 7b1c3a6..90943c1 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl1.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl1.rst @@ -115,13 +115,13 @@ following simple example computes `Fibonacci numbers `_: -.. code-block:: python +.. code-block:: text # Compute the x'th fibonacci number. - def fib(x): - if x < 3: + def fib(x) + if x < 3 return 1 - else: + else return fib(x-1)+fib(x-2) # This expression will compute the 40th number. From 78f81fec73f69ec14cf894ebdb9c32b2b5aa2631 Mon Sep 17 00:00:00 2001 From: John Szakmeister Date: Fri, 30 Nov 2012 04:04:14 -0500 Subject: [PATCH 007/414] Fix the id matching in the kaleidoscope tutorial. --- docs/source/doc/kaleidoscope/PythonLangImpl1.rst | 2 +- docs/source/doc/kaleidoscope/PythonLangImpl2.rst | 2 +- docs/source/doc/kaleidoscope/PythonLangImpl6.rst | 2 +- docs/source/doc/kaleidoscope/PythonLangImpl7.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl1.rst b/docs/source/doc/kaleidoscope/PythonLangImpl1.rst index 90943c1..00b16fb 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl1.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl1.rst @@ -226,7 +226,7 @@ the line. # Regular expressions that tokens and comments of our language. REGEX_NUMBER = re.compile('[0-9]+(?:.[0-9]+)?') - REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9]\ *') + REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9]*') REGEX_COMMENT = re.compile('#.*') diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl2.rst b/docs/source/doc/kaleidoscope/PythonLangImpl2.rst index d5d6efc..a375512 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl2.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl2.rst @@ -772,7 +772,7 @@ Lexer # Regular expressions that tokens and comments of our language. REGEX_NUMBER = re.compile('[0-9]+(?:\.[0-9]+)?') - REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9] *') + REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9]*') REGEX_COMMENT = re.compile('#.*') def Tokenize(string): diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl6.rst b/docs/source/doc/kaleidoscope/PythonLangImpl6.rst index 2e98cef..8ff31d4 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl6.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl6.rst @@ -847,7 +847,7 @@ Lexer # Regular expressions that tokens and comments of our language. REGEX_NUMBER = re.compile('[0-9]+(?:\.[0-9]+)?') - REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9] *') + REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9]*') REGEX_COMMENT = re.compile('#.*') def Tokenize(string): diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl7.rst b/docs/source/doc/kaleidoscope/PythonLangImpl7.rst index d3dfb74..629608c 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl7.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl7.rst @@ -1000,7 +1000,7 @@ Lexer # Regular expressions that tokens and comments of our language. REGEX_NUMBER = re.compile('[0-9]+(?:\.[0-9]+)?') - REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9] *') + REGEX_IDENTIFIER = re.compile('[a-zA-Z][a-zA-Z0-9] *') REGEX_COMMENT = re.compile('#.*') def Tokenize(string): From b3a04c4a34213e29b27245c91ab2998a4bed407d Mon Sep 17 00:00:00 2001 From: John Szakmeister Date: Fri, 30 Nov 2012 04:45:30 -0500 Subject: [PATCH 008/414] Move the closing curly branch to line up with the rest of the code. --- docs/source/doc/kaleidoscope/PythonLangImpl3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/doc/kaleidoscope/PythonLangImpl3.rst b/docs/source/doc/kaleidoscope/PythonLangImpl3.rst index 5719bb2..15ec212 100644 --- a/docs/source/doc/kaleidoscope/PythonLangImpl3.rst +++ b/docs/source/doc/kaleidoscope/PythonLangImpl3.rst @@ -1058,7 +1058,7 @@ Main driver code. '+': 20, '-': 20, '*': 40 - } + } # Run the main "interpreter loop". while True: From 03e54f2c123a9618bdd4b9dc89478f047b952562 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Tue, 4 Dec 2012 13:50:16 -0600 Subject: [PATCH 009/414] Expose preserve flag for Module.link_in --- llvm/core.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/llvm/core.py b/llvm/core.py index b264b50..bfbab1c 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -450,7 +450,7 @@ class Module(llvm.Ownable, llvm.Cacheable): llvm::Module::AnyPointerSize.""" return _core.LLVMModuleGetPointerSize(self.ptr) - def link_in(self, other): + def link_in(self, other, preserve=False): """Link the `other' module into this one. The `other' module is linked into this one such that types, @@ -463,12 +463,12 @@ class Module(llvm.Ownable, llvm.Cacheable): Linker class. """ check_is_module(other) - other.forget() # remove it from object cache - ret = _core.LLVMLinkModules(self.ptr, other.ptr) - if isinstance(ret, str): - raise llvm.LLVMException(ret) - # Do not try to destroy the other module's llvm::Module*. - other._own(llvm.DummyOwner()) + if not preserve: + other.forget() # remove it from object cache + _core.LLVMLinkModules(self.ptr, other.ptr, int(bool(preserve))) + if not preserve: + # Do not try to destroy the other module's llvm::Module*. + other._own(llvm.DummyOwner()) def get_type_named(self, name): """Return a Type object with the given name.""" From 5c5f3015f729c339f7097784caae9cba0f7c2033 Mon Sep 17 00:00:00 2001 From: Alberto Valverde Date: Fri, 14 Dec 2012 23:54:49 +0100 Subject: [PATCH 010/414] exposed LLVMInstructionEraseFromParent --- llvm/_core.cpp | 2 ++ llvm/core.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/llvm/_core.cpp b/llvm/_core.cpp index 1b7ec09..75b50ed 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -761,6 +761,7 @@ _wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int) _wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef) _wrap_objstrobj2none(LLVMInstSetMetaData, LLVMValueRef, LLVMValueRef) +_wrap_obj2none(LLVMInstructionEraseFromParent, LLVMValueRef) /*===-- Call Sites (Call or Invoke) --------------------------------------===*/ @@ -1857,6 +1858,7 @@ static PyMethodDef core_methods[] = { _method( LLVMInstGetOpcodeName ) _method( LLVMInstSetMetaData ) + _method( LLVMInstructionEraseFromParent ) /* Call Sites (Call or Invoke) */ _method( LLVMSetInstructionCallConv ) diff --git a/llvm/core.py b/llvm/core.py index bfbab1c..6a7cc1d 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -1654,6 +1654,8 @@ class Instruction(User): def opcode_name(self): return _core.LLVMInstGetOpcodeName(self.ptr) + def erase_from_parent(self): + return _core.LLVMInstructionEraseFromParent(self.ptr) class CallOrInvokeInstruction(Instruction): From 436a12db03f1bbd196fd70383202b4d05fb135dc Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Thu, 13 Dec 2012 12:03:28 -0600 Subject: [PATCH 011/414] Add Stephen's llvm-cbuilder examples. --- README_LLVM_CBUILDER.md | 144 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 README_LLVM_CBUILDER.md diff --git a/README_LLVM_CBUILDER.md b/README_LLVM_CBUILDER.md new file mode 100644 index 0000000..da180c4 --- /dev/null +++ b/README_LLVM_CBUILDER.md @@ -0,0 +1,144 @@ +LLVM CBuilder +============= + +A few short examples: +(TODO: add more later) + +```python +from llvm.core import * +from llvm_cbuilder import * +import llvm_cbuilder.shortnames as C +``` + +```python +class Square(CDefinition): + _name_ = 'square' + _retty_ = C.double + _argtys_ = [ ('x', C.double) ] + + def body(self, x): + y = x * x + self.ret(y) +``` + +```python +m = Module.new('my_module') +llvm_square = Square()(m) +print(m) +``` + +``` +; ModuleID = 'my_module' + +define double @square(double %x) { +decl: + %0 = fmul double %x, %x + ret double %0 +} +``` + + +```python +class IsPrime(CDefinition): + _name_ = 'isprime' + _retty_ = C.int + _argtys_ = [('x', C.int)] + + def body(self, x): + false = zero = self.constant(C.int, 0) + true = one = self.constant(C.int, 1) + + two = self.constant(C.int, 2) + + with self.ifelse( x <= two ) as ifelse: + with ifelse.then(): + self.ret(true) + + with self.ifelse( (x % two) == zero ) as ifelse: + with ifelse.then(): + self.ret(false) + + idx = self.var(C.int, 3, name='idx') + + with self.loop() as loop: + with loop.condition() as setcond: + setcond( idx < x ) + + with loop.body(): + with self.ifelse( (x % idx ) == zero ) as ifelse: + with ifelse.then(): + self.ret(false) + idx += two + + self.ret(true) +``` + + + +``` +define i32 @isprime(i32 %x) { +decl: + %0 = icmp sle i32 %x, 2 + br i1 %0, label %if.then, label %if.end + +if.then: ; preds = %loop.body, %loop.cond, %if.end, %decl + %merge = phi i32 [ 1, %decl ], [ 0, %if.end ], [ 1, %loop.cond ], [ 0, %loop.body ] + ret i32 %merge + +if.end: ; preds = %decl + %1 = srem i32 %x, 2 + %2 = icmp eq i32 %1, 0 + br i1 %2, label %if.then, label %if.end4 + +if.end4: ; preds = %if.end + br label %loop.cond + +loop.cond: ; preds = %if.end7, %if.end4 + %idx.0 = phi i32 [ 3, %if.end4 ], [ %6, %if.end7 ] + %3 = icmp slt i32 %idx.0, %x + br i1 %3, label %loop.body, label %if.then + +loop.body: ; preds = %loop.cond + %4 = srem i32 %x, %idx.0 + %5 = icmp eq i32 %4, 0 + br i1 %5, label %if.then, label %if.end7 + +if.end7: ; preds = %loop.body + %6 = add i32 %idx.0, 2 + br label %loop.cond +} + +; ModuleID = 'my_module' + +define i32 @isprime(i32 %x) { +decl: + %0 = icmp sle i32 %x, 2 + br i1 %0, label %if.then, label %if.end + +if.then: ; preds = %loop.body, %loop.cond, %if.end, %decl + %merge = phi i32 [ 1, %decl ], [ 0, %if.end ], [ 1, %loop.cond ], [ 0, %loop.body ] + ret i32 %merge + +if.end: ; preds = %decl + %1 = srem i32 %x, 2 + %2 = icmp eq i32 %1, 0 + br i1 %2, label %if.then, label %if.end4 + +if.end4: ; preds = %if.end + br label %loop.cond + +loop.cond: ; preds = %if.end7, %if.end4 + %idx.0 = phi i32 [ 3, %if.end4 ], [ %6, %if.end7 ] + %3 = icmp slt i32 %idx.0, %x + br i1 %3, label %loop.body, label %if.then + +loop.body: ; preds = %loop.cond + %4 = srem i32 %x, %idx.0 + %5 = icmp eq i32 %4, 0 + br i1 %5, label %if.then, label %if.end7 + +if.end7: ; preds = %loop.body + %6 = add i32 %idx.0, 2 + br label %loop.cond +} +``` From f2e65c6c54debf2fa107ab7809e2523574c9926e Mon Sep 17 00:00:00 2001 From: Jon Riehl Date: Thu, 15 Nov 2012 12:13:50 -0600 Subject: [PATCH 012/414] Proposed fix for issue #31. --- llvm_cbuilder/shortnames.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/llvm_cbuilder/shortnames.py b/llvm_cbuilder/shortnames.py index 2acd69d..2d966d4 100644 --- a/llvm_cbuilder/shortnames.py +++ b/llvm_cbuilder/shortnames.py @@ -1,5 +1,3 @@ -from numba.minivect import minitypes -import numba.decorators from llvm.core import Type void = Type.void() @@ -13,8 +11,21 @@ int64 = Type.int(64) float = Type.float() double = Type.double() -npy_intp = minitypes.npy_intp.to_llvm(numba.decorators.context) -py_ssize_t = minitypes.Py_ssize_t.to_llvm(numba.decorators.context) +# platform dependent + +def _determine_sizes(): + import ctypes + # Makes following assumption: + # sizeof(py_ssize_t) == sizeof(ssize_t) == sizeof(size_t) + any_size_t = getattr(ctypes, 'c_ssize_t', ctypes.c_size_t) + return ctypes.sizeof(ctypes.c_void_p) * 8, ctypes.sizeof(any_ssize_t) * 8 + +pointer_size, _py_ssize_t_bits = _determine_pointer_size() + +intp = {32: int32, 64: int64}[pointer_size] + +npy_intp = Type.int(pointer_size) +py_ssize_t = Type.int(_py_ssize_t_bits) # pointers @@ -24,17 +35,6 @@ void_p = pointer(char) char_p = pointer(char) npy_intp_p = pointer(npy_intp) -# platform dependent - -def _determine_pointer_size(): - from ctypes import sizeof, c_void_p - return sizeof(c_void_p) * 8 - -pointer_size = _determine_pointer_size() - -intp = {32: int32, 64: int64}[pointer_size] - - # vector def vector(ty, ct): return Type.vector(ty, 4) From e2e6221f258a80890cd0a2f7ba57a12d7347b7b8 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Mon, 17 Dec 2012 14:24:05 -0600 Subject: [PATCH 013/414] Fix last commit --- llvm_cbuilder/shortnames.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm_cbuilder/shortnames.py b/llvm_cbuilder/shortnames.py index 2d966d4..44bb1ad 100644 --- a/llvm_cbuilder/shortnames.py +++ b/llvm_cbuilder/shortnames.py @@ -18,9 +18,9 @@ def _determine_sizes(): # Makes following assumption: # sizeof(py_ssize_t) == sizeof(ssize_t) == sizeof(size_t) any_size_t = getattr(ctypes, 'c_ssize_t', ctypes.c_size_t) - return ctypes.sizeof(ctypes.c_void_p) * 8, ctypes.sizeof(any_ssize_t) * 8 + return ctypes.sizeof(ctypes.c_void_p) * 8, ctypes.sizeof(any_size_t) * 8 -pointer_size, _py_ssize_t_bits = _determine_pointer_size() +pointer_size, _py_ssize_t_bits = _determine_sizes() intp = {32: int32, 64: int64}[pointer_size] From f3e9eb0b05d2db2ba28274a75e638945c27df2c8 Mon Sep 17 00:00:00 2001 From: xol Date: Mon, 24 Dec 2012 13:27:04 +0100 Subject: [PATCH 014/414] Fix for llvm 3.2 - TargetData -> DataLayout --- llvm/extra.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index b8545ea..04215ee 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -53,7 +53,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetData.h" +//#include "llvm/Target/TargetData.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Host.h" @@ -356,12 +356,12 @@ unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, PassManager pm; - if (!tm->getTargetData()){ + if (!tm->getDataLayout()){ error = "No target data in target machine"; return NULL; } - pm.add(new TargetData(*tm->getTargetData())); + pm.add(new DataLayout(*tm->getDataLayout())); bool failed; if( assembly ) { @@ -427,7 +427,7 @@ void LLVMPrintRegisteredTargetsForVersion(){ LLVMTargetDataRef LLVMTargetMachineGetTargetData(LLVMTargetMachineRef tm) { using namespace llvm; - return wrap(new TargetData(*unwrap(tm)->getTargetData())); + return wrap(new DataLayout(*unwrap(tm)->getDataLayout())); } unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, @@ -992,7 +992,8 @@ void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow) llvm::Function *fnp = llvm::unwrap(fn); assert(fnp); - return fnp->setDoesNotThrow((bool)DoesNotThrow); + if ((bool)DoesNotThrow) + fnp->setDoesNotThrow(); } From 5da98dac495df40e2712726b03564afeb10e99d1 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Thu, 27 Dec 2012 17:10:12 -0600 Subject: [PATCH 015/414] Add macros to enable support for llvm3.1. --- llvm/extra.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 04215ee..1b6d9fc 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -53,7 +53,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/FormattedStream.h" -//#include "llvm/Target/TargetData.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Host.h" @@ -75,8 +74,15 @@ #include "llvm/Linker.h" #include "llvm/Support/SourceMgr.h" #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" @@ -105,7 +111,7 @@ class PassRegistryPrinter : public llvm::PassRegistrationListener{ public: std::ostringstream stringstream; - void passEnumerate(const llvm::PassInfo * pass_info){ + inline virtual void passEnumerate(const llvm::PassInfo * pass_info){ stringstream << pass_info->getPassArgument() << "\t" << pass_info->getPassName() @@ -355,13 +361,21 @@ unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, 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 ) { @@ -427,7 +441,11 @@ void LLVMPrintRegisteredTargetsForVersion(){ 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, From d397f4c49757ec0e5c420418a0d9731b8bc46400 Mon Sep 17 00:00:00 2001 From: Ewan Higgs Date: Sun, 30 Dec 2012 21:08:38 +0000 Subject: [PATCH 016/414] Issue #34 - Add tools to MANIFEST.in --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index ec22b21..295794c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,3 +2,4 @@ include CHANGELOG LICENSE README setup.py MANIFEST.in recursive-include llvm * recursive-include www * recursive-include test * +recursive-include tools * From 10e83f306fef2e9294df08e1c2e0819a898f8dd2 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Thu, 27 Dec 2012 17:58:15 -0600 Subject: [PATCH 017/414] Add PassManagerBuilder.loop_vectorize property --- llvm/_core.cpp | 10 +++++++++- llvm/extra.cpp | 13 +++++++++++++ llvm/extra.h | 13 +++++++++++++ llvm/passes.py | 16 ++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/llvm/_core.cpp b/llvm/_core.cpp index 75b50ed..fa6087a 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -988,6 +988,11 @@ _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, @@ -1989,7 +1994,10 @@ static PyMethodDef core_methods[] = { _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 ) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 1b6d9fc..484f9ac 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -669,6 +669,19 @@ 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; diff --git a/llvm/extra.h b/llvm/extra.h index 26235e1..97cc31b 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -312,6 +312,19 @@ void LLVMPassManagerBuilderSetVectorize(LLVMPassManagerBuilderRef pmb, int flag) */ 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 */ diff --git a/llvm/passes.py b/llvm/passes.py index fb5dc7c..d06fa59 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -41,6 +41,7 @@ import llvm.core as core # module, function etc. import llvm._core as _core # C wrappers import llvm._util as _util # Utility functions +import warnings #===----------------------------------------------------------------------=== # Pass manager builder #===----------------------------------------------------------------------=== @@ -89,6 +90,21 @@ class PassManagerBuilder(object): vectorize = property(_get_vectorize, _set_vectorize) + def _set_loop_vectorize(self, enable): + try: + _core.LLVMPassManagerBuilderSetLoopVectorize(self.ptr, + int(bool(enable))) + except AttributeError: + warnings.warn("Ignored. LLVM-3.1 & prior do not support loop vectorizer.") + + def _get_loop_vectorize(self): + try: + return bool(_core.LLVMPassManagerBuilderGetLoopVectorize(self.ptr)) + except AttributeError: + return False + + loop_vectorize = property(_get_loop_vectorize, _set_loop_vectorize) + def _set_disable_unit_at_a_time(self, disable): return _core.LLVMPassManagerBuilderSetDisableUnitAtATime( self.ptr, disable) From ff515528383aefad97ceb5d755d21138bd2d0b53 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Mon, 31 Dec 2012 10:43:37 -0600 Subject: [PATCH 018/414] Update README for LLVM 3.2. --- README.rst | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 3f9d23d..973dfdb 100644 --- a/README.rst +++ b/README.rst @@ -10,15 +10,19 @@ http://www.llvmpy.org Versions -------- -This package has been tested with LLVM 3.1, Python 2.7 and Python 3.2. -Other Python versions should work, but some modifications may be -needed for the upcoming LLVM 3.2 +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 3.1 version of LLVM, build it. Make sure ``--enable-pic`` is passed to - LLVM's ``configure``. +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. Get llvm-py and install it:: From b22c0233011e039061ceb4839643b63ebfa16181 Mon Sep 17 00:00:00 2001 From: Mark Florisson Date: Wed, 2 Jan 2013 19:17:12 +0000 Subject: [PATCH 019/414] Make cbuilder optimizations optional --- llvm_cbuilder/builder.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/llvm_cbuilder/builder.py b/llvm_cbuilder/builder.py index 628ed85..45e58d1 100644 --- a/llvm_cbuilder/builder.py +++ b/llvm_cbuilder/builder.py @@ -784,7 +784,7 @@ class CDefinition(object): cls._name_ = "%s_%d" % (cls._name_, counter) cls.counter = counter + 1 - def define(self, module): + def define(self, module, optimize=True): '''define the function in the module. Raises NameError if a function of the same name has already been @@ -814,13 +814,14 @@ class CDefinition(object): self.cbuilder.close() self.cbuilder = None - # optimize - fpm = lp.FunctionPassManager.new(module) - pmb = lp.PassManagerBuilder.new() - pmb.opt_level = 3 - pmb.vectorize = True - pmb.populate(fpm) - fpm.run(func) + if optimize: + fpm = lp.FunctionPassManager.new(module) + pmb = lp.PassManagerBuilder.new() + pmb.opt_level = 3 + pmb.vectorize = True + pmb.populate(fpm) + fpm.run(func) + return func def __call__(self, module): From ff92a05858364cb1ae5441445e8e33a51928b730 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Mon, 31 Dec 2012 18:46:57 -0600 Subject: [PATCH 020/414] Begin to expose Pass class. --- llvm/_core.cpp | 188 +++----------------------------------------- llvm/ee.py | 75 ++---------------- llvm/extra.cpp | 26 ++++++ llvm/extra.h | 20 +++++ llvm/llvm_c_extra.h | 2 +- llvm/passes.py | 130 +++++++++++++++++++++++++++--- 6 files changed, 182 insertions(+), 259 deletions(-) diff --git a/llvm/_core.cpp b/llvm/_core.cpp index fa6087a..0b53138 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -1057,97 +1057,11 @@ _wrap_none2none(LLVMInitializePTXAsmPrinter) /*===----------------------------------------------------------------------===*/ /* Passes */ /*===----------------------------------------------------------------------===*/ -/* - -#define _wrap_pass(P) \ -_wrap_obj2none( LLVMAdd ## P ## Pass, LLVMPassManagerRef) - -_wrap_pass( AAEval ) -_wrap_pass( AggressiveDCE ) -_wrap_pass( AliasAnalysisCounter ) -_wrap_pass( AlwaysInliner ) -_wrap_pass( ArgumentPromotion ) -_wrap_pass( BasicAliasAnalysis ) -_wrap_pass( BlockPlacement ) -_wrap_pass( BreakCriticalEdges ) -_wrap_pass( CFGSimplification ) -_wrap_pass( CodeGenPrepare ) -_wrap_pass( ConstantMerge ) -_wrap_pass( ConstantPropagation ) -_wrap_pass( DbgInfoPrinter ) -_wrap_pass( DeadArgElimination ) -_wrap_pass( DeadCodeElimination ) -_wrap_pass( DeadInstElimination ) -_wrap_pass( DeadStoreElimination ) -_wrap_pass( DemoteRegisterToMemory ) -_wrap_pass( DomOnlyPrinter ) -_wrap_pass( DomOnlyViewer ) -_wrap_pass( DomPrinter ) -_wrap_pass( DomViewer ) -_wrap_pass( EdgeProfiler ) -_wrap_pass( FunctionAttrs ) -_wrap_pass( FunctionInlining ) -//_wrap_pass( GEPSplitter ) -_wrap_pass( GlobalDCE ) -_wrap_pass( GlobalOptimizer ) -_wrap_pass( GlobalsModRef ) -_wrap_pass( GVN ) -_wrap_pass( IndVarSimplify ) -_wrap_pass( InstCount ) -_wrap_pass( InstructionCombining ) -_wrap_pass( InstructionNamer ) -_wrap_pass( IPConstantPropagation ) -_wrap_pass( IPSCCP ) -_wrap_pass( JumpThreading ) -_wrap_pass( LazyValueInfo ) -_wrap_pass( LCSSA ) -_wrap_pass( LICM ) -//_wrap_pass( LiveValues ) -_wrap_pass( LoopDeletion ) -_wrap_pass( LoopDependenceAnalysis ) -_wrap_pass( LoopExtractor ) -//_wrap_pass( LoopIndexSplit ) -_wrap_pass( LoopRotate ) -_wrap_pass( LoopSimplify ) -_wrap_pass( LoopStrengthReduce ) -_wrap_pass( LoopUnroll ) -_wrap_pass( LoopUnswitch ) -_wrap_pass( LowerInvoke ) -_wrap_pass( LowerSwitch ) -_wrap_pass( MemCpyOpt ) -_wrap_pass( MergeFunctions ) -_wrap_pass( NoAA ) -_wrap_pass( NoProfileInfo ) -_wrap_pass( OptimalEdgeProfiler ) -_wrap_pass( PartialInlining ) -//_wrap_pass( PartialSpecialization ) -_wrap_pass( PostDomOnlyPrinter ) -_wrap_pass( PostDomOnlyViewer ) -_wrap_pass( PostDomPrinter ) -_wrap_pass( PostDomViewer ) -_wrap_pass( ProfileEstimator ) -_wrap_pass( ProfileLoader ) -_wrap_pass( ProfileVerifier ) -_wrap_pass( PromoteMemoryToRegister ) -_wrap_pass( PruneEH ) -_wrap_pass( Reassociate ) -_wrap_pass( ScalarEvolutionAliasAnalysis ) -_wrap_pass( ScalarReplAggregates ) -_wrap_pass( SCCP ) -//_wrap_pass( SimplifyHalfPowrLibCalls ) -_wrap_pass( SimplifyLibCalls ) -_wrap_pass( SingleLoopExtractor ) -_wrap_pass( StripDeadPrototypes ) -_wrap_pass( StripNonDebugSymbols ) -_wrap_pass( StripSymbols ) -//_wrap_pass( StructRetPromotion ) -_wrap_pass( TailCallElimination ) -//_wrap_pass( TailDuplication ) -_wrap_pass( UnifyFunctionExitNodes ) - -_wrap_pass( Internalize2 ) -*/ +_wrap_str2obj(LLVMCreatePassByName, LLVMPassRef) +_wrap_obj2none(LLVMDisposePass, LLVMPassRef) +_wrap_obj2str(LLVMGetPassName, LLVMPassRef) +_wrap_objobj2none(LLVMAddPass, LLVMPassManagerRef, LLVMPassRef) /*===----------------------------------------------------------------------===*/ /* Target Machine */ @@ -2040,94 +1954,6 @@ static PyMethodDef core_methods[] = { _method( LLVMInitializePTXAsmPrinter ) # endif #endif - /* Passes */ - - /* - _pass( AAEval ) - _pass( AggressiveDCE ) - _pass( AliasAnalysisCounter ) - _pass( AlwaysInliner ) - _pass( ArgumentPromotion ) - _pass( BasicAliasAnalysis ) - _pass( BlockPlacement ) - _pass( BreakCriticalEdges ) - _pass( CFGSimplification ) - _pass( CodeGenPrepare ) - _pass( ConstantMerge ) - _pass( ConstantPropagation ) - _pass( DbgInfoPrinter ) - _pass( DeadArgElimination ) - _pass( DeadCodeElimination ) - _pass( DeadInstElimination ) - _pass( DeadStoreElimination ) - _pass( DemoteRegisterToMemory ) - _pass( DomOnlyPrinter ) - _pass( DomOnlyViewer ) - _pass( DomPrinter ) - _pass( DomViewer ) - _pass( EdgeProfiler ) - _pass( FunctionAttrs ) - _pass( FunctionInlining ) - //_pass( GEPSplitter ) - _pass( GlobalDCE ) - _pass( GlobalOptimizer ) - _pass( GlobalsModRef ) - _pass( GVN ) - _pass( IndVarSimplify ) - _pass( InstCount ) - _pass( InstructionCombining ) - _pass( InstructionNamer ) - _pass( IPConstantPropagation ) - _pass( IPSCCP ) - _pass( JumpThreading ) - _pass( LazyValueInfo ) - _pass( LCSSA ) - _pass( LICM ) - //_pass( LiveValues ) - _pass( LoopDeletion ) - _pass( LoopDependenceAnalysis ) - _pass( LoopExtractor ) - //_pass( LoopIndexSplit ) - _pass( LoopRotate ) - _pass( LoopSimplify ) - _pass( LoopStrengthReduce ) - _pass( LoopUnroll ) - _pass( LoopUnswitch ) - _pass( LowerInvoke ) - _pass( LowerSwitch ) - _pass( MemCpyOpt ) - _pass( MergeFunctions ) - _pass( NoAA ) - _pass( NoProfileInfo ) - _pass( OptimalEdgeProfiler ) - _pass( PartialInlining ) - //_pass( PartialSpecialization ) - _pass( PostDomOnlyPrinter ) - _pass( PostDomOnlyViewer ) - _pass( PostDomPrinter ) - _pass( PostDomViewer ) - _pass( ProfileEstimator ) - _pass( ProfileLoader ) - _pass( ProfileVerifier ) - _pass( PromoteMemoryToRegister ) - _pass( PruneEH ) - _pass( Reassociate ) - _pass( ScalarEvolutionAliasAnalysis ) - _pass( ScalarReplAggregates ) - _pass( SCCP ) - //_pass( SimplifyHalfPowrLibCalls ) - _pass( SimplifyLibCalls ) - _pass( SingleLoopExtractor ) - _pass( StripDeadPrototypes ) - _pass( StripNonDebugSymbols ) - _pass( StripSymbols ) - //_pass( StructRetPromotion ) - _pass( TailCallElimination ) - //_pass( TailDuplication ) - _pass( UnifyFunctionExitNodes ) - - _pass( Internalize2 ) - */ /* Target Machine */ _method( LLVMTargetMachineFromEngineBuilder ) @@ -2194,6 +2020,12 @@ static PyMethodDef core_methods[] = { _method( LLVMGenericValueToPointer ) _method( LLVMDisposeGenericValue ) + /* Passes */ + _method( LLVMCreatePassByName ) + _method( LLVMDisposePass ) + _method( LLVMGetPassName ) + _method( LLVMAddPass ) + /* Misc */ _method( LLVMGetIntrinsic ) _method( LLVMLoadLibraryPermanently ) diff --git a/llvm/ee.py b/llvm/ee.py index a23aaf4..ebe5e87 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -40,6 +40,10 @@ import logging logger = logging.getLogger(__name__) + +# re-export TargetData for backward compatibility. +from llvm.passes import TargetData + #===----------------------------------------------------------------------=== # Enumerations #===----------------------------------------------------------------------=== @@ -48,76 +52,6 @@ BO_BIG_ENDIAN = 0 BO_LITTLE_ENDIAN = 1 -#===----------------------------------------------------------------------=== -# Target data -#===----------------------------------------------------------------------=== - -class TargetData(llvm.Ownable): - - @staticmethod - def new(strrep): - return TargetData(_core.LLVMCreateTargetData(strrep)) - - def __init__(self, ptr): - llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeTargetData) - - def __str__(self): - return _core.LLVMTargetDataAsString(self.ptr) - - @property - def byte_order(self): - return _core.LLVMByteOrder(self.ptr) - - @property - def pointer_size(self): - return _core.LLVMPointerSize(self.ptr) - - @property - def target_integer_type(self): - ptr = _core.LLVMIntPtrType(self.ptr); - return core.IntegerType(ptr, core.TYPE_INTEGER) - - def size(self, ty): - core.check_is_type(ty) - return _core.LLVMSizeOfTypeInBits(self.ptr, ty.ptr) - - def store_size(self, ty): - core.check_is_type(ty) - return _core.LLVMStoreSizeOfType(self.ptr, ty.ptr) - - def abi_size(self, ty): - core.check_is_type(ty) - return _core.LLVMABISizeOfType(self.ptr, ty.ptr) - - def abi_alignment(self, ty): - core.check_is_type(ty) - return _core.LLVMABIAlignmentOfType(self.ptr, ty.ptr) - - def callframe_alignment(self, ty): - core.check_is_type(ty) - return _core.LLVMCallFrameAlignmentOfType(self.ptr, ty.ptr) - - def preferred_alignment(self, ty_or_gv): - if isinstance(ty_or_gv, core.Type): - return _core.LLVMPreferredAlignmentOfType(self.ptr, - ty_or_gv.ptr) - elif isinstance(ty_or_gv, core.GlobalVariable): - return _core.LLVMPreferredAlignmentOfGlobal(self.ptr, - ty_or_gv.ptr) - else: - raise core.LLVMException("argument is neither a type nor a global variable") - - def element_at_offset(self, ty, ofs): - core.check_is_type_struct(ty) - ofs = int(ofs) # ofs is unsigned long long - return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs) - - def offset_of_element(self, ty, el): - core.check_is_type_struct(ty) - el = int(el) # el should be an int - return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el) - - #===----------------------------------------------------------------------=== # Generic value #===----------------------------------------------------------------------=== @@ -383,3 +317,4 @@ class TargetMachine(object): @property def feature_string(self): return _core.LLVMTargetMachineGetFS(self.ptr) + diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 484f9ac..e58220d 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -95,6 +95,7 @@ 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) { @@ -143,6 +144,31 @@ const CodeGenOpt::Level OptLevelMap[] = { } // end anony namespace +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 LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref){ + using namespace llvm; + unwrap(pmref)->add(unwrap(passref)); +} + LLVMValueRef LLVMGetFunctionFromInlineAsm(LLVMTypeRef funcType, const char inlineAsm[], const char constrains[], diff --git a/llvm/extra.h b/llvm/extra.h index 97cc31b..49a75d1 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -54,6 +54,26 @@ extern "C" { #endif +/* + * 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 llvm:InlineAsm::get */ diff --git a/llvm/llvm_c_extra.h b/llvm/llvm_c_extra.h index 9eb77dc..5728875 100644 --- a/llvm/llvm_c_extra.h +++ b/llvm/llvm_c_extra.h @@ -21,7 +21,7 @@ inline ref wrap(const ty *P) { \ typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef; typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; typedef struct LLVMOpaqueNamedMD *LLVMNamedMDRef; - +typedef struct LLVMOpaquePass *LLVMPassRef; #ifdef __cplusplus } diff --git a/llvm/passes.py b/llvm/passes.py index d06fa59..71de28d 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -36,7 +36,6 @@ are available. """ import llvm # top-level, for common stuff -import llvm.ee as ee # target data import llvm.core as core # module, function etc. import llvm._core as _core # C wrappers import llvm._util as _util # Utility functions @@ -155,16 +154,18 @@ class PassManager(object): def __del__(self): _core.LLVMDisposePassManager(self.ptr) - def add(self, tgt_data_or_pass_name): - if isinstance(tgt_data_or_pass_name, ee.TargetData): - self._add_target_data(tgt_data_or_pass_name) - elif _util.isstring(tgt_data_or_pass_name): - self._add_pass(tgt_data_or_pass_name) + def add(self, pass_obj): + '''Add a pass to the pass manager. + + pass_obj --- Either a Pass instance, a string name of a pass + ''' + if isinstance(pass_obj, Pass): + _core.LLVMAddPass(self.ptr, pass_obj.ptr) + pass_obj._own(self) # PassManager owns the pass + elif _util.isstring(pass_obj): + self._add_pass(pass_obj) else: - raise llvm.LLVMException("invalid pass_id (%s)" % tgt_data_or_pass_name) - - def _add_target_data(self, tgt): - _core.LLVMAddTargetData(tgt.ptr, self.ptr) + raise llvm.LLVMException("invalid pass_id (%s)" % pass_obj) def _add_pass(self, pass_name): status = _core.LLVMAddPassByName(self.ptr, pass_name) @@ -197,6 +198,115 @@ class FunctionPassManager(PassManager): def finalize(self): _core.LLVMFinalizeFunctionPassManager(self.ptr) + + +#===----------------------------------------------------------------------=== +# Passes +#===----------------------------------------------------------------------=== + +class Pass(llvm.Ownable): + '''Pass Inferface + ''' + def __init__(self, ptr): + llvm.Ownable.__init__(self, ptr, _core.LLVMDisposePass) + + @staticmethod + def new(name): + '''Create a new pass by name. + + Note: Not all pass has a default constructor. LLVM will kill + the process if an the pass requires arguments to construct. + The error cannot be caught. + ''' + ptr = _core.LLVMCreatePassByName(name) + p = Pass(ptr) + p.__name = name + return p + + @property + def name(self): + return self.__name + + @property + def description(self): + return _core.LLVMGetPassName(self.ptr) + + def dump(self): + return _core.LLVMPassDump(self.ptr) + + +#===----------------------------------------------------------------------=== +# Target data +#===----------------------------------------------------------------------=== + +class TargetData(Pass): + + @staticmethod + def new(strrep): + return TargetData(_core.LLVMCreateTargetData(strrep)) + + def __str__(self): + return _core.LLVMTargetDataAsString(self.ptr) + + @property + def byte_order(self): + return _core.LLVMByteOrder(self.ptr) + + @property + def pointer_size(self): + return _core.LLVMPointerSize(self.ptr) + + @property + def target_integer_type(self): + ptr = _core.LLVMIntPtrType(self.ptr); + return core.IntegerType(ptr, core.TYPE_INTEGER) + + def size(self, ty): + core.check_is_type(ty) + return _core.LLVMSizeOfTypeInBits(self.ptr, ty.ptr) + + def store_size(self, ty): + core.check_is_type(ty) + return _core.LLVMStoreSizeOfType(self.ptr, ty.ptr) + + def abi_size(self, ty): + core.check_is_type(ty) + return _core.LLVMABISizeOfType(self.ptr, ty.ptr) + + def abi_alignment(self, ty): + core.check_is_type(ty) + return _core.LLVMABIAlignmentOfType(self.ptr, ty.ptr) + + def callframe_alignment(self, ty): + core.check_is_type(ty) + return _core.LLVMCallFrameAlignmentOfType(self.ptr, ty.ptr) + + def preferred_alignment(self, ty_or_gv): + if isinstance(ty_or_gv, core.Type): + return _core.LLVMPreferredAlignmentOfType(self.ptr, + ty_or_gv.ptr) + elif isinstance(ty_or_gv, core.GlobalVariable): + return _core.LLVMPreferredAlignmentOfGlobal(self.ptr, + ty_or_gv.ptr) + else: + raise core.LLVMException("argument is neither a type nor a global variable") + + def element_at_offset(self, ty, ofs): + core.check_is_type_struct(ty) + ofs = int(ofs) # ofs is unsigned long long + return _core.LLVMElementAtOffset(self.ptr, ty.ptr, ofs) + + def offset_of_element(self, ty, el): + core.check_is_type_struct(ty) + el = int(el) # el should be an int + return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el) + + + +#===----------------------------------------------------------------------=== +# Misc. +#===----------------------------------------------------------------------=== + # Intialize passes PASSES = None From bcc467b2b53a16713eec4517376fcd9d16d666e0 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Wed, 2 Jan 2013 12:20:10 -0600 Subject: [PATCH 021/414] Add auto detect PTX/NVPTX support and disable them in the C-extension. --- setup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 1fba3db..94c9f95 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,8 @@ print('LLVM version = %d.%d' % llvm_version) auto_intrinsic_gen(incdir) +macros = [('__STDC_CONSTANT_MACROS', None), + ('__STDC_LIMIT_MACROS', None)] if dynlink: libs_core = ['LLVM-%d.%d' % llvm_version] objs_core = [] @@ -89,6 +91,7 @@ else: extra_components.extend(ptx_components) else: print("No CUDA support") + macros.append(('LLVM_DISABLE_PTX', None)) libs_core, objs_core = get_libs_and_objs( ['core', 'analysis', 'scalaropts', 'executionengine', @@ -97,12 +100,10 @@ else: 'asmparser', 'linker', 'support', 'vectorize'] + extra_components) -macros = [('__STDC_CONSTANT_MACROS', None), - ('__STDC_LIMIT_MACROS', None)] if sys.platform == 'win32': # If no PTX lib got added, disable PTX in the build if 'LLVMPTXCodeGen' not in libs_core: - macros.append(('LLVM_DISABLE_PTX', None)), + macros.append(('LLVM_DISABLE_PTX', None)) else: macros.append(('_GNU_SOURCE', None)) From 3b399f9d8bf7e272fb0d3f7822e30f01ddc74895 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Wed, 2 Jan 2013 17:00:59 -0600 Subject: [PATCH 022/414] Adding target specific passes. --- llvm/_core.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- llvm/ee.py | 13 +++++++++++++ llvm/extra.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ llvm/extra.h | 26 ++++++++++++++++++++++++++ llvm/passes.py | 23 +++++++++++++++++++++++ 5 files changed, 149 insertions(+), 3 deletions(-) diff --git a/llvm/_core.cpp b/llvm/_core.cpp index 0b53138..b3fb298 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -1036,6 +1036,7 @@ _wrap_none2str(LLVMDumpPasses) _wrap_objstr2obj(LLVMAddPassByName, LLVMPassManagerRef, int) +_wrap_objobj2none(LLVMAddPass, LLVMPassManagerRef, LLVMPassRef) _wrap_none2none(LLVMInitializePasses) _wrap_none2obj(LLVMInitializeNativeTarget, int) @@ -1061,7 +1062,11 @@ _wrap_none2none(LLVMInitializePTXAsmPrinter) _wrap_str2obj(LLVMCreatePassByName, LLVMPassRef) _wrap_obj2none(LLVMDisposePass, LLVMPassRef) _wrap_obj2str(LLVMGetPassName, LLVMPassRef) -_wrap_objobj2none(LLVMAddPass, LLVMPassManagerRef, LLVMPassRef) +_wrap_obj2none(LLVMPassDump, LLVMPassRef) + +_wrap_str2obj(LLVMCreateTargetLibraryInfo, LLVMPassRef) +_wrap_obj2obj(LLVMCreateTargetTransformInfo, LLVMTargetMachineRef, LLVMPassRef) + /*===----------------------------------------------------------------------===*/ /* Target Machine */ @@ -1096,6 +1101,30 @@ _wLLVMTargetMachineLookup(PyObject * self, PyObject * args) LLVMPY_CATCH_ALL } + +static PyObject * +_wLLVMCreateTargetMachine(PyObject * self, PyObject * args) +{ + LLVMPY_TRY + const char *triple; + const char *cpu; + const char *features; + int opt; + + if (!PyArg_ParseTuple(args, "sssi", &triple, &cpu, &features, &opt)) + return NULL; + + std::string error; + LLVMTargetMachineRef tm = LLVMCreateTargetMachine(triple, cpu, features, opt, + 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) { @@ -1482,6 +1511,9 @@ _wLLVMParseEnvOpts(PyObject *self, PyObject *args) _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 * @@ -1937,6 +1969,7 @@ static PyMethodDef core_methods[] = { _method( LLVMDisposePassManager ) _method( LLVMDumpPasses ) _method( LLVMAddPassByName ) + _method( LLVMAddPass ) _method( LLVMInitializePasses ) _method( LLVMInitializeNativeTarget ) @@ -1958,6 +1991,7 @@ static PyMethodDef core_methods[] = { /* Target Machine */ _method( LLVMTargetMachineFromEngineBuilder ) _method( LLVMDisposeTargetMachine ) + _method( LLVMCreateTargetMachine ) _method( LLVMTargetMachineLookup ) _method( LLVMTargetMachineEmitFile ) _method( LLVMTargetMachineGetTargetData ) @@ -2024,13 +2058,16 @@ static PyMethodDef core_methods[] = { _method( LLVMCreatePassByName ) _method( LLVMDisposePass ) _method( LLVMGetPassName ) - _method( LLVMAddPass ) + _method( LLVMPassDump ) + + _method( LLVMCreateTargetLibraryInfo ) + _method( LLVMCreateTargetTransformInfo ) /* Misc */ _method( LLVMGetIntrinsic ) _method( LLVMLoadLibraryPermanently ) _method( LLVMParseEnvOpts ) - + _method( LLVMDefaultTargetTriple ) _method( LLVMInlineFunction ) _method( PyCObjectVoidPtrToPyLong ) { NULL } diff --git a/llvm/ee.py b/llvm/ee.py index ebe5e87..8469138 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -257,8 +257,21 @@ def get_host_cpu_name(): ''' return _core.LLVMGetHostCPUName() +def get_default_triple(): + '''return the target triple of the host in str-rep + ''' + return _core.LLVMDefaultTargetTriple() + class TargetMachine(object): + @staticmethod + def new(triple='', cpu='', features='', opt=2): + if not triple and not cpu: + triple = get_default_triple() + cpu = get_host_cpu_name() + ptr = _core.LLVMCreateTargetMachine(triple, cpu, features, opt) + return TargetMachine(ptr) + @staticmethod def lookup(arch, cpu='', features='', opt=2): '''create a targetmachine given an architecture name diff --git a/llvm/extra.cpp b/llvm/extra.cpp index e58220d..10d090a 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -75,6 +75,7 @@ #include "llvm/Support/SourceMgr.h" #include #include +#include #if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 @@ -143,6 +144,23 @@ const CodeGenOpt::Level OptLevelMap[] = { }; } // end anony namespace +LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref){ + using namespace llvm; + TargetMachine * tm = unwrap(tmref); + Pass * tti = new TargetTransformInfo(tm->getScalarTargetTransformInfo(), + tm->getVectorTargetTransformInfo()); + return wrap(tti); +} + +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; @@ -164,6 +182,11 @@ const char * LLVMGetPassName(LLVMPassRef passref){ 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)); @@ -354,6 +377,30 @@ LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, return wrap(tm); } +LLVMTargetMachineRef LLVMCreateTargetMachine(const char *triple, + const char *cpu, + const char *features, + int opt, + 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, + CodeModel::Default, + OptLevelMap[opt]); + if (!tm) { + error = "Cannot create target machine"; + return NULL; + } + return wrap(tm); +} LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb) { diff --git a/llvm/extra.h b/llvm/extra.h index 49a75d1..3f2a413 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -54,6 +54,23 @@ extern "C" { #endif +/* + * Wraps new TargetTransformInfo( + * TargetMachine::getScalarTargetTransformInfo, + * TargetMachine::getVectorTargetTransformInfo) + */ +LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref); + +/* + * Wraps new TargetLibraryInfo + */ +LLVMPassRef LLVMCreateTargetLibraryInfo(const char * triple); + +/* + * Wraps llvm::getDefaultTargetTriple + */ +const char * LLVMDefaultTargetTriple(); + /* * Wraps Pass::lookupPassInfo and PassInfo::createPass */ @@ -74,6 +91,11 @@ const char * LLVMGetPassName(LLVMPassRef passref); */ void LLVMAddPass(LLVMPassManagerRef pmref, LLVMPassRef passref); +/* + * Wraps Pass::dump + */ +void LLVMPassDump(LLVMPassRef passref); + /* * Wraps llvm:InlineAsm::get */ @@ -176,6 +198,10 @@ LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, const char *features, int opt, std::string &error); +LLVMTargetMachineRef LLVMCreateTargetMachine(const char *arch, const char *cpu, + const char *features, int opt, + std::string &error); + /* * Wraps EngineBuilder::selectTarget */ diff --git a/llvm/passes.py b/llvm/passes.py index 71de28d..106b86d 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -209,6 +209,7 @@ class Pass(llvm.Ownable): ''' def __init__(self, ptr): llvm.Ownable.__init__(self, ptr, _core.LLVMDisposePass) + self.__name = '' @staticmethod def new(name): @@ -225,6 +226,8 @@ class Pass(llvm.Ownable): @property def name(self): + '''The name used in PassRegistry. + ''' return self.__name @property @@ -302,6 +305,26 @@ class TargetData(Pass): return _core.LLVMOffsetOfElement(self.ptr, ty.ptr, el) +#===----------------------------------------------------------------------=== +# Target Library Info +#===----------------------------------------------------------------------=== + +class TargetLibraryInfo(Pass): + @staticmethod + def new(triple): + ptr = _core.LLVMCreateTargetLibraryInfo(triple) + return TargetLibraryInfo(ptr) + + +#===----------------------------------------------------------------------=== +# Target Transform Info +#===----------------------------------------------------------------------=== + +class TargetTransformInfo(Pass): + @staticmethod + def new(targetmachine): + ptr = _core.LLVMCreateTargetTransformInfo(targetmachine.ptr) + return TargetTransformInfo(ptr) #===----------------------------------------------------------------------=== # Misc. From 7f9c91e2aa9811c33553023ea6fce28e54ea5f33 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Wed, 2 Jan 2013 17:37:14 -0600 Subject: [PATCH 023/414] Add simpler API for building pass-managers given a TargetMachine. --- llvm/passes.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/llvm/passes.py b/llvm/passes.py index 106b86d..5660a24 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -326,6 +326,56 @@ class TargetTransformInfo(Pass): ptr = _core.LLVMCreateTargetTransformInfo(targetmachine.ptr) return TargetTransformInfo(ptr) +#===----------------------------------------------------------------------=== +# Helpers +#===----------------------------------------------------------------------=== + +def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False, + inline_threshold=2000, pm=True, fpm=True, mod=None): + ''' + tm --- The TargetMachine for which the passes are optimizing for. + The TargetMachine must stay alive until the pass managers + are removed. + opt --- [0-3] Optimization level. Default to 2. + loop_vectorize --- [boolean] Whether to use loop-vectorizer. + vectorize --- [boolean] Whether to use basic-block vectorizer. + inline_threshold --- [int] Threshold for the inliner. + features --- [str] CPU feature string. + pm --- [boolean] Whether to build a module-level pass-manager. + fpm --- [boolean] Whether to build a function-level pass-manager. + mod --- [Module] The module object for the FunctionPassManager. + ''' + if pm: + pm = PassManager.new() + if fpm: + if not mod: + raise TypeError("Keyword 'mod' must be defined") + fpm = FunctionPassManager.new(mod) + + # Populate PassManagers with target specific passes + pmb = PassManagerBuilder.new() + pmb.opt_level = opt + pmb.vectorize = vectorize + pmb.loop_vectorize = loop_vectorize + if inline_threshold: + pmb.use_inliner_with_threshold(inline_threshold) + if pm: + pm.add(tm.target_data) + pm.add(TargetLibraryInfo.new(tm.triple)) + pm.add(TargetTransformInfo.new(tm)) + pmb.populate(pm) + + if fpm: + fpm.add(tm.target_data) + fpm.add(TargetLibraryInfo.new(tm.triple)) + fpm.add(TargetTransformInfo.new(tm)) + pmb.populate(fpm) + fpm.initialize() + + from collections import namedtuple + return namedtuple('passmanagers', ['pm', 'fpm'])(pm=pm, fpm=fpm) + + #===----------------------------------------------------------------------=== # Misc. #===----------------------------------------------------------------------=== From e2ec14bbb9fada32a4d18674a8ecc5d614ab28d9 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Wed, 2 Jan 2013 17:42:16 -0600 Subject: [PATCH 024/414] Add test to verify new pass APIs and loop-vectorizer. --- test/loopvectorize.c | 44 +++++ test/loopvectorize.ll | 369 ++++++++++++++++++++++++++++++++++++++++++ test/loopvectorize.py | 38 +++++ test/pass.py | 45 ++++++ 4 files changed, 496 insertions(+) create mode 100644 test/loopvectorize.c create mode 100644 test/loopvectorize.ll create mode 100644 test/loopvectorize.py create mode 100644 test/pass.py diff --git a/test/loopvectorize.c b/test/loopvectorize.c new file mode 100644 index 0000000..a46b633 --- /dev/null +++ b/test/loopvectorize.c @@ -0,0 +1,44 @@ +void ex1(float *A, float* B, float K, int start, int end) { + for (int i = start; i < end; ++i) + A[i] *= B[i] + K; +} + +void ex2(float *A, float* B, float K, int n) { + for (int i = 0; i < n; ++i) + A[i] *= B[i] + K; +} + +int ex3(int *A, int *B, int n) { + unsigned sum = 0; + for (int i = 0; i < n; ++i) + sum += A[i] + 5; + return sum; +} + +void ex4(float *A, float* B, float K, int n) { + for (int i = 0; i < n; ++i) + A[i] = i; +} + +int ex5(int *A, int *B, int n) { + unsigned sum = 0; + for (int i = 0; i < n; ++i) + if (A[i] > B[i]) + sum += A[i] + 5; + return sum; +} + +void ex6(int *A, int *B, int n) { + for (int i = n; i > 0; --i) + A[i] +=1; +} + +void ex7(int *A, int *B, int n, int k) { + for (int i = 0; i < n; ++i) + A[i*7] += B[i*k]; +} + +void ex8(int *A, char *B, int n, int k) { + for (int i = 0; i < n; ++i) + A[i] += 4 * B[i]; +} \ No newline at end of file diff --git a/test/loopvectorize.ll b/test/loopvectorize.ll new file mode 100644 index 0000000..8d651ca --- /dev/null +++ b/test/loopvectorize.ll @@ -0,0 +1,369 @@ +; ModuleID = 'loopvectorize.c' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +;target triple = "x86_64-apple-macosx10.8.0" +target triple = "x86-64-unknown-linux-gnu" + +define void @ex1(float* %A, float* %B, float %K, i32 %start, i32 %end) nounwind uwtable ssp { + %1 = alloca float*, align 8 + %2 = alloca float*, align 8 + %3 = alloca float, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %i = alloca i32, align 4 + store float* %A, float** %1, align 8 + store float* %B, float** %2, align 8 + store float %K, float* %3, align 4 + store i32 %start, i32* %4, align 4 + store i32 %end, i32* %5, align 4 + %6 = load i32* %4, align 4 + store i32 %6, i32* %i, align 4 + br label %7 + +;