Example #1
0
    def get_resume_point_link(self, block):
        try:
            return self.resumepoints[block]
        except KeyError:
            resumeblock = Block([])
            redcount   = 0
            greencount = 0
            newvars = []
            for v in block.inputargs:
                if v.concretetype is lltype.Void:
                    v1 = self.c_dummy
                elif self.hannotator.binding(v).is_green():
                    c = inputconst(lltype.Signed, greencount)
                    v1 = self.genop(resumeblock, 'restore_green', [c],
                                    result_like = v)
                    greencount += 1
                else:
                    c = inputconst(lltype.Signed, redcount)
                    v1 = self.genop(resumeblock, 'restore_local', [c],
                                    result_like = v)
                    redcount += 1
                newvars.append(v1)

            resumeblock.closeblock(Link(newvars, block))
            reenter_link = Link([], resumeblock)
            N = len(self.resumepoints)
            reenter_link.exitcase = N
            self.resumepoints[block] = reenter_link
            return reenter_link
Example #2
0
File: rpbc.py Project: njues/Sypy
 def dispatcher(self, shape, index, argtypes, resulttype):
     key = shape, index, tuple(argtypes), resulttype
     if key in self._dispatch_cache:
         return self._dispatch_cache[key]
     from pypy.translator.unsimplify import varoftype
     from pypy.objspace.flow.model import FunctionGraph, Link, Block, SpaceOperation
     inputargs = [varoftype(t) for t in [Char] + argtypes]
     startblock = Block(inputargs)
     startblock.exitswitch = inputargs[0]
     graph = FunctionGraph("dispatcher", startblock, varoftype(resulttype))
     row_of_graphs = self.callfamily.calltables[shape][index]
     links = []
     descs = list(self.s_pbc.descriptions)
     if self.s_pbc.can_be_None:
         descs.insert(0, None)
     for desc in descs:
         if desc is None:
             continue
         args_v = [varoftype(t) for t in argtypes]
         b = Block(args_v)
         llfn = self.rtyper.getcallable(row_of_graphs[desc])
         v_fn = inputconst(typeOf(llfn), llfn)
         v_result = varoftype(resulttype)
         b.operations.append(
             SpaceOperation("direct_call", [v_fn] + args_v, v_result))
         b.closeblock(Link([v_result], graph.returnblock))
         i = self.descriptions.index(desc)
         links.append(Link(inputargs[1:], b, chr(i)))
         links[-1].llexitcase = chr(i)
     startblock.closeblock(*links)
     self.rtyper.annotator.translator.graphs.append(graph)
     ll_ret = self.rtyper.type_system.getcallable(graph)
     #FTYPE = FuncType
     c_ret = self._dispatch_cache[key] = inputconst(typeOf(ll_ret), ll_ret)
     return c_ret
Example #3
0
 def genswitch(self, block, v_exitswitch, false, true):
     block.exitswitch = v_exitswitch
     link_f = Link([], false)
     link_f.exitcase = False
     link_t = Link([], true)
     link_t.exitcase = True
     block.recloseblock(link_f, link_t)
Example #4
0
def test_funny_links():
    from pypy.objspace.flow.model import Block, FunctionGraph, \
         SpaceOperation, Variable, Constant, Link
    for i in range(2):
        v_i = Variable("i")
        v_case = Variable("case")
        block = Block([v_i])
        g = FunctionGraph("is_one", block)
        block.operations.append(
            SpaceOperation("eq", [v_i, Constant(1)], v_case))
        block.exitswitch = v_case
        tlink = Link([Constant(1)], g.returnblock, True)
        flink = Link([Constant(0)], g.returnblock, False)
        links = [tlink, flink]
        if i:
            links.reverse()
        block.closeblock(*links)
        t = TranslationContext()
        a = t.buildannotator()
        a.build_graph_types(g, [annmodel.SomeInteger()])
        rtyper = t.buildrtyper()
        rtyper.specialize()
        interp = LLInterpreter(rtyper)
        assert interp.eval_graph(g, [1]) == 1
        assert interp.eval_graph(g, [0]) == 0
Example #5
0
    def handle_after_residual_call_details(self, block, pos, newops, blockset,
                                           withexc, oop = False):
        dopts = {'withexc': withexc, 'oop': oop }
        copts = Constant(dopts, lltype.Void)
        v_flags = self.genop(newops, 'after_residual_call', [copts],
                             resulttype=lltype.Signed, red=True)
        residual_fetch_index = len(newops)
        self.genop(newops, 'residual_fetch', [v_flags, copts])
        residual_fetch_pos = pos+residual_fetch_index
        block.operations[pos:pos+1] = newops

        link_t = split_block(self.hannotator, block, residual_fetch_pos)
        nextblock = link_t.target
        blockset[nextblock] = False
        i_flags = link_t.args.index(v_flags)

        reds, greens = self.sort_by_color(link_t.args)
        self.genop(block, 'save_locals', reds)

        SPLIT_FOR_ZERO = False

        if SPLIT_FOR_ZERO:
            promoteblock = Block([copyvar(self.hannotator, v)
                                  for v in link_t.args])
            link_f = Link(link_t.args, promoteblock)
            promoteblock.recloseblock(Link(promoteblock.inputargs, nextblock))
            blockset[promoteblock] = False
            v_flags2 = promoteblock.inputargs[i_flags]
        else:
            promoteblock = block
            v_flags2 = v_flags
        # if there is no global merge point, this 'promote' will actually
        # always see a constant red box
        v_finished_flag = self.genop(promoteblock, 'promote', [v_flags2],
                                     resulttype = lltype.Bool)
        self.go_to_dispatcher_if(promoteblock, v_finished_flag)

        if SPLIT_FOR_ZERO:
            c_zero = inputconst(lltype.Signed, 0)
            link_t.args = link_t.args[:]
            link_t.args[i_flags] = c_zero

            resumepoint = self.get_resume_point(promoteblock)
            c_resumepoint = inputconst(lltype.Signed, resumepoint)
            v_is_zero = self.genop(block, 'int_eq', [v_flags, c_zero],
                                   resulttype=lltype.Bool, red=True)
            v_is_zero = self.genop(block, 'split',
                                   [v_is_zero, c_resumepoint] + greens,
                                   resulttype = lltype.Bool)
            block.exitswitch = v_is_zero
            link_t.exitcase = True
            link_f.exitcase = False
            block.recloseblock(link_f, link_t)
Example #6
0
    def create_proxy_graph(self, op):
        """ creates a graph which calls the original function, checks for
        raised exceptions, fetches and then raises them again. If this graph is
        inlined, the correct exception matching blocks are produced."""
        # XXX slightly annoying: construct a graph by hand
        # but better than the alternative
        result = copyvar(None, op.result)
        opargs = []
        inputargs = []
        callargs = []
        ARGTYPES = []
        for var in op.args:
            if isinstance(var, Variable):
                v = Variable()
                v.concretetype = var.concretetype
                inputargs.append(v)
                opargs.append(v)
                callargs.append(var)
                ARGTYPES.append(var.concretetype)
            else:
                opargs.append(var)
        newop = SpaceOperation(op.opname, opargs, result)
        startblock = Block(inputargs)
        startblock.operations.append(newop)
        newgraph = FunctionGraph("dummy_exc1", startblock)
        startblock.closeblock(Link([result], newgraph.returnblock))
        newgraph.returnblock.inputargs[0].concretetype = op.result.concretetype
        self.gen_exc_check(startblock, newgraph.returnblock)
        excblock = Block([])

        llops = rtyper.LowLevelOpList(None)
        var_value = self.gen_getfield('exc_value', llops)
        var_type = self.gen_getfield('exc_type', llops)
        #
        c_check1 = self.c_assertion_error_ll_exc_type
        c_check2 = self.c_n_i_error_ll_exc_type
        llops.genop('debug_catch_exception', [var_type, c_check1, c_check2])
        #
        self.gen_setfield('exc_value', self.c_null_evalue, llops)
        self.gen_setfield('exc_type', self.c_null_etype, llops)
        excblock.operations[:] = llops
        newgraph.exceptblock.inputargs[
            0].concretetype = self.lltype_of_exception_type
        newgraph.exceptblock.inputargs[
            1].concretetype = self.lltype_of_exception_value
        excblock.closeblock(Link([var_type, var_value], newgraph.exceptblock))
        startblock.exits[True].target = excblock
        startblock.exits[True].args = []
        fptr = self.constant_func("dummy_exc1", ARGTYPES,
                                  op.result.concretetype, newgraph)
        return newgraph, SpaceOperation("direct_call", [fptr] + callargs,
                                        op.result)
Example #7
0
 def test_regalloc_lists(self):
     v1 = Variable()
     v1.concretetype = lltype.Signed
     v2 = Variable()
     v2.concretetype = lltype.Signed
     v3 = Variable()
     v3.concretetype = lltype.Signed
     v4 = Variable()
     v4.concretetype = lltype.Signed
     v5 = Variable()
     v5.concretetype = lltype.Signed
     block = Block([v1])
     block.operations = [
         SpaceOperation('int_add', [v1, Constant(1, lltype.Signed)], v2),
         SpaceOperation('rescall', [ListOfKind('int', [v1, v2])], v5),
         SpaceOperation('rescall', [ListOfKind('int', [v1, v2])], v3),
     ]
     graph = FunctionGraph('f', block, v4)
     block.closeblock(Link([v3], graph.returnblock))
     #
     self.check_assembler(
         graph, """
         int_add %i0, $1 -> %i1
         rescall I[%i0, %i1] -> %i2
         rescall I[%i0, %i1] -> %i0
         int_return %i0
     """)
Example #8
0
 def new_block_before(self, block):
     newinputargs = [copyvar(self.hannotator, var)
                     for var in block.inputargs]
     newblock = Block(newinputargs)
     bridge = Link(newinputargs, block)
     newblock.closeblock(bridge)
     return newblock
Example #9
0
def cutoff_alwaysraising_block(self, block):
    "Fix a block whose end can never be reached at run-time."
    # search the operation that cannot succeed
    can_succeed    = [op for op in block.operations
                         if op.result in self.bindings]
    cannot_succeed = [op for op in block.operations
                         if op.result not in self.bindings]
    n = len(can_succeed)
    # check consistency
    assert can_succeed == block.operations[:n]
    assert cannot_succeed == block.operations[n:]
    assert 0 <= n < len(block.operations)
    # chop off the unreachable end of the block
    del block.operations[n+1:]
    s_impossible = annmodel.SomeImpossibleValue()
    self.bindings[block.operations[n].result] = s_impossible
    # insert the equivalent of 'raise AssertionError'
    graph = self.annotated[block]
    msg = "Call to %r should have raised an exception" % (getattr(graph, 'func', None),)
    c1 = Constant(AssertionError)
    c2 = Constant(AssertionError(msg))
    errlink = Link([c1, c2], graph.exceptblock)
    block.recloseblock(errlink, *block.exits)
    # record new link to make the transformation idempotent
    self.links_followed[errlink] = True
    # fix the annotation of the exceptblock.inputargs
    etype, evalue = graph.exceptblock.inputargs
    s_type = annmodel.SomeObject()
    s_type.knowntype = type
    s_type.is_type_of = [evalue]
    s_value = annmodel.SomeInstance(self.bookkeeper.getuniqueclassdef(Exception))
    self.setbinding(etype, s_type)
    self.setbinding(evalue, s_value)
    # make sure the bookkeeper knows about AssertionError
    self.bookkeeper.getuniqueclassdef(AssertionError)
Example #10
0
def test_func_simple():
    # -------------------- flowgraph building --------------------
    #     def f(x):
    #         return x+1
    x = Variable("x")
    x.concretetype = Signed
    result = Variable("result")
    result.concretetype = Signed
    one = Constant(1)
    one.concretetype = Signed
    op = SpaceOperation("int_add", [x, one], result)
    block = Block([x])
    graph = FunctionGraph("f", block)
    block.operations.append(op)
    block.closeblock(Link([result], graph.returnblock))
    graph.getreturnvar().concretetype = Signed
    # --------------------         end        --------------------

    F = FuncType([Signed], Signed)
    f = functionptr(F, "f", graph=graph)
    db = LowLevelDatabase()
    db.get(f)
    db.complete()
    dump_on_stdout(db)

    S = GcStruct('testing', ('fptr', Ptr(F)))
    s = malloc(S)
    s.fptr = f
    db = LowLevelDatabase()
    db.get(s)
    db.complete()
    dump_on_stdout(db)
Example #11
0
 def builder(translator, func):
     # build a hacked graph that doesn't take a *arg any more, but
     # individual extra arguments
     graph = translator.buildflowgraph(func)
     argnames, vararg, kwarg = graph.signature
     assert vararg, "graph should have a *arg at this point"
     assert not kwarg, "where does this **arg come from??"
     argscopy = [Variable(v) for v in graph.getargs()]
     starargs = [
         Variable('stararg%d' % i) for i in range(nb_extra_args)
     ]
     newstartblock = Block(argscopy[:-1] + starargs)
     newtup = SpaceOperation('newtuple', starargs, argscopy[-1])
     newstartblock.operations.append(newtup)
     newstartblock.closeblock(Link(argscopy, graph.startblock))
     graph.startblock.isstartblock = False
     graph.startblock = newstartblock
     newstartblock.isstartblock = True
     argnames = argnames + ['.star%d' % i for i in range(nb_extra_args)]
     graph.signature = Signature(argnames)
     # note that we can mostly ignore defaults: if nb_extra_args > 0,
     # then defaults aren't applied.  if nb_extra_args == 0, then this
     # just removes the *arg and the defaults keep their meaning.
     if nb_extra_args > 0:
         graph.defaults = None  # shouldn't be used in this case
     checkgraph(graph)
     return graph
Example #12
0
    def create_outgoing_link(self, currentframe, targetblock,
                             nodelist, renamings, v_expand_malloc=None):
        assert len(nodelist) == len(targetblock.inputargs)
        #
        if is_except(targetblock):
            v_expand_malloc = None
            while currentframe.callerframe is not None:
                currentframe = currentframe.callerframe
                newlink = self.handle_catch(currentframe, nodelist, renamings)
                if newlink:
                    return newlink
            else:
                targetblock = self.exception_escapes(nodelist, renamings)
                assert len(nodelist) == len(targetblock.inputargs)

        if (currentframe.callerframe is None and
              is_trivial_nodelist(nodelist)):
            # there is no more VirtualSpecNodes being passed around,
            # so we can stop specializing
            rtnodes = nodelist
            specblock = targetblock
        else:
            if is_return(targetblock):
                v_expand_malloc = None
                newframe = self.return_to_caller(currentframe, nodelist[0])
            else:
                targetnodes = dict(zip(targetblock.inputargs, nodelist))
                newframe = VirtualFrame(targetblock, 0, targetnodes,
                                        callerframe=currentframe.callerframe,
                                        calledgraphs=currentframe.calledgraphs)
            rtnodes = newframe.find_rt_nodes()
            specblock = self.get_specialized_block(newframe, v_expand_malloc)

        linkargs = [renamings[rtnode] for rtnode in rtnodes]
        return Link(linkargs, specblock)
Example #13
0
    def handle_oopspec_call(self, block, pos, withexc):
        op = block.operations[pos]
        assert op.opname == 'direct_call'
        if withexc:
            op.opname = 'oopspec_call'            
        else:
            op.opname = 'oopspec_call_noexc'            
        if withexc:
            link = split_block(self.hannotator, block, pos+1)
            nextblock = link.target
            linkargs = link.args
            v_residual  =self.genop(block, 'oopspec_was_residual', [],
                                    resulttype = lltype.Bool)
            residualblock = Block([])
            self.genswitch(block, v_residual, true = residualblock,
                                              false = None)
            link_f = block.exits[0]
            link_f.args = linkargs
            link_f.target = nextblock
            residualblock.closeblock(Link(linkargs, nextblock))
            blockset = { block: True,
                         nextblock: False,
                         residualblock: False }
            self.handle_after_residual_call_details(
                                  residualblock, 0, [], blockset, oop=True,
                                  withexc=True)

            SSA_to_SSI(blockset, self.hannotator)
Example #14
0
 def go_to_if(self, block, target, v_finished_flag):
     block.exitswitch = v_finished_flag
     [link_f] = block.exits
     link_t = Link([self.c_dummy], target)
     link_f.exitcase = False
     link_t.exitcase = True
     block.recloseblock(link_f, link_t)
Example #15
0
 def copy_link(self, link, prevblock):
     newargs = [self.get_new_name(a) for a in link.args] + self.passon_vars(prevblock)
     newlink = Link(newargs, self.copy_block(link.target), link.exitcase)
     newlink.last_exception = self.get_new_name(link.last_exception)
     newlink.last_exc_value = self.get_new_name(link.last_exc_value)
     if hasattr(link, 'llexitcase'):
         newlink.llexitcase = link.llexitcase
     return newlink
Example #16
0
File: inline.py Project: njues/Sypy
 def rewire_returnblock(self, afterblock):
     copiedreturnblock = self.copy_block(self.graph_to_inline.returnblock)
     linkargs = ([copiedreturnblock.inputargs[0]] +
                 self.passon_vars(self.graph_to_inline.returnblock))
     linkfrominlined = Link(linkargs, afterblock)
     copiedreturnblock.exitswitch = None
     copiedreturnblock.recloseblock(linkfrominlined)
     assert copiedreturnblock.exits[0].target == afterblock
Example #17
0
 def naive_split_block(self, block, position):
     newblock = Block([])
     newblock.operations = block.operations[position:]
     del block.operations[position:]
     newblock.exitswitch = block.exitswitch
     block.exitswitch = None
     newblock.recloseblock(*block.exits)
     block.recloseblock(Link([], newblock))
     return newblock
Example #18
0
    def generic_exception_matching(self, afterblock, copiedexceptblock):
        #XXXXX don't look: insert blocks that do exception matching
        #for the cases where direct matching did not work        
        exc_match = Constant(
            self.translator.rtyper.getexceptiondata().fn_exception_match)
        exc_match.concretetype = typeOf(exc_match.value)
        blocks = []
        for i, link in enumerate(afterblock.exits[1:]):
            etype = copyvar(None, copiedexceptblock.inputargs[0])
            evalue = copyvar(None, copiedexceptblock.inputargs[1])
            passon_vars = self.passon_vars(i)
            block = Block([etype, evalue] + passon_vars)
            res = Variable()
            res.concretetype = Bool
            cexitcase = Constant(link.llexitcase)
            cexitcase.concretetype = typeOf(cexitcase.value)
            args = [exc_match, etype, cexitcase]
            block.operations.append(SpaceOperation("direct_call", args, res))
            block.exitswitch = res
            linkargs = self.find_args_in_exceptional_case(link, link.target,
                                                          etype, evalue, afterblock,
                                                          passon_vars)
            l = Link(linkargs, link.target)
            l.prevblock = block
            l.exitcase = True
            l.llexitcase = True
            block.closeblock(l)
            if i > 0:
                l = Link(blocks[-1].inputargs, block)
                l.exitcase = False
                l.llexitcase = False
                blocks[-1].recloseblock(l, *blocks[-1].exits)
            blocks.append(block)

        blocks[-1].recloseblock(*blocks[-1].exits[:1])
        blocks[-1].operations = []
        blocks[-1].exitswitch = None
        blocks[-1].exits[0].exitcase = None
        del blocks[-1].exits[0].llexitcase
        linkargs = copiedexceptblock.inputargs
        copiedexceptblock.recloseblock(Link(linkargs, blocks[0]))
        copiedexceptblock.operations += self.generate_keepalive(linkargs)
Example #19
0
def test_SSA_to_SSI_2():
    x = Variable('x')
    y = Variable('y')
    z = Variable('z')
    b1 = Block([x])
    b2 = Block([y])
    b3 = Block([])

    b3.operations.append(SpaceOperation('hello', [y], z))
    b1.closeblock(Link([x], b2), Link([], b3))

    SSA_to_SSI({
        b1: True,  # reachable from outside
        b2: False,
        b3: False
    })

    assert b1.inputargs == [x]
    assert b2.inputargs == [y]
    assert b3.inputargs == [b3.operations[0].args[0]]
    assert b1.exits[0].args == [x]
    assert b1.exits[1].args == [x]
Example #20
0
def normalize_calltable_row_annotation(annotator, graphs):
    if len(graphs) <= 1:
        return False   # nothing to do
    graph_bindings = {}
    for graph in graphs:
        graph_bindings[graph] = [annotator.binding(v)
                                 for v in graph.getargs()]
    iterbindings = graph_bindings.itervalues()
    nbargs = len(iterbindings.next())
    for binding in iterbindings:
        assert len(binding) == nbargs

    generalizedargs = []
    for i in range(nbargs):
        args_s = []
        for graph, bindings in graph_bindings.items():
            args_s.append(bindings[i])
        s_value = annmodel.unionof(*args_s)
        generalizedargs.append(s_value)
    result_s = [annotator.binding(graph.getreturnvar())
                for graph in graph_bindings]
    generalizedresult = annmodel.unionof(*result_s)

    conversion = False
    for graph in graphs:
        bindings = graph_bindings[graph]
        need_conversion = (generalizedargs != bindings)
        if need_conversion:
            conversion = True
            oldblock = graph.startblock
            inlist = []
            for j, s_value in enumerate(generalizedargs):
                v = Variable(graph.getargs()[j])
                annotator.setbinding(v, s_value)
                inlist.append(v)
            newblock = Block(inlist)
            # prepare the output args of newblock and link
            outlist = inlist[:]
            newblock.closeblock(Link(outlist, oldblock))
            oldblock.isstartblock = False
            newblock.isstartblock = True
            graph.startblock = newblock
            # finished
            checkgraph(graph)
            annotator.annotated[newblock] = annotator.annotated[oldblock]
        # convert the return value too
        if annotator.binding(graph.getreturnvar()) != generalizedresult:
            conversion = True
            annotator.setbinding(graph.getreturnvar(), generalizedresult)

    return conversion
Example #21
0
def test_SSA_to_SSI():
    c = Variable('c')
    x = Variable('x')
    y = Variable('y')
    b1 = Block([c])
    b2 = Block([x])
    b3 = Block([])

    b2.operations.append(SpaceOperation('add', [x, c], y))
    b2.exitswitch = y

    b1.closeblock(Link([Constant(0)], b2))
    b2.closeblock(Link([y], b2), Link([], b3))
    b3.closeblock(Link([y, c], None))

    SSA_to_SSI({
        b1: True,  # reachable from outside
        b2: False,
        b3: False
    })

    assert len(b1.inputargs) == 1
    assert len(b2.inputargs) == 2
    assert len(b3.inputargs) == 2

    assert b2.inputargs == b2.operations[0].args
    assert len(b1.exits[0].args) == 2
    assert b1.exits[0].args[1] is c
    assert len(b2.exits[0].args) == 2
    assert b2.exits[0].args == [y, b2.inputargs[1]]
    assert len(b2.exits[1].args) == 2
    assert len(b3.exits[0].args) == 2

    index = b3.inputargs.index(b3.exits[0].args[0])
    assert b2.exits[1].args[index] is b2.operations[0].result

    index = b3.inputargs.index(b3.exits[0].args[1])
    assert b2.exits[1].args[index] is b2.inputargs[1]
Example #22
0
def test_rename_on_links():
    v1 = Variable()
    v2 = Variable()
    v2.concretetype = llmemory.Address
    v3 = Variable()
    block = Block([v1])
    block.operations = [SpaceOperation('cast_pointer', [v1], v2)]
    block2 = Block([v3])
    block.closeblock(Link([v2], block2))
    Transformer().optimize_block(block)
    assert block.inputargs == [v1]
    assert block.operations == []
    assert block.exits[0].target is block2
    assert block.exits[0].args == [v1]
Example #23
0
 def test_regalloc_exitswitch_2(self):
     v1 = Variable()
     v1.concretetype = rclass.CLASSTYPE
     v2 = Variable()
     v2.concretetype = rclass.CLASSTYPE
     v3 = Variable()
     v3.concretetype = rclass.CLASSTYPE
     v4 = Variable()
     v4.concretetype = rclass.CLASSTYPE
     block = Block([])
     block.operations = [
         SpaceOperation('res_call', [], v1),
         SpaceOperation('-live-', [], None),
     ]
     graph = FunctionGraph('f', block, v4)
     exclink = Link([v2], graph.returnblock)
     exclink.llexitcase = 123  # normally an exception class
     exclink.last_exception = v2
     exclink.last_exc_value = "unused"
     block.exitswitch = c_last_exception
     block.closeblock(Link([v1], graph.returnblock), exclink)
     #
     self.check_assembler(
         graph, """
         res_call -> %i0
         -live-
         catch_exception L1
         int_return %i0
         ---
         L1:
         goto_if_exception_mismatch $123, L2
         last_exception -> %i0
         int_return %i0
         ---
         L2:
         reraise
     """)
Example #24
0
    def insert_merge(self, block, kind):
        allvars = block.inputargs[:]
        block.inputargs[:] = [copyvar(self.hannotator, v) for v in allvars]
        reds1, greens1 = self.sort_by_color(block.inputargs)
        reds3, greens3 = self.sort_by_color(allvars)
        nextblock = self.naive_split_block(block, 0)
        self.genop(block, 'save_locals', reds1)

        mp   = self.mergepointfamily.add(kind)
        c_mp = inputconst(lltype.Void, mp)
        if kind == 'global':
            prefix = 'global_'

            greens2 = [copyvar(self.hannotator, v) for v in greens1]
            mergeblock = self.naive_split_block(block, len(block.operations))
            mergeblock.inputargs[:] = greens2

            self.genop(block, 'save_greens', greens1)
            block.recloseblock(Link([self.c_dummy], self.graph.returnblock))

            N = self.get_resume_point(mergeblock)
            c_resumeindex = inputconst(lltype.Signed, N)
            self.genop(block, 'guard_global_merge', [c_resumeindex])

            # Note: the jitstate.greens list will contain the correct
            # green gv's for the following global_merge_point, because
            # the green values have just been restored by the resume
            # point logic here
        else:
            mergeblock = block
            greens2 = greens1
            prefix = ''
        mergeblock.exits[0].args[:] = greens2
        nextblock.inputargs[:] = greens3

        v_finished_flag = self.genop(mergeblock, '%smerge_point' % (prefix,),
                                     [self.c_mpfamily, c_mp] + greens2,
                                     resulttype = lltype.Bool)
        self.go_to_dispatcher_if(mergeblock, v_finished_flag)

        restoreops = []
        for i, v in enumerate(reds3):
            c = inputconst(lltype.Signed, i)
            restoreops.append(SpaceOperation('restore_local', [c], v))
        nextblock.operations[:0] = restoreops

        if kind == 'global':
            N = self.get_resume_point(nextblock)
            self.mergepointfamily.resumepoint_after_mergepoint[mp] = N
Example #25
0
def replace_graph_with_bootstrap(GeneratorIterator, graph):
    Entry = GeneratorIterator.Entry
    newblock = Block(graph.startblock.inputargs)
    v_generator = Variable('generator')
    v_entry = Variable('entry')
    newblock.operations.append(
        SpaceOperation('simple_call', [Constant(Entry)], v_entry))
    assert len(graph.startblock.inputargs) == len(Entry.varnames)
    for v, name in zip(graph.startblock.inputargs, Entry.varnames):
        newblock.operations.append(
            SpaceOperation('setattr', [v_entry, Constant(name), v],
                           Variable()))
    newblock.operations.append(
        SpaceOperation('simple_call', [Constant(GeneratorIterator), v_entry],
                       v_generator))
    newblock.closeblock(Link([v_generator], graph.returnblock))
    graph.startblock = newblock
Example #26
0
 def get_exc_reconstruction_block(self, typedesc):
     exceptblock = self.graph.exceptblock
     self.mallocv.fixup_except_block(exceptblock)
     TEXC = exceptblock.inputargs[0].concretetype
     TVAL = exceptblock.inputargs[1].concretetype
     #
     v_ignored_type = varoftype(TEXC)
     v_incoming_value = varoftype(TVAL)
     block = Block([v_ignored_type, v_incoming_value])
     #
     c_EXCTYPE = Constant(typedesc.MALLOCTYPE, lltype.Void)
     v = varoftype(lltype.Ptr(typedesc.MALLOCTYPE))
     c_flavor = Constant({'flavor': 'gc'}, lltype.Void)
     op = SpaceOperation('malloc', [c_EXCTYPE, c_flavor], v)
     block.operations.append(op)
     #
     for name, FIELDTYPE in typedesc.names_and_types:
         EXACTPTR = lltype.Ptr(typedesc.name2subtype[name])
         c_name = Constant(name)
         c_name.concretetype = lltype.Void
         #
         v_in = varoftype(EXACTPTR)
         op = SpaceOperation('cast_pointer', [v_incoming_value], v_in)
         block.operations.append(op)
         #
         v_field = varoftype(FIELDTYPE)
         op = SpaceOperation('getfield', [v_in, c_name], v_field)
         block.operations.append(op)
         #
         v_out = varoftype(EXACTPTR)
         op = SpaceOperation('cast_pointer', [v], v_out)
         block.operations.append(op)
         #
         v0 = varoftype(lltype.Void)
         op = SpaceOperation('setfield', [v_out, c_name, v_field], v0)
         block.operations.append(op)
     #
     v_exc_value = varoftype(TVAL)
     op = SpaceOperation('cast_pointer', [v], v_exc_value)
     block.operations.append(op)
     #
     exc_type = self.mallocv.EXCTYPE_to_vtable[typedesc.MALLOCTYPE]
     c_exc_type = Constant(exc_type, TEXC)
     block.closeblock(Link([c_exc_type, v_exc_value], exceptblock))
     return block
Example #27
0
    def transform_except_block(self, graph, block):
        # attach an except block -- let's hope that nobody uses it
        graph.exceptblock = Block([
            Variable('etype'),  # exception class
            Variable('evalue')
        ])  # exception value
        graph.exceptblock.operations = ()
        graph.exceptblock.closeblock()

        result = Variable()
        result.concretetype = lltype.Void
        block.operations = [
            SpaceOperation("direct_call",
                           [self.rpyexc_raise_ptr] + block.inputargs, result)
        ]
        l = Link([error_constant(graph.returnblock.inputargs[0].concretetype)],
                 graph.returnblock)
        block.recloseblock(l)
Example #28
0
def test_switch_no_default():
    from pypy.objspace.flow.model import FunctionGraph, Block, Constant, Link
    from pypy.rpython.lltypesystem.lltype import FuncType, Signed, functionptr
    from pypy.translator.unsimplify import varoftype
    block = Block([varoftype(Signed)])
    block.exitswitch = block.inputargs[0]
    graph = FunctionGraph("t", block, varoftype(Signed))
    links = []
    for i in range(10):
        links.append(Link([Constant(i*i, Signed)], graph.returnblock, i))
        links[-1].llexitcase = i
    block.closeblock(*links)
    fptr = functionptr(FuncType([Signed], Signed), "t", graph=graph)
    def func(x):
        return fptr(x)
    f = compile_function(func, [int])
    res = f(4)
    assert res == 16
Example #29
0
def test_promote_2():
    v1 = varoftype(lltype.Signed)
    v2 = varoftype(lltype.Signed)
    op = SpaceOperation('hint',
                        [v1, Constant({'promote': True}, lltype.Void)], v2)
    returnblock = Block([varoftype(lltype.Signed)])
    returnblock.operations = ()
    block = Block([v1])
    block.operations = [op]
    block.closeblock(Link([v2], returnblock))
    Transformer().optimize_block(block)
    assert len(block.operations) == 2
    assert block.operations[0].opname == '-live-'
    assert block.operations[0].args == []
    assert block.operations[1].opname == 'int_guard_value'
    assert block.operations[1].args == [v1]
    assert block.operations[1].result is None
    assert block.exits[0].args == [v1]
Example #30
0
def create_instantiate_function(annotator, classdef):
    # build the graph of a function that looks like
    # 
    # def my_instantiate():
    #     return instantiate(cls)
    #
    if hasattr(classdef, 'my_instantiate_graph'):
        return
    v = Variable()
    block = Block([])
    block.operations.append(SpaceOperation('instantiate1', [], v))
    name = valid_identifier('instantiate_'+classdef.name)
    graph = FunctionGraph(name, block)
    block.closeblock(Link([v], graph.returnblock))
    annotator.setbinding(v, annmodel.SomeInstance(classdef))
    annotator.annotated[block] = graph
    # force the result to be converted to a generic OBJECTPTR
    generalizedresult = annmodel.SomeInstance(classdef=None)
    annotator.setbinding(graph.getreturnvar(), generalizedresult)
    classdef.my_instantiate_graph = graph
    annotator.translator.graphs.append(graph)