diff --git a/llvm/__init__.py b/llvm/__init__.py index c5e1123..395e698 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -8,7 +8,19 @@ __version__ = '0.9.1' from weakref import WeakValueDictionary from llvm._utils.finalizer import track as track_resource from llvm._utils.finalizer import OwnerMixin as _OwnerMixin +from llvm import _core +#===----------------------------------------------------------------------=== +# LLVM Version +#===----------------------------------------------------------------------=== + +version = _core.LLVMGetVersion() + +def require_version_at_least(major, minor): + '''Sentry to guard version requirement + ''' + if version < (major, minor): + raise Exception(major, minor) #===----------------------------------------------------------------------=== # Exceptions diff --git a/llvm/_core.cpp b/llvm/_core.cpp index e791439..cb7ae76 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -1065,7 +1065,10 @@ _wrap_obj2str(LLVMGetPassName, LLVMPassRef) _wrap_obj2none(LLVMPassDump, LLVMPassRef) _wrap_str2obj(LLVMCreateTargetLibraryInfo, LLVMPassRef) + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 _wrap_obj2obj(LLVMCreateTargetTransformInfo, LLVMTargetMachineRef, LLVMPassRef) +#endif /*===----------------------------------------------------------------------===*/ @@ -1510,6 +1513,14 @@ _wrap_obj2none(LLVMDisposeGenericValue, LLVMGenericValueRef) /* Misc */ /*===----------------------------------------------------------------------===*/ +static PyObject * +_wLLVMGetVersion(PyObject *self, PyObject *args) +{ + int major = LLVM_VERSION_MAJOR; + int minor = LLVM_VERSION_MINOR; + return Py_BuildValue("(i,i)", major, minor); +} + _wrap_objintlist2obj(LLVMGetIntrinsic, LLVMModuleRef, LLVMTypeRef, LLVMValueRef) @@ -2108,9 +2119,13 @@ static PyMethodDef core_methods[] = { _method( LLVMPassDump ) _method( LLVMCreateTargetLibraryInfo ) + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 _method( LLVMCreateTargetTransformInfo ) +#endif /* Misc */ + _method( LLVMGetVersion ) _method( LLVMGetIntrinsic ) _method( LLVMLoadLibraryPermanently ) _method( LLVMParseEnvOpts ) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index a39579d..e200eec 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -155,6 +155,7 @@ const CodeModel::Model CodeModelMap[] = { } // end anony namespace +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref){ using namespace llvm; TargetMachine * tm = unwrap(tmref); @@ -162,6 +163,7 @@ LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref){ tm->getVectorTargetTransformInfo()); return wrap(tti); } +#endif LLVMPassRef LLVMCreateTargetLibraryInfo(const char * triple){ using namespace llvm; diff --git a/llvm/extra.h b/llvm/extra.h index bfd4651..6080bdb 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -54,12 +54,15 @@ extern "C" { #endif + +#if LLVM_VERSION_MAJOR >= 3 && LLVM_VERSION_MINOR >= 2 /* * Wraps new TargetTransformInfo( * TargetMachine::getScalarTargetTransformInfo, * TargetMachine::getVectorTargetTransformInfo) */ LLVMPassRef LLVMCreateTargetTransformInfo(LLVMTargetMachineRef tmref); +#endif /* * Wraps new TargetLibraryInfo diff --git a/llvm/passes.py b/llvm/passes.py index bca8caf..f7cf0fe 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -89,10 +89,10 @@ class PassManagerBuilder(llvm.Handle): vectorize = property(_get_vectorize, _set_vectorize) def _set_loop_vectorize(self, enable): - try: + if llvm.version >= (3, 2): _core.LLVMPassManagerBuilderSetLoopVectorize(self.ptr, int(bool(enable))) - except AttributeError: + else: warnings.warn("Ignored. LLVM-3.1 & prior do not support loop vectorizer.") def _get_loop_vectorize(self): @@ -326,9 +326,11 @@ class TargetLibraryInfo(Pass): class TargetTransformInfo(Pass): @staticmethod def new(targetmachine): + llvm.require_version_at_least(3, 2) ptr = _core.LLVMCreateTargetTransformInfo(targetmachine.ptr) return TargetTransformInfo(ptr) + #===----------------------------------------------------------------------=== # Helpers #===----------------------------------------------------------------------=== @@ -365,13 +367,15 @@ def build_pass_managers(tm, opt=2, loop_vectorize=False, vectorize=False, if pm: pm.add(tm.target_data) pm.add(TargetLibraryInfo.new(tm.triple)) - pm.add(TargetTransformInfo.new(tm)) + if llvm.version >= (3, 2): + 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)) + if llvm.version >= (3, 2): + fpm.add(TargetTransformInfo.new(tm)) pmb.populate(fpm) fpm.initialize() diff --git a/test/loopvectorize.py b/test/loopvectorize.py index 27db483..ff7cb10 100644 --- a/test/loopvectorize.py +++ b/test/loopvectorize.py @@ -1,13 +1,17 @@ from llvm.core import * from llvm.passes import * from llvm.ee import * +import llvm from os.path import dirname, join as join_path + import unittest import re class TestLoopVectorizer(unittest.TestCase): def test_loop_vectorizer(self): + if llvm.version <= (3, 1): + return # SKIP re_vector = re.compile("<\d+ x \w+>") diff --git a/test/pass.py b/test/pass.py index c9ea654..20429d7 100644 --- a/test/pass.py +++ b/test/pass.py @@ -1,6 +1,7 @@ from llvm.core import * from llvm.passes import * from llvm.ee import * +import llvm import unittest class TestPass(unittest.TestCase): @@ -26,11 +27,12 @@ class TestPass(unittest.TestCase): self.assertTrue(tli.description) pm.add(tli) - tti = TargetTransformInfo.new(tm) - self.assertFalse(tti.name) - self.assertTrue(tti.description) + if llvm.version >= (3, 2): + tti = TargetTransformInfo.new(tm) + self.assertFalse(tti.name) + self.assertTrue(tti.description) - pm.add(tti) + pm.add(tti) pmb = PassManagerBuilder.new() pmb.opt_level = 3