From 1f49bb6d7c7e1fcfeb0ab47c3770ec35e65917dc Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Sun, 3 Feb 2013 12:57:13 -0600 Subject: [PATCH] Binding for PassManagerBuilder --- newbinding/binding.py | 92 +++++++++++++++++++++++++ newbinding/include/llvm_binding/extra.h | 14 ++-- newbinding/{src => }/namespace.py | 0 newbinding/src/EngineBuilder.py | 3 +- newbinding/src/PassManagerBuilder.py | 24 +++++++ newbinding/src/Transforms/IPO.py | 9 +++ newbinding/src/Transforms/__init__.py | 10 +++ newbinding/src/__init__.py | 5 +- newbinding/test2.py | 4 ++ 9 files changed, 151 insertions(+), 10 deletions(-) rename newbinding/{src => }/namespace.py (100%) create mode 100644 newbinding/src/Transforms/IPO.py create mode 100644 newbinding/src/Transforms/__init__.py diff --git a/newbinding/binding.py b/newbinding/binding.py index 4205c64..142c8ef 100644 --- a/newbinding/binding.py +++ b/newbinding/binding.py @@ -83,6 +83,7 @@ class Class(_Type): self.methods = [] self.pymethods = [] self.enums = [] + self.attrs = [] self.includes = set() self.downcastables = set() @@ -103,6 +104,10 @@ class Class(_Type): v.name = k v.parent = self setattr(self, k, v) + elif isinstance(v, Attr): + self.attrs.append(v) + v.name = k + v.parent = self elif isinstance(v, CustomPythonMethod): self.pymethods.append(v) elif k == '_include_': @@ -127,6 +132,8 @@ class Class(_Type): meth.compile_cpp(writer) for enum in self.enums: enum.compile_cpp(writer) + for attr in self.attrs: + attr.compile_cpp(writer) # generate method table writer.println('static') @@ -142,6 +149,16 @@ class Class(_Type): name = enum func = enumkind.c_name(enum) writer.println(fmt % locals()) + for attr in self.attrs: + # getter + name = attr.getter_name + func = attr.getter_c_name + writer.println(fmt % locals()) + # setter + name = attr.setter_name + func = attr.setter_c_name + writer.println(fmt % locals()) + writer.println('{ NULL },') writer.println('};') writer.println() @@ -160,6 +177,8 @@ class Class(_Type): meth.compile_py(writer) for meth in self.pymethods: meth.compile_py(writer) + for attr in self.attrs: + attr.compile_py(writer) writer.println() @property @@ -587,3 +606,76 @@ class CustomPythonStaticMethod(CustomPythonMethod): writer.println('@staticmethod') super(CustomPythonStaticMethod, self).compile_py(writer) + +class Attr(object): + def __init__(self, getter, setter): + self.getter = getter + self.setter = setter + + @property + def fullname(self): + try: + name = self.realname + except AttributeError: + name = self.name + return '::'.join([self.parent.fullname, name]) + + def __str__(self): + return self.fullname + + @property + def getter_name(self): + return '%s_get' % self.name + + @property + def setter_name(self): + return '%s_set' % self.name + + @property + def getter_c_name(self): + return cg.mangle('%s_get' % self.fullname) + + @property + def setter_c_name(self): + return cg.mangle('%s_set' % self.fullname) + + def compile_cpp(self, writer): + # getter + with writer.py_function(self.getter_c_name): + (this,) = writer.parse_arguments('args', ptr(self.parent)) + attr = self.name + ret = writer.declare(self.getter.fullname, + '%(this)s->%(attr)s' % locals()) + writer.return_value(self.getter.wrap(writer, ret)) + # setter + with writer.py_function(self.setter_c_name): + (this, value) = writer.parse_arguments('args', ptr(self.parent), + self.setter) + attr = self.name + writer.println('%(this)s->%(attr)s = %(value)s;' % locals()) + writer.return_value(None) + + def compile_py(self, writer): + name = self.name + parent = '.'.join(self.parent.fullname.split('::')[1:]) + getter = '.'.join([parent, self.getter_name]) + setter = '.'.join([parent, self.setter_name]) + writer.println('@property') + with writer.block('def %(name)s(self):' % locals()): + unself = writer.unwrap('self') + ret = writer.new_symbol('ret') + writer.println('%(ret)s = _api.%(getter)s(%(unself)s)' % locals()) + is_ownedptr = isinstance(self.getter, ownedptr) + writer.return_value(writer.wrap(ret, is_ownedptr)) + writer.println() + writer.println('@%(name)s.setter' % locals()) + with writer.block('def %(name)s(self, value):' % locals()): + unself = writer.unwrap('self') + unvalue = writer.unwrap('value') + if isinstance(self.setter, ownedptr): + writer.release_ownership(unvalue) + writer.println('return _api.%(setter)s(%(unself)s, %(unvalue)s)' % + locals()) + writer.println() + + diff --git a/newbinding/include/llvm_binding/extra.h b/newbinding/include/llvm_binding/extra.h index 46dd42a..c69f177 100644 --- a/newbinding/include/llvm_binding/extra.h +++ b/newbinding/include/llvm_binding/extra.h @@ -163,13 +163,13 @@ PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName, className); } -static -bool string_equal(const char *A, const char *B){ - for (; *A and *B; ++A, ++B) { - if (*A != *B) return false; - } - return true; -} +//static +//bool string_equal(const char *A, const char *B){ +// for (; *A and *B; ++A, ++B) { +// if (*A != *B) return false; +// } +// return true; +//} //////////// static diff --git a/newbinding/src/namespace.py b/newbinding/namespace.py similarity index 100% rename from newbinding/src/namespace.py rename to newbinding/namespace.py diff --git a/newbinding/src/EngineBuilder.py b/newbinding/src/EngineBuilder.py index 07ffcc0..d9594f0 100644 --- a/newbinding/src/EngineBuilder.py +++ b/newbinding/src/EngineBuilder.py @@ -50,8 +50,9 @@ class EngineBuilder: _selectTarget0.realname = 'selectTarget' _selectTarget1 = CustomMethod('EngineBuilder_selectTarget', + PyObjectPtr, const(ref(Triple)), cast(str, StringRef), - cast(str, StringRef), PyObjectPtr), + cast(str, StringRef), PyObjectPtr) @CustomPythonMethod def selectTarget(self, *args): diff --git a/newbinding/src/PassManagerBuilder.py b/newbinding/src/PassManagerBuilder.py index 2e2ea5e..11fedfb 100644 --- a/newbinding/src/PassManagerBuilder.py +++ b/newbinding/src/PassManagerBuilder.py @@ -1,6 +1,8 @@ from binding import * from namespace import llvm from PassManager import PassManagerBase, FunctionPassManager +from TargetLibraryInfo import TargetLibraryInfo +from Pass import Pass @llvm.Class() class PassManagerBuilder: @@ -17,3 +19,25 @@ class PassManagerBuilder: cast(bool, Bool), cast(bool, Bool)).require_only(3) + def _attr_int(): + return Attr(getter=cast(Unsigned, int), + setter=cast(int, Unsigned)) + + OptLevel = _attr_int() + SizeLevel = _attr_int() + + def _attr_bool(): + return Attr(getter=cast(Bool, bool), + setter=cast(bool, Bool)) + + DisableSimplifyLibCalls = _attr_bool() + DisableUnitAtATime = _attr_bool() + DisableUnrollLoops = _attr_bool() + Vectorize = _attr_bool() + LoopVectorize = _attr_bool() + + LibraryInfo = Attr(getter=ownedptr(TargetLibraryInfo), + setter=ownedptr(TargetLibraryInfo)) + + Inliner = Attr(getter=ownedptr(Pass), + setter=ownedptr(Pass)) diff --git a/newbinding/src/Transforms/IPO.py b/newbinding/src/Transforms/IPO.py new file mode 100644 index 0000000..6c2fc26 --- /dev/null +++ b/newbinding/src/Transforms/IPO.py @@ -0,0 +1,9 @@ +from binding import * +from namespace import llvm +from ..Pass import Pass + +llvm.includes.add('llvm/Transforms/IPO.h') + +createFunctionInliningPass = llvm.Function('createFunctionInliningPass', + ptr(Pass), + cast(int, Unsigned)).require_only(0) diff --git a/newbinding/src/Transforms/__init__.py b/newbinding/src/Transforms/__init__.py new file mode 100644 index 0000000..da0beed --- /dev/null +++ b/newbinding/src/Transforms/__init__.py @@ -0,0 +1,10 @@ +import os.path, importlib + +def _init(): + for fname in os.listdir(os.path.dirname(__file__)): + if ((fname.endswith('.py') or fname.endswith('.pyc')) and + not fname.startswith('__init__')): + modname = os.path.basename(fname).rsplit('.', 1)[0] + importlib.import_module('.' + modname, __name__) + +_init() diff --git a/newbinding/src/__init__.py b/newbinding/src/__init__.py index 1042826..f67a3c4 100644 --- a/newbinding/src/__init__.py +++ b/newbinding/src/__init__.py @@ -5,7 +5,8 @@ def _init(): if ((fname.endswith('.py') or fname.endswith('.pyc')) and not fname.startswith('__init__')): modname = os.path.basename(fname).rsplit('.', 1)[0] - topname = __name__.rsplit('.', 1)[0] - importlib.import_module('.' + modname, topname) + importlib.import_module('.' + modname, __name__) _init() + +import Transforms \ No newline at end of file diff --git a/newbinding/test2.py b/newbinding/test2.py index e2f8dd2..248e32a 100644 --- a/newbinding/test2.py +++ b/newbinding/test2.py @@ -84,6 +84,10 @@ def test_basic_jit_use(): # build pass manager pmb = api.PassManagerBuilder.new() + pmb.OptLevel = 3 + assert pmb.OptLevel == 3 + pmb.LibraryInfo = api.TargetLibraryInfo.new() + pmb.Inliner = api.createFunctionInliningPass() fpm = api.FunctionPassManager.new(m) pm = api.PassManager.new()