[pypy-commit] pypy py3k: hg merge default
antocuni
noreply at buildbot.pypy.org
Wed Oct 17 17:20:21 CEST 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: py3k
Changeset: r58176:b4e0f5b4079b
Date: 2012-10-17 16:04 +0200
http://bitbucket.org/pypy/pypy/changeset/b4e0f5b4079b/
Log: hg merge default
diff too long, truncating to 2000 out of 4137 lines
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -17,12 +17,6 @@
projects, or anything else in PyPy, pop up on IRC or write to us on the
`mailing list`_.
-Make big integers faster
--------------------------
-
-PyPy's implementation of the Python ``long`` type is slower than CPython's.
-Find out why and optimize them. **UPDATE:** this was done (thanks stian).
-
Make bytearray type fast
------------------------
@@ -81,14 +75,6 @@
* Allow separate compilation of extension modules.
-Work on some of other languages
--------------------------------
-
-There are various languages implemented using the RPython translation toolchain.
-One of the most interesting is the `JavaScript implementation`_, but there
-are others like scheme or prolog. An interesting project would be to improve
-the jittability of those or to experiment with various optimizations.
-
Various GCs
-----------
@@ -144,8 +130,6 @@
* `hg`
-* `sympy`
-
Experiment (again) with LLVM backend for RPython compilation
------------------------------------------------------------
@@ -191,4 +175,3 @@
.. _`issue tracker`: http://bugs.pypy.org
.. _`mailing list`: http://mail.python.org/mailman/listinfo/pypy-dev
.. _`jitviewer`: http://bitbucket.org/pypy/jitviewer
-.. _`JavaScript implementation`: https://bitbucket.org/pypy/lang-js/overview
diff --git a/pypy/jit/backend/llvm/__init__.py b/pypy/jit/backend/llvm/__init__.py
deleted file mode 100644
diff --git a/pypy/jit/backend/llvm/compile.py b/pypy/jit/backend/llvm/compile.py
deleted file mode 100644
--- a/pypy/jit/backend/llvm/compile.py
+++ /dev/null
@@ -1,732 +0,0 @@
-import py
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib.unroll import unrolling_iterable
-from pypy.jit.metainterp.history import Const, INT
-from pypy.jit.backend.llvm import llvm_rffi
-from pypy.jit.metainterp import resoperation
-from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.backend.llsupport import symbolic
-from pypy.jit.backend.llvm.runner import SizeDescr, CallDescr
-from pypy.jit.backend.llvm.runner import FieldDescr, ArrayDescr
-
-# ____________________________________________________________
-
-class LLVMJITCompiler(object):
- FUNC = lltype.FuncType([], lltype.Signed)
- lastovf = lltype.nullptr(llvm_rffi.LLVMValueRef.TO)
-
- def __init__(self, cpu, loop):
- self.cpu = cpu
- self.loop = loop
-
- def compile(self):
- self.start_generating_function()
- self.generate_initial_arguments_load()
- self.generate_loop_body()
- self.close_phi_nodes()
- self.done_generating_function()
-
- def start_generating_function(self):
- func = llvm_rffi.LLVMAddFunction(self.cpu.module, "", self.cpu.ty_func)
- self.compiling_func = func
- self.builder = llvm_rffi.LLVMCreateBuilder()
- self.vars = {}
-
- def generate_initial_arguments_load(self):
- loop = self.loop
- func = self.compiling_func
- bb_entry = llvm_rffi.LLVMAppendBasicBlock(func, "entry")
- llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_entry)
- self.cpu._ensure_in_args(len(loop.inputargs))
- self.phi_incoming_blocks = [bb_entry]
- self.phi_incoming_values = []
- for i in range(len(loop.inputargs)):
- ty = self.cpu._get_pointer_type(loop.inputargs[i])
- llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty)
- res = llvm_rffi.LLVMBuildLoad(self.builder, llvmconstptr, "")
- self.phi_incoming_values.append([res])
- self.bb_start = llvm_rffi.LLVMAppendBasicBlock(func, "")
- llvm_rffi.LLVMBuildBr(self.builder, self.bb_start)
- #
- llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, self.bb_start)
- for v in loop.inputargs:
- ty = self.cpu._get_var_type(v)
- phi = llvm_rffi.LLVMBuildPhi(self.builder, ty, "")
- self.vars[v] = phi
-
- def generate_loop_body(self):
- func = self.compiling_func
- self.pending_blocks = [(self.loop.operations, self.bb_start, False)]
- while self.pending_blocks:
- operations, bb, exc = self.pending_blocks.pop()
- self._generate_branch(operations, bb, exc)
- self.bb_start = lltype.nullptr(llvm_rffi.LLVMBasicBlockRef.TO)
-
- def close_phi_nodes(self):
- incoming_blocks = lltype.malloc(
- rffi.CArray(llvm_rffi.LLVMBasicBlockRef),
- len(self.phi_incoming_blocks), flavor='raw')
- incoming_values = lltype.malloc(
- rffi.CArray(llvm_rffi.LLVMValueRef),
- len(self.phi_incoming_blocks), flavor='raw')
- for j in range(len(self.phi_incoming_blocks)):
- incoming_blocks[j] = self.phi_incoming_blocks[j]
- loop = self.loop
- for i in range(len(loop.inputargs)):
- phi = self.vars[loop.inputargs[i]]
- incoming = self.phi_incoming_values[i]
- for j in range(len(self.phi_incoming_blocks)):
- incoming_values[j] = incoming[j]
- llvm_rffi.LLVMAddIncoming(phi, incoming_values, incoming_blocks,
- len(self.phi_incoming_blocks))
- lltype.free(incoming_values, flavor='raw')
- lltype.free(incoming_blocks, flavor='raw')
-
- def done_generating_function(self):
- llvm_rffi.LLVMDisposeBuilder(self.builder)
- llvm_rffi.LLVMDumpValue(self.compiling_func) # xxx for debugging
- #
- func_addr = llvm_rffi.LLVM_EE_getPointerToFunction(self.cpu.ee,
- self.compiling_func)
- if not we_are_translated():
- print '--- function is at %r ---' % (func_addr,)
- #
- func_ptr = rffi.cast(lltype.Ptr(self.FUNC), func_addr)
- index = self.loop._llvm_compiled_index
- if index < 0:
- self.loop._llvm_compiled_index = len(self.cpu.compiled_functions)
- self.cpu.compiled_functions.append(func_ptr)
- else:
- self.cpu.compiled_functions[index] = func_ptr
-
- def _generate_branch(self, operations, basicblock, exc):
- llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, basicblock)
- # The flag 'exc' is set to True if we are a branch handling a
- # GUARD_EXCEPTION or GUARD_NO_EXCEPTION. In this case, we have to
- # store away the exception into self.backup_exc_xxx, *unless* the
- # branch starts with a further GUARD_EXCEPTION/GUARD_NO_EXCEPTION.
- if exc:
- opnum = operations[0].getopnum()
- if opnum not in (rop.GUARD_EXCEPTION, rop.GUARD_NO_EXCEPTION):
- self._store_away_exception()
- # Normal handling of the operations follows.
- for op in operations:
- self._generate_op(op)
-
- def _generate_op(self, op):
- opnum = op.getopnum()
- for i, name in all_operations:
- if opnum == i:
- meth = getattr(self, name)
- meth(op)
- return
- else:
- raise MissingOperation(resoperation.opname[opnum])
-
- def _store_away_exception(self):
- # etype, evalue: ty_char_ptr
- etype = llvm_rffi.LLVMBuildLoad(self.builder,
- self.cpu.const_exc_type, "")
- llvm_rffi.LLVMBuildStore(self.builder,
- self.cpu.const_null_charptr,
- self.cpu.const_exc_type)
- llvm_rffi.LLVMBuildStore(self.builder,
- etype,
- self.cpu.const_backup_exc_type)
- evalue = llvm_rffi.LLVMBuildLoad(self.builder,
- self.cpu.const_exc_value, "")
- llvm_rffi.LLVMBuildStore(self.builder,
- self.cpu.const_null_charptr,
- self.cpu.const_exc_value)
- llvm_rffi.LLVMBuildStore(self.builder,
- evalue,
- self.cpu.const_backup_exc_value)
-
- def getintarg(self, v):
- try:
- value_ref = self.vars[v]
- except KeyError:
- assert isinstance(v, Const)
- return self.cpu._make_const_int(v.getint())
- else:
- return self._cast_to_int(value_ref)
-
- def _cast_to_int(self, value_ref):
- ty = llvm_rffi.LLVMTypeOf(value_ref)
- if ty == self.cpu.ty_int:
- return value_ref
- else:
- return llvm_rffi.LLVMBuildZExt(self.builder, value_ref,
- self.cpu.ty_int, "")
-
- def getbitarg(self, v):
- try:
- value_ref = self.vars[v]
- except KeyError:
- assert isinstance(v, Const)
- return self.cpu._make_const_bit(v.getint())
- else:
- return self._cast_to_bit(value_ref)
-
- def _cast_to_bit(self, value_ref):
- ty = llvm_rffi.LLVMTypeOf(value_ref)
- if ty == self.cpu.ty_bit:
- return value_ref
- else:
- return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref,
- self.cpu.ty_bit, "")
-
- def getchararg(self, v):
- try:
- value_ref = self.vars[v]
- except KeyError:
- assert isinstance(v, Const)
- return self.cpu._make_const_char(v.getint())
- else:
- return self._cast_to_char(value_ref)
-
- def _cast_to_char(self, value_ref):
- ty = llvm_rffi.LLVMTypeOf(value_ref)
- if ty == self.cpu.ty_char:
- return value_ref
- elif ty == self.cpu.ty_int or ty == self.cpu.ty_unichar:
- return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref,
- self.cpu.ty_char, "")
- elif ty == self.cpu.ty_bit:
- return llvm_rffi.LLVMBuildZExt(self.builder, value_ref,
- self.cpu.ty_char, "")
- else:
- raise AssertionError("type is not an int nor a bit")
-
- def getunichararg(self, v):
- try:
- value_ref = self.vars[v]
- except KeyError:
- assert isinstance(v, Const)
- return self.cpu._make_const_unichar(v.getint())
- else:
- return self._cast_to_unichar(value_ref)
-
- def _cast_to_unichar(self, value_ref):
- ty = llvm_rffi.LLVMTypeOf(value_ref)
- if ty == self.cpu.ty_unichar:
- return value_ref
- elif ty == self.cpu.ty_int:
- return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref,
- self.cpu.ty_char, "")
- elif ty == self.cpu.ty_bit or ty == self.cpu.ty_char:
- return llvm_rffi.LLVMBuildZExt(self.builder, value_ref,
- self.cpu.ty_char, "")
- else:
- raise AssertionError("type is not an int nor a bit")
-
- def getptrarg(self, v):
- try:
- value_ref = self.vars[v]
- except KeyError:
- return self.cpu._make_const(v.getaddr(self.cpu),
- self.cpu.ty_char_ptr)
- else:
- ty = llvm_rffi.LLVMTypeOf(value_ref)
- if ty == self.cpu.ty_int:
- value_ref = llvm_rffi.LLVMBuildIntToPtr(self.builder,
- value_ref,
- self.cpu.ty_char_ptr,
- "")
- else:
- assert (ty != self.cpu.ty_bit and
- ty != self.cpu.ty_char and
- ty != self.cpu.ty_unichar)
- return value_ref
-
- for _opname, _llvmname in [('INT_ADD', 'Add'),
- ('INT_SUB', 'Sub'),
- ('INT_MUL', 'Mul'),
- ('INT_FLOORDIV', 'SDiv'),
- ('INT_MOD', 'SRem'),
- ('INT_LSHIFT', 'Shl'),
- ('INT_RSHIFT', 'AShr'),
- ('UINT_RSHIFT', 'LShr'),
- ('INT_AND', 'And'),
- ('INT_OR', 'Or'),
- ('INT_XOR', 'Xor'),
- ]:
- exec py.code.Source('''
- def generate_%s(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuild%s(
- self.builder,
- self.getintarg(op.args[0]),
- self.getintarg(op.args[1]),
- "")
- ''' % (_opname, _llvmname)).compile()
-
- for _opname, _predicate in [('INT_LT', llvm_rffi.Predicate.SLT),
- ('INT_LE', llvm_rffi.Predicate.SLE),
- ('INT_EQ', llvm_rffi.Predicate.EQ),
- ('INT_NE', llvm_rffi.Predicate.NE),
- ('INT_GT', llvm_rffi.Predicate.SGT),
- ('INT_GE', llvm_rffi.Predicate.SGE),
- ('UINT_LT', llvm_rffi.Predicate.ULT),
- ('UINT_LE', llvm_rffi.Predicate.ULE),
- ('UINT_GT', llvm_rffi.Predicate.UGT),
- ('UINT_GE', llvm_rffi.Predicate.UGE)]:
- exec py.code.Source('''
- def generate_%s(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuildICmp(
- self.builder,
- %d,
- self.getintarg(op.args[0]),
- self.getintarg(op.args[1]),
- "")
- ''' % (_opname, _predicate)).compile()
-
- def generate_INT_NEG(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuildNeg(self.builder,
- self.getintarg(op.args[0]),
- "")
-
- def generate_INT_INVERT(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuildNot(self.builder,
- self.getintarg(op.args[0]),
- "")
-
- def generate_INT_IS_TRUE(self, op):
- v = op.args[0]
- try:
- value_ref = self.vars[v]
- if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit:
- raise KeyError
- except KeyError:
- res = llvm_rffi.LLVMBuildICmp(self.builder,
- llvm_rffi.Predicate.NE,
- self.getintarg(op.args[0]),
- self.cpu.const_zero,
- "")
- else:
- res = value_ref # value_ref: ty_bit. this is a no-op
- self.vars[op.result] = res
-
- def generate_BOOL_NOT(self, op):
- v = op.args[0]
- try:
- value_ref = self.vars[v]
- if llvm_rffi.LLVMTypeOf(value_ref) != self.cpu.ty_bit:
- raise KeyError
- except KeyError:
- res = llvm_rffi.LLVMBuildICmp(self.builder,
- llvm_rffi.Predicate.EQ,
- self.getintarg(op.args[0]),
- self.cpu.const_zero,
- "")
- else:
- # value_ref: ty_bit
- res = llvm_rffi.LLVMBuildNot(self.builder, value_ref, "")
- self.vars[op.result] = res
-
- def generate_INT_ADD_OVF(self, op):
- self._generate_ovf_op(op, self.cpu.f_add_ovf)
-
- def generate_INT_SUB_OVF(self, op):
- self._generate_ovf_op(op, self.cpu.f_sub_ovf)
-
- def generate_INT_MUL_OVF(self, op):
- self._generate_ovf_op(op, self.cpu.f_mul_ovf)
-
- def _generate_ovf_op(self, op, f_intrinsic):
- self._generate_ovf_test(f_intrinsic,
- self.getintarg(op.args[0]),
- self.getintarg(op.args[1]),
- op.result)
-
- def _generate_ovf_test(self, f_intrinsic, arg0, arg1, result):
- arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2,
- flavor='raw')
- arglist[0] = arg0
- arglist[1] = arg1
- tmp = llvm_rffi.LLVMBuildCall(self.builder, f_intrinsic,
- arglist, 2, "")
- lltype.free(arglist, flavor='raw')
- self.vars[result] = llvm_rffi.LLVMBuildExtractValue(self.builder,
- tmp, 0, "")
- self.lastovf = llvm_rffi.LLVMBuildExtractValue(self.builder, tmp, 1,
- "")
-
- def generate_GUARD_FALSE(self, op):
- self._generate_guard(op, self.getbitarg(op.args[0]), True)
-
- def generate_GUARD_TRUE(self, op):
- self._generate_guard(op, self.getbitarg(op.args[0]), False)
-
- def generate_GUARD_VALUE(self, op):
- if op.args[0].type == INT:
- arg0 = self.getintarg(op.args[0])
- arg1 = self.getintarg(op.args[1])
- else:
- arg0 = self.getptrarg(op.args[0])
- arg1 = self.getptrarg(op.args[1])
- equal = llvm_rffi.LLVMBuildICmp(self.builder,
- llvm_rffi.Predicate.EQ,
- arg0, arg1, "")
- self._generate_guard(op, equal, False)
-
- def generate_GUARD_CLASS(self, op):
- loc = self._generate_field_gep(op.args[0], self.cpu.fielddescr_vtable)
- cls = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
- equal = llvm_rffi.LLVMBuildICmp(self.builder,
- llvm_rffi.Predicate.EQ,
- cls,
- self.getintarg(op.args[1]), "")
- self._generate_guard(op, equal, False)
-
- def generate_GUARD_NO_EXCEPTION(self, op):
- # etype: ty_char_ptr
- etype = llvm_rffi.LLVMBuildLoad(self.builder,
- self.cpu.const_exc_type, "")
- eisnull = llvm_rffi.LLVMBuildICmp(self.builder,
- llvm_rffi.Predicate.EQ,
- etype,
- self.cpu.const_null_charptr, "")
- self._generate_guard(op, eisnull, False, exc=True)
-
- def generate_GUARD_EXCEPTION(self, op):
- v = op.args[0]
- assert isinstance(v, Const)
- # etype, expectedtype: ty_char_ptr
- expectedtype = self.cpu._make_const(v.getint(), self.cpu.ty_char_ptr)
- etype = llvm_rffi.LLVMBuildLoad(self.builder,
- self.cpu.const_exc_type, "")
- eisequal = llvm_rffi.LLVMBuildICmp(self.builder,
- llvm_rffi.Predicate.EQ,
- etype,
- expectedtype, "")
- self._generate_guard(op, eisequal, False, exc=True)
- self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder,
- self.cpu.const_exc_value,
- "")
-
- def generate_GUARD_NO_OVERFLOW(self, op):
- self._generate_guard(op, self.lastovf, True)
-
- def generate_GUARD_OVERFLOW(self, op):
- self._generate_guard(op, self.lastovf, False)
-
- def _generate_guard(self, op, verify_condition, reversed, exc=False):
- func = self.compiling_func
- bb_on_track = llvm_rffi.LLVMAppendBasicBlock(func, "")
- bb_off_track = llvm_rffi.LLVMAppendBasicBlock(func, "")
- llvm_rffi.LLVMBuildCondBr(self.builder, verify_condition,
- bb_on_track, bb_off_track)
- if reversed:
- bb_on_track, bb_off_track = bb_off_track, bb_on_track
- # generate the on-track part first, and the off-track part later
- self.pending_blocks.append((op.suboperations, bb_off_track, exc))
- llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_on_track)
-
- def generate_JUMP(self, op):
- if op.jump_target is self.loop:
- basicblock = llvm_rffi.LLVMGetInsertBlock(self.builder)
- self.phi_incoming_blocks.append(basicblock)
- for i in range(len(op.args)):
- incoming = self.phi_incoming_values[i]
- v = op.args[i]
- if v.type == INT:
- value_ref = self.getintarg(v)
- else:
- value_ref = self.getptrarg(v)
- incoming.append(value_ref)
- llvm_rffi.LLVMBuildBr(self.builder, self.bb_start)
- else:
- index = op.jump_target._llvm_compiled_index
- assert index >= 0
- self._generate_fail(op.args, index)
-
- def generate_FAIL(self, op):
- i = len(self.cpu.fail_ops)
- self.cpu.fail_ops.append(op)
- self._generate_fail(op.args, ~i)
-
- def _generate_fail(self, args, index):
- self.cpu._ensure_out_args(len(args))
- for i in range(len(args)):
- v = args[i]
- if v.type == INT:
- value_ref = self.getintarg(v)
- ty = self.cpu.ty_int_ptr
- else:
- value_ref = self.getptrarg(v)
- ty = self.cpu.ty_char_ptr_ptr
- llvmconstptr = self.cpu._make_const(self.cpu.in_out_args[i], ty)
- llvm_rffi.LLVMBuildStore(self.builder, value_ref,
- llvmconstptr)
- llvm_rffi.LLVMBuildRet(self.builder, self.cpu._make_const_int(index))
-
- def _generate_field_gep(self, v_structure, fielddescr):
- assert isinstance(fielddescr, FieldDescr)
- indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1,
- flavor='raw')
- indices[0] = self.cpu._make_const_int(fielddescr.offset)
- location = llvm_rffi.LLVMBuildGEP(self.builder,
- self.getptrarg(v_structure),
- indices, 1, "")
- lltype.free(indices, flavor='raw')
- ty = self.cpu.types_ptr_by_index[fielddescr.size_index]
- location = llvm_rffi.LLVMBuildBitCast(self.builder, location, ty, "")
- return location
-
- def generate_GETFIELD_GC(self, op):
- loc = self._generate_field_gep(op.args[0], op.getdescr())
- self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
-
- generate_GETFIELD_GC_PURE = generate_GETFIELD_GC
- generate_GETFIELD_RAW = generate_GETFIELD_GC
- generate_GETFIELD_RAW_PURE = generate_GETFIELD_GC
-
- def generate_SETFIELD_GC(self, op):
- fielddescr = op.getdescr()
- loc = self._generate_field_gep(op.args[0], fielddescr)
- assert isinstance(fielddescr, FieldDescr)
- getarg = self.cpu.getarg_by_index[fielddescr.size_index]
- value_ref = getarg(self, op.args[1])
- llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
-
- def generate_CALL(self, op):
- calldescr = op.getdescr()
- assert isinstance(calldescr, CallDescr)
- ty_function_ptr = self.cpu.get_calldescr_ty_function_ptr(calldescr)
- v = op.args[0]
- if isinstance(v, Const):
- func = self.cpu._make_const(v.getint(), ty_function_ptr)
- else:
- func = self.getintarg(v)
- func = llvm_rffi.LLVMBuildIntToPtr(self.builder,
- func,
- ty_function_ptr, "")
- nb_args = len(op.args) - 1
- arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), nb_args,
- flavor='raw')
- for i in range(nb_args):
- v = op.args[1 + i]
- index = calldescr.args_indices[i]
- getarg = self.cpu.getarg_by_index[index]
- value_ref = getarg(self, v)
- arglist[i] = value_ref
- res = llvm_rffi.LLVMBuildCall(self.builder,
- func, arglist, nb_args, "")
- lltype.free(arglist, flavor='raw')
- if op.result is not None:
- assert calldescr.res_index >= 0
- self.vars[op.result] = res
-
- generate_CALL_PURE = generate_CALL
-
- def generate_CAST_PTR_TO_INT(self, op):
- res = llvm_rffi.LLVMBuildPtrToInt(self.builder,
- self.getptrarg(op.args[0]),
- self.cpu.ty_int, "")
- self.vars[op.result] = res
-
- def generate_CAST_INT_TO_PTR(self, op):
- res = llvm_rffi.LLVMBuildIntToPtr(self.builder,
- self.getintarg(op.args[0]),
- self.cpu.ty_char_ptr, "")
- self.vars[op.result] = res
-
- def generate_OOIS(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuildICmp(
- self.builder, llvm_rffi.Predicate.EQ,
- self.getptrarg(op.args[0]),
- self.getptrarg(op.args[1]), "")
-
- def generate_OOISNOT(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuildICmp(
- self.builder, llvm_rffi.Predicate.NE,
- self.getptrarg(op.args[0]),
- self.getptrarg(op.args[1]), "")
-
- def generate_OOISNULL(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuildICmp(
- self.builder, llvm_rffi.Predicate.EQ,
- self.getptrarg(op.args[0]),
- self.cpu.const_null_charptr, "")
-
- def generate_OONONNULL(self, op):
- self.vars[op.result] = llvm_rffi.LLVMBuildICmp(
- self.builder, llvm_rffi.Predicate.NE,
- self.getptrarg(op.args[0]),
- self.cpu.const_null_charptr, "")
-
- def generate_SAME_AS(self, op):
- if op.args[0].type == INT:
- self.vars[op.result] = self.getintarg(op.args[0])
- else:
- self.vars[op.result] = self.getptrarg(op.args[0])
-
- def _generate_len_gep(self, array_ref, ty, const_index_length):
- array = llvm_rffi.LLVMBuildBitCast(self.builder,
- array_ref, ty, "")
- indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2,
- flavor='raw')
- indices[0] = self.cpu.const_zero
- indices[1] = const_index_length
- loc = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 2, "")
- lltype.free(indices, flavor='raw')
- return loc
-
- def _generate_len(self, op, ty, const_index_length):
- loc = self._generate_len_gep(self.getptrarg(op.args[0]),
- ty, const_index_length)
- self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
-
- def generate_ARRAYLEN_GC(self, op):
- arraydescr = op.getdescr()
- assert isinstance(arraydescr, ArrayDescr)
- self._generate_len(op, arraydescr.ty_array_ptr,
- self.cpu.const_array_index_length)
-
- def _generate_gep(self, op, ty, const_index_array):
- array = llvm_rffi.LLVMBuildBitCast(self.builder,
- self.getptrarg(op.args[0]),
- ty, "")
- indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 3,
- flavor='raw')
- indices[0] = self.cpu.const_zero
- indices[1] = const_index_array
- indices[2] = self.getintarg(op.args[1])
- location = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 3, "")
- lltype.free(indices, flavor='raw')
- return location
-
- def _generate_array_gep(self, op):
- arraydescr = op.getdescr()
- assert isinstance(arraydescr, ArrayDescr)
- location = self._generate_gep(op, arraydescr.ty_array_ptr,
- self.cpu.const_array_index_array)
- return location
-
- def generate_GETARRAYITEM_GC(self, op):
- loc = self._generate_array_gep(op)
- self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
-
- generate_GETARRAYITEM_GC_PURE = generate_GETARRAYITEM_GC
-
- def generate_SETARRAYITEM_GC(self, op):
- loc = self._generate_array_gep(op)
- arraydescr = op.getdescr()
- assert isinstance(arraydescr, ArrayDescr)
- getarg = self.cpu.getarg_by_index[arraydescr.itemsize_index]
- value_ref = getarg(self, op.args[2])
- llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
-
- def generate_STRLEN(self, op):
- self._generate_len(op, self.cpu.ty_string_ptr,
- self.cpu.const_string_index_length)
-
- def generate_UNICODELEN(self, op):
- self._generate_len(op, self.cpu.ty_unicode_ptr,
- self.cpu.const_unicode_index_length)
-
- def generate_STRGETITEM(self, op):
- loc = self._generate_gep(op, self.cpu.ty_string_ptr,
- self.cpu.const_string_index_array)
- self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
-
- def generate_UNICODEGETITEM(self, op):
- loc = self._generate_gep(op, self.cpu.ty_unicode_ptr,
- self.cpu.const_unicode_index_array)
- self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
-
- def generate_STRSETITEM(self, op):
- loc = self._generate_gep(op, self.cpu.ty_string_ptr,
- self.cpu.const_string_index_array)
- value_ref = self.getchararg(op.args[2])
- llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
-
- def generate_UNICODESETITEM(self, op):
- loc = self._generate_gep(op, self.cpu.ty_unicode_ptr,
- self.cpu.const_unicode_index_array)
- value_ref = self.getunichararg(op.args[2])
- llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
-
- def _generate_new(self, size_ref):
- malloc_func = self.cpu._make_const(self.cpu.malloc_fn_ptr,
- self.cpu.ty_malloc_fn)
- arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 1,
- flavor='raw')
- arglist[0] = size_ref
- res = llvm_rffi.LLVMBuildCall(self.builder, malloc_func,
- arglist, 1, "")
- lltype.free(arglist, flavor='raw')
- return res
-
- def generate_NEW(self, op):
- sizedescr = op.getdescr()
- assert isinstance(sizedescr, SizeDescr)
- res = self._generate_new(self.cpu._make_const_int(sizedescr.size))
- self.vars[op.result] = res
-
- def generate_NEW_WITH_VTABLE(self, op):
- sizedescr = self.cpu.class_sizes[op.args[0].getint()]
- res = self._generate_new(self.cpu._make_const_int(sizedescr.size))
- self.vars[op.result] = res
- loc = self._generate_field_gep(op.result, self.cpu.vtable_descr)
- value_ref = self.getintarg(op.args[0])
- llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
-
- def _generate_new_array(self, op, ty_array, const_item_size,
- const_index_array, const_index_length):
- length_ref = self.getintarg(op.args[0])
- if const_item_size == self.cpu.const_one:
- arraysize_ref = length_ref
- else:
- arraysize_ref = llvm_rffi.LLVMBuildMul(self.builder,
- length_ref,
- const_item_size,
- "")
- size_ref = llvm_rffi.LLVMBuildAdd(self.builder,
- const_index_array,
- arraysize_ref,
- "")
- res = self._generate_new(size_ref)
- loc = self._generate_len_gep(res, ty_array, const_index_length)
- llvm_rffi.LLVMBuildStore(self.builder,
- length_ref,
- loc, "")
- self.vars[op.result] = res
-
- def generate_NEW_ARRAY(self, op):
- arraydescr = op.getdescr()
- assert isinstance(arraydescr, ArrayDescr)
- self._generate_new_array(op, arraydescr.ty_array_ptr,
- self.cpu._make_const_int(arraydescr.itemsize),
- self.cpu.const_array_index_array,
- self.cpu.const_array_index_length)
-
- def generate_NEWSTR(self, op):
- self._generate_new_array(op, self.cpu.ty_string_ptr,
- self.cpu.const_one,
- self.cpu.const_string_index_array,
- self.cpu.const_string_index_length)
-
- def generate_NEWUNICODE(self, op):
- self._generate_new_array(op, self.cpu.ty_unicode_ptr,
- self.cpu._make_const_int(self.cpu.size_of_unicode),
- self.cpu.const_unicode_index_array,
- self.cpu.const_unicode_index_length)
-
- def generate_DEBUG_MERGE_POINT(self, op):
- pass
-
-# ____________________________________________________________
-
-class MissingOperation(Exception):
- pass
-
-all_operations = {}
-for _key, _value in rop.__dict__.items():
- if 'A' <= _key <= 'Z':
- assert _value not in all_operations
- methname = 'generate_' + _key
- if hasattr(LLVMJITCompiler, methname):
- all_operations[_value] = methname
-all_operations = unrolling_iterable(all_operations.items())
diff --git a/pypy/jit/backend/llvm/demo1.c b/pypy/jit/backend/llvm/demo1.c
deleted file mode 100644
--- a/pypy/jit/backend/llvm/demo1.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* LLVM includes */
-#include "llvm-c/Analysis.h"
-#include "llvm-c/Transforms/Scalar.h"
-#include "llvm-c/ExecutionEngine.h"
-#include "demo2.h"
-
-/* The following list of functions seems to be necessary to force the
- * functions to be included in pypy_cache_llvm.so. The list is never
- * used. Actually, any single function seems to be enough...
- */
-void* llvm_c_functions[] = {
- (void*) LLVMModuleCreateWithName,
- (void*) _LLVM_EE_getPointerToFunction,
- (void*) _LLVM_Intrinsic_add_ovf,
- (void*) _LLVM_Intrinsic_sub_ovf,
- (void*) _LLVM_Intrinsic_mul_ovf
-};
diff --git a/pypy/jit/backend/llvm/demo2.cpp b/pypy/jit/backend/llvm/demo2.cpp
deleted file mode 100644
--- a/pypy/jit/backend/llvm/demo2.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* LLVM includes */
-#include <cstdio>
-#include "llvm-c/ExecutionEngine.h"
-#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/Intrinsics.h"
-#include "demo2.h"
-
-using namespace llvm;
-
-
-/* Set the flag to true.
- */
-void _LLVM_SetFlags(void)
-{
- //PerformTailCallOpt = true;
-}
-
-/* This piece of code regroups conveniently a part of the initialization.
- */
-LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M)
-{
- LLVMModuleProviderRef mp = LLVMCreateModuleProviderForExistingModule(M);
- LLVMExecutionEngineRef ee;
- char* errormsg;
- int error = LLVMCreateJITCompiler(&ee, mp, 0 /*Fast*/, &errormsg);
- if (error)
- {
- fprintf(stderr, "Error creating the JIT compiler:\n%s", errormsg);
- abort();
- }
- return ee;
-}
-
-/* Missing pieces of the C interface...
- */
-void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE,
- LLVMValueRef F)
-{
- return unwrap(EE)->getPointerToFunction(unwrap<Function>(F));
-}
-
-static LLVMValueRef _LLVM_Intrinsic_ovf(LLVMModuleRef M, LLVMTypeRef Ty,
- Intrinsic::ID num)
-{
- const Type *array_of_types[1];
- Function *F;
- array_of_types[0] = unwrap(Ty);
- F = Intrinsic::getDeclaration(unwrap(M), num, array_of_types, 1);
- return wrap(F);
-}
-
-LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty)
-{
- return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::sadd_with_overflow);
-}
-
-LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty)
-{
- return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::ssub_with_overflow);
-}
-
-LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty)
-{
- return _LLVM_Intrinsic_ovf(M, Ty, Intrinsic::smul_with_overflow);
-}
diff --git a/pypy/jit/backend/llvm/demo2.h b/pypy/jit/backend/llvm/demo2.h
deleted file mode 100644
--- a/pypy/jit/backend/llvm/demo2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void _LLVM_SetFlags(void);
-LLVMExecutionEngineRef _LLVM_EE_Create(LLVMModuleRef M);
-void *_LLVM_EE_getPointerToFunction(LLVMExecutionEngineRef EE,
- LLVMValueRef F);
-LLVMValueRef _LLVM_Intrinsic_add_ovf(LLVMModuleRef M, LLVMTypeRef Ty);
-LLVMValueRef _LLVM_Intrinsic_sub_ovf(LLVMModuleRef M, LLVMTypeRef Ty);
-LLVMValueRef _LLVM_Intrinsic_mul_ovf(LLVMModuleRef M, LLVMTypeRef Ty);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/pypy/jit/backend/llvm/llvm_rffi.py b/pypy/jit/backend/llvm/llvm_rffi.py
deleted file mode 100644
--- a/pypy/jit/backend/llvm/llvm_rffi.py
+++ /dev/null
@@ -1,371 +0,0 @@
-import py, os, sys
-import pypy
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.translator.tool.cbuild import ExternalCompilationInfo, log
-
-if not sys.platform.startswith('linux'):
- py.test.skip("Linux only for now")
-
-# ____________________________________________________________
-
-llvm_config = 'llvm-config'
-cachename = os.path.join(os.path.dirname(pypy.__file__), '_cache')
-dirname = os.path.join(cachename, 'libs')
-libname = os.path.join(dirname, 'pypy_cache_llvm.so')
-cname = os.path.join(os.path.dirname(__file__), 'demo1.c')
-cppname = os.path.join(os.path.dirname(__file__), 'demo2.cpp')
-o1name = os.path.join(dirname, 'demo1.o')
-o2name = os.path.join(dirname, 'demo2.o')
-
-if (not os.path.isfile(libname) or
- os.path.getmtime(cname) > os.path.getmtime(libname) or
- os.path.getmtime(cppname) > os.path.getmtime(libname)):
- g = os.popen('%s --version' % llvm_config, 'r')
- data = g.read()
- g.close()
- if not data.startswith('2.'):
- py.test.skip("llvm (version 2) is required")
-
- if not os.path.isdir(dirname):
- if not os.path.isdir(cachename):
- os.mkdir(cachename)
- os.mkdir(dirname)
-
- def do(cmdline):
- log(cmdline)
- err = os.system(cmdline)
- if err:
- raise Exception("gcc command failed")
-
- do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cname, o1name, llvm_config))
- do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cppname, o2name, llvm_config))
- do("g++ -g -shared '%s' '%s' -o '%s'" % (o1name, o2name, libname) +
- " `%s --cflags --ldflags --libs jit engine`" % llvm_config)
-
-ctypes_compilation_info = ExternalCompilationInfo(
- library_dirs = [dirname],
- libraries = ['pypy_cache_llvm'],
-)
-
-compilation_info = ExternalCompilationInfo.from_linker_flags(
- os.popen("%s --ldflags --libs jit engine" % llvm_config, 'r').read())
-
-compilation_info = compilation_info.merge(ExternalCompilationInfo(
- link_extra = [o1name, o2name],
- use_cpp_linker = True,
- ))
-
-compilation_info._with_ctypes = ctypes_compilation_info
-
-_teardown = None
-
-def set_teardown_function(fn):
- global _teardown
- _teardown = fn
-
-def teardown_now():
- global _teardown
- fn = _teardown
- _teardown = None
- if fn is not None:
- fn()
-
-# ____________________________________________________________
-
-Debug = True
-
-def llexternal(name, args, result, **kwds):
- ll = rffi.llexternal(name, args, result,
- compilation_info=compilation_info,
- **kwds)
- if Debug:
- def func(*args):
- print name
- res = ll(*args)
- print '\t->', res
- return res
- return func
- else:
- return ll
-
-def opaqueptr(name):
- return rffi.VOIDP # lltype.Ptr(rffi.COpaque(name))
-
-LLVMModuleRef = opaqueptr('struct LLVMOpaqueModule')
-LLVMTypeRef = opaqueptr('struct LLVMOpaqueType')
-LLVMValueRef = opaqueptr('struct LLVMOpaqueValue')
-LLVMBasicBlockRef = opaqueptr('struct LLVMOpaqueBasicBlock')
-LLVMBuilderRef = opaqueptr('struct LLVMOpaqueBuilder')
-LLVMModuleProviderRef = opaqueptr('struct LLVMOpaqueModuleProvider')
-LLVMGenericValueRef = opaqueptr('struct LLVMOpaqueGenericValue')
-LLVMExecutionEngineRef = opaqueptr('struct LLVMOpaqueExecutionEngine')
-
-class Predicate:
- EQ = 32 # equal
- NE = 33 # not equal
- UGT = 34 # unsigned greater than
- UGE = 35 # unsigned greater or equal
- ULT = 36 # unsigned less than
- ULE = 37 # unsigned less or equal
- SGT = 38 # signed greater than
- SGE = 39 # signed greater or equal
- SLT = 40 # signed less than
- SLE = 41 # signed less or equal
-
-class CallConv:
- C = 0
- Fast = 8
- Cold = 9
- X86Stdcall = 64
- X86Fastcall = 65
-
-# ____________________________________________________________
-
-LLVMDisposeMessage = llexternal('LLVMDisposeMessage', [rffi.CCHARP],
- lltype.Void)
-
-LLVMModuleCreateWithName = llexternal('LLVMModuleCreateWithName',
- [rffi.CCHARP],
- LLVMModuleRef)
-LLVMDumpModule = llexternal('LLVMDumpModule', [LLVMModuleRef], lltype.Void)
-
-LLVMInt1Type = llexternal('LLVMInt1Type', [], LLVMTypeRef)
-LLVMInt8Type = llexternal('LLVMInt8Type', [], LLVMTypeRef)
-LLVMInt16Type = llexternal('LLVMInt16Type', [], LLVMTypeRef)
-LLVMInt32Type = llexternal('LLVMInt32Type', [], LLVMTypeRef)
-LLVMInt64Type = llexternal('LLVMInt64Type', [], LLVMTypeRef)
-LLVMFunctionType = llexternal('LLVMFunctionType',
- [LLVMTypeRef, # return type
- rffi.CArrayPtr(LLVMTypeRef), # param types
- rffi.UINT, # param count
- rffi.INT], # flag: is_vararg
- LLVMTypeRef)
-LLVMStructType = llexternal('LLVMStructType',
- [rffi.CArrayPtr(LLVMTypeRef), # element types
- rffi.UINT, # element count
- rffi.INT], # flag: packed
- LLVMTypeRef)
-LLVMArrayType = llexternal('LLVMArrayType', [LLVMTypeRef, # element type
- rffi.UINT], # element count
- LLVMTypeRef)
-LLVMPointerType = llexternal('LLVMPointerType', [LLVMTypeRef, # element type
- rffi.UINT], # address space
- LLVMTypeRef)
-LLVMVoidType = llexternal('LLVMVoidType', [], LLVMTypeRef)
-
-LLVMTypeOf = llexternal('LLVMTypeOf', [LLVMValueRef], LLVMTypeRef)
-LLVMDumpValue = llexternal('LLVMDumpValue', [LLVMValueRef], lltype.Void)
-LLVMConstNull = llexternal('LLVMConstNull', [LLVMTypeRef], LLVMValueRef)
-LLVMConstInt = llexternal('LLVMConstInt', [LLVMTypeRef, # type
- rffi.ULONGLONG, # value
- rffi.INT], # flag: is_signed
- LLVMValueRef)
-LLVMConstIntToPtr = llexternal('LLVMConstIntToPtr',
- [LLVMValueRef, # constant integer value
- LLVMTypeRef], # type of the result
- LLVMValueRef)
-
-LLVMAddFunction = llexternal('LLVMAddFunction',
- [LLVMModuleRef, # module
- rffi.CCHARP, # name
- LLVMTypeRef], # function type
- LLVMValueRef)
-LLVMSetFunctionCallConv = llexternal('LLVMSetFunctionCallConv',
- [LLVMValueRef, # function
- rffi.UINT], # new call conv
- lltype.Void)
-LLVMGetParam = llexternal('LLVMGetParam',
- [LLVMValueRef, # function
- rffi.UINT], # index
- LLVMValueRef)
-
-LLVMAppendBasicBlock = llexternal('LLVMAppendBasicBlock',
- [LLVMValueRef, # function
- rffi.CCHARP], # name
- LLVMBasicBlockRef)
-
-LLVMSetInstructionCallConv = llexternal('LLVMSetInstructionCallConv',
- [LLVMValueRef, # call instruction
- rffi.UINT], # new call conv
- lltype.Void)
-LLVMSetTailCall = llexternal('LLVMSetTailCall',
- [LLVMValueRef, # call instruction
- rffi.INT], # flag: is_tail
- lltype.Void)
-LLVMAddIncoming = llexternal('LLVMAddIncoming',
- [LLVMValueRef, # phi node
- rffi.CArrayPtr(LLVMValueRef), # incoming values
- rffi.CArrayPtr(LLVMBasicBlockRef), # incom.blocks
- rffi.UINT], # count
- lltype.Void)
-LLVMCreateBuilder = llexternal('LLVMCreateBuilder', [], LLVMBuilderRef)
-LLVMPositionBuilderAtEnd = llexternal('LLVMPositionBuilderAtEnd',
- [LLVMBuilderRef, # builder
- LLVMBasicBlockRef], # block
- lltype.Void)
-LLVMGetInsertBlock = llexternal('LLVMGetInsertBlock', [LLVMBuilderRef],
- LLVMBasicBlockRef)
-LLVMDisposeBuilder = llexternal('LLVMDisposeBuilder', [LLVMBuilderRef],
- lltype.Void)
-
-LLVMBuildRet = llexternal('LLVMBuildRet', [LLVMBuilderRef, # builder,
- LLVMValueRef], # result
- LLVMValueRef)
-LLVMBuildBr = llexternal('LLVMBuildBr', [LLVMBuilderRef, # builder,
- LLVMBasicBlockRef],# destination block
- LLVMValueRef)
-LLVMBuildCondBr = llexternal('LLVMBuildCondBr',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # condition
- LLVMBasicBlockRef, # block if true
- LLVMBasicBlockRef], # block if false
- LLVMValueRef)
-
-for _name in ['Add', 'Sub', 'Mul', 'SDiv', 'SRem', 'Shl', 'LShr', 'AShr',
- 'And', 'Or', 'Xor']:
- globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name,
- [LLVMBuilderRef, # builder
- LLVMValueRef, # left-hand side
- LLVMValueRef, # right-hand side
- rffi.CCHARP], # name of result
- LLVMValueRef)
-
-for _name in ['Neg', 'Not']:
- globals()['LLVMBuild' + _name] = llexternal('LLVMBuild' + _name,
- [LLVMBuilderRef, # builder
- LLVMValueRef, # argument
- rffi.CCHARP], # name of result
- LLVMValueRef)
-
-LLVMBuildLoad = llexternal('LLVMBuildLoad',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # pointer location
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildStore = llexternal('LLVMBuildStore',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # value
- LLVMValueRef], # pointer location
- LLVMValueRef)
-LLVMBuildGEP = llexternal('LLVMBuildGEP', # GEP = 'getelementptr'
- [LLVMBuilderRef, # builder
- LLVMValueRef, # base pointer
- rffi.CArrayPtr(LLVMValueRef), # indices
- rffi.UINT, # num indices
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildTrunc = llexternal('LLVMBuildTrunc',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # value
- LLVMTypeRef, # destination type
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildZExt = llexternal('LLVMBuildZExt',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # value
- LLVMTypeRef, # destination type
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildPtrToInt = llexternal('LLVMBuildPtrToInt',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # value
- LLVMTypeRef, # destination type
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildIntToPtr = llexternal('LLVMBuildIntToPtr',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # value
- LLVMTypeRef, # destination type
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildBitCast = llexternal('LLVMBuildBitCast',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # value
- LLVMTypeRef, # destination type
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildICmp = llexternal('LLVMBuildICmp',
- [LLVMBuilderRef, # builder
- rffi.INT, # predicate (see Predicate above)
- LLVMValueRef, # left-hand side
- LLVMValueRef, # right-hand side
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildPhi = llexternal('LLVMBuildPhi',
- [LLVMBuilderRef, # builder
- LLVMTypeRef, # type of value
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildCall = llexternal('LLVMBuildCall',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # function
- rffi.CArrayPtr(LLVMValueRef), # arguments
- rffi.UINT, # argument count
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildSelect = llexternal('LLVMBuildSelect',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # if
- LLVMValueRef, # then
- LLVMValueRef, # else
- rffi.CCHARP], # name of result
- LLVMValueRef)
-LLVMBuildExtractValue = llexternal('LLVMBuildExtractValue',
- [LLVMBuilderRef, # builder
- LLVMValueRef, # aggregated value
- rffi.UINT, # index
- rffi.CCHARP], # name of result
- LLVMValueRef)
-
-LLVMCreateModuleProviderForExistingModule = llexternal(
- 'LLVMCreateModuleProviderForExistingModule', [LLVMModuleRef],
- LLVMModuleProviderRef)
-
-# ____________________________________________________________
-
-LLVMCreateGenericValueOfInt = llexternal('LLVMCreateGenericValueOfInt',
- [LLVMTypeRef, # type
- rffi.ULONGLONG, # value
- rffi.INT], # flag: is_signed
- LLVMGenericValueRef)
-LLVMDisposeGenericValue = llexternal('LLVMDisposeGenericValue',
- [LLVMGenericValueRef], lltype.Void)
-
-LLVMGenericValueToInt = llexternal('LLVMGenericValueToInt',
- [LLVMGenericValueRef,
- rffi.INT], # flag: is_signed
- rffi.ULONGLONG)
-
-LLVMCreateJITCompiler = llexternal('LLVMCreateJITCompiler',
- [rffi.CArrayPtr(LLVMExecutionEngineRef),
- LLVMModuleProviderRef,
- rffi.INT, # "fast"
- rffi.CArrayPtr(rffi.CCHARP)], # -> error
- rffi.INT)
-LLVMDisposeExecutionEngine = llexternal('LLVMDisposeExecutionEngine',
- [LLVMExecutionEngineRef],
- lltype.Void)
-
-LLVMRunFunction = llexternal('LLVMRunFunction',
- [LLVMExecutionEngineRef,
- LLVMValueRef, # function
- rffi.UINT, # num args
- rffi.CArrayPtr(LLVMGenericValueRef)], # args
- LLVMGenericValueRef) # return value
-
-LLVM_SetFlags = llexternal('_LLVM_SetFlags', [], lltype.Void)
-LLVM_EE_Create = llexternal('_LLVM_EE_Create', [LLVMModuleRef],
- LLVMExecutionEngineRef)
-LLVM_EE_getPointerToFunction = llexternal('_LLVM_EE_getPointerToFunction',
- [LLVMExecutionEngineRef,
- LLVMValueRef], # function
- rffi.VOIDP)
-LLVM_Intrinsic_add_ovf = llexternal('_LLVM_Intrinsic_add_ovf',
- [LLVMModuleRef, LLVMTypeRef],
- LLVMValueRef)
-LLVM_Intrinsic_sub_ovf = llexternal('_LLVM_Intrinsic_sub_ovf',
- [LLVMModuleRef, LLVMTypeRef],
- LLVMValueRef)
-LLVM_Intrinsic_mul_ovf = llexternal('_LLVM_Intrinsic_mul_ovf',
- [LLVMModuleRef, LLVMTypeRef],
- LLVMValueRef)
diff --git a/pypy/jit/backend/llvm/runner.py b/pypy/jit/backend/llvm/runner.py
deleted file mode 100644
--- a/pypy/jit/backend/llvm/runner.py
+++ /dev/null
@@ -1,731 +0,0 @@
-import sys
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
-from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.rlib.objectmodel import we_are_translated, specialize
-from pypy.rlib import runicode
-from pypy.jit.metainterp.history import AbstractDescr, INT
-from pypy.jit.metainterp.history import BoxInt, BoxPtr
-from pypy.jit.backend.model import AbstractCPU
-from pypy.jit.backend.llvm import llvm_rffi
-from pypy.jit.metainterp import history
-from pypy.jit.metainterp.resoperation import rop, ResOperation
-from pypy.jit.backend.llsupport import symbolic
-from pypy.jit.metainterp.typesystem import llhelper
-
-history.TreeLoop._llvm_compiled_index = -1
-
-
-class LLVMCPU(object):
- ts = llhelper
- RAW_VALUE = rffi.CFixedArray(rffi.ULONGLONG, 1)
- SIGNED_VALUE = rffi.CFixedArray(lltype.Signed, 1)
- POINTER_VALUE = rffi.CFixedArray(llmemory.GCREF, 1)
-
- SIZE_GCPTR = 0
- SIZE_INT = 1
- SIZE_CHAR = 2
- SIZE_UNICHAR = 3
-
- def __init__(self, rtyper, stats=None, translate_support_code=False,
- annmixlevel=None, gcdescr=None):
- self.rtyper = rtyper
- self.translate_support_code = translate_support_code
- self.compiled_functions = []
- self.fail_ops = []
- self.in_out_args = []
- if translate_support_code:
- get_size = llmemory.sizeof
- else:
- get_size = rffi.sizeof
- self._arraydescrs = [
- ArrayDescr(get_size(llmemory.GCREF), self.SIZE_GCPTR), # 0
- ArrayDescr(get_size(lltype.Signed), self.SIZE_INT), # 1
- ArrayDescr(get_size(lltype.Char), self.SIZE_CHAR), # 2
- ArrayDescr(get_size(lltype.UniChar), self.SIZE_UNICHAR), # 3
- ]
- self._descr_caches = {}
- self.fielddescr_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr')
- if sys.maxint == 2147483647:
- self.size_of_int = 4
- else:
- self.size_of_int = 8
- if runicode.MAXUNICODE > 0xffff:
- self.size_of_unicode = 4
- else:
- self.size_of_unicode = 2
- self.gcarray_gcref = lltype.GcArray(llmemory.GCREF)
- self.gcarray_signed = lltype.GcArray(lltype.Signed)
- self.gcarray_char = lltype.GcArray(lltype.Char)
- self.gcarray_unichar = lltype.GcArray(lltype.UniChar)
- basesize, _, ofs_length = symbolic.get_array_token(
- self.gcarray_signed, self.translate_support_code)
- self.array_index_array = basesize
- self.array_index_length = ofs_length
- basesize, _, ofs_length = symbolic.get_array_token(
- rstr.STR, self.translate_support_code)
- self.string_index_array = basesize
- self.string_index_length = ofs_length
- basesize, _, ofs_length = symbolic.get_array_token(
- rstr.UNICODE, self.translate_support_code)
- self.unicode_index_array = basesize
- self.unicode_index_length = ofs_length
- self.vtable_descr = self.fielddescrof(rclass.OBJECT, 'typeptr')
- self._ovf_error_instance = self._get_prebuilt_error(OverflowError)
- self._zer_error_instance = self._get_prebuilt_error(ZeroDivisionError)
- #
- # temporary (Boehm only)
- from pypy.translator.tool.cbuild import ExternalCompilationInfo
- compilation_info = ExternalCompilationInfo(libraries=['gc'])
- self.malloc_fn_ptr = rffi.llexternal("GC_malloc",
- [rffi.SIZE_T],
- llmemory.GCREF,
- compilation_info=compilation_info,
- sandboxsafe=True,
- _nowrapper=True)
- assert rffi.sizeof(rffi.SIZE_T) == self.size_of_int
-
- def set_class_sizes(self, class_sizes):
- self.class_sizes = class_sizes
-
- def setup_once(self):
- if not we_are_translated():
- llvm_rffi.teardown_now()
- llvm_rffi.LLVM_SetFlags()
- self.module = llvm_rffi.LLVMModuleCreateWithName("pypyjit")
- if self.size_of_int == 4:
- self.ty_int = llvm_rffi.LLVMInt32Type()
- else:
- self.ty_int = llvm_rffi.LLVMInt64Type()
- if self.size_of_unicode == 2:
- self.ty_unichar = llvm_rffi.LLVMInt16Type()
- else:
- self.ty_unichar = llvm_rffi.LLVMInt32Type()
- self.ty_void = llvm_rffi.LLVMVoidType()
- self.ty_bit = llvm_rffi.LLVMInt1Type()
- self.ty_char = llvm_rffi.LLVMInt8Type()
- self.ty_char_ptr = llvm_rffi.LLVMPointerType(self.ty_char, 0)
- self.ty_char_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_char_ptr, 0)
- self.ty_int_ptr = llvm_rffi.LLVMPointerType(self.ty_int, 0)
- self.ty_int_ptr_ptr = llvm_rffi.LLVMPointerType(self.ty_int_ptr, 0)
- self.ty_unichar_ptr = llvm_rffi.LLVMPointerType(self.ty_unichar, 0)
- self.const_zero = self._make_const_int(0)
- self.const_one = self._make_const_int(1)
- self.const_null_charptr = self._make_const(0, self.ty_char_ptr)
- #
- from pypy.jit.backend.llvm.compile import LLVMJITCompiler
- self.types_by_index = [self.ty_char_ptr, # SIZE_GCPTR
- self.ty_int, # SIZE_INT
- self.ty_char, # SIZE_CHAR
- self.ty_unichar] # SIZE_UNICHAR
- self.types_ptr_by_index = [self.ty_char_ptr_ptr, # SIZE_GCPTR
- self.ty_int_ptr, # SIZE_INT
- self.ty_char_ptr, # SIZE_CHAR
- self.ty_unichar_ptr] # SIZE_UNICHAR
- self.getarg_by_index = [LLVMJITCompiler.getptrarg, # SIZE_GCPTR
- LLVMJITCompiler.getintarg, # SIZE_INT
- LLVMJITCompiler.getchararg, # SIZE_CHAR
- LLVMJITCompiler.getunichararg] # SIZE_UNICHAR
- for i in range(len(self.types_by_index)):
- arraydescr = self._arraydescrs[i]
- (arraydescr.ty_array_ptr,
- self.const_array_index_length,
- self.const_array_index_array) = \
- self._build_ty_array_ptr(self.array_index_array,
- self.types_by_index[i],
- self.array_index_length)
- (self.ty_string_ptr,
- self.const_string_index_length,
- self.const_string_index_array) = \
- self._build_ty_array_ptr(self.string_index_array,
- self.ty_char,
- self.string_index_length)
- (self.ty_unicode_ptr,
- self.const_unicode_index_length,
- self.const_unicode_index_array) = \
- self._build_ty_array_ptr(self.unicode_index_array,
- self.ty_unichar,
- self.unicode_index_length)
- #
- arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 0,
- flavor='raw')
- self.ty_func = llvm_rffi.LLVMFunctionType(self.ty_int, arglist, 0,
- False)
- lltype.free(arglist, flavor='raw')
- #
- self.f_add_ovf = llvm_rffi.LLVM_Intrinsic_add_ovf(self.module,
- self.ty_int)
- self.f_sub_ovf = llvm_rffi.LLVM_Intrinsic_sub_ovf(self.module,
- self.ty_int)
- self.f_mul_ovf = llvm_rffi.LLVM_Intrinsic_mul_ovf(self.module,
- self.ty_int)
- if we_are_translated():
- addr = llop.get_exception_addr(llmemory.Address)
- self.exc_type = rffi.cast(rffi.CArrayPtr(lltype.Signed), addr)
- addr = llop.get_exc_value_addr(llmemory.Address)
- self.exc_value = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), addr)
- else:
- self.exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1,
- zero=True, flavor='raw')
- self.exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1,
- zero=True, flavor='raw')
- self.backup_exc_type = lltype.malloc(rffi.CArray(lltype.Signed), 1,
- zero=True, flavor='raw')
- self.backup_exc_value = lltype.malloc(rffi.CArray(llmemory.GCREF), 1,
- zero=True, flavor='raw')
- self.const_exc_type = self._make_const(self.exc_type,
- self.ty_char_ptr_ptr)
- self.const_exc_value = self._make_const(self.exc_value,
- self.ty_char_ptr_ptr)
- self.const_backup_exc_type = self._make_const(self.backup_exc_type,
- self.ty_char_ptr_ptr)
- self.const_backup_exc_value = self._make_const(self.backup_exc_value,
- self.ty_char_ptr_ptr)
- #
- self._setup_prebuilt_error('ovf')
- self._setup_prebuilt_error('zer')
- #
- # temporary (Boehm only)
- param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 1,
- flavor='raw')
- param_types[0] = self.ty_int
- self.ty_malloc_fn = llvm_rffi.LLVMPointerType(
- llvm_rffi.LLVMFunctionType(self.ty_char_ptr, param_types, 1, 0),
- 0)
- lltype.free(param_types, flavor='raw')
- #
- self.ee = llvm_rffi.LLVM_EE_Create(self.module)
- if not we_are_translated():
- llvm_rffi.set_teardown_function(self._teardown)
-
- def _teardown(self):
- llvm_rffi.LLVMDisposeExecutionEngine(self.ee)
-
- def _get_prebuilt_error(self, Class):
- "NOT_RPYTHON"
- if self.rtyper is not None: # normal case
- bk = self.rtyper.annotator.bookkeeper
- clsdef = bk.getuniqueclassdef(Class)
- ll_inst = self.rtyper.exceptiondata.get_standard_ll_exc_instance(
- self.rtyper, clsdef)
- else:
- # for tests, a random emulated ll_inst will do
- ll_inst = lltype.malloc(rclass.OBJECT)
- ll_inst.typeptr = lltype.malloc(rclass.OBJECT_VTABLE,
- immortal=True)
- return ll_inst
-
- @specialize.arg(1)
- def _setup_prebuilt_error(self, prefix):
- ll_inst = getattr(self, '_' + prefix + '_error_instance')
- setattr(self, '_' + prefix + '_error_type',
- rffi.cast(lltype.Signed, ll_inst.typeptr))
- setattr(self, '_' + prefix + '_error_value',
- lltype.cast_opaque_ptr(llmemory.GCREF, ll_inst))
- setattr(self, 'const_' + prefix + '_error_type',
- self._make_const(ll_inst.typeptr, self.ty_char_ptr))
- setattr(self, 'const_' + prefix + '_error_value',
- self._make_const(ll_inst, self.ty_char_ptr))
-
- def _build_ty_array_ptr(self, basesize, ty_item, ofs_length):
- pad1 = ofs_length
- pad2 = basesize - ofs_length - self.size_of_int
- assert pad1 >= 0 and pad2 >= 0
- const_index_length = self._make_const_int(pad1)
- const_index_array = self._make_const_int(pad1 + 1 + pad2)
- # build the type "struct{pad1.., length, pad2.., array{type}}"
- typeslist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef),
- pad1+pad2+2, flavor='raw')
- # add the first padding
- for n in range(pad1):
- typeslist[n] = self.ty_char
- # add the length field
- typeslist[pad1] = self.ty_int
- # add the second padding
- for n in range(pad1+1, pad1+1+pad2):
- typeslist[n] = self.ty_char
- # add the array field
- typeslist[pad1+1+pad2] = llvm_rffi.LLVMArrayType(ty_item, 0)
- # done
- ty_array = llvm_rffi.LLVMStructType(typeslist,
- pad1+pad2+2,
- 1)
- lltype.free(typeslist, flavor='raw')
- ty_array_ptr = llvm_rffi.LLVMPointerType(ty_array, 0)
- return (ty_array_ptr, const_index_length, const_index_array)
-
- # ------------------------------
- # Compilation
-
- def compile_operations(self, loop, _guard_op=None):
- from pypy.jit.backend.llvm.compile import LLVMJITCompiler
- compiler = LLVMJITCompiler(self, loop)
- compiler.compile()
-
- def _ensure_in_args(self, count):
- while len(self.in_out_args) < count:
- self.in_out_args.append(lltype.malloc(self.RAW_VALUE, flavor='raw'))
-
- _ensure_out_args = _ensure_in_args
-
- def _make_const_int(self, value):
- return llvm_rffi.LLVMConstInt(self.ty_int, value, True)
-
- def _make_const_char(self, value):
- assert (value & ~255) == 0, "value is not in range(256)"
- return llvm_rffi.LLVMConstInt(self.ty_char, value, True)
-
- def _make_const_unichar(self, value):
- #xxx assert something about 'value'
- return llvm_rffi.LLVMConstInt(self.ty_unichar, value, True)
-
- def _make_const_bit(self, value):
- assert (value & ~1) == 0, "value is not 0 or 1"
- return llvm_rffi.LLVMConstInt(self.ty_bit, value, True)
-
- @specialize.arglltype(1)
- def _make_const(self, value, ty_result):
- value_as_signed = rffi.cast(lltype.Signed, value)
- llvmconstint = self._make_const_int(value_as_signed)
- llvmconstptr = llvm_rffi.LLVMConstIntToPtr(llvmconstint, ty_result)
- return llvmconstptr
-
- def _get_var_type(self, v):
- if v.type == INT:
- return self.ty_int
- else:
- return self.ty_char_ptr
-
- def _get_pointer_type(self, v):
- if v.type == INT:
- return self.ty_int_ptr
- else:
- return self.ty_char_ptr_ptr
-
- # ------------------------------
- # Execution
-
- def set_future_value_int(self, index, intvalue):
- p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index])
- p[0] = intvalue
-
- def set_future_value_ref(self, index, ptrvalue):
- p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index])
- p[0] = ptrvalue
-
- def execute_operations(self, loop):
- index = loop._llvm_compiled_index
- assert index >= 0
- while True:
- func_ptr = self.compiled_functions[index]
- print 'execute_operations: %d (at 0x%x)' % (
- index, rffi.cast(lltype.Signed, func_ptr))
- index = func_ptr()
- print '\t--->', index
- if index < 0:
- break
- return self.fail_ops[~index]
-
- def get_latest_value_int(self, index):
- p = rffi.cast(lltype.Ptr(self.SIGNED_VALUE), self.in_out_args[index])
- return p[0]
-
- def get_latest_value_ref(self, index):
- p = rffi.cast(lltype.Ptr(self.POINTER_VALUE), self.in_out_args[index])
- return p[0]
-
- def get_exception(self):
- return self.backup_exc_type[0]
-
- def get_exc_value(self):
- return self.backup_exc_value[0]
-
- def clear_exception(self):
- self.backup_exc_type[0] = 0
- self.backup_exc_value[0] = lltype.nullptr(llmemory.GCREF.TO)
-
- # XXX wrong, but untested
-
- def set_overflow_error(self):
- self.backup_exc_type[0] = self._ovf_error_type
- self.backup_exc_value[0] = self._ovf_error_value
-
- def set_zero_division_error(self):
- self.backup_exc_type[0] = self._zer_error_type
- self.backup_exc_value[0] = self._zer_error_value
-
- @staticmethod
- def cast_adr_to_int(x):
- return rffi.cast(lltype.Signed, x)
-
- @staticmethod
- def cast_int_to_adr(x):
- assert x == 0 or x > (1<<20) or x < (-1<<20)
- if we_are_translated():
- return rffi.cast(llmemory.Address, x)
- else:
- # indirect casting because the above doesn't work with ll2ctypes
- return llmemory.cast_ptr_to_adr(rffi.cast(llmemory.GCREF, x))
-
- def _get_size_index(self, TYPE):
- if isinstance(TYPE, lltype.Ptr):
- if TYPE.TO._gckind == 'gc':
- return self.SIZE_GCPTR
- else:
- return self.SIZE_INT
- else:
- if TYPE == lltype.Signed or TYPE == lltype.Unsigned:
- return self.SIZE_INT
- elif TYPE == lltype.Char or TYPE == lltype.Bool:
- return self.SIZE_CHAR
- elif TYPE == lltype.UniChar:
- return self.SIZE_UNICHAR
- else:
- raise BadSizeError(TYPE)
-
- def sizeof(self, S):
- try:
- return self._descr_caches['size', S]
- except KeyError:
- pass
- descr = SizeDescr(symbolic.get_size(S, self.translate_support_code))
- self._descr_caches['size', S] = descr
- return descr
-
- def fielddescrof(self, S, fieldname):
- try:
- return self._descr_caches['field', S, fieldname]
- except KeyError:
- pass
- ofs, _ = symbolic.get_field_token(S, fieldname,
- self.translate_support_code)
- size_index = self._get_size_index(getattr(S, fieldname))
- descr = FieldDescr(ofs, size_index)
- self._descr_caches['field', S, fieldname] = descr
- return descr
-
- def arraydescrof(self, A):
- basesize, _, ofs_length = symbolic.get_array_token(A,
- self.translate_support_code)
- if isinstance(basesize, int): # else Symbolics, can't be compared...
- assert self.array_index_array == basesize
- assert self.array_index_length == ofs_length
- itemsize_index = self._get_size_index(A.OF)
- return self._arraydescrs[itemsize_index]
-
- def calldescrof(self, FUNC, ARGS, RESULT):
- args_indices = [self._get_size_index(ARG) for ARG in ARGS]
- if RESULT is lltype.Void:
- res_index = -1
- else:
- res_index = self._get_size_index(RESULT)
- #
- key = ('call', tuple(args_indices), res_index)
- try:
- descr = self._descr_caches[key]
- except KeyError:
- descr = CallDescr(args_indices, res_index)
- self._descr_caches[key] = descr
- return descr
-
- def get_calldescr_ty_function_ptr(self, calldescr):
- if not calldescr.ty_function_ptr:
- #
- args_indices = calldescr.args_indices
- param_types = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef),
- len(args_indices), flavor='raw')
- for i in range(len(args_indices)):
- param_types[i] = self.types_by_index[args_indices[i]]
- #
- res_index = calldescr.res_index
- if res_index < 0:
- ty_result = self.ty_void
- else:
- ty_result = self.types_by_index[res_index]
- #
- ty_func = llvm_rffi.LLVMFunctionType(ty_result, param_types,
- len(args_indices), 0)
- lltype.free(param_types, flavor='raw')
- ty_funcptr = llvm_rffi.LLVMPointerType(ty_func, 0)
- calldescr.ty_function_ptr = ty_funcptr
- #
- return calldescr.ty_function_ptr
-
- # ------------------------------
- # do_xxx methods
-
- def do_arraylen_gc(self, args, arraydescr):
- array = args[0].getref_base()
- p = rffi.cast(lltype.Ptr(self.gcarray_signed), array)
- res = len(p)
- return BoxInt(res)
-
- def do_strlen(self, args, descr=None):
- s = args[0].getref_base()
- p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s)
- res = len(p.chars)
- return BoxInt(res)
-
- def do_strgetitem(self, args, descr=None):
- s = args[0].getref_base()
- p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s)
- res = ord(p.chars[args[1].getint()])
- return BoxInt(res)
-
- def do_unicodelen(self, args, descr=None):
- s = args[0].getref_base()
- p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s)
- res = len(p.chars)
- return BoxInt(res)
-
- def do_unicodegetitem(self, args, descr=None):
- s = args[0].getref_base()
- p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s)
- res = ord(p.chars[args[1].getint()])
- return BoxInt(res)
-
- def do_getarrayitem_gc(self, args, arraydescr):
- array = args[0].getref_base()
- index = args[1].getint()
- assert isinstance(arraydescr, ArrayDescr)
- itemsize_index = arraydescr.itemsize_index
- if itemsize_index == self.SIZE_GCPTR:
- p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array)
- res = p[index]
- return BoxPtr(res)
- elif itemsize_index == self.SIZE_INT:
- p = rffi.cast(lltype.Ptr(self.gcarray_signed), array)
- res = p[index]
- elif itemsize_index == self.SIZE_CHAR:
- p = rffi.cast(lltype.Ptr(self.gcarray_char), array)
- res = ord(p[index])
- elif itemsize_index == self.SIZE_UNICHAR:
- p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array)
- res = ord(p[index])
- else:
- raise BadSizeError
- return BoxInt(res)
-
- @specialize.argtype(1)
- def _do_getfield(self, struct, fielddescr):
- assert isinstance(fielddescr, FieldDescr)
- size_index = fielddescr.size_index
- if size_index == self.SIZE_GCPTR:
- p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct)
- res = p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)]
- return BoxPtr(res)
- elif size_index == self.SIZE_INT:
- p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct)
- res = p[fielddescr.offset / rffi.sizeof(lltype.Signed)]
- elif size_index == self.SIZE_CHAR:
- p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct)
- res = ord(p[fielddescr.offset / rffi.sizeof(lltype.Char)])
- elif size_index == self.SIZE_UNICHAR:
- p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct)
- res = ord(p[fielddescr.offset / rffi.sizeof(lltype.UniChar)])
- else:
- raise BadSizeError
- return BoxInt(res)
-
- def do_getfield_gc(self, args, fielddescr):
- struct = args[0].getref_base()
- return self._do_getfield(struct, fielddescr)
-
- def do_getfield_raw(self, args, fielddescr):
- struct = args[0].getaddr(self)
- return self._do_getfield(struct, fielddescr)
-
- def do_new(self, args, sizedescr):
- assert isinstance(sizedescr, SizeDescr)
- res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size))
- return BoxPtr(res)
-
- def do_new_with_vtable(self, args, descr=None):
- assert descr is None
- sizedescr = self.class_sizes[args[0].getint()]
- res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, sizedescr.size))
- self._do_setfield(res, args[0], self.vtable_descr)
- return BoxPtr(res)
-
- def _allocate_new_array(self, args, item_size, index_array, index_length):
- length = args[0].getint()
- #try:
- size = index_array + length * item_size
- #except OverflowError:
- # ...
- res = self.malloc_fn_ptr(rffi.cast(rffi.SIZE_T, size))
- p = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
- p[index_length / rffi.sizeof(lltype.Signed)] = length
- return BoxPtr(res)
-
- def do_new_array(self, args, arraydescr):
- assert isinstance(arraydescr, ArrayDescr)
- return self._allocate_new_array(args, arraydescr.itemsize,
- self.array_index_array,
- self.array_index_length)
-
- def do_setarrayitem_gc(self, args, arraydescr):
- array = args[0].getref_base()
- index = args[1].getint()
- assert isinstance(arraydescr, ArrayDescr)
- itemsize_index = arraydescr.itemsize_index
- if itemsize_index == self.SIZE_GCPTR:
- p = rffi.cast(lltype.Ptr(self.gcarray_gcref), array)
- res = args[2].getref_base()
- p[index] = res
- elif itemsize_index == self.SIZE_INT:
- p = rffi.cast(lltype.Ptr(self.gcarray_signed), array)
- res = args[2].getint()
- p[index] = res
- elif itemsize_index == self.SIZE_CHAR:
- p = rffi.cast(lltype.Ptr(self.gcarray_char), array)
- res = chr(args[2].getint())
- p[index] = res
- elif itemsize_index == self.SIZE_UNICHAR:
- p = rffi.cast(lltype.Ptr(self.gcarray_unichar), array)
- res = unichr(args[2].getint())
- p[index] = res
- else:
- raise BadSizeError
-
- @specialize.argtype(1)
- def _do_setfield(self, struct, v_value, fielddescr):
- assert isinstance(fielddescr, FieldDescr)
- size_index = fielddescr.size_index
- if size_index == self.SIZE_GCPTR:
- p = rffi.cast(rffi.CArrayPtr(llmemory.GCREF), struct)
- res = v_value.getref_base()
- p[fielddescr.offset / rffi.sizeof(llmemory.GCREF)] = res
- elif size_index == self.SIZE_INT:
- p = rffi.cast(rffi.CArrayPtr(lltype.Signed), struct)
- res = v_value.getint()
- p[fielddescr.offset / rffi.sizeof(lltype.Signed)] = res
- elif size_index == self.SIZE_CHAR:
- p = rffi.cast(rffi.CArrayPtr(lltype.Char), struct)
- res = chr(v_value.getint())
- p[fielddescr.offset / rffi.sizeof(lltype.Char)] = res
- elif size_index == self.SIZE_UNICHAR:
- p = rffi.cast(rffi.CArrayPtr(lltype.UniChar), struct)
- res = unichr(v_value.getint())
- p[fielddescr.offset / rffi.sizeof(lltype.UniChar)] = res
- else:
- raise BadSizeError
-
- def do_setfield_gc(self, args, fielddescr):
- struct = args[0].getref_base()
- self._do_setfield(struct, args[1], fielddescr)
-
- def do_setfield_raw(self, args, fielddescr):
- struct = args[0].getaddr(self)
- self._do_setfield(struct, args[1], fielddescr)
-
- def do_newstr(self, args, descr=None):
- return self._allocate_new_array(args, 1,
- self.string_index_array,
- self.string_index_length)
-
- def do_newunicode(self, args, descr=None):
- return self._allocate_new_array(args, self.size_of_unicode,
- self.unicode_index_array,
- self.unicode_index_length)
-
- def do_strsetitem(self, args, descr=None):
- s = args[0].getref_base()
- res = chr(args[2].getint())
- p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), s)
- p.chars[args[1].getint()] = res
-
- def do_unicodesetitem(self, args, descr=None):
- s = args[0].getref_base()
- res = unichr(args[2].getint())
- p = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), s)
- p.chars[args[1].getint()] = res
-
- def _get_loop_for_call(self, argnum, calldescr):
- loop = calldescr._generated_mp
- if loop is None:
- args = [BoxInt() for i in range(argnum + 1)]
- if calldescr.res_index < 0:
- result = None
- elif calldescr.res_index == self.SIZE_GCPTR:
- result = BoxPtr(lltype.nullptr(llmemory.GCREF.TO))
- else:
- result = BoxInt(0)
- result_list = []
- if result is not None:
- result_list.append(result)
- operations = [
- ResOperation(rop.CALL, args, result, calldescr),
- ResOperation(rop.GUARD_NO_EXCEPTION, [], None),
- ResOperation(rop.FAIL, result_list, None)]
- operations[1].suboperations = [ResOperation(rop.FAIL, [], None)]
- loop = history.TreeLoop('call')
- loop.inputargs = args
- loop.operations = operations
- self.compile_operations(loop)
- calldescr._generated_mp = loop
- return loop
-
- def do_call(self, args, calldescr):
- assert isinstance(calldescr, CallDescr)
- num_args = len(calldescr.args_indices)
- assert num_args == len(args) - 1
- loop = self._get_loop_for_call(num_args, calldescr)
- history.set_future_values(self, args)
- self.execute_operations(loop)
- # Note: if an exception is set, the rest of the code does a bit of
- # nonsense but nothing wrong (the return value should be ignored)
- if calldescr.res_index < 0:
- return None
- elif calldescr.res_index == self.SIZE_GCPTR:
- return BoxPtr(self.get_latest_value_ref(0))
- else:
- return BoxInt(self.get_latest_value_int(0))
-
- def do_cast_int_to_ptr(self, args, descr=None):
- int = args[0].getint()
- res = rffi.cast(llmemory.GCREF, int)
- return BoxPtr(res)
-
- def do_cast_ptr_to_int(self, args, descr=None):
- ptr = args[0].getref_base()
- res = rffi.cast(lltype.Signed, ptr)
- return BoxInt(res)
-
-
-class SizeDescr(AbstractDescr):
- def __init__(self, size):
- self.size = size
-
-class FieldDescr(AbstractDescr):
- def __init__(self, offset, size_index):
- self.offset = offset
- self.size_index = size_index # index in cpu.types_by_index
- def is_pointer_field(self):
- return self.size_index == LLVMCPU.SIZE_GCPTR
-
-class ArrayDescr(AbstractDescr):
- def __init__(self, itemsize, itemsize_index):
- self.itemsize = itemsize
- self.itemsize_index = itemsize_index # index in cpu.types_by_index
- self.ty_array_ptr = lltype.nullptr(llvm_rffi.LLVMTypeRef.TO)
- # ^^^ set by setup_once()
- def is_array_of_pointers(self):
- return self.itemsize_index == LLVMCPU.SIZE_GCPTR
-
-class CallDescr(AbstractDescr):
- ty_function_ptr = lltype.nullptr(llvm_rffi.LLVMTypeRef.TO)
- args_indices = [0] # dummy value to make annotation happy
- res_index = 0
- _generated_mp = None
- #
More information about the pypy-commit
mailing list