def newgraph(gv_FUNCTYPE, name): FUNCTYPE = _from_opaque(gv_FUNCTYPE).value # 'name' is just a way to track things name = from_opaque_string(name) inputargs = [] erasedinputargs = [] for ARG in FUNCTYPE.ARGS: v = flowmodel.Variable() v.concretetype = ARG inputargs.append(v) v = flowmodel.Variable() v.concretetype = lltype.erasedType(ARG) erasedinputargs.append(v) startblock = flowmodel.Block(inputargs) # insert an exploding operation here which is removed by # builder.end() to ensure that builder.end() is actually called. startblock.operations.append( flowmodel.SpaceOperation("debug_assert", [ flowmodel.Constant(False, lltype.Bool), flowmodel.Constant("you didn't call builder.end()?", lltype.Void) ], varoftype(lltype.Void))) return_var = flowmodel.Variable() return_var.concretetype = FUNCTYPE.RESULT graph = flowmodel.FunctionGraph(name, startblock, return_var) v1 = flowmodel.Variable() v1.concretetype = lltype.erasedType(FUNCTYPE.RESULT) graph.prereturnblock = flowmodel.Block([v1]) casting_link(graph.prereturnblock, [v1], graph.returnblock) substartblock = flowmodel.Block(erasedinputargs) casting_link(graph.startblock, inputargs, substartblock) fptr = lltype.functionptr(FUNCTYPE, name, graph=graph) return genconst(fptr)
def meet(hs1, hs2): bk = HintBookkeeper(None) block = flowmodel.Block([]) block.operations.append(flowmodel.SpaceOperation('x', [], flowmodel.Variable())) bk.enter(("graph", block, 0)) bk.current_op_concretetype = lambda: lltype.Signed # hack return pair(hs1, hs2).int_add()
def erasedvar(v, block): T = lltype.erasedType(v.concretetype) if T != v.concretetype: v2 = flowmodel.Variable() v2.concretetype = T op = flowmodel.SpaceOperation("cast_pointer", [v], v2) block.operations.append(op) return v2 return v
def geninputarg(block, gv_CONCRETE_TYPE): block = _from_opaque(block) assert not block.operations, "block already contains operations" assert block.exits == [], "block already closed" CONCRETE_TYPE = _from_opaque(gv_CONCRETE_TYPE).value v = flowmodel.Variable() v.concretetype = lltype.erasedType(CONCRETE_TYPE) block.inputargs.append(v) return _to_opaque(v)
def casting_link(source, sourcevars, target): assert len(sourcevars) == len(target.inputargs) linkargs = [] for v, target_v in zip(sourcevars, target.inputargs): if v.concretetype == target_v.concretetype: linkargs.append(v) else: erasedv = flowmodel.Variable() erasedv.concretetype = target_v.concretetype source.operations.append( flowmodel.SpaceOperation('cast_pointer', [v], erasedv)) linkargs.append(erasedv) source.closeblock(flowmodel.Link(linkargs, target))
def fixduplicatevars(graph): # just rename all vars in all blocks try: done = graph._llimpl_blocks_already_renamed except AttributeError: done = graph._llimpl_blocks_already_renamed = {} for block in graph.iterblocks(): if block not in done: mapping = {} for a in block.inputargs: mapping[a] = a1 = flowmodel.Variable(a) a1.concretetype = a.concretetype block.renamevariables(mapping) done[block] = True
def genop(block, opname, vars_gv, gv_RESULT_TYPE): # 'opname' is a constant string # gv_RESULT_TYPE comes from constTYPE opname = from_opaque_string(opname) block = _from_opaque(block) assert block.exits == [], "block already closed" opvars = _inputvars(vars_gv) if gv_RESULT_TYPE is guess: RESULT_TYPE = guess_result_type(opname, opvars) elif isinstance(gv_RESULT_TYPE, lltype.LowLevelType): RESULT_TYPE = gv_RESULT_TYPE else: RESULT_TYPE = _from_opaque(gv_RESULT_TYPE).value v = flowmodel.Variable() v.concretetype = RESULT_TYPE op = flowmodel.SpaceOperation(opname, opvars, v) block.operations.append(op) return _to_opaque(erasedvar(v, block))
def cast(block, gv_TYPE, gv_var): TYPE = _from_opaque(gv_TYPE).value v = _from_opaque(gv_var) if TYPE != v.concretetype: if TYPE is llmemory.GCREF or v.concretetype is llmemory.GCREF: lltype.cast_opaque_ptr(TYPE, v.concretetype._defl()) # sanity check opname = 'cast_opaque_ptr' else: assert v.concretetype == lltype.erasedType(TYPE) opname = 'cast_pointer' block = _from_opaque(block) v2 = flowmodel.Variable() v2.concretetype = TYPE op = flowmodel.SpaceOperation(opname, [v], v2) block.operations.append(op) v = v2 return _to_opaque(v)