[pypy-svn] r36257 - in pypy/branch/jit-codegen-refactor/pypy/jit/codegen: . llgraph llgraph/test
arigo at codespeak.net
arigo at codespeak.net
Mon Jan 8 13:04:25 CET 2007
Author: arigo
Date: Mon Jan 8 13:04:19 2007
New Revision: 36257
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
Log:
(mwh, arigo)
New rgenop interface, implemented for the llgraph backend.
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py Mon Jan 8 13:04:19 2007
@@ -350,6 +350,31 @@
graph = _getgraph(gv_func)
_closelink(link, [returnvar], graph.prereturnblock)
+def closelinktofreshblock(link, inputargs=None):
+ link = from_opaque_object(link)
+ vars = link.prevblock.getvariables()
+ if inputargs is not None:
+ existing_vars = dict.fromkeys(vars)
+ vars = _inputvars(inputargs)
+ for v in vars:
+ assert v in existing_vars
+ nextblock = flowmodel.Block(list(vars))
+ link.args = vars
+ link.target = nextblock
+ return to_opaque_object(nextblock)
+
+def closelinktofreshblockwithsameargsasotherlink(link, otherlink):
+ link = from_opaque_object(link)
+ otherlink = from_opaque_object(otherlink)
+ existing_vars = dict.fromkeys(link.prevblock.getvariables())
+ vars = list(otherlink.args)
+ for v in vars:
+ assert v in existing_vars
+ nextblock = flowmodel.Block(list(vars))
+ link.args = vars
+ link.target = nextblock
+ return to_opaque_object(nextblock)
+
def casting_link(source, sourcevars, target):
assert len(sourcevars) == len(target.inputargs)
linkargs = []
@@ -372,7 +397,27 @@
from pypy.rpython.typesystem import LowLevelTypeSystem
self.type_system = LowLevelTypeSystem.instance
+def fixduplicatevars(graph):
+ incomingvars = {} # {block: {var_from_link_args: True}}
+ for link in graph.iterlinks():
+ vars = incomingvars.setdefault(link.target, {})
+ for v in link.args:
+ if isinstance(v, flowmodel.Variable):
+ vars[v] = True
+ for block, vars in incomingvars.items():
+ for v in block.inputargs:
+ if v in vars:
+ # this block needs renaming of all its input variables
+ mapping = {}
+ for a in block.inputargs:
+ mapping[a] = a1 = flowmodel.Variable(a)
+ a1.concretetype = a.concretetype
+ block.renamevariables(mapping)
+ break
+
def _buildgraph(graph):
+ # rgenop makes graphs that use the same variable in several blocks,
+ fixduplicatevars(graph) # fix this now
flowmodel.checkgraph(graph)
eliminate_empty_blocks(graph)
join_blocks(graph)
@@ -486,6 +531,8 @@
setannotation(add_default, s_Link)
setannotation(closelink, None)
setannotation(closereturnlink, None)
+setannotation(closelinktofreshblock, s_Block)
+setannotation(closelinktofreshblockwithsameargsasotherlink, s_Block)
setannotation(isptrtype, annmodel.SomeBool())
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py Mon Jan 8 13:04:19 2007
@@ -55,22 +55,22 @@
def add_case(self, gv_case):
self.cases_gv.append(gv_case) # not used so far, but keeps ptrs alive
l_case = llimpl.add_case(self.b, gv_case.v)
- builder = LLBuilder(self.gv_f)
- builder.lnk = l_case
- return builder
+ b = llimpl.closelinktofreshblockwithsameargsasotherlink(l_case,
+ self.l_default)
+ return LLBuilder(self.gv_f, b)
- def add_default(self):
+ def _add_default(self, args_gv):
l_default = llimpl.add_default(self.b)
- builder = LLBuilder(self.gv_f)
- builder.lnk = l_default
- return builder
+ self.l_default = l_default
+ b = llimpl.closelinktofreshblock(l_default, args_gv)
+ return LLBuilder(self.gv_f, b)
class LLBuilder(GenBuilder):
- lnk = llimpl.nulllink
- def __init__(self, g):
+ def __init__(self, g, block):
self.rgenop = rgenop
self.gv_f = g
+ self.b = block
def end(self):
llimpl.end(self.gv_f)
@@ -156,8 +156,7 @@
return [LLVar(llimpl.geninputarg(newb, kind.v)) for kind in kinds]
def enter_next_block(self, kinds, args_gv):
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
newb_args_gv = self._newblock(kinds)
llimpl.closelink(lnk, args_gv, self.b)
for i in range(len(args_gv)):
@@ -165,38 +164,35 @@
return LLLabel(self.b, self.gv_f)
def finish_and_goto(self, args_gv, target):
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
+ self.b = llimpl.nullblock
llimpl.closelink(lnk, args_gv, target.b)
def finish_and_return(self, sigtoken, gv_returnvar):
gv_returnvar = gv_returnvar or gv_dummy_placeholder
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
+ self.b = llimpl.nullblock
llimpl.closereturnlink(lnk, gv_returnvar.v, self.gv_f)
- def jump_if_true(self, gv_cond):
+ def jump_if_true(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.nullblock
- later_builder = LLBuilder(self.gv_f)
- later_builder.lnk = l_true
- self.lnk = l_false
+ self.b = llimpl.closelinktofreshblock(l_false, None)
+ b2 = llimpl.closelinktofreshblock(l_true, args_for_jump_gv)
+ later_builder = LLBuilder(self.gv_f, b2)
return later_builder
- def jump_if_false(self, gv_cond):
+ def jump_if_false(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.nullblock
- later_builder = LLBuilder(self.gv_f)
- later_builder.lnk = l_false
- self.lnk = l_true
+ self.b = llimpl.closelinktofreshblock(l_true, None)
+ b2 = llimpl.closelinktofreshblock(l_false, args_for_jump_gv)
+ later_builder = LLBuilder(self.gv_f, b2)
return later_builder
- def flexswitch(self, gv_switchvar):
+ def flexswitch(self, gv_switchvar, args_gv):
llimpl.closeblockswitch(self.b, gv_switchvar.v)
flexswitch = LLFlexSwitch(self.b, self.gv_f)
self.b = llimpl.nullblock
- self.lnk = llimpl.nulllink
- return flexswitch
+ return (flexswitch, flexswitch._add_default(args_gv))
def show_incremental_progress(self):
llimpl.show_incremental_progress(self.gv_f)
@@ -208,8 +204,7 @@
def newgraph(self, (ARGS_gv, gv_RESULT, gv_FUNCTYPE), name):
gv_func = llimpl.newgraph(gv_FUNCTYPE.v, name)
- builder = LLBuilder(gv_func)
- builder.b = llimpl.getstartblock(gv_func)
+ builder = LLBuilder(gv_func, llimpl.getstartblock(gv_func))
inputargs_gv = [LLVar(llimpl.getinputarg(builder.b, i))
for i in range(len(ARGS_gv))]
return builder, LLConst(gv_func), inputargs_gv
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py Mon Jan 8 13:04:19 2007
@@ -67,7 +67,7 @@
const0 = rgenop.genconst(0)
gv1 = builder.genop2('int_lt', gv0, const0)
- false_builder = builder.jump_if_false(gv1)
+ false_builder = builder.jump_if_false(gv1, [gv0])
builder.finish_and_return(f1_token, const0)
false_builder.finish_and_return(f1_token, gv0)
builder.end()
@@ -110,7 +110,7 @@
gv_result1 = builder.genop2('int_mul', gv_result0, gv_i0)
gv_i1 = builder.genop2('int_add', gv_i0, const1)
gv2 = builder.genop2('int_le', gv_i1, gv1)
- loop_builder = builder.jump_if_true(gv2)
+ loop_builder = builder.jump_if_true(gv2, [gv_result1, gv_i1, gv1])
builder.finish_and_return(f1_token, gv_result1)
loop_builder.finish_and_goto([gv_result1, gv_i1, gv1], loopblock)
@@ -167,31 +167,21 @@
"""
builder, gv_switch, (gv0, gv1) = rgenop.newgraph(f2_token, "switch")
- flexswitch = builder.flexswitch(gv0)
+ flexswitch, default_builder = builder.flexswitch(gv0, [gv1])
const21 = rgenop.genconst(21)
# case == 0
const0 = rgenop.genconst(0)
case_builder = flexswitch.add_case(const0)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_case0] = case_args_gv
- gv_res_case0 = case_builder.genop2('int_mul', const21, gv1_case0)
+ gv_res_case0 = case_builder.genop2('int_mul', const21, gv1)
case_builder.finish_and_return(f2_token, gv_res_case0)
# case == 1
const1 = rgenop.genconst(1)
case_builder = flexswitch.add_case(const1)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_case1] = case_args_gv
- gv_res_case1 = case_builder.genop2('int_add', const21, gv1_case1)
+ gv_res_case1 = case_builder.genop2('int_add', const21, gv1)
case_builder.finish_and_return(f2_token, gv_res_case1)
# default
- default_builder = flexswitch.add_default()
- default_args_gv = [gv1]
- default_builder.enter_next_block([signed_tok], default_args_gv)
- [gv1_default] = default_args_gv
- default_builder.finish_and_return(f2_token, gv1_default)
+ default_builder.finish_and_return(f2_token, gv1)
builder.end()
switch_ptr = gv_switch.revealconst(lltype.Ptr(F2))
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py Mon Jan 8 13:04:19 2007
@@ -86,22 +86,27 @@
zip(kinds, args_gv) gives the kindtoken and GenVarOrConst for
each inputarg of the block.
- The Obscure Bit: args_gv must be mutated in place to replace
- GenConsts with GenVars and optionally GenVars can be replaced
- with new GenVars, for example if the same value might live in
- different locations (registers, places on the stack) in
- different basic blocks.
+ The Obscure Bit: args_gv must be mutated in place until it is a
+ list of unique GenVars. So GenConsts must be replaced with
+ GenVars, and duplicate GenVars must be made unique. Optionally,
+ *all* GenVars can be replaced with new GenVars, for example if
+ the same value might live in different locations (registers,
+ places on the stack) in different basic blocks.
Returns an instance of GenLabel that can later be jumped to.
'''
- def jump_if_false(self, gv_condition):
+ def jump_if_false(self, gv_condition, args_for_jump_gv):
'''Make a fresh builder, insert in the current block a
check of gv_condition and a conditional jump to the new block
that is taken if gv_condition is false and return the new
- builder.'''
+ builder.
- def jump_if_true(self, gv_condition):
+ The current builder stays open, and it must be closed before
+ the fresh builder is used at all, to make the backend\'s life
+ easier.'''
+
+ def jump_if_true(self, gv_condition, args_for_jump_gv):
'''See above, with the obvious difference :)'''
def finish_and_return(self, sigtoken, gv_returnvar):
@@ -120,14 +125,20 @@
This "closes" the current builder.
'''
- def flexswitch(self, gv_exitswitch):
+ def flexswitch(self, gv_exitswitch, args_gv):
'''The Fun Stuff.
Generates a switch on the value of gv_exitswitch that can have
cases added to it later, i.e. even after it\'s been executed a
few times.
- Returns an instance of CodeGenSwitch, see below.
+ args_gv is the list of live variables. It\'s the list of
+ variables that can be used in each switch case.
+
+ Returns a tuple:
+ - an instance of CodeGenSwitch (see below)
+ - a new builder for the default case, that will be jumped to
+ when the switched-on GenVar does not take the value of any case.
This "closes" the current builder.
'''
@@ -258,8 +269,3 @@
def add_case(self, gv_case):
'''Make a new builder that will be jumped to when the
switched-on GenVar takes the value of the GenConst gv_case.'''
-
- def add_default(self):
- '''Make a new builder that will be jumped to when the
- switched-on GenVar does not take the value of any case.'''
-
More information about the Pypy-commit
mailing list