[pypy-svn] r22715 - in pypy/dist: . pypy/doc/discussion pypy/jit pypy/rpython pypy/rpython/test
ac at codespeak.net
ac at codespeak.net
Fri Jan 27 10:26:12 CET 2006
Author: ac
Date: Fri Jan 27 10:26:11 2006
New Revision: 22715
Modified:
pypy/dist/ (props changed)
pypy/dist/pypy/doc/discussion/draft-jit-ideas.txt
pypy/dist/pypy/jit/llabstractinterp.py
pypy/dist/pypy/jit/llcontainer.py
pypy/dist/pypy/jit/llvalue.py
pypy/dist/pypy/jit/vlist.py
pypy/dist/pypy/rpython/rgenop.py
pypy/dist/pypy/rpython/test/test_rlist.py
Log:
Merged revisions 22667-22668,22678,22681-22685 via svnmerge from
svn+ssh://codespeak.net/svn/pypy/branch/jit-refactoring
........
r22667 | ac | 2006-01-25 19:45:52 +0100 (Wed, 25 Jan 2006) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-22663" from
svn+ssh://codespeak.net/svn/pypy/dist
........
r22668 | ac | 2006-01-25 19:46:27 +0100 (Wed, 25 Jan 2006) | 1 line
Intermediary work.
........
r22678 | pedronis | 2006-01-26 12:59:23 +0100 (Thu, 26 Jan 2006) | 5 lines
use AConstant and AVariable for LLAbstractValue.runtimevar, these have a getgenvar(builder) to retrieve a stored
corresponding rgenop API var/const opaque object, or to lazily comnpute such a const object in the context of
the given builder.
........
r22681 | pedronis | 2006-01-26 13:55:05 +0100 (Thu, 26 Jan 2006) | 3 lines
fix test that was broken by changes.
........
r22682 | pedronis | 2006-01-26 14:02:48 +0100 (Thu, 26 Jan 2006) | 3 lines
remove unncessary import
........
r22683 | pedronis | 2006-01-26 14:07:02 +0100 (Thu, 26 Jan 2006) | 3 lines
refactor to avoid accessing rgenop opaque constant .value!
........
r22684 | pedronis | 2006-01-26 14:12:19 +0100 (Thu, 26 Jan 2006) | 3 lines
more consistent naming: gengraphconst -> gencallableconst. rgenop API doesn't expose the notion of a graph.
........
r22685 | pedronis | 2006-01-26 14:17:36 +0100 (Thu, 26 Jan 2006) | 5 lines
addconst seems not necessary, for now for Void constant we simply constuct Constant directly.
Document gencallableconst.
........
Modified: pypy/dist/pypy/doc/discussion/draft-jit-ideas.txt
==============================================================================
--- pypy/dist/pypy/doc/discussion/draft-jit-ideas.txt (original)
+++ pypy/dist/pypy/doc/discussion/draft-jit-ideas.txt Fri Jan 27 10:26:11 2006
@@ -100,7 +100,7 @@
* genconst(block, llvalue) -> (result var)
-* addconst(block, const) -> (result var)
+* gencallableconst(block, name, target-block, FUNCTYPE) -> (result var)
* closeblock1(block) -> link
Modified: pypy/dist/pypy/jit/llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp.py Fri Jan 27 10:26:11 2006
@@ -1,8 +1,8 @@
import operator
-from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
+from pypy.objspace.flow.model import Variable, Constant
from pypy.objspace.flow.model import checkgraph, c_last_exception
from pypy.rpython.lltypesystem import lltype
-from pypy.jit.llvalue import LLAbstractValue, const
+from pypy.jit.llvalue import LLAbstractValue, AConstant, AVariable, const
from pypy.jit.llvalue import ll_no_return_value
from pypy.jit.llvalue import FlattenMemo, MatchMemo, FreezeMemo, UnfreezeMemo
from pypy.jit.llcontainer import LLAbstractContainer, virtualcontainervalue
@@ -41,7 +41,7 @@
assert len(incoming_link_args) == len(selfvalues)
for linkarg, fr in zip(incoming_link_args, selfvalues):
if fr.fixed:
- assert isinstance(linkarg, Constant), (
+ assert isinstance(linkarg, AConstant), (
"unexpected Variable %r reaching the fixed input arg %r"
% (linkarg, fr))
yield linkarg
@@ -51,7 +51,7 @@
def getruntimevars(self):
assert not self.frozen, "getruntimevars(): not for frozen states"
return [a.runtimevar for a in self.flatten()]
-
+
def flatten(self, memo=None):
if memo is None:
memo = FlattenMemo()
@@ -102,8 +102,8 @@
for v, a in zip(self.getlivevars(), self.args_a):
a = a.unfreeze(memo, block)
# try to preserve the name
- if isinstance(a.runtimevar, Variable):
- a.runtimevar.rename(v)
+ #if isinstance(a.runtimevar, Variable):
+ # a.runtimevar.rename(v)
new_args_a.append(a)
return self.__class__(new_back, new_args_a, *self.localkey())
@@ -171,10 +171,10 @@
args_a = []
for i, v in enumerate(origgraph.getargs()):
if i in arghints:
- a = LLAbstractValue(const(arghints[i]))
+ a = LLAbstractValue(AConstant(arghints[i]))
a.concrete = self.policy.concrete_args
else:
- a = LLAbstractValue(input=v.concretetype)
+ a = LLAbstractValue(AVariable(v.concretetype))
args_a.append(a)
graphstate = self.schedule_graph(args_a, origgraph)
graphstate.complete()
@@ -192,11 +192,11 @@
#print "SCHEDULE_GRAPH", graphstate
return graphstate
- def schedule(self, inputstate):
+ def schedule(self, inputstate, builder):
#print "SCHEDULE", args_a, origblock
frozenstate = self.schedule_getstate(inputstate)
args_v = inputstate.getruntimevars()
- return LinkState(args_v, frozenstate)
+ return LinkState(builder, args_v, frozenstate)
def schedule_getstate(self, inputstate):
# NOTA BENE: copyblocks can get shared between different copygraphs!
@@ -253,19 +253,21 @@
exitcase = None
llexitcase = None
- def __init__(self, args_v, frozenstate):
+ def __init__(self, builder, args_v, frozenstate):
self.args_v = args_v
+ self.args_genv = [v.getgenvar(builder) for v in args_v]
self.frozenstate = frozenstate
self.link = None
def setreturn(self):
- rgenop.closereturnlink(self.link, self.args_v[0])
+ rgenop.closereturnlink(self.link, self.args_genv[0])
def settarget(self, block, blockargs):
args = []
- for v1, v2 in zip(self.args_v, blockargs):
- if isinstance(v2, Constant):
- assert v1 == v2
+ for v1, v2 in zip(self.args_genv, blockargs):
+ assert isinstance(v2, (AVariable, AConstant))
+ if isinstance(v2, AConstant):
+ assert v1.value == v2.value # sanity check violating encapsulation
else:
args.append(v1)
rgenop.closelink(self.link, args, block)
@@ -370,7 +372,7 @@
merged_key = []
recompute = False
for c1, c2 in zip(blockargs, next.args_v):
- if isinstance(c1, Constant) and c1 != c2:
+ if isinstance(c1, AConstant) and c1 != c2:
# incompatibility
merged_key.append(None) # force a Variable
recompute = True
@@ -418,7 +420,7 @@
for a1, a2, k in zip(state.flatten(),
builder.runningstate.flatten(),
key):
- if isinstance(k, Constant):
+ if isinstance(k, AConstant):
arglist.append('%s => %s' % (a1, k))
else:
arglist.append('%s => %s' % (a1, a2))
@@ -435,7 +437,7 @@
# except block of the copygraph.
args_v = [builder.binding(v).forcevarorconst(builder)
for v in origblock.inputargs]
- ls = LinkState(args_v, frozenstate=None)
+ ls = LinkState(builder, args_v, frozenstate=None)
raise InsertNextLink(ls)
else:
# finishing a handle_call_inlining(): link back to
@@ -477,7 +479,7 @@
else:
a = builder.bindings[origblock.exitswitch]
v = a.forcevarorconst(builder)
- if isinstance(v, Variable):
+ if isinstance(v, AVariable):
newexitswitch = v
links = origblock.exits
else:
@@ -488,7 +490,7 @@
args_a = [builder.binding(v) for v in origlink.args]
nextinputstate = LLBlockState(builder.runningstate.back,
args_a, origlink.target)
- newlinkstate = self.interp.schedule(nextinputstate)
+ newlinkstate = self.interp.schedule(nextinputstate, builder)
if newexitswitch is not None:
newlinkstate.exitcase = origlink.exitcase
newlinkstate.llexitcase = origlink.llexitcase
@@ -520,7 +522,7 @@
assert len(newlinkstates) == 2
- false_link, true_link = rgenop.closeblock2(b, newexitswitch)
+ false_link, true_link = rgenop.closeblock2(b, newexitswitch.getgenvar(self))
cases = {False: false_link, True: true_link}
for ls in newlinkstates:
ls.link = cases[ls.exitcase]
@@ -533,8 +535,9 @@
return rgenop.genconst(self.newblock, llvalue)
def binding(self, v):
+ assert isinstance(v, (Constant, Variable))
if isinstance(v, Constant):
- return LLAbstractValue(v)
+ return LLAbstractValue(AConstant(v.value, v.concretetype))
else:
return self.bindings[v]
@@ -564,7 +567,7 @@
# can constant-fold
print 'fold:', constant_op.__name__, concretevalues
concreteresult = constant_op(*concretevalues)
- a_result = LLAbstractValue(const(concreteresult))
+ a_result = LLAbstractValue(AConstant(concreteresult))
if any_concrete and self.interp.policy.concrete_propagate:
a_result.concrete = True
else:
@@ -572,14 +575,23 @@
return a_result
def residual(self, op, args_a):
- retvar = rgenop.genop(self.newblock, op.opname,
- [a.forcevarorconst(self) for a in args_a],
- op.result.concretetype)
- return LLAbstractValue(retvar)
-
- def residual_direct_call(self, name, block, args_a,):
+ T= op.result.concretetype
+ retvar = self.genop(op.opname,
+ [a.forcegenvarorconst(self) for a in args_a],
+ T)
+ return LLAbstractValue(AVariable(T, genvar=retvar))
+
+ def residual_direct_call(self, FUNCTYPE, name, target, args_a):
+ T = FUNCTYPE.RESULT
+ gen_fn_const = rgenop.gencallableconst(self.newblock,
+ name,
+ target,
+ FUNCTYPE)
+ retvar = self.genop('direct_call', [gen_fn_const] +
+ [a.forcegenvarorconst(self) for a in args_a],
+ T)
+ return LLAbstractValue(AVariable(T, genvar=retvar))
- return LLAbstractValue(retvar)
def residualize(self, op, args_a, constant_op=None):
if constant_op:
@@ -723,7 +735,7 @@
parentstate = LLSuspendedBlockState(self.runningstate.back, alive_a,
origblock, origposition)
nextstate = LLBlockState(parentstate, args_a, origgraph.startblock)
- raise InsertNextLink(self.interp.schedule(nextstate))
+ raise InsertNextLink(self.interp.schedule(nextstate, self))
def handle_call_residual(self, op, origgraph, *args_a):
# residual call: for now we need to force all arguments
@@ -751,13 +763,9 @@
if not a.concrete:
ARGS.append(a.getconcretetype())
new_args_a.append(a)
- args_a = new_args_a
TYPE = lltype.FuncType(ARGS, op.result.concretetype)
- a_func = LLAbstractValue(rgenop.gengraphconst(self.newblock,
- graphstate.name,
- graphstate.startblock,
- TYPE))
- return self.residual(op, [a_func] + args_a)
+ return self.residual_direct_call(TYPE, graphstate.name,
+ graphstate.startblock, new_args_a)
def op_getfield(self, op, a_ptr, a_attrname):
if hasllcontent(a_ptr):
@@ -781,7 +789,7 @@
def op_getarraysize(self, op, a_ptr):
if hasllcontent(a_ptr):
- return LLAbstractValue(const(a_ptr.content.length))
+ return LLAbstractValue(AConstant(a_ptr.content.length))
return self.residualize(op, [a_ptr], len)
def op_getarrayitem(self, op, a_ptr, a_index):
@@ -846,9 +854,10 @@
memo = FlattenMemo()
a_ptr.flatten(memo)
for a in memo.result:
- v = a.runtimevar
- if isinstance(v, Variable) and not v.concretetype._is_atomic():
- rgenop.genop(self.newblock, 'keepalive', [v], lltype.Void)
+ if (a.is_variable and
+ not a.getconcretetype()._is_atomic()):
+ self.genop('keepalive', [a.forcegenvarorconst()],
+ lltype.Void)
return ll_no_return_value
# High-level operation dispatcher
@@ -863,7 +872,7 @@
args_a = []
for a in argtuple:
if not isinstance(a, LLAbstractValue):
- a = LLAbstractValue(const(a))
+ a = LLAbstractValue(AConstant(a))
args_a.append(a)
# end of rather XXX'edly hackish parsing
Modified: pypy/dist/pypy/jit/llcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/llcontainer.py (original)
+++ pypy/dist/pypy/jit/llcontainer.py Fri Jan 27 10:26:11 2006
@@ -1,6 +1,5 @@
-from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
from pypy.rpython.lltypesystem import lltype
-from pypy.jit.llvalue import LLAbstractValue, const
+from pypy.jit.llvalue import LLAbstractValue, AConstant, const
class LLAbstractContainer(object):
@@ -53,7 +52,7 @@
RESULT_TYPE = lltype.Ptr(self.T)
if self.a_parent is not None:
parentindex = const(self.parentindex, lltype.Void)
- v_parent = self.a_parent.forcevarorconst(builder)
+ v_parent = self.a_parent.forcegenvarorconst(builder)
v_result = builder.genop('getsubstruct',
[v_parent, parentindex], RESULT_TYPE)
else:
@@ -82,7 +81,7 @@
assert isinstance(a_value.content, LLVirtualContainer)
a_value.content.buildcontent(builder, v_subptr)
else:
- v_value = a_value.forcevarorconst(builder)
+ v_value = a_value.forcegenvarorconst(builder)
self.setop(builder, v_target, name, v_value)
def flatten(self, memo):
@@ -216,7 +215,7 @@
a.content.parentindex = parentindex
else:
# primitive initialized to zero
- a = LLAbstractValue(const(T._defl()))
+ a = LLAbstractValue(AConstant(T._defl()))
return a
def hasllcontent(a_ptr):
Modified: pypy/dist/pypy/jit/llvalue.py
==============================================================================
--- pypy/dist/pypy/jit/llvalue.py (original)
+++ pypy/dist/pypy/jit/llvalue.py Fri Jan 27 10:26:11 2006
@@ -1,6 +1,26 @@
-from pypy.objspace.flow.model import Variable, Constant
+from pypy.objspace.flow.model import Constant
from pypy.rpython.lltypesystem import lltype
from pypy.rpython import rgenop
+from pypy.tool.uid import Hashable
+
+class AVariable(object):
+ def __init__(self, T, genvar=None):
+ self.concretetype = T
+ self.genvar = genvar
+
+ def getgenvar(self, builder):
+ return self.genvar
+
+class AConstant(Hashable):
+ def __init__(self, value, T=None, genvar=None):
+ Hashable.__init__(self, value)
+ self.concretetype = T or lltype.typeOf(value)
+ self.genvar = genvar
+
+ def getgenvar(self, builder):
+ if self.genvar is None:
+ self.genvar = builder.genconst(self.value)
+ return self.genvar
class LLAbstractValue(object):
"""An abstract value, propagated through the blocks of the low-level
@@ -15,16 +35,13 @@
concrete = False # concrete constants propagate eagerly
- def __init__(self, runtimevar=None, content=None, input=None):
- self.runtimevar = runtimevar # None or a Variable or a Constant
+ def __init__(self, runtimevar=None, content=None):
+ self.runtimevar = runtimevar # None or a AVariable or a AConstant
self.content = content # None or an LLAbstractContainer
self.origin = [] # list of frozen values: the sources that did or
# could allow 'self' to be computed as a constant
- self.input = input
-
+
def __repr__(self):
- if self.input:
- return '<input>'
if self.runtimevar is None:
if self.content is None:
return '<dummy>'
@@ -33,7 +50,7 @@
else:
# runtime value -- display more precisely if it's a
# Variable or a Constant
- if isinstance(self.runtimevar, Variable):
+ if isinstance(self.runtimevar, AVariable):
kind = 'runtime'
elif self.concrete:
kind = 'concrete'
@@ -43,8 +60,6 @@
def freeze(self, memo):
# turn a run-time value into a frozen value
- if self.input:
- return LLFrozenRuntimeValue(self)
if self.runtimevar is not None:
if self.concrete:
return LLFrozenConcreteValue(self)
@@ -65,8 +80,6 @@
return frozen_dummy_value # dummy
def getconcretetype(self):
- if self.input:
- return self.input
if self.runtimevar is not None:
return self.runtimevar.concretetype
elif self.content is not None:
@@ -78,12 +91,17 @@
if self.runtimevar is None:
if self.content is None:
raise ValueError("ll_dummy_value.forcevarorconst()")
- self.runtimevar = self.content.build_runtime_container(builder)
+ genvar = self.content.build_runtime_container(builder)
+ assert self.content.T == genvar.concretetype.TO # sanity check
+ self.runtimevar = AVariable(lltype.Ptr(self.content.T), genvar=genvar)
self.content = None
return self.runtimevar
+ def forcegenvarorconst(self, builder):
+ return self.forcevarorconst(builder).getgenvar(builder)
+
def maybe_get_constant(self):
- if isinstance(self.runtimevar, Constant):
+ if isinstance(self.runtimevar, AConstant):
return self.runtimevar
else:
return None
@@ -92,9 +110,7 @@
"""Recursively flatten the LLAbstractValue into a list of run-time
LLAbstractValues.
"""
- if self.input:
- memo.result.append(self)
- elif self.runtimevar is not None:
+ if self.runtimevar is not None:
if not self.concrete: # skip concrete values, they don't need
# to be present in the residual graph at all
memo.result.append(self)
@@ -177,12 +193,13 @@
# no need to worry about sharing here: LLFrozenRuntimeValues are
# never shared
propagateconst = memo.propagateconsts.next()
- if isinstance(propagateconst, Constant):
- v = propagateconst # allowed to propagate as a Constant
- assert v.concretetype == self.concretetype
+ if isinstance(propagateconst, AConstant):
+ c = propagateconst # allowed to propagate as a Constant
+ assert c.concretetype == self.concretetype
+ result = LLAbstractValue(c)
else:
- v = rgenop.geninputarg(block, self.concretetype)
- result = LLAbstractValue(v)
+ gen_v = rgenop.geninputarg(block, self.concretetype)
+ result = LLAbstractValue(AVariable(self.concretetype, genvar=gen_v))
result.origin.append(self)
return result
@@ -257,6 +274,6 @@
c.concretetype = T or lltype.typeOf(value)
return c
-ll_no_return_value = LLAbstractValue(const(None, lltype.Void))
+ll_no_return_value = LLAbstractValue(AConstant(None, lltype.Void))
ll_dummy_value = LLAbstractValue()
frozen_dummy_value = LLFrozenDummyValue()
Modified: pypy/dist/pypy/jit/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/vlist.py (original)
+++ pypy/dist/pypy/jit/vlist.py Fri Jan 27 10:26:11 2006
@@ -1,6 +1,6 @@
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.rtyper import LowLevelOpList
-from pypy.jit.llvalue import LLAbstractValue, const, ll_dummy_value
+from pypy.jit.llvalue import LLAbstractValue, AConstant, ll_dummy_value
from pypy.jit.llcontainer import LLAbstractContainer
@@ -39,7 +39,7 @@
return LLVirtualList(self.T, items_a)
def build_runtime_container(self, builder):
- items_v = [a.forcevarorconst(builder) for a in self.items_a]
+ items_v = [a.forcegenvarorconst(builder) for a in self.items_a]
v_result = self.T.list_builder(builder, items_v)
return v_result
@@ -47,10 +47,10 @@
# High-level operations
def oop_len(self, op):
- return LLAbstractValue(const(len(self.items_a)))
+ return LLAbstractValue(AConstant(len(self.items_a)))
def oop_nonzero(self, op):
- return LLAbstractValue(const(bool(self.items_a)))
+ return LLAbstractValue(AConstant(bool(self.items_a)))
def oop_getitem(self, op, a_index):
c_index = a_index.maybe_get_constant()
Modified: pypy/dist/pypy/rpython/rgenop.py
==============================================================================
--- pypy/dist/pypy/rpython/rgenop.py (original)
+++ pypy/dist/pypy/rpython/rgenop.py Fri Jan 27 10:26:11 2006
@@ -28,7 +28,7 @@
block.operations.append(op)
return v
-def gengraphconst(block, name, target, FUNCTYPE):
+def gencallableconst(block, name, target, FUNCTYPE):
fptr = lltype.functionptr(FUNCTYPE, name,
graph=buildgraph(target))
return genconst(block, fptr)
@@ -44,6 +44,7 @@
return link
def closeblock2(block, exitswitch):
+ assert isinstance(exitswitch, flowmodel.Variable)
block.exitswitch = exitswitch
false_link = flowmodel.Link([], None)
false_link.exitcase = False
@@ -56,6 +57,8 @@
def closelink(link, vars, targetblock):
if isinstance(link, flowmodel.Link):
+ for v in vars:
+ assert isinstance(v, (flowmodel.Variable, flowmodel.Constant))
assert ([v.concretetype for v in vars] ==
[v.concretetype for v in targetblock.inputargs])
link.args[:] = vars
Modified: pypy/dist/pypy/rpython/test/test_rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rlist.py (original)
+++ pypy/dist/pypy/rpython/test/test_rlist.py Fri Jan 27 10:26:11 2006
@@ -1,6 +1,5 @@
import sys
from pypy.rpython.lltypesystem.lltype import *
-from pypy.rpython.rtyper import LowLevelOpList
from pypy.rpython.rlist import *
from pypy.rpython.rslice import ll_newslice
from pypy.rpython.rint import signed_repr
@@ -902,12 +901,33 @@
lst.append(42)
return lst
+ from pypy.rpython import rgenop
+
+ class DummyBlockBuilder:
+
+ def __init__(self):
+ self.newblock = rgenop.newblock()
+
+ def genop(self, opname, args, RESULT_TYPE):
+ return rgenop.genop(self.newblock, opname, args, RESULT_TYPE)
+
+ def genconst(self, llvalue):
+ return rgenop.genconst(self.newblock, llvalue)
+
+ # inspection
+ def __getitem__(self, index):
+ return self.newblock.operations[index]
+
+ def __len__(self):
+ return len(self.newblock.operations)
+
+
for fn in [fixed_size_case, variable_size_case]:
t = TranslationContext()
t.buildannotator().build_types(fn, [])
t.buildrtyper().specialize()
LIST = t.graphs[0].getreturnvar().concretetype.TO
- llop = LowLevelOpList(None)
+ llop = DummyBlockBuilder()
v0 = Constant(42)
v0.concretetype = Signed
v1 = Variable()
More information about the Pypy-commit
mailing list