def transform_jump_to_except_block(self, graph, entrymap, link): reraise = self.comes_from_last_exception(entrymap, link) result = Variable() result.concretetype = lltype.Void block = Block([v.copy() for v in graph.exceptblock.inputargs]) if reraise: block.operations = [ SpaceOperation("direct_call", [self.rpyexc_reraise_ptr] + block.inputargs, result), ] else: block.operations = [ SpaceOperation("direct_call", [self.rpyexc_raise_ptr] + block.inputargs, result), SpaceOperation('debug_record_traceback', [], varoftype(lltype.Void)), ] link.target = block l = Link([error_constant(graph)], graph.returnblock) block.recloseblock(l)
def transform_jump_to_except_block(self, graph, entrymap, link): reraise = self.comes_from_last_exception(entrymap, link) result = Variable() result.concretetype = lltype.Void block = Block([v.copy() for v in graph.exceptblock.inputargs]) if reraise: block.operations = [ SpaceOperation("direct_call", [self.rpyexc_reraise_ptr] + block.inputargs, result), ] else: block.operations = [ SpaceOperation("direct_call", [self.rpyexc_raise_ptr] + block.inputargs, result), SpaceOperation('debug_record_traceback', [], varoftype(lltype.Void)), ] link.target = block RETTYPE = graph.returnblock.inputargs[0].concretetype l = Link([error_constant(RETTYPE)], graph.returnblock) block.recloseblock(l)
def split_block(annotator, block, index, _forcelink=None): """return a link where prevblock is the block leading up but excluding the index'th operation and target is a new block with the neccessary variables passed on. """ assert 0 <= index <= len(block.operations) if block.exitswitch == c_last_exception: assert index < len(block.operations) #varmap is the map between names in the new and the old block #but only for variables that are produced in the old block and needed in #the new one varmap = {} vars_produced_in_new_block = {} def get_new_name(var): if var is None: return None if isinstance(var, Constant): return var if var in vars_produced_in_new_block: return var if var not in varmap: varmap[var] = copyvar(annotator, var) return varmap[var] moved_operations = block.operations[index:] new_moved_ops = [] for op in moved_operations: newop = SpaceOperation(op.opname, [get_new_name(arg) for arg in op.args], op.result) new_moved_ops.append(newop) vars_produced_in_new_block[op.result] = True moved_operations = new_moved_ops links = block.exits block.exits = None for link in links: for i, arg in enumerate(link.args): #last_exception and last_exc_value are considered to be created #when the link is entered if link.args[i] not in [link.last_exception, link.last_exc_value]: link.args[i] = get_new_name(link.args[i]) exitswitch = get_new_name(block.exitswitch) #the new block gets all the attributes relevant to outgoing links #from block the old block if _forcelink is not None: assert index == 0 linkargs = list(_forcelink) for v in varmap: if v not in linkargs: # 'v' was not specified by _forcelink, but we found out that # we need it! Hack: if it is 'concretetype is lltype.Void' # then it's ok to recreate its value in the target block. # If not, then we have a problem :-) from rpython.rtyper.lltypesystem import lltype if v.concretetype is not lltype.Void: raise Exception( "The variable %r of type %r was not explicitly listed" " in _forcelink. This issue can be caused by a" " jitdriver.jit_merge_point() where some variable" " containing an int or str or instance is actually" " known to be constant, e.g. always 42." % ( v, v.concretetype)) c = Constant(None, lltype.Void) w = varmap[v] newop = SpaceOperation('same_as', [c], w) i = 0 while i < len(moved_operations): if w in moved_operations[i].args: break i += 1 moved_operations.insert(i, newop) else: linkargs = varmap.keys() newblock = Block([get_new_name(v) for v in linkargs]) newblock.operations = moved_operations newblock.recloseblock(*links) newblock.exitswitch = exitswitch link = Link(linkargs, newblock) block.operations = block.operations[:index] block.recloseblock(link) block.exitswitch = None return link
def split_block(block, index, _forcelink=None): """return a link where prevblock is the block leading up but excluding the index'th operation and target is a new block with the neccessary variables passed on. """ assert 0 <= index <= len(block.operations) if block.exitswitch == c_last_exception: assert index < len(block.operations) #varmap is the map between names in the new and the old block #but only for variables that are produced in the old block and needed in #the new one varmap = {} vars_produced_in_new_block = set() def get_new_name(var): if var is None: return None if isinstance(var, Constant): return var if var in vars_produced_in_new_block: return var if var not in varmap: varmap[var] = var.copy() return varmap[var] moved_operations = block.operations[index:] new_moved_ops = [] for op in moved_operations: repl = dict((arg, get_new_name(arg)) for arg in op.args) newop = op.replace(repl) new_moved_ops.append(newop) vars_produced_in_new_block.add(op.result) moved_operations = new_moved_ops links = block.exits block.exits = None for link in links: for i, arg in enumerate(link.args): #last_exception and last_exc_value are considered to be created #when the link is entered if link.args[i] not in [link.last_exception, link.last_exc_value]: link.args[i] = get_new_name(link.args[i]) exitswitch = get_new_name(block.exitswitch) #the new block gets all the attributes relevant to outgoing links #from block the old block if _forcelink is not None: assert index == 0 linkargs = list(_forcelink) for v in varmap: if v not in linkargs: # 'v' was not specified by _forcelink, but we found out that # we need it! Hack: if it is 'concretetype is lltype.Void' # then it's ok to recreate its value in the target block. # If not, then we have a problem :-) from rpython.rtyper.lltypesystem import lltype if v.concretetype is not lltype.Void: raise Exception( "The variable %r of type %r was not explicitly listed" " in _forcelink. This issue can be caused by a" " jitdriver.jit_merge_point() where some variable" " containing an int or str or instance is actually" " known to be constant, e.g. always 42." % (v, v.concretetype)) c = Constant(None, lltype.Void) w = varmap[v] newop = SpaceOperation('same_as', [c], w) i = 0 while i < len(moved_operations): if w in moved_operations[i].args: break i += 1 moved_operations.insert(i, newop) else: linkargs = varmap.keys() newblock = Block([get_new_name(v) for v in linkargs]) newblock.operations = moved_operations newblock.recloseblock(*links) newblock.exitswitch = exitswitch link = Link(linkargs, newblock) block.operations = block.operations[:index] block.recloseblock(link) block.exitswitch = None return link