[pypy-svn] r21756 - pypy/dist/pypy/translator/llvm
rxe at codespeak.net
rxe at codespeak.net
Fri Jan 6 19:31:25 CET 2006
Author: rxe
Date: Fri Jan 6 19:31:20 2006
New Revision: 21756
Modified:
pypy/dist/pypy/translator/llvm/arraynode.py
pypy/dist/pypy/translator/llvm/codewriter.py
pypy/dist/pypy/translator/llvm/exception.py
pypy/dist/pypy/translator/llvm/extfuncnode.py
pypy/dist/pypy/translator/llvm/funcnode.py
pypy/dist/pypy/translator/llvm/gc.py
pypy/dist/pypy/translator/llvm/genllvm.py
pypy/dist/pypy/translator/llvm/node.py
pypy/dist/pypy/translator/llvm/opaquenode.py
pypy/dist/pypy/translator/llvm/opwriter.py
pypy/dist/pypy/translator/llvm/structnode.py
Log:
Finish off the boring codewriter/opwriter refactors from before Xmas.
Need to fix up the policies now.
Modified: pypy/dist/pypy/translator/llvm/arraynode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/arraynode.py (original)
+++ pypy/dist/pypy/translator/llvm/arraynode.py Fri Jan 6 19:31:20 2006
@@ -116,9 +116,9 @@
def get_ref(self):
typeval = self.db.repr_type(lltype.typeOf(self.value))
- ref = "cast (%s* %s to %s*)" % (self.get_typerepr(),
- self.ref,
- typeval)
+ ref = "cast(%s* %s to %s*)" % (self.get_typerepr(),
+ self.ref,
+ typeval)
p, c = lltype.parentlink(self.value)
assert p is None, "child arrays are NOT needed by rtyper"
Modified: pypy/dist/pypy/translator/llvm/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/codewriter.py (original)
+++ pypy/dist/pypy/translator/llvm/codewriter.py Fri Jan 6 19:31:20 2006
@@ -131,20 +131,14 @@
self._indent("%(targetvar)s = cast %(fromtype)s "
"%(fromvar)s to %(targettype)s" % locals())
- # XXX refactor - should only be one getelementptr
- def raw_getelementptr(self, targetvar, type, typevar, *indices):
- word = self.word_repr
+ def getelementptr(self, targetvar, type, typevar, indices, getptr=True):
+ # XXX comment getptr
+ if getptr:
+ indices = [(self.word_repr, 0)] + list(indices)
res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, " % locals()
res += ", ".join(["%s %s" % (t, i) for t, i in indices])
self._indent(res)
- def getelementptr(self, targetvar, type, typevar, *indices):
- word = self.word_repr
- res = "%(targetvar)s = getelementptr " \
- "%(type)s %(typevar)s, %(word)s 0, " % locals()
- res += ", ".join(["%s %s" % (t, i) for t, i in indices])
- self._indent(res)
-
def load(self, target, targettype, ptr):
self._indent("%(target)s = load %(targettype)s* %(ptr)s" % locals())
@@ -155,22 +149,21 @@
def unwind(self):
self._indent("unwind")
- def call(self, targetvar, returntype, functionref, argrefs, argtypes,
+ def call(self, targetvar, returntype, functionref, argtypes, argrefs,
tail=DEFAULT_TAIL, cconv=DEFAULT_CCONV):
tail = self._resolvetail(tail, cconv)
args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)])
if returntype == 'void':
- self._indent("%scall %s void %s(%s)" % (tail,
- cconv,
- functionref,
- args))
+ return_str = ''
else:
- self._indent("%s = %scall %s %s %s(%s)" % (targetvar,
- tail,
- cconv,
- returntype,
- functionref,
- args))
-
+ return_str = '%s = ' % targetvar
+
+ self._indent("%s%scall %s %s %s(%s)" % (return_str,
+ tail,
+ cconv,
+ returntype,
+ functionref,
+ args))
+
Modified: pypy/dist/pypy/translator/llvm/exception.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/exception.py (original)
+++ pypy/dist/pypy/translator/llvm/exception.py Fri Jan 6 19:31:20 2006
@@ -1,4 +1,5 @@
-from pypy.objspace.flow.model import c_last_exception
+from pypy.objspace.flow.model import Variable, c_last_exception
+
from pypy.translator.llvm.codewriter import DEFAULT_CCONV
from pypy.translator.llvm.backendopt.exception import create_exception_handling
@@ -26,6 +27,7 @@
''' % (RINGBUFFER_ENTRY_MAXSIZE, RINGBUGGER_OVERSIZE, RINGBUGGER_SIZE-1)
def __init__(self, db):
+ self.db = db
raise Exception, 'ExceptionPolicy should not be used directly'
def transform(self, translator, graph=None):
@@ -55,7 +57,6 @@
return ' 0'
return 'null'
-
def _nonoderesult(self, node):
returntype, name, dummy = node.getdecl_parts()
noresult = self._noresult(returntype)
@@ -184,6 +185,12 @@
def llc_options(self):
return '-enable-correct-eh-support'
+
+
+def repr_if_variable(db, arg):
+ if isinstance(arg, Variable):
+ return db.repr_arg(arg)
+
class ExplicitExceptionPolicy(ExceptionPolicy):
""" uses issubclass() and last_exception tests after each call """
def __init__(self, db):
@@ -227,12 +234,21 @@
for graph in translator.flowgraphs.itervalues():
create_exception_handling(translator, graph)
-
def invoke(self, codewriter, targetvar, returntype, functionref,
- argrefs, argtypes, label, except_label):
+ argrefs, argtypes,
+ node, block): # XXX Unsure of these being passed in
assert functionref != '%keepalive'
+ # at least one label and one exception label
+ assert len(block.exits) >= 2
+ link = block.exits[0]
+ assert link.exitcase is None
+
+ none_label = node.block_to_name[link.target]
+ block_label = node.block_to_name[block]
+ exc_label = block_label + '_exception_handling'
+
tmp = '%%invoke.tmp.%d' % self.invoke_count
exc = '%%invoke.exc.%d' % self.invoke_count
self.invoke_count += 1
@@ -240,10 +256,94 @@
# XXX Hardcoded type...
type_ = "%RPYTHON_EXCEPTION_VTABLE*"
- codewriter.call(targetvar, returntype, functionref, argrefs, argtypes)
+ codewriter.call(targetvar, returntype, functionref, argtypes, argrefs)
codewriter.load(tmp, type_, "%last_exception_type")
codewriter.binaryop("seteq", exc, type_, tmp, "null")
- codewriter.br(exc, except_label, label)
+ codewriter.br(exc, exc_label, none_label)
+
+ # write exception handling blocks
+
+ e = self.db.translator.rtyper.getexceptiondata()
+ ll_exception_match = self.db.repr_value(e.fn_exception_match._obj)
+ lltype_of_exception_type = self.db.repr_type(e.lltype_of_exception_type)
+ lltype_of_exception_value = self.db.repr_type(e.lltype_of_exception_value)
+
+ # start with the exception handling block
+ # * load the last exception type
+ # * check it with call to ll_exception_match()
+ # * branch to to correct block?
+
+ codewriter.label(exc_label)
+
+ catch_all = False
+ found_blocks_info = []
+ last_exception_type = None
+
+ # XXX tmp - debugging info
+
+ # block_label = "block28"
+ # exc_label = "block28_exception_handling"
+ # ll_exception_match = function for catching exception
+ # lltype_of_exception_type, lltype_of_exception_value = generic
+ # catch_all = ???
+ # found_blocks_info = list of found block data to write those blocks
+ # last_exception_type = Load exception pointer once for handle and not found blocks
+
+ # link = iteration thru rest of links in block
+ # etype = node for exception
+ # current_exception_type = repr for node etype
+ # target = label of the destination block
+ # exc_found_label = label of intermediate exc found block
+ # last_exc_type_var = ????
+ # last_exc_value_var = ???
+
+ for link in block.exits[1:]:
+ assert issubclass(link.exitcase, Exception)
+
+ # information for found blocks
+ target = node.block_to_name[link.target]
+ exc_found_label = block_label + '_exception_found_branchto_' + target
+ link_exc_type = repr_if_variable(self.db, link.last_exception)
+ link_exc_value = repr_if_variable(self.db, link.last_exc_value)
+ found_blocks_info.append((exc_found_label, target,
+ link_exc_type, link_exc_value))
+
+ # XXX fix database to handle this case
+ etype = self.db.obj2node[link.llexitcase._obj]
+ current_exception_type = etype.get_ref()
+ not_this_exception_label = block_label + '_not_exception_' + etype.ref[1:]
+
+ # catch specific exception (class) type
+
+ # load pointer only once
+ if not last_exception_type:
+ last_exception_type = self.db.repr_tmpvar()
+ codewriter.load(last_exception_type,
+ lltype_of_exception_type,
+ '%last_exception_type')
+ codewriter.newline()
+
+ ll_issubclass_cond = self.db.repr_tmpvar()
+
+ codewriter.call(ll_issubclass_cond,
+ 'bool',
+ ll_exception_match,
+ [lltype_of_exception_type, lltype_of_exception_type],
+ [last_exception_type, current_exception_type])
+
+ codewriter.br(ll_issubclass_cond,
+ not_this_exception_label,
+ exc_found_label)
+
+ codewriter.label(not_this_exception_label)
+
+ if not catch_all:
+ self.reraise(node, codewriter)
+
+ self.fetch_exceptions(codewriter,
+ found_blocks_info,
+ lltype_of_exception_type,
+ lltype_of_exception_value)
def write_exceptblock(self, funcnode, codewriter, block):
""" Raises an exception - called from FuncNode """
Modified: pypy/dist/pypy/translator/llvm/extfuncnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/extfuncnode.py (original)
+++ pypy/dist/pypy/translator/llvm/extfuncnode.py Fri Jan 6 19:31:20 2006
@@ -93,7 +93,7 @@
# call
codewriter.call(returnval, expected_rettype, self.ref,
- expected_argrefs, expected_argtypes)
+ expected_argtypes, expected_argrefs)
if self.wrapper.rettype:
# cast to desired return type
Modified: pypy/dist/pypy/translator/llvm/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/funcnode.py (original)
+++ pypy/dist/pypy/translator/llvm/funcnode.py Fri Jan 6 19:31:20 2006
@@ -41,17 +41,10 @@
self.ref = self.make_ref('%pypy_', value.graph.name)
self.graph = value.graph
- self.db.exceptionpolicy.transform(self.db.translator,
- self.graph)
-
- remove_exception_mallocs(self.db.translator, self.graph, self.ref)
-
#XXX experimental
#from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs
#merge_mallocs(self.db.translator, self.graph, self.ref)
- remove_double_links(self.db.translator, self.graph)
-
def __str__(self):
return "<FuncNode %r>" %(self.ref,)
@@ -75,7 +68,13 @@
traverse(visit, self.graph)
# ______________________________________________________________________
- # main entry points from genllvm
+ # main entry points from genllvm
+
+ def post_setup_transform(self):
+ self.db.exceptionpolicy.transform(self.db.translator, self.graph)
+ remove_exception_mallocs(self.db.translator, self.graph, self.ref)
+ remove_double_links(self.db.translator, self.graph)
+
def writedecl(self, codewriter):
codewriter.declare(self.getdecl())
@@ -196,20 +195,24 @@
block.exitswitch.concretetype)
def write_block_operations(self, codewriter, block):
- opwriter = OpWriter(self.db, codewriter, self, block)
-
+ # XXX We dont need multiple of these
+ opwriter = OpWriter(self.db, codewriter)
+
+ invoke_op = None
+ block_ops = block.operations
if block.exitswitch == c_last_exception:
- invoke_prefix = 'invoke:'
- # could raise an exception and should therefor have a function
- # implementation that can be invoked by the llvm-code.
- op = block.operations[len(block.operations) - 1]
- assert not op.opname.startswith(invoke_prefix)
- op.opname = invoke_prefix + op.opname
+ invoke_op = block.operations[-1]
+ block_ops = block.operations[:-1]
# emit operations
- for op in block.operations:
+ for op in block_ops:
opwriter.write_operation(op)
+ if invoke_op:
+ # could raise an exception and should therefore have a function
+ # implementation that can be invoked by the llvm-code.
+ opwriter.write_invoke_op(invoke_op, self, block)
+
# ______________________________________________________________________
# actual block writers
Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py (original)
+++ pypy/dist/pypy/translator/llvm/gc.py Fri Jan 6 19:31:20 2006
@@ -41,9 +41,9 @@
elemindices = list(indices_to_array)
elemindices += [("uint", 1), (lentype, "%actuallen")]
- codewriter.getelementptr("%size", ref + "*", "null", *elemindices)
+ codewriter.getelementptr("%size", ref + "*", "null", elemindices)
codewriter.cast("%usize", elemtype + "*", "%size", uword)
- self.malloc(codewriter, "%ptr", "sbyte", "%usize", atomic=atomic)
+ self.malloc(codewriter, "%ptr", "sbyte*", "%usize", atomic=atomic)
codewriter.cast("%result", "sbyte*", "%ptr", ref + "*")
indices_to_arraylength = tuple(indices_to_array) + (("uint", 0),)
@@ -51,21 +51,21 @@
# the following accesses the length field of the array
codewriter.getelementptr("%arraylength", ref + "*",
"%result",
- *indices_to_arraylength)
+ indices_to_arraylength)
codewriter.store(lentype, "%len", "%arraylength")
#if is_str:
# indices_to_hash = (("uint", 0),)
# codewriter.getelementptr("%ptrhash", ref + "*",
# "%result",
- # *indices_to_hash)
+ # indices_to_hash)
# codewriter.store("int", "0", "%ptrhash")
#if ARRAY is STR.chars:
# codewriter.getelementptr("%ptrendofchar", ref + "*",
# "%result",
- # *elemindices)
+ # elemindices)
# codewriter.store(elemtype, "0", "%ptrendofchar")
codewriter.ret(ref + "*", "%result")
@@ -122,10 +122,10 @@
cnt = '.%d' % self.n_malloced
atomic = is_atomic and '_atomic' or ''
t = '''
-%%malloc_Size%(cnt)s = getelementptr %(type_)s* null, %(uword)s %(s)s
-%%malloc_SizeU%(cnt)s = cast %(type_)s* %%malloc_Size%(cnt)s to %(uword)s
+%%malloc_Size%(cnt)s = getelementptr %(type_)s null, %(uword)s %(s)s
+%%malloc_SizeU%(cnt)s = cast %(type_)s %%malloc_Size%(cnt)s to %(uword)s
%%malloc_Ptr%(cnt)s = call fastcc sbyte* %%pypy_malloc%(atomic)s(%(uword)s %%malloc_SizeU%(cnt)s)
-%(targetvar)s = cast sbyte* %%malloc_Ptr%(cnt)s to %(type_)s*
+%(targetvar)s = cast sbyte* %%malloc_Ptr%(cnt)s to %(type_)s
''' % locals()
if is_atomic:
Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py Fri Jan 6 19:31:20 2006
@@ -86,6 +86,9 @@
self.db.setup_all()
self._checkpoint('setup_all externs')
+ for node in self.db.getnodes():
+ node.post_setup_transform()
+
self._print_node_stats()
# create ll file from c code
@@ -290,7 +293,12 @@
if optimize:
backend_optimizations(t, ssa_form=False)
else:
- backend_optimizations(t, ssa_form=False, mallocs=False, inline_threshold=0, merge_if_blocks_to_switch=False, propagate=False)
+ backend_optimizations(t, ssa_form=False,
+ inline_threshold=0,
+ mallocs=False,
+ merge_if_blocks_to_switch=False,
+ propagate=False)
+
# note: this is without policy transforms
if view:
t.view()
Modified: pypy/dist/pypy/translator/llvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/node.py (original)
+++ pypy/dist/pypy/translator/llvm/node.py Fri Jan 6 19:31:20 2006
@@ -26,6 +26,11 @@
pass
# __________________ before "implementation" ____________________
+
+
+ def post_setup_transform(self):
+ pass
+
def writedatatypedecl(self, codewriter):
""" write out declare names of data types
(structs/arrays/function pointers)
Modified: pypy/dist/pypy/translator/llvm/opaquenode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opaquenode.py (original)
+++ pypy/dist/pypy/translator/llvm/opaquenode.py Fri Jan 6 19:31:20 2006
@@ -82,5 +82,5 @@
codewriter.call(self.db.repr_tmpvar(),
"sbyte*",
"%RPyOpaque_LLVM_SETUP_ThreadLock",
- argrefs, argtypes)
+ argtypes, argrefs)
# XXX Check result
Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py (original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py Fri Jan 6 19:31:20 2006
@@ -1,349 +1,278 @@
-from pypy.objspace.flow.model import Constant, Variable
+from pypy.objspace.flow.model import Constant
from pypy.rpython.lltypesystem import lltype
from pypy.translator.llvm.log import log
log = log.opwriter
-def repr_if_variable(db, arg):
- if isinstance(arg, Variable):
- return db.repr_arg(arg)
-
-class OpWriter(object):
- binary_operations = {'int_mul': 'mul',
- 'int_add': 'add',
- 'int_sub': 'sub',
- 'int_floordiv': 'div',
- 'int_mod': 'rem',
- 'int_and': 'and',
- 'int_or': 'or',
- 'int_xor': 'xor',
- 'int_lt': 'setlt',
- 'int_le': 'setle',
- 'int_eq': 'seteq',
- 'int_ne': 'setne',
- 'int_ge': 'setge',
- 'int_gt': 'setgt',
-
- 'llong_mul': 'mul',
- 'llong_add': 'add',
- 'llong_sub': 'sub',
- 'llong_floordiv': 'div',
- 'llong_mod': 'rem',
- 'llong_and': 'and',
- 'llong_or': 'or',
- 'llong_xor': 'xor',
- 'llong_lt': 'setlt',
- 'llong_le': 'setle',
- 'llong_eq': 'seteq',
- 'llong_ne': 'setne',
- 'llong_ge': 'setge',
- 'llong_gt': 'setgt',
-
- 'uint_mul': 'mul',
- 'uint_add': 'add',
- 'uint_sub': 'sub',
- 'uint_floordiv': 'div',
- 'uint_mod': 'rem',
- 'uint_and': 'and',
- 'uint_or': 'or',
- 'uint_xor': 'xor',
- 'uint_lt': 'setlt',
- 'uint_le': 'setle',
- 'uint_eq': 'seteq',
- 'uint_ne': 'setne',
- 'uint_ge': 'setge',
- 'uint_gt': 'setgt',
-
- 'unichar_lt': 'setlt',
- 'unichar_le': 'setle',
- 'unichar_eq': 'seteq',
- 'unichar_ne': 'setne',
- 'unichar_ge': 'setge',
- 'unichar_gt': 'setgt',
-
- 'float_mul': 'mul',
- 'float_add': 'add',
- 'float_sub': 'sub',
- 'float_truediv': 'div',
- 'float_lt': 'setlt',
- 'float_le': 'setle',
- 'float_eq': 'seteq',
- 'float_ne': 'setne',
- 'float_ge': 'setge',
- 'float_gt': 'setgt',
-
- 'ptr_eq': 'seteq',
- 'ptr_ne': 'setne',
- }
-
- shift_operations = {'int_lshift': 'shl',
- 'int_rshift': 'shr',
+class OpRepr(object):
+ __slots__ = "db op retref rettype argrefs argtypes".split()
+ def __init__(self, op, db):
+ self.db = db
+ self.op = op
+ self.argrefs = db.repr_arg_multi(op.args)
+ self.argtypes = db.repr_arg_type_multi(op.args)
+ self.retref = db.repr_arg(op.result)
+ self.rettype = db.repr_arg_type(op.result)
+
+class OpReprCall(OpRepr):
+ __slots__ = "db op retref rettype argrefs argtypes".split()
+ def __init__(self, op, db):
+ super(OpReprCall, self).__init__(op, db)
+ self.argrefs = [aref for arg, aref in zip(op.args, self.argrefs)
+ if arg.concretetype is not lltype.Void]
+ self.argtypes = [atype for arg, atype in zip(op.args, self.argtypes)
+ if arg.concretetype is not lltype.Void]
+ if self.db.is_function_ptr(self.op.result):
+ self.rettype = "%s (%s)*" % (self.rettype,
+ ", ".join(self.argtypes[1:]))
+
+class OpReprInvoke(OpReprCall):
+ __slots__ = "db op retref rettype argrefs argtypes functionref".split()
+ def __init__(self, op, db):
+ super(OpReprInvoke, self).__init__(op, db)
+
+ if op.opname == 'direct_call':
+ self.functionref = self.argrefs[0]
+ self.argrefs = self.argrefs[1:]
+ self.argtypes = self.argtypes[1:]
+ else:
+ self.functionref = '%pypyop_' + op.opname
- 'uint_lshift': 'shl',
- 'uint_rshift': 'shr',
-
- 'llong_lshift': 'shl',
- 'llong_rshift': 'shr',
+class OpWriter(object):
+
+ binary_operations = {
+ 'float_mul' : 'mul',
+ 'float_add' : 'add',
+ 'float_sub' : 'sub',
+ 'float_truediv' : 'div',
+
+ 'ptr_eq' : 'seteq',
+ 'ptr_ne' : 'setne' }
+
+ # generic numeric ops
+ for tt in 'int llong uint'.split():
+ for oo in 'mul add sub and or xor'.split():
+ binary_operations['%s_%s' % (tt, oo)] = oo
+ binary_operations['%s_floordiv' % tt] = 'div'
+ binary_operations['%s_mod' % tt] = 'rem'
+
+ # comparison ops
+ for tt in 'int llong uint unichar float'.split():
+ for oo in 'lt le eq ne ge gt'.split():
+ binary_operations['%s_%s' % (tt, oo)] = 'set%s' % oo
+
+
+ shift_operations = {'int_lshift': 'shl',
+ 'int_rshift': 'shr',
+
+ 'uint_lshift': 'shl',
+ 'uint_rshift': 'shr',
+
+ 'llong_lshift': 'shl',
+ 'llong_rshift': 'shr',
}
+ char_operations = {'char_lt': 'setlt',
+ 'char_le': 'setle',
+ 'char_eq': 'seteq',
+ 'char_ne': 'setne',
+ 'char_ge': 'setge',
+ 'char_gt': 'setgt'}
- char_operations = {'char_lt': 'setlt',
- 'char_le': 'setle',
- 'char_eq': 'seteq',
- 'char_ne': 'setne',
- 'char_ge': 'setge',
- 'char_gt': 'setgt'}
-
- def __init__(self, db, codewriter, node, block):
+ def __init__(self, db, codewriter):
self.db = db
self.codewriter = codewriter
- self.node = node
- self.block = block
+ def _tmp(self, count=1):
+ if count == 1:
+ return self.db.repr_tmpvar()
+ else:
+ return [self.db.repr_tmpvar() for ii in range(count)]
+
def write_operation(self, op):
- invoke = op.opname.startswith('invoke:')
- if invoke:
- self.invoke(op)
+ if op.opname == "direct_call":
+ opr = OpReprCall(op, self.db)
else:
- if op.opname in self.binary_operations:
- self.binaryop(op)
- elif op.opname in self.shift_operations:
- self.shiftop(op)
- elif op.opname in self.char_operations:
- self.char_binaryop(op)
- elif op.opname.startswith('cast_') or op.opname.startswith('truncate_'):
- if op.opname == 'cast_char_to_int':
- self.cast_char_to_int(op)
- else:
- self.cast_primitive(op)
+ opr = OpRepr(op, self.db)
+
+ if op.opname in self.binary_operations:
+ self.binaryop(opr)
+ elif op.opname in self.shift_operations:
+ self.shiftop(opr)
+ elif op.opname in self.char_operations:
+ self.char_binaryop(opr)
+ elif op.opname.startswith('cast_') or op.opname.startswith('truncate_'):
+ if op.opname == 'cast_char_to_int':
+ self.cast_char_to_int(opr)
else:
- meth = getattr(self, op.opname, None)
- if not meth:
- raise Exception, "operation %s not found" % op.opname
- meth(op)
-
- def _generic_pow(self, op, onestr):
- mult_type = self.db.repr_arg_type(op.args[0])
- mult_val = self.db.repr_arg(op.args[0])
- last_val = mult_val
+ self.cast_primitive(opr)
+ else:
+ meth = getattr(self, op.opname, None)
+ if not meth:
+ raise Exception, "operation %s not found" % op.opname
+ meth(opr)
+
+ def write_invoke_op(self, op, node, block):
+ opr = OpReprInvoke(op, self.db)
+ ep = self.db.exceptionpolicy
+ ep.invoke(self.codewriter, opr.retref, opr.rettype, opr.functionref,
+ opr.argrefs, opr.argtypes, node, block)
+
+ def _generic_pow(self, opr, onestr):
+
+ # XXX This broken as... will only work for constants
try:
value = "NO VALUE"
- value = op.args[1].value
+ value = opr.op.args[1].value
operand = int(value)
except Exception, exc:
msg = 'XXX: Error: _generic_pow: Variable '\
'%s - failed to convert to int %s' % (value, str(exc))
self.codewriter.comment(msg)
raise Exception(msg)
+
+ mult_type = opr.argtypes[0]
+ mult_val = opr.argrefs[0]
+ last_val = mult_val
if operand < 1:
res_val = onestr
else:
res_val = mult_val
for ii in range(operand - 1):
- res_val = self.db.repr_tmpvar()
- self.codewriter.binaryop("mul",
- res_val,
- mult_type,
- last_val,
- mult_val)
+ res_val = self._tmp()
+ self.codewriter.binaryop("mul", res_val, mult_type,
+ last_val, mult_val)
last_val = res_val
- targetvar = self.db.repr_arg(op.result)
- self.codewriter.cast(targetvar, mult_type, res_val, mult_type)
+ self.codewriter.cast(opr.retref, mult_type, res_val, mult_type)
- def _skipped(self, op):
- self.codewriter.comment('***Skipping operation %s()' % (op.opname,))
+ def _skipped(self, opr):
+ self.codewriter.comment('***Skipping operation %s()' % opr.op.opname)
keepalive = _skipped
- def int_abs(self, op):
- functionref = '%pypyop_' + op.opname
- self.codewriter.call(self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.result),
- functionref,
- [self.db.repr_arg(op.args[0])],
- [self.db.repr_arg_type(op.args[0])])
+ def int_abs(self, opr):
+ assert len(opr.argrefs) == 1
+ functionref = '%pypyop_' + opr.op.opname
+ self.codewriter.call(opr.retref, opr.rettype, functionref,
+ opr.argtypes, opr.argrefs)
+
float_abs = int_abs
llong_abs = int_abs
- def int_pow(self, op):
- self._generic_pow(op, "1")
+ def int_pow(self, opr):
+ self._generic_pow(opr, "1")
uint_pow = int_pow
- def float_pow(self, op):
- self._generic_pow(op, "1.0")
+ def float_pow(self, opr):
+ self._generic_pow(opr, "1.0")
+
+ def _generic_neg(self, opr, zerostr):
+ self.codewriter.binaryop("sub", opr.retref, opr.argtypes[0],
+ zerostr, opr.argrefs[0])
- def _generic_neg(self, op, zerostr):
- self.codewriter.binaryop("sub",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- zerostr,
- self.db.repr_arg(op.args[0]),
- )
- def int_neg(self, op):
- self._generic_neg(op, "0")
+ def int_neg(self, opr):
+ self._generic_neg(opr, "0")
- #this is really generated, don't know why
+ # this is really generated, don't know why
# XXX rxe: Surely that cant be right?
uint_neg = int_neg
- def float_neg(self, op):
- self._generic_neg(op, "0.0")
-
- def bool_not(self, op):
- self.codewriter.binaryop("xor",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- "true")
-
- def int_invert(self, op):
- self.codewriter.binaryop("xor",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- -1)
-
- def uint_invert(self, op):
- self.codewriter.binaryop("xor",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- str((1L<<32) - 1))
-
- def binaryop(self, op):
- name = self.binary_operations[op.opname]
- assert len(op.args) == 2
- self.codewriter.binaryop(name,
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- self.db.repr_arg(op.args[1]))
-
- def char_binaryop(self, op):
- name = self.char_operations[op.opname]
- assert len(op.args) == 2
- res = self.db.repr_arg(op.result)
- c1 = self.db.repr_tmpvar()
- c2 = self.db.repr_tmpvar()
- self.codewriter.cast(c1, "sbyte", self.db.repr_arg(op.args[0]), "ubyte")
- self.codewriter.cast(c2, "sbyte", self.db.repr_arg(op.args[1]), "ubyte")
- self.codewriter.binaryop(name, res, "ubyte", c1, c2)
+ def float_neg(self, opr):
+ self._generic_neg(opr, "0.0")
+ def bool_not(self, opr):
+ self.codewriter.binaryop("xor", opr.retref, opr.argtypes[0],
+ opr.argrefs[0], "true")
+
+ def int_invert(self, opr):
+ self.codewriter.binaryop("xor", opr.retref, opr.argtypes[0],
+ opr.argrefs[0], -1)
+
+ def uint_invert(self, opr):
+ self.codewriter.binaryop("xor", opr.retref, opr.argtypes[0],
+ opr.argrefs[0], str((1L<<32) - 1))
+
+ def binaryop(self, opr):
+ assert len(opr.argrefs) == 2
+ name = self.binary_operations[opr.op.opname]
+ self.codewriter.binaryop(name, opr.retref, opr.argtypes[0],
+ opr.argrefs[0], opr.argrefs[1])
+
+ def char_binaryop(self, opr):
+ assert len(opr.argrefs) == 2
+ name = self.char_operations[opr.op.opname]
+ c1, c2 = self._tmp(2)
+ self.codewriter.cast(c1, "sbyte", opr.argrefs[0], "ubyte")
+ self.codewriter.cast(c2, "sbyte", opr.argrefs[1], "ubyte")
+ self.codewriter.binaryop(name, opr.retref, "ubyte", c1, c2)
- def shiftop(self, op):
+ def shiftop(self, opr):
+ op = opr.op
name = self.shift_operations[op.opname]
- assert len(op.args) == 2
+
if isinstance(op.args[1], Constant):
- tmpvar = self.db.repr_arg(op.args[1])
+ var = opr.argrefs[1]
else:
- tmpvar = self.db.repr_tmpvar()
- self.codewriter.cast(tmpvar, self.db.repr_arg_type(op.args[1]), self.db.repr_arg(op.args[1]), 'ubyte')
- self.codewriter.shiftop(name,
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- tmpvar)
+ var = self._tmp()
+ self.codewriter.cast(var, opr.argtypes[1], opr.argrefs[1], 'ubyte')
+
+ self.codewriter.shiftop(name, opr.retref, opr.argtypes[0],
+ opr.argrefs[0], var)
- def cast_char_to_int(self, op):
+ def cast_char_to_int(self, opr):
" works for all casts "
- assert len(op.args) == 1
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- fromvar = self.db.repr_arg(op.args[0])
- fromtype = self.db.repr_arg_type(op.args[0])
- intermediate = self.db.repr_tmpvar()
- self.codewriter.cast(intermediate, fromtype, fromvar, "ubyte")
- self.codewriter.cast(targetvar, "ubyte", intermediate, targettype)
+ assert len(opr.argrefs) == 1
+ intermediate = self._tmp()
+ self.codewriter.cast(intermediate, opr.argtypes[0],
+ opr.argrefs[0], "ubyte")
+ self.codewriter.cast(opr.retref, "ubyte", intermediate, opr.rettype)
- def cast_primitive(self, op):
+ def cast_primitive(self, opr):
" works for all casts "
- assert len(op.args) == 1
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- fromvar = self.db.repr_arg(op.args[0])
- fromtype = self.db.repr_arg_type(op.args[0])
- self.codewriter.cast(targetvar, fromtype, fromvar, targettype)
+ assert len(opr.argrefs) == 1
+ self.codewriter.cast(opr.retref, opr.argtypes[0],
+ opr.argrefs[0], opr.rettype)
same_as = cast_primitive
- def int_is_true(self, op):
- self.codewriter.binaryop("setne",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- "0")
+ def int_is_true(self, opr):
+ self.codewriter.binaryop("setne", opr.retref, opr.argtypes[0],
+ opr.argrefs[0], "0")
uint_is_true = int_is_true
llong_is_true = int_is_true
- def float_is_true(self, op):
- self.codewriter.binaryop("setne",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- "0.0")
-
- def ptr_nonzero(self, op):
- self.codewriter.binaryop("setne",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- "null")
-
- def ptr_iszero(self, op):
- self.codewriter.binaryop("seteq",
- self.db.repr_arg(op.result),
- self.db.repr_arg_type(op.args[0]),
- self.db.repr_arg(op.args[0]),
- "null")
-
- def direct_call(self, op):
- op_args = [arg for arg in op.args
- if arg.concretetype is not lltype.Void]
- assert len(op_args) >= 1
- targetvar = self.db.repr_arg(op.result)
- returntype = self.db.repr_arg_type(op.result)
- functionref = self.db.repr_arg(op_args[0])
- argrefs = self.db.repr_arg_multi(op_args[1:])
- argtypes = self.db.repr_arg_type_multi(op_args[1:])
- if self.db.is_function_ptr(op.result):
- returntype = "%s (%s)*" % (returntype, ", ".join(argtypes))
- self.codewriter.call(targetvar, returntype,
- functionref, argrefs, argtypes)
-
- def malloc_exception(self, op):
- arg_type = op.args[0].value
- targetvar = self.db.repr_arg(op.result)
- type_ = self.db.repr_type(arg_type)
- tmpvar1 = self.db.repr_tmpvar()
- tmpvar2 = self.db.repr_tmpvar()
- tmpvar3 = self.db.repr_tmpvar()
-
- ptr_type = type_ + '*'
- self.codewriter.raw_getelementptr(tmpvar1, ptr_type, "null", ("int", 1))
- self.codewriter.cast(tmpvar2, ptr_type, tmpvar1, 'uint')
- self.codewriter.call(tmpvar3, 'sbyte*', '%malloc_exception', [tmpvar2], ['uint'])
- self.codewriter.cast(targetvar, 'sbyte*', tmpvar3, type_+'*')
-
- def malloc(self, op):
- arg_type = op.args[0].value
- targetvar = self.db.repr_arg(op.result)
- type_ = self.db.repr_type(arg_type)
- gp = self.db.gcpolicy
- gp.malloc(self.codewriter, targetvar, type_,
- atomic=arg_type._is_atomic())
+ def float_is_true(self, opr):
+ self.codewriter.binaryop("setne", opr.retref, opr.argtypes[0],
+ opr.argrefs[0], "0.0")
+
+ def ptr_nonzero(self, opr):
+ self.codewriter.binaryop("setne", opr.retref, opr.argtypes[0],
+ opr.argrefs[0], "null")
+
+ def ptr_iszero(self, opr):
+ self.codewriter.binaryop("seteq", opr.retref, opr.argtypes[0],
+ opr.argrefs[0], "null")
+
+ def direct_call(self, opr):
+ self.codewriter.call(opr.retref, opr.rettype, opr.argrefs[0],
+ opr.argtypes[1:], opr.argrefs[1:])
+
+ def malloc(self, opr):
+ arg_type = opr.op.args[0].value
+ self.db.gcpolicy.malloc(self.codewriter, opr.retref, opr.rettype,
+ atomic=arg_type._is_atomic())
+
+ def malloc_varsize(self, opr):
- def malloc_varsize(self, op):
- arg_type = op.args[0].value
+ # XXX transformation
+ arg_type = opr.op.args[0].value
if isinstance(arg_type, lltype.Array) and arg_type.OF is lltype.Void:
# This is a backend decision to NOT represent a void array with
# anything and save space - therefore not varsized anymore
- self.malloc(op)
+ self.malloc(opr)
return
-
- targetvar = self.db.repr_arg(op.result)
- type_ = self.db.repr_type(arg_type) + "*"
- type_cons = self.db.repr_constructor(arg_type)
- argrefs = self.db.repr_arg_multi(op.args[1:])
- argtypes = self.db.repr_arg_type_multi(op.args[1:])
- self.codewriter.call(targetvar, type_, type_cons, argrefs, argtypes)
+
+ self.codewriter.call(opr.retref, opr.rettype,
+ self.db.repr_constructor(arg_type),
+ opr.argtypes[1:], opr.argrefs[1:])
def _getindexhelper(self, name, struct):
assert name in list(struct._names)
@@ -355,186 +284,139 @@
index = -1
return index
- def getfield(self, op):
- tmpvar = self.db.repr_tmpvar()
- struct, structtype = self.db.repr_argwithtype(op.args[0])
- index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO)
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- if targettype != "void":
+ def getfield(self, opr):
+ op = opr.op
+ if opr.rettype != "void":
+ index = self._getindexhelper(op.args[1].value,
+ op.args[0].concretetype.TO)
assert index != -1
- self.codewriter.getelementptr(tmpvar, structtype, struct,
- ("uint", index))
- self.codewriter.load(targetvar, targettype, tmpvar)
+ tmpvar = self._tmp()
+ self.codewriter.getelementptr(tmpvar, opr.argtypes[0],
+ opr.argrefs[0], [("uint", index)])
+ self.codewriter.load(opr.retref, opr.rettype, tmpvar)
else:
- self._skipped(op)
+ self._skipped(opr)
- def getsubstruct(self, op):
- struct, structtype = self.db.repr_argwithtype(op.args[0])
- index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO)
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- assert targettype != "void"
- self.codewriter.getelementptr(targetvar, structtype,
- struct, ("uint", index))
+ def getsubstruct(self, opr):
+ index = self._getindexhelper(opr.op.args[1].value,
+ opr.op.args[0].concretetype.TO)
+ assert opr.rettype != "void"
+ self.codewriter.getelementptr(opr.retref, opr.argtypes[0],
+ opr.argrefs[0], [("uint", index)])
- def setfield(self, op):
- tmpvar = self.db.repr_tmpvar()
- struct, structtype = self.db.repr_argwithtype(op.args[0])
- index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO)
- valuevar, valuetype = self.db.repr_argwithtype(op.args[2])
- if valuetype != "void":
- #Structure types require uint constants!
- #see: http://llvm.cs.uiuc.edu/docs/LangRef.html#i_getelementptr
- self.codewriter.getelementptr(tmpvar, structtype, struct,
- ("uint", index))
- self.codewriter.store(valuetype, valuevar, tmpvar)
+ def setfield(self, opr):
+ op = opr.op
+ if opr.argtypes[2] != "void":
+ tmpvar = self._tmp()
+ index = self._getindexhelper(op.args[1].value,
+ op.args[0].concretetype.TO)
+ self.codewriter.getelementptr(tmpvar, opr.argtypes[0],
+ opr.argrefs[0], [("uint", index)])
+ self.codewriter.store(opr.argtypes[2], opr.argrefs[2], tmpvar)
+
else:
- self._skipped(op)
+ self._skipped(opr)
- def getarrayitem(self, op):
- array, arraytype = self.db.repr_argwithtype(op.args[0])
- index = self.db.repr_arg(op.args[1])
- indextype = self.db.repr_arg_type(op.args[1])
- tmpvar = self.db.repr_tmpvar()
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- if targettype != "void":
+ def getarrayitem(self, opr):
+ if opr.rettype != "void":
+ arraytype, indextype = opr.argtypes
+ array, index = opr.argrefs
+ tmpvar = self._tmp()
self.codewriter.getelementptr(tmpvar, arraytype, array,
- ("uint", 1), (indextype, index))
- self.codewriter.load(targetvar, targettype, tmpvar)
+ [("uint", 1), (indextype, index)])
+ self.codewriter.load(opr.retref, opr.rettype, tmpvar)
else:
- self._skipped(op)
-
- def getarraysubstruct(self, op):
- array, arraytype = self.db.repr_argwithtype(op.args[0])
- index = self.db.repr_arg(op.args[1])
- indextype = self.db.repr_arg_type(op.args[1])
- targetvar = self.db.repr_arg(op.result)
- self.codewriter.getelementptr(targetvar, arraytype, array,
- ("uint", 1), (indextype, index))
-
- def setarrayitem(self, op):
- array, arraytype = self.db.repr_argwithtype(op.args[0])
- index = self.db.repr_arg(op.args[1])
- indextype = self.db.repr_arg_type(op.args[1])
+ self._skipped(opr)
- tmpvar = self.db.repr_tmpvar()
-
- valuevar = self.db.repr_arg(op.args[2])
- valuetype = self.db.repr_arg_type(op.args[2])
+ def getarraysubstruct(self, opr):
+ arraytype, indextype = opr.argtypes
+ array, index = opr.argrefs
+ self.codewriter.getelementptr(opr.retref, arraytype, array,
+ [("uint", 1), (indextype, index)])
+
+ def setarrayitem(self, opr):
+ array, index, valuevar = opr.argrefs
+ arraytype, indextype, valuetype = opr.argtypes
+ tmpvar = self._tmp()
if valuetype != "void":
self.codewriter.getelementptr(tmpvar, arraytype, array,
- ("uint", 1), (indextype, index))
+ [("uint", 1), (indextype, index)])
self.codewriter.store(valuetype, valuevar, tmpvar)
else:
- self._skipped(op)
+ self._skipped(opr)
- def getarraysize(self, op):
- array, arraytype = self.db.repr_argwithtype(op.args[0])
- tmpvar = self.db.repr_tmpvar()
- self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 0))
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- self.codewriter.load(targetvar, targettype, tmpvar)
-
- def adr_delta(self, op):
- tmp = self.db.repr_tmpvar
- addr1, addr2 = tmp(), tmp()
- arg1, argtype1 = self.db.repr_argwithtype(op.args[0])
- arg2, argtype2 = self.db.repr_argwithtype(op.args[1])
- self.codewriter.cast(addr1, argtype1, arg1, "int")
- self.codewriter.cast(addr2, argtype2, arg2, "int")
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- self.codewriter.binaryop("sub",
- targetvar, targettype,
- addr1, addr2,)
-
- def _op_adr_generic(self, op, llvm_op):
- tmp = self.db.repr_tmpvar
- addr, res = tmp(), tmp()
- arg, argtype = self.db.repr_argwithtype(op.args[0])
- self.codewriter.cast(addr, argtype, arg, "int")
- arg2, argtype2 = self.db.repr_argwithtype(op.args[1])
- self.codewriter.binaryop(llvm_op,
- res, "int",
- addr, arg2)
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- self.codewriter.cast(targetvar, "int", res, targettype)
-
- def adr_add(self, op):
- self._op_adr_generic(op, "add")
-
- def adr_sub(self, op):
- self._op_adr_generic(op, "sub")
-
- def _op_adr_comparison_generic(self, op, llvm_op):
- tmp = self.db.repr_tmpvar
- addr1, addr2 = tmp(), tmp()
- arg1, argtype1 = self.db.repr_argwithtype(op.args[0])
- arg2, argtype2 = self.db.repr_argwithtype(op.args[1])
- self.codewriter.cast(addr1, argtype1, arg1, "int")
- self.codewriter.cast(addr2, argtype2, arg2, "int")
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- assert targettype == "bool"
- self.codewriter.binaryop(llvm_op,
- targetvar, "int",
- addr1, addr2)
-
- def adr_eq(self, op):
- self._op_adr_comparison_generic(op, "seteq")
-
- def adr_ne(self, op):
- self._op_adr_comparison_generic(op, "setne")
-
- def adr_le(self, op):
- self._op_adr_comparison_generic(op, "setle")
-
- def adr_gt(self, op):
- self._op_adr_comparison_generic(op, "setgt")
-
- def adr_lt(self, op):
- self._op_adr_comparison_generic(op, "setlt")
-
- def adr_ge(self, op):
- self._op_adr_comparison_generic(op, "setge")
-
- def raw_malloc(self, op):
- # XXX ignore raise as not last op
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- argrefs = self.db.repr_arg_multi(op.args)
- argtypes = self.db.repr_arg_type_multi(op.args)
- self.codewriter.call(targetvar, targettype, "%raw_malloc",
- argrefs, argtypes)
- def raw_free(self, op):
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- argrefs = self.db.repr_arg_multi(op.args)
- argtypes = self.db.repr_arg_type_multi(op.args)
- self.codewriter.call(targetvar, targettype, "%raw_free",
- argrefs, argtypes)
-
- def raw_memcopy(self, op):
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
- argrefs = self.db.repr_arg_multi(op.args)
- argtypes = self.db.repr_arg_type_multi(op.args)
- self.codewriter.call(targetvar, targettype, "%raw_memcopy",
- argrefs, argtypes)
+ def getarraysize(self, opr):
+ tmpvar = self._tmp()
+ self.codewriter.getelementptr(tmpvar, opr.argtypes[0],
+ opr.argrefs[0], [("uint", 0)])
+ self.codewriter.load(opr.retref, opr.rettype, tmpvar)
- def raw_store(self, op):
- tmp = self.db.repr_tmpvar
+
+ # XXX use machine word size
+
+ def adr_delta(self, opr):
+ addr1, addr2 = self._tmp(2)
+ self.codewriter.cast(addr1, opr.argtypes[0], opr.argrefs[0], "int")
+ self.codewriter.cast(addr2, opr.argtypes[1], opr.argrefs[1], "int")
+ self.codewriter.binaryop("sub", opr.retref, opr.rettype, addr1, addr2)
+
+ def _op_adr_generic(self, opr, llvm_op):
+ addr, res = self._tmp(2)
+ self.codewriter.cast(addr, opr.argtypes[0], opr.argrefs[0], "int")
+ self.codewriter.binaryop(llvm_op, res, "int", addr, opr.argrefs[1])
+ self.codewriter.cast(opr.retref, "int", res, opr.rettype)
+
+ def adr_add(self, opr):
+ self._op_adr_generic(opr, "add")
+
+ def adr_sub(self, opr):
+ self._op_adr_generic(opr, "sub")
+
+ def _op_adr_cmp(self, opr, llvm_op):
+ addr1, addr2 = self._tmp(2)
+ self.codewriter.cast(addr1, opr.argtypes[0], opr.argrefs[0], "int")
+ self.codewriter.cast(addr2, opr.argtypes[1], opr.argrefs[1], "int")
+ assert opr.rettype == "bool"
+ self.codewriter.binaryop(llvm_op, opr.retref, "int", addr1, addr2)
+
+ def adr_eq(self, opr):
+ self._op_adr_cmp(opr, "seteq")
+
+ def adr_ne(self, opr):
+ self._op_adr_cmp(opr, "setne")
+
+ def adr_le(self, opr):
+ self._op_adr_cmp(opr, "setle")
+
+ def adr_gt(self, opr):
+ self._op_adr_cmp(opr, "setgt")
+
+ def adr_lt(self, opr):
+ self._op_adr_cmp(opr, "setlt")
+
+ def adr_ge(self, opr):
+ self._op_adr_cmp(opr, "setge")
+
+ # XXX Not sure any of this makes sense - maybe seperate policy for
+ # different flavours of mallocs? Well it depend on what happens the GC
+ # developments
+ def raw_malloc(self, opr):
+ self.codewriter.call(opr.retref, opr.rettype, "%raw_malloc",
+ opr.argtypes, opr.argrefs)
+ def raw_free(self, opr):
+ self.codewriter.call(opr.retref, opr.rettype, "%raw_free",
+ opr.argtypes, opr.argrefs)
+
+ def raw_memcopy(self, opr):
+ self.codewriter.call(opr.retref, opr.rettype, "%raw_memcopy",
+ opr.argtypes, opr.argrefs)
- (arg_addr, arg_dummy,
- arg_incr, arg_value) = self.db.repr_arg_multi(op.args)
+ def raw_store(self, opr):
+ arg_addr, arg_dummy, arg_incr, arg_value = opr.argrefs
(argtype_addr, argtype_dummy,
- argtype_incr, argtype_value) = self.db.repr_arg_type_multi(op.args)
+ argtype_incr, argtype_value) = opr.argtypes
- cast_addr = tmp()
+ cast_addr = self._tmp()
addr_type = argtype_value + "*"
# cast to the correct type before arithmetic/storing
@@ -542,168 +424,54 @@
# pointer arithmetic
if arg_incr:
- incr_addr = tmp()
- self.codewriter.raw_getelementptr(incr_addr,
- addr_type,
- cast_addr,
- ("int", arg_incr))
+ incr_addr = self._tmp()
+ self.codewriter.getelementptr(incr_addr,
+ addr_type,
+ cast_addr,
+ [("int", arg_incr)],
+ getptr=False)
cast_addr = incr_addr
self.codewriter.store(argtype_value, arg_value, cast_addr)
- def raw_load(self, op):
- tmp = self.db.repr_tmpvar
-
- arg_addr, arg_dummy, arg_incr = self.db.repr_arg_multi(op.args)
- argtype_addr, argtype_dummy, argtype_incr = \
- self.db.repr_arg_type_multi(op.args)
- targetvar = self.db.repr_arg(op.result)
- targettype = self.db.repr_arg_type(op.result)
+ def raw_load(self, opr):
+ arg_addr, arg_dummy, arg_incr = opr.argrefs
+ argtype_addr, argtype_dummy, argtype_incr = opr.argtypes
- cast_addr = tmp()
- addr_type = targettype + "*"
+ cast_addr = self._tmp()
+ addr_type = opr.rettype + "*"
# cast to the correct type before arithmetic/loading
self.codewriter.cast(cast_addr, argtype_addr, arg_addr, addr_type)
+
# pointer arithmetic
if arg_incr:
- incr_addr = tmp()
- self.codewriter.raw_getelementptr(incr_addr,
- addr_type,
- cast_addr,
- ("int", arg_incr))
+ incr_addr = self._tmp()
+ self.codewriter.getelementptr(incr_addr,
+ addr_type,
+ cast_addr,
+ [("int", arg_incr)],
+ getptr=False)
cast_addr = incr_addr
- self.codewriter.load(targetvar, targettype, cast_addr)
+ self.codewriter.load(opr.retref, opr.rettype, cast_addr)
# ______________________________________________________________________
- # exception specific
+ #
+ # XXX exception specific - move to policy?
- def last_exception_type_ptr(self, op):
+ def malloc_exception(self, opr):
+ tmpvar1, tmpvar2, tmpvar3 = self._tmp(3)
+ cw = self.codewriter
+ cw.getelementptr(tmpvar1, opr.rettype, "null", [("int", 1)], getptr=False)
+ cw.cast(tmpvar2, opr.rettype, tmpvar1, 'uint')
+ cw.call(tmpvar3, 'sbyte*', '%malloc_exception', ['uint'], [tmpvar2])
+ cw.cast(opr.retref, 'sbyte*', tmpvar3, opr.rettype)
+
+ def last_exception_type_ptr(self, opr):
+ op = opr.op
e = self.db.translator.rtyper.getexceptiondata()
self.codewriter.load('%' + str(op.result),
self.db.repr_type(e.lltype_of_exception_type),
'%last_exception_type')
- def invoke(self, op):
- ep = self.db.exceptionpolicy
-
- op_args = [arg for arg in op.args
- if arg.concretetype is not lltype.Void]
-
- if op.opname == 'invoke:direct_call':
- functionref = self.db.repr_arg(op_args[0])
-
- else:
- # operation - provided by genexterns
- opname = op.opname.split(':', 1)[1]
- op_args = ['%pypyop_' + opname] + op_args
- functionref = op_args[0]
-
- assert len(op_args) >= 1
-
- # at least one label and one exception label
- assert len(self.block.exits) >= 2
-
- link = self.block.exits[0]
- assert link.exitcase is None
-
- targetvar = self.db.repr_arg(op.result)
- returntype = self.db.repr_arg_type(op.result)
- argrefs = self.db.repr_arg_multi(op_args[1:])
- argtypes = self.db.repr_arg_type_multi(op_args[1:])
-
- none_label = self.node.block_to_name[link.target]
- block_label = self.node.block_to_name[self.block]
- exc_label = block_label + '_exception_handling'
-
- # use longhand form
- if self.db.is_function_ptr(op.result):
- returntype = "%s (%s)*" % (returntype, ", ".join(argtypes))
-
- ep.invoke(self.codewriter, targetvar, returntype, functionref,
- argrefs, argtypes, none_label, exc_label)
-
- # write exception handling blocks
-
- e = self.db.translator.rtyper.getexceptiondata()
- ll_exception_match = self.db.repr_value(e.fn_exception_match._obj)
- lltype_of_exception_type = self.db.repr_type(e.lltype_of_exception_type)
- lltype_of_exception_value = self.db.repr_type(e.lltype_of_exception_value)
-
- # start with the exception handling block
- # * load the last exception type
- # * check it with call to ll_exception_match()
- # * branch to to correct block?
-
- self.codewriter.label(exc_label)
-
- catch_all = False
- found_blocks_info = []
- last_exception_type = None
-
- # XXX tmp - debugging info
-
- # block_label = "block28"
- # exc_label = "block28_exception_handling"
- # ll_exception_match = function for catching exception
- # lltype_of_exception_type, lltype_of_exception_value = generic
- # catch_all = ???
- # found_blocks_info = list of found block data to write those blocks
- # last_exception_type = Load exception pointer once for handle and not found blocks
-
- # link = iteration thru rest of links in block
- # etype = node for exception
- # current_exception_type = repr for node etype
- # target = label of the destination block
- # exc_found_label = label of intermediate exc found block
- # last_exc_type_var = ????
- # last_exc_value_var = ???
-
- for link in self.block.exits[1:]:
- assert issubclass(link.exitcase, Exception)
-
- # information for found blocks
- target = self.node.block_to_name[link.target]
- exc_found_label = block_label + '_exception_found_branchto_' + target
- link_exc_type = repr_if_variable(self.db, link.last_exception)
- link_exc_value = repr_if_variable(self.db, link.last_exc_value)
- found_blocks_info.append((exc_found_label, target,
- link_exc_type, link_exc_value))
-
- # XXX fix database to handle this case
- etype = self.db.obj2node[link.llexitcase._obj]
- current_exception_type = etype.get_ref()
- not_this_exception_label = block_label + '_not_exception_' + etype.ref[1:]
-
- # catch specific exception (class) type
-
- # load pointer only once
- if not last_exception_type:
- last_exception_type = self.db.repr_tmpvar()
- self.codewriter.load(last_exception_type,
- lltype_of_exception_type,
- '%last_exception_type')
- self.codewriter.newline()
-
- ll_issubclass_cond = self.db.repr_tmpvar()
-
- self.codewriter.call(ll_issubclass_cond,
- 'bool',
- ll_exception_match,
- [last_exception_type, current_exception_type],
- [lltype_of_exception_type, lltype_of_exception_type])
-
- self.codewriter.br(ll_issubclass_cond,
- not_this_exception_label,
- exc_found_label)
-
- self.codewriter.label(not_this_exception_label)
-
- if not catch_all:
- ep.reraise(self.node, self.codewriter)
-
- ep.fetch_exceptions(self.codewriter,
- found_blocks_info,
- lltype_of_exception_type,
- lltype_of_exception_value)
Modified: pypy/dist/pypy/translator/llvm/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/structnode.py (original)
+++ pypy/dist/pypy/translator/llvm/structnode.py Fri Jan 6 19:31:20 2006
@@ -201,25 +201,25 @@
super(StructVarsizeNode, self).setup()
def get_typerepr(self):
- try:
- return self._get_typerepr_cache
- except:
- # last type is a special case and need to be worked out recursively
- types = self._get_types[:-1]
- types_repr = [self.db.repr_type(T) for name, T in types]
- types_repr.append(self._get_lastnode().get_typerepr())
- result = "{%s}" % ", ".join(types_repr)
- self._get_typerepr_cache = result
- return result
+ try:
+ return self._get_typerepr_cache
+ except:
+ # last type is a special case and need to be worked out recursively
+ types = self._get_types[:-1]
+ types_repr = [self.db.repr_type(T) for name, T in types]
+ types_repr.append(self._get_lastnode().get_typerepr())
+ result = "{%s}" % ", ".join(types_repr)
+ self._get_typerepr_cache = result
+ return result
def get_ref(self):
if self._get_ref_cache:
return self._get_ref_cache
ref = super(StructVarsizeNode, self).get_ref()
typeval = self.db.repr_type(lltype.typeOf(self.value))
- ref = "cast (%s* %s to %s*)" % (self.get_typerepr(),
- ref,
- typeval)
+ ref = "cast(%s* %s to %s*)" % (self.get_typerepr(),
+ ref,
+ typeval)
self._get_ref_cache = ref
return ref
@@ -229,6 +229,6 @@
p, c = lltype.parentlink(self.value)
assert p is None, "child arrays are NOT needed by rtyper"
fromptr = "%s*" % self.get_typerepr()
- refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref)
+ refptr = "getelementptr(%s %s, int 0)" % (fromptr, ref)
ref = "cast(%s %s to %s)" % (fromptr, refptr, toptr)
return ref
More information about the Pypy-commit
mailing list