[pypy-svn] r59302 - in pypy/branch/oo-jit/pypy: jit/codegen/cli translator/cli/src
antocuni at codespeak.net
antocuni at codespeak.net
Tue Oct 21 17:24:22 CEST 2008
Author: antocuni
Date: Tue Oct 21 17:24:20 2008
New Revision: 59302
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/translator/cli/src/pypylib.cs
Log:
(IN-PROGRESS) more refactoring; now all the FlexCaseMethods have their own
dispatch block. Still need to do the proper transformation from block_id to
block_num, and to handle non-local jumps
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 17:24:20 2008
@@ -308,18 +308,13 @@
args_manager.copy_to_inputargs(graph, self.args_gv)
# jumpto = flexswitch.execute(exitswitch, inputargs);
- # goto dispatch_jump;
+ # goto dispatch_block;
self.gv_flexswitch.load(graph)
self.gv_exitswitch.load(graph)
graph.gv_inputargs.load(graph)
il.Emit(OpCodes.Callvirt, meth_execute)
- 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)
+ il.Emit(OpCodes.Stloc, graph.jumpto_var)
+ il.Emit(OpCodes.Br, graph.il_dispatch_block_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 17:24:20 2008
@@ -450,11 +450,11 @@
- 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
+ - FlexCaseMethod: 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
+ FlexCaseMethod) inside a graph. MainMethod.method_id == 0
- block_num: unique 16 bit number that identifies a block inside a method
@@ -552,7 +552,7 @@
for branchbuilder in self.branches:
branchbuilder.replayops()
- # emit dispatch_jump, if there are flexswitches
+ # emit dispatch_block, if there are flexswitches
self.emit_before_returnblock()
# emit the return block at last, else the verifier complains
@@ -577,9 +577,35 @@
pass
def setup_dispatch_block(self):
- self.il_dispatch_jump_label = self.il.DefineLabel()
+ self.il_dispatch_block_label = self.il.DefineLabel()
self.jumpto_var = self.il.DeclareLocal(class2type(cInt32))
+ def emit_dispatch_block(self):
+ # make sure we don't enter dispatch_block by mistake
+ self.il.Emit(OpCodes.Br, self.retlabel.il_label)
+ self.il.MarkLabel(self.il_dispatch_block_label)
+
+ blocks = self.blocks
+ il_labels = new_array(System.Reflection.Emit.Label, len(blocks))
+ for block_num in range(len(blocks)):
+ label = blocks[block_num]
+ il_labels[block_num] = label.il_trampoline_label
+
+ # XXX: do the right thing if no block was found
+ # (depends if we are in the MainMethod or in a FlexCaseMethod)
+
+ self.il.Emit(OpCodes.Ldloc, self.jumpto_var)
+ self.il.Emit(OpCodes.Switch, il_labels)
+ # default: Utils.throwInvalidBlockId(jumpto)
+ clitype = class2type(cUtils)
+ meth = clitype.GetMethod("throwInvalidBlockId")
+ self.il.Emit(OpCodes.Ldloc, self.jumpto_var)
+ self.il.Emit(OpCodes.Call, meth)
+
+ # emit all the trampolines to the blocks
+ for label in blocks:
+ label.emit_trampoline(self)
+
class MainMethod(MethodGenerator):
@@ -603,11 +629,9 @@
def emit_preamble(self):
if not self.has_flexswitches:
return
-
# compute the shape of InputArgs
args_manager = self.graphinfo.args_manager
args_manager.close()
-
# InputArgs inputargs = new InputArgs()
self.gv_inputargs = self.newlocalvar(args_manager.getCliType())
clitype = self.gv_inputargs.getCliType()
@@ -618,33 +642,11 @@
def emit_before_returnblock(self):
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)
+ self.emit_dispatch_block()
- blocks = self.blocks
- il_labels = new_array(System.Reflection.Emit.Label, len(blocks))
- 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 block_ids that are inside flexswitch cases
- # default: Utils.throwInvalidBlockId(jumpto)
- clitype = class2type(cUtils)
- meth = clitype.GetMethod("throwInvalidBlockId")
- self.il.Emit(OpCodes.Ldloc, self.jumpto_var)
- self.il.Emit(OpCodes.Call, meth)
-
- # emit all the trampolines to the blocks
- for label in blocks:
- label.emit_trampoline(self)
-class FlexSwitchCaseGenerator(MethodGenerator):
+class FlexCaseMethod(MethodGenerator):
flexswitch = None
value = -1
linkargs_gv = None
@@ -655,6 +657,7 @@
def set_parent_flexswitch(self, flexswitch, value):
self.parent_flexswitch = flexswitch
self.value = value
+ self.setup_dispatch_block()
def set_linkargs_gv(self, linkargs_gv):
self.linkargs_gv = linkargs_gv
@@ -678,7 +681,10 @@
self.parent_flexswitch.llflexswitch.add_case(self.value, func2)
def emit_preamble(self):
- # InputArgs inputargs = (InputArgs)obj // obj is the 2nd arg
+ # the signature of the method is
+ # int case_0(int jumpto, object args)
+
+ # InputArgs inputargs = (InputArgs)obj
args_manager = self.graphinfo.args_manager
clitype = args_manager.getCliType()
self.gv_inputargs = self.newlocalvar(clitype)
@@ -686,6 +692,16 @@
self.il.Emit(OpCodes.Castclass, clitype)
self.gv_inputargs.store(self)
+ # 0 is a special value that means "first block of the function",
+ # i.e. don't go through the dispatch block. 0 can never passed as
+ # blockid, because it's used as the returnblock of the MainMethod, and
+ # it's handled by its dispatch block
+
+ # if (jumpto != 0) goto dispatch_block
+ self.inputargs_gv[0].load(self)
+ self.il.Emit(OpCodes.Ldc_I4_0)
+ self.il.Emit(OpCodes.Bne_Un, self.il_dispatch_block_label)
+
linkargs_out_gv = []
for gv_linkarg in self.linkargs_gv:
gv_var = self.linkargs_gv_map[gv_linkarg]
@@ -693,6 +709,11 @@
args_manager.copy_from_inputargs(self, linkargs_out_gv)
+ def emit_before_returnblock(self):
+ self.emit_dispatch_block()
+
+
+
class BranchBuilder(GenBuilder):
def __init__(self, meth, il_label):
@@ -868,8 +889,8 @@
arglist = [class2type(cInt32), class2type(cObject)]
delegatetype = class2type(cFlexSwitchCase)
graphinfo = graph.graphinfo
- meth = FlexSwitchCaseGenerator(graph.rgenop, name, restype,
- arglist, delegatetype, graphinfo)
+ meth = FlexCaseMethod(graph.rgenop, name, restype,
+ arglist, delegatetype, graphinfo)
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/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs (original)
+++ pypy/branch/oo-jit/pypy/translator/cli/src/pypylib.cs Tue Oct 21 17:24:20 2008
@@ -156,7 +156,9 @@
{
for(int i=0; i<numcases; i++)
if (values[i] == v) {
- return cases[i](-1, args); // -1 stands for "the first block of the function"
+ // 0 stands for "the first block of the function", see the comment
+ // in rgenop.FlexCaseMethod.emit_preamble
+ return cases[i](0, args);
}
return default_blockid;
}
More information about the Pypy-commit
mailing list