From da55b762029b6bbc8567c411ac0fa245436d2263 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Sat, 5 Oct 2013 14:03:13 +0800 Subject: [PATCH 1/2] Add buildscript for devel branch --- buildscripts/condarecipe_devel/bld.bat | 6 +++++ buildscripts/condarecipe_devel/build.sh | 13 ++++++++++ buildscripts/condarecipe_devel/meta.yaml | 28 ++++++++++++++++++++++ buildscripts/condarecipe_devel/run_test.py | 19 +++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 buildscripts/condarecipe_devel/bld.bat create mode 100644 buildscripts/condarecipe_devel/build.sh create mode 100644 buildscripts/condarecipe_devel/meta.yaml create mode 100644 buildscripts/condarecipe_devel/run_test.py diff --git a/buildscripts/condarecipe_devel/bld.bat b/buildscripts/condarecipe_devel/bld.bat new file mode 100644 index 0000000..e9177c5 --- /dev/null +++ b/buildscripts/condarecipe_devel/bld.bat @@ -0,0 +1,6 @@ +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_devel/build.sh b/buildscripts/condarecipe_devel/build.sh new file mode 100644 index 0000000..5c98fde --- /dev/null +++ b/buildscripts/condarecipe_devel/build.sh @@ -0,0 +1,13 @@ +#!/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_devel/meta.yaml b/buildscripts/condarecipe_devel/meta.yaml new file mode 100644 index 0000000..4f7162b --- /dev/null +++ b/buildscripts/condarecipe_devel/meta.yaml @@ -0,0 +1,28 @@ +package: + name: llvmpy + version: 99.9.9 + +source: + git_url: git@github.com:llvmpy/llvmpy.git + git_tag: devel + +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_devel/run_test.py b/buildscripts/condarecipe_devel/run_test.py new file mode 100644 index 0000000..281a599 --- /dev/null +++ b/buildscripts/condarecipe_devel/run_test.py @@ -0,0 +1,19 @@ +import sys +import platform +import llvm + +from llvm.core import Module +from llvm.ee import EngineBuilder +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) == 0 + +print('llvm.__version__: %s' % llvm.__version__) +#assert llvm.__version__ == '0.12.0' From 0dc22f26a0a7ad59f99791eafc19ed289b9b97f4 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Sat, 5 Oct 2013 15:06:19 +0800 Subject: [PATCH 2/2] Begin to add C-ABI ArgInfo --- llvm/abi.py | 195 +++++++++++++++++++++++++++++++++++++++++ llvm/tests/test_abi.py | 28 ++++++ 2 files changed, 223 insertions(+) create mode 100644 llvm/abi.py create mode 100644 llvm/tests/test_abi.py diff --git a/llvm/abi.py b/llvm/abi.py new file mode 100644 index 0000000..49f9271 --- /dev/null +++ b/llvm/abi.py @@ -0,0 +1,195 @@ +''' +Provide C ABI information + +Reference to +- http://clang.llvm.org/doxygen/classclang_1_1ABIArgInfo.html +- http://clang.llvm.org/doxygen/CodeGen_2TargetInfo_8cpp_source.html + See X86_32ABIInfo, computeInfo, classifyArgumentType +''' +from collections import namedtuple +import llvm.core as lc + +AGGREGATE_TYPES = frozenset([lc.TYPE_STRUCT, lc.TYPE_ARRAY]) + +class ABIArgInfo(object): + ''' + ABI argument info + + Try to be a close translation of clang::ABIArgInfo. + (See http://clang.llvm.org/doxygen/classclang_1_1ABIArgInfo.html) + But, this is for C not C++. + ''' + __slots__ = ['_kind', '_typedata', '_paddingtype', '_uintdata', + '_booldata0', '_booldata1', '_inreg', '_paddinginreg'] + + # Enum for argument info kind + DIRECT = 0 + EXTEND = 1 + IGNORE = 2 + INDIRECT = 3 + EXPAND = 4 + + def __init__(self, kind, td=None, ui=0, b0=False, b1=False, ir=False, + pir=False, p=None): + self._kind = kind + self._typedata = td + self._paddingtype = p + self._uintdata = ui + self._booldata0 = b0 + self._booldata1 = b1 + self._inreg = ir + self._paddinginreg = pir + + def __repr__(self): + data = [] + if self.is_direct: + data.append('Direct') + data.append('coerce=%s' % self.coerce_to_type) + elif self.is_indirect: + data.append('Indirect') + data.append('align=%s' % self.indirect_align) + data.append('byval=%s' % self.indirect_by_val) + data.append('realign=%s' % self.indirect_by_realign) + elif self.is_extend: + data.append('Extend') + elif self.is_ignore: + data.append('Ignore') + elif self.is_expand: + data.append('Expand') + else: + raise AssertionError('invalid kind: %s' % self._kind) + + return '' % ' '.join(data) + + # ---- accessors ---- + + @property + def is_direct(self): + return self._kind == self.DIRECT + + @property + def is_indirect(self): + return self._kind == self.INDIRECT + + @property + def is_extend(self): + return self._kind == self.EXTEND + + @property + def is_ignore(self): + return self._kind == self.IGNORE + + @property + def is_expand(self): + return self._kind == self.EXPAND + + @property + def can_have_coerce_to_type(self): + return self.is_direct or self.is_extend + + @property + def direct_offset(self): + assert self.is_direct or self.is_extend + return self._uintdata + + @property + def padding_type(self): + return self._paddingtype + + @property + def padding_in_reg(self): + return self._paddinginreg + + @property + def coerce_to_type(self): + assert self.can_have_coerce_to_type + return self._typedata + + @coerce_to_type.setter + def coerce_to_type(self, ty): + self._typedata = ty + + @property + def in_reg(self): + return self.is_direct() or self.is_extend or self.is_indirect + + @property + def indirect_align(self): + assert self.is_indirect + return self._uintdata + + @property + def indirect_by_val(self): + assert self.is_indirect + return self._booldata0 + + @property + def indirect_by_realign(self): + assert self.is_indirect + return self._booldata1 + + # ---- factories ---- + + @classmethod + def get_ignore(cls): + return cls(kind=cls.IGNORE) + + @classmethod + def get_extend(cls, ty=None): + return cls(kind=cls.EXTEND, td=ty) + + @classmethod + def get_direct(cls): + return cls(kind=cls.DIRECT) + +class ABIInfo(object): + def __init__(self, datalayout): + self.datalayout = datalayout + + def compute_info(self, return_type, args): + self.return_info = self.classify_return_type(return_type) + self.arg_infos = [] + for a in args: + info = self.classify_argument_type(a) + self.arg_infos.append(info) + + def classify_return_type(self, retty): + raise NotImplementedError + + def classify_argument_type(self, argty): + raise NotImplementedError + +class DefaultABIInfo(ABIInfo): + def classify_argument_type(self, argty): + if argty.kind in AGGREGATE_TYPES: + return ABIArgInfo.get_indirect() + + if self.promotable_integers(argty): + return ABIArgInfo.get_extend() + else: + return ABIArgInfo.get_direct() + + def classify_return_type(self, retty): + if retty.kind == lc.TYPE_VOID: + return ABIArgInfo.get_ignore() + + if retty.kind in AGGREGATE_TYPES: + return ABIArgInfo.get_indirect() + + if self.promotable_integers(retty): + return ABIArgInfo.get_extend() + else: + return ABIArgInfo.get_direct() + + def promotable_integers(self, ty): + if ty.kind != lc.TYPE_INTEGER: + return False + abisize = self.datalayout.abi_size(ty) * 8 + return ty.width < abisize + +#------------------------------------------------------------------------------ +# X86-32 +#------------------------------------------------------------------------------ + +class X86_32ABIInfo(ABIInfo): + MIN_ABI_STACK_ALIGN = 4 # bytes diff --git a/llvm/tests/test_abi.py b/llvm/tests/test_abi.py new file mode 100644 index 0000000..35fc269 --- /dev/null +++ b/llvm/tests/test_abi.py @@ -0,0 +1,28 @@ +from __future__ import print_function +import unittest +from llvm.core import Type +from llvm.ee import TargetMachine +from llvm.abi import DefaultABIInfo +from .support import TestCase, tests + +class TestDefaultABIArgInfo(TestCase): + '''Simply exercise the API + ''' + def test_abi_int(self): + tm = TargetMachine.new() + td = tm.target_data.clone() + abiinfo = DefaultABIInfo(td) + abiinfo.compute_info(Type.void(), [Type.int(1), Type.int(8), + Type.int(16), Type.int(32), + Type.int(64)]) + print(abiinfo.arg_infos) + print(abiinfo.return_info) + + abiinfo.compute_info(Type.int(32), []) + print(abiinfo.arg_infos) + print(abiinfo.return_info) + +tests.append(TestDefaultABIArgInfo) + +if __name__ == '__main__': + unittest.main()