[pypy-svn] r59301 - in pypy/branch/oo-jit/pypy/jit/codegen/cli: . test
antocuni at codespeak.net
antocuni at codespeak.net
Tue Oct 21 16:28:27 CEST 2008
Author: antocuni
Date: Tue Oct 21 16:28:25 2008
New Revision: 59301
Modified:
pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py
pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py
pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py
Log:
(IN-PROGRESS) a bit of refactoring and renaming while thinking how to fully support
jumps between methods
Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py (original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/operation.py Tue Oct 21 16:28:25 2008
@@ -147,8 +147,9 @@
il = self.meth.il
graphinfo = self.meth.graphinfo
graphinfo.args_manager.copy_to_inputargs(self.meth, self.args_gv)
- blockid = self.target.blockid
- il.Emit(OpCodes.Ldc_I4, blockid)
+ block_id = self.target.block_id
+ #import pdb;pdb.set_trace()
+ il.Emit(OpCodes.Ldc_I4, block_id)
il.Emit(OpCodes.Ret)
@@ -312,8 +313,13 @@
self.gv_exitswitch.load(graph)
graph.gv_inputargs.load(graph)
il.Emit(OpCodes.Callvirt, meth_execute)
- il.Emit(OpCodes.Stloc, graph.jumpto_var)
- il.Emit(OpCodes.Br, graph.il_dispatch_jump_label)
+ if graph.jumpto_var is None:
+ # we are inside a nested flexswitch, just return to parent
+ il.Emit(OpCodes.Ret)
+ else:
+ # we are in the main method, do the dispatching
+ il.Emit(OpCodes.Stloc, graph.jumpto_var)
+ il.Emit(OpCodes.Br, graph.il_dispatch_jump_label)
class WriteLine(Operation):
Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py (original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/rgenop.py Tue Oct 21 16:28:25 2008
@@ -313,9 +313,9 @@
class Label(GenLabel):
- def __init__(self, meth, blockid, inputargs_gv):
+ def __init__(self, meth, block_id, inputargs_gv):
self.meth = meth
- self.blockid = blockid
+ self.block_id = block_id
self.il_label = meth.il.DefineLabel()
self.il_trampoline_label = meth.il.DefineLabel()
self.inputargs_gv = inputargs_gv
@@ -427,7 +427,7 @@
arglist = [class2type(cls) for cls in sigtoken.args]
restype = class2type(sigtoken.res)
delegatetype = class2type(sigtoken.funcclass)
- graph = GraphGenerator(self, name, restype, arglist,
+ graph = MainMethod(self, name, restype, arglist,
delegatetype)
builder = graph.branches[0]
return builder, graph.gv_entrypoint, graph.inputargs_gv[:]
@@ -436,15 +436,40 @@
return ReplayBuilder(self), [dummy_var] * len(label.inputargs_gv)
+"""
+Glossary:
+
+ - Graph: a RPython graph
+
+ - Method: a .NET method
+
+ - in case of flexswitches, a graph is composed by many methods
+
+ - each method is a collections of blocks
+
+ - MainMethod: the method containing the first block of the graph, and all
+ the blocks reachable without passing throgh a flexswitch
+
+ - CaseMethod: a method containing the blocks for a specific case of a
+ flexswitch
+
+ - method_id: unique 16 bit number that identifies a method (either MainMethod or
+ CaseMethod) inside a graph. MainMethod.method_id == 0
+
+ - block_num: unique 16 bit number that identifies a block inside a method
+
+ - block_id: unique 32 bit number that identifies a block inside a graph; it
+ is computed as (method_id << 16 | block_num)
+"""
+
class GraphInfo:
- def __init__(self):
- self.has_flexswitches = False
- self.blocks = [] # blockid -> (meth, label)
- self.flexswitch_meths = []
- self.main_retlabel = None
+ def __init__(self):
+ #self.blocks = [] # block_id -> (meth, label)
self.args_manager = ArgsManager()
class MethodGenerator:
+
+ method_id = -1 # must be overridden
def __init__(self, rgenop, name, restype, arglist,
delegatetype, graphinfo):
@@ -465,6 +490,7 @@
self.genconsts = {}
self.branches = []
self.newbranch()
+ self.blocks = [] # block_num -> label
if restype is None:
self.gv_retvar = None
self.retlabel = self.newblock([])
@@ -485,12 +511,19 @@
return branch
def newblock(self, args_gv):
- blocks = self.graphinfo.blocks
- blockid = len(blocks)
- result = Label(self, blockid, args_gv)
- blocks.append((self, result))
+## blocks = self.graphinfo.blocks
+## block_id = len(blocks)
+## result = Label(self, block_id, args_gv)
+## blocks.append((self, result))
+
+ block_num = len(self.blocks)
+ assert block_num < 2**16
+ assert self.method_id >= 0
+ block_id = self.method_id << 16 | block_num
+ lbl = Label(self, block_id, args_gv)
+ self.blocks.append(lbl)
self.graphinfo.args_manager.register(args_gv)
- return result
+ return lbl
def newlocalvar(self, clitype):
return GenLocalVar(self, self.il.DeclareLocal(clitype))
@@ -543,25 +576,32 @@
def emit_before_returnblock(self):
pass
+ def setup_dispatch_block(self):
+ self.il_dispatch_jump_label = self.il.DefineLabel()
+ self.jumpto_var = self.il.DeclareLocal(class2type(cInt32))
+
-class GraphGenerator(MethodGenerator):
+class MainMethod(MethodGenerator):
+
+ method_id = 0
+
def __init__(self, rgenop, name, restype, args, delegatetype):
graphinfo = GraphInfo()
MethodGenerator.__init__(self, rgenop, name, restype, args, delegatetype, graphinfo)
graphinfo.graph_retlabel = self.retlabel
+ self.has_flexswitches = False
def setup_flexswitches(self):
- if self.graphinfo.has_flexswitches:
+ if self.has_flexswitches:
return
- self.graphinfo.has_flexswitches = True
- self.il_dispatch_jump_label = self.il.DefineLabel()
- self.jumpto_var = self.il.DeclareLocal(class2type(cInt32))
+ self.has_flexswitches = True
+ self.setup_dispatch_block()
def get_op_Return(self, gv_returnvar):
return ops.Return(self, gv_returnvar)
def emit_preamble(self):
- if not self.graphinfo.has_flexswitches:
+ if not self.has_flexswitches:
return
# compute the shape of InputArgs
@@ -576,23 +616,23 @@
self.gv_inputargs.store(self)
def emit_before_returnblock(self):
- if not self.graphinfo.has_flexswitches:
+ if not self.has_flexswitches:
return
# make sure we don't enter dispatch_jump by mistake
self.il.Emit(OpCodes.Br, self.retlabel.il_label)
self.il.MarkLabel(self.il_dispatch_jump_label)
- blocks = self.graphinfo.blocks
+ blocks = self.blocks
il_labels = new_array(System.Reflection.Emit.Label, len(blocks))
- for blockid in range(len(blocks)):
- builder, label = blocks[blockid]
- if builder is not self:
- continue # XXX FIXME
- il_labels[blockid] = label.il_trampoline_label
+ for block_num in range(len(blocks)):
+ label = blocks[block_num]
+ il_labels[block_num] = label.il_trampoline_label
+ # XXX: call the right case if no block was found
+ #print 'Emitting dispatch switch'
self.il.Emit(OpCodes.Ldloc, self.jumpto_var)
self.il.Emit(OpCodes.Switch, il_labels)
- # XXX: handle blockids that are inside flexswitch cases
+ # XXX: handle block_ids that are inside flexswitch cases
# default: Utils.throwInvalidBlockId(jumpto)
clitype = class2type(cUtils)
meth = clitype.GetMethod("throwInvalidBlockId")
@@ -600,17 +640,18 @@
self.il.Emit(OpCodes.Call, meth)
# emit all the trampolines to the blocks
- for builder, label in blocks:
- if builder is not self:
- continue #XXX?
+ for label in blocks:
label.emit_trampoline(self)
+
class FlexSwitchCaseGenerator(MethodGenerator):
flexswitch = None
value = -1
linkargs_gv = None
linkargs_gv_map = None
+ method_id = 10 # XXX
+
def set_parent_flexswitch(self, flexswitch, value):
self.parent_flexswitch = flexswitch
self.value = value
@@ -651,6 +692,7 @@
linkargs_out_gv.append(gv_var)
args_manager.copy_from_inputargs(self, linkargs_out_gv)
+
class BranchBuilder(GenBuilder):
def __init__(self, meth, il_label):
@@ -783,14 +825,14 @@
return self._jump_if(gv_condition, OpCodes.Brtrue)
def flexswitch(self, gv_exitswitch, args_gv):
- # XXX: this code is valid only for GraphGenerator
+ # XXX: this code is valid only for MainMethod
self.meth.setup_flexswitches()
flexswitch = IntFlexSwitch(self.meth, args_gv)
gv_flexswitch = flexswitch.gv_flexswitch
default_branch = self.meth.newbranch()
label = default_branch.enter_next_block(args_gv)
- flexswitch.llflexswitch.set_default_blockid(label.blockid)
+ flexswitch.llflexswitch.set_default_blockid(label.block_id)
op = ops.DoFlexSwitch(self.meth, gv_flexswitch,
gv_exitswitch, args_gv)
self.appendop(op)
@@ -828,7 +870,6 @@
graphinfo = graph.graphinfo
meth = FlexSwitchCaseGenerator(graph.rgenop, name, restype,
arglist, delegatetype, graphinfo)
- graphinfo.flexswitch_meths.append(meth)
value = gv_case.revealconst(ootype.Signed)
meth.set_parent_flexswitch(self, value)
meth.set_linkargs_gv(self.linkargs_gv)
Modified: pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py (original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/cli/test/test_rgenop.py Tue Oct 21 16:28:25 2008
@@ -84,6 +84,9 @@
def test_interior_access(self):
py.test.skip('fixme')
+ def test_switch_goto_between_flexswitches_direct(self):
+ py.test.skip('fixme')
+
class TestRCliGenopCompile(AbstractRGenOpTestsCompile):
RGenOp = RCliGenOp
@@ -142,3 +145,6 @@
def test_ovfcheck1_compile(self):
py.test.skip('fixme')
+
+ def test_switch_goto_between_flexswitches_compile(self):
+ py.test.skip('fixme')
More information about the Pypy-commit
mailing list