[pypy-svn] r20996 - pypy/dist/pypy/jit
arigo at codespeak.net
arigo at codespeak.net
Sat Dec 10 14:07:16 CET 2005
Author: arigo
Date: Sat Dec 10 14:07:14 2005
New Revision: 20996
Modified:
pypy/dist/pypy/jit/llabstractinterp.py
Log:
(mwh, arigo, pedronis around)
Did stuff. Reorganized a bit the classes: LLAbstractFrame is replaced by a
BlockBuilder, responsible for building only one block; the process of
completing a graph is now driven by the GraphState directly. We also replaced
most usages of 'isinstance(_, LLXxxValue)' with method calls, in preparation
for the next test -- a new LLXxxValue class for virtual structures.
Modified: pypy/dist/pypy/jit/llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp.py Sat Dec 10 14:07:14 2005
@@ -29,11 +29,22 @@
def getconcretetype(self):
return lltype.typeOf(self.value)
- def getvarorconst(self):
+ def forcevarorconst(self, builder):
c = Constant(self.value)
c.concretetype = self.getconcretetype()
return c
+ def getruntimevars(self):
+ return []
+
+ def maybe_get_constant(self):
+ c = Constant(self.value)
+ c.concretetype = self.getconcretetype()
+ return c
+
+ def with_fresh_variables(self, to_be_stored_into):
+ return self
+
def match(self, other):
return isinstance(other, LLConcreteValue) and self.value == other.value
@@ -54,9 +65,21 @@
def getconcretetype(self):
return self.copy_v.concretetype
- def getvarorconst(self):
+ def forcevarorconst(self, builder):
return self.copy_v
+ def getruntimevars(self):
+ return [self.copy_v]
+
+ def maybe_get_constant(self):
+ if isinstance(self.copy_v, Constant):
+ return self.copy_v
+ else:
+ return None
+
+ def with_fresh_variables(self, to_be_stored_into):
+ return LLRuntimeValue(orig_v=to_be_stored_into)
+
def match(self, other):
return isinstance(other, LLRuntimeValue) # XXX and ...
@@ -88,37 +111,6 @@
#print "RESOLVING BLOCK", newblock
self.copyblock = newblock
-
-class GraphState(object):
- """Entry state of a graph."""
-
- def __init__(self, origgraph, args_a, n):
- self.origgraph = origgraph
- name = '%s_%d' % (origgraph.name, n)
- self.copygraph = FunctionGraph(name, Block([])) # grumble
- for orig_v, copy_v in [(origgraph.getreturnvar(),
- self.copygraph.getreturnvar()),
- (origgraph.exceptblock.inputargs[0],
- self.copygraph.exceptblock.inputargs[0]),
- (origgraph.exceptblock.inputargs[1],
- self.copygraph.exceptblock.inputargs[1])]:
- if hasattr(orig_v, 'concretetype'):
- copy_v.concretetype = orig_v.concretetype
- self.a_return = None
- self.state = "before"
-
- def settarget(self, block):
- block.isstartblock = True
- self.copygraph.startblock = block
-
- def complete(self, interp):
- assert self.state != "during"
- if self.state == "before":
- self.state = "during"
- builderframe = LLAbstractFrame(interp, self)
- builderframe.complete()
- self.state = "after"
-
# ____________________________________________________________
class LLAbstractInterp(object):
@@ -139,7 +131,7 @@
self.blocks = {} # {origblock: list-of-LLStates}
args_a = [LLRuntimeValue(orig_v=v) for v in origgraph.getargs()]
graphstate, args_a = self.schedule_graph(args_a, origgraph)
- graphstate.complete(self)
+ graphstate.complete()
return graphstate.copygraph
def applyhint(self, args_a, origblock):
@@ -159,7 +151,7 @@
graphstate = self.graphs[origgraph][state]
except KeyError:
d = self.graphs.setdefault(origgraph, {})
- graphstate = GraphState(origgraph, args_a, n=len(d))
+ graphstate = GraphState(self, origgraph, args_a, n=len(d))
d[state] = graphstate
self.pendingstates[graphstate] = state
#print "SCHEDULE_GRAPH", graphstate
@@ -167,10 +159,11 @@
def schedule(self, args_a, origblock):
#print "SCHEDULE", args_a, origblock
- # args_a: [a_value for v in origblock.inputargs]
+ # args_a: [the-a-corresponding-to-v for v in origblock.inputargs]
state, args_a = self.schedule_getstate(args_a, origblock)
- args_v = [a.getvarorconst() for a in args_a
- if not isinstance(a, LLConcreteValue)]
+ args_v = []
+ for a in args_a:
+ args_v.extend(a.getruntimevars())
newlink = Link(args_v, None)
self.pendingstates[newlink] = state
return newlink
@@ -191,16 +184,37 @@
return state, args_a
-class LLAbstractFrame(object):
+class GraphState(object):
+ """Entry state of a graph."""
- def __init__(self, interp, graphstate):
+ def __init__(self, interp, origgraph, args_a, n):
self.interp = interp
- self.graphstate = graphstate
+ self.origgraph = origgraph
+ name = '%s_%d' % (origgraph.name, n)
+ self.copygraph = FunctionGraph(name, Block([])) # grumble
+ for orig_v, copy_v in [(origgraph.getreturnvar(),
+ self.copygraph.getreturnvar()),
+ (origgraph.exceptblock.inputargs[0],
+ self.copygraph.exceptblock.inputargs[0]),
+ (origgraph.exceptblock.inputargs[1],
+ self.copygraph.exceptblock.inputargs[1])]:
+ if hasattr(orig_v, 'concretetype'):
+ copy_v.concretetype = orig_v.concretetype
+ self.a_return = None
+ self.state = "before"
+
+ def settarget(self, block):
+ block.isstartblock = True
+ self.copygraph.startblock = block
def complete(self):
- graph = self.graphstate.copygraph
+ assert self.state != "during"
+ if self.state == "after":
+ return
+ self.state = "during"
+ graph = self.copygraph
interp = self.interp
- pending = [self.graphstate]
+ pending = [self]
seen = {}
# follow all possible links, forcing the blocks along the way to be
# computed
@@ -220,7 +234,7 @@
# that it is really the one from 'graph' -- by patching
# 'graph' if necessary.
if len(link.target.inputargs) == 1:
- self.graphstate.a_return = state.args_a[0]
+ self.a_return = state.args_a[0]
graph.returnblock = link.target
elif len(link.target.inputargs) == 2:
graph.exceptblock = link.target
@@ -230,35 +244,21 @@
checkgraph(graph)
eliminate_empty_blocks(graph)
join_blocks(graph)
+ self.state = "after"
def flowin(self, state):
# flow in the block
origblock = state.origblock
- bindings = {} # {Variables-of-origblock: a_value}
- def binding(v):
- if isinstance(v, Constant):
- return LLRuntimeValue(orig_v=v)
- else:
- return bindings[v]
+ builder = BlockBuilder(self.interp)
for v, a in zip(origblock.inputargs, state.args_a):
- if not isinstance(a, LLConcreteValue):
- a = LLRuntimeValue(orig_v=v)
- bindings[v] = a
+ builder.bindings[v] = a.with_fresh_variables(to_be_stored_into=v)
print
- self.residual_operations = []
+ # flow the actual operations of the block
for op in origblock.operations:
- handler = getattr(self, 'op_' + op.opname)
- a_result = handler(op, *[binding(v) for v in op.args])
- bindings[op.result] = a_result
- inputargs = []
- for v in origblock.inputargs:
- a = bindings[v]
- if not isinstance(a, LLConcreteValue):
- inputargs.append(a.getvarorconst())
- newblock = Block(inputargs)
- newblock.operations = self.residual_operations
- del self.residual_operations # just in case
+ builder.dispatch(op)
+ # done
+ newexitswitch = None
if origblock.operations != ():
# build exit links and schedule their target for later completion
if origblock.exitswitch is None:
@@ -266,16 +266,17 @@
elif origblock.exitswitch == Constant(last_exception):
XXX
else:
- v = bindings[origblock.exitswitch].getvarorconst()
+ a = builder.bindings[origblock.exitswitch]
+ v = a.forcevarorconst(builder)
if isinstance(v, Variable):
- newblock.exitswitch = v
+ newexitswitch = v
links = origblock.exits
else:
links = [link for link in origblock.exits
if link.llexitcase == v.value]
newlinks = []
for origlink in links:
- args_a = [binding(v) for v in origlink.args]
+ args_a = [builder.binding(v) for v in origlink.args]
newlink = self.interp.schedule(args_a, origlink.target)
newlinks.append(newlink)
else:
@@ -283,24 +284,57 @@
# they are linked to the official return or except block of the
# copygraph. If needed, LLConcreteValues are turned into Constants.
if len(origblock.inputargs) == 1:
- target = self.graphstate.copygraph.returnblock
+ target = self.copygraph.returnblock
else:
- target = self.graphstate.copygraph.exceptblock
- args_v = [binding(v).getvarorconst() for v in origblock.inputargs]
+ target = self.copygraph.exceptblock
+ args_v = [builder.binding(v).forcevarorconst(builder)
+ for v in origblock.inputargs]
newlinks = [Link(args_v, target)]
#print "CLOSING"
- newblock.closeblock(*newlinks)
+
+ newblock = builder.buildblock(origblock.inputargs,
+ newexitswitch, newlinks)
state.resolveblock(newblock)
+
+class BlockBuilder(object):
+
+ def __init__(self, interp):
+ self.interp = interp
+ self.bindings = {} # {Variables-of-origblock: a_value}
+ self.residual_operations = []
+
+ def buildblock(self, originputargs, newexitswitch, newlinks):
+ inputargs = []
+ for v in originputargs:
+ a = self.bindings[v]
+ inputargs.extend(a.getruntimevars())
+ b = Block(inputargs)
+ b.operations = self.residual_operations
+ b.exitswitch = newexitswitch
+ b.closeblock(*newlinks)
+ return b
+
+ def binding(self, v):
+ if isinstance(v, Constant):
+ return LLRuntimeValue(orig_v=v)
+ else:
+ return self.bindings[v]
+
+ def dispatch(self, op):
+ handler = getattr(self, 'op_' + op.opname)
+ a_result = handler(op, *[self.binding(v) for v in op.args])
+ self.bindings[op.result] = a_result
+
+
def constantfold(self, constant_op, args_a):
concretevalues = []
any_concrete = False
for a in args_a:
- v = a.getvarorconst()
- if isinstance(v, Constant):
- concretevalues.append(v.value)
- else:
+ v = a.maybe_get_constant()
+ if v is None:
return None # cannot constant-fold
+ concretevalues.append(v.value)
any_concrete = any_concrete or isinstance(a, LLConcreteValue)
# can constant-fold
print 'fold:', constant_op, concretevalues
@@ -313,13 +347,13 @@
return LLRuntimeValue(c)
def residual(self, opname, args_a, a_result):
- v_result = a_result.getvarorconst()
+ v_result = a_result.forcevarorconst(self)
if isinstance(v_result, Constant):
v = Variable()
v.concretetype = v_result.concretetype
v_result = v
op = SpaceOperation(opname,
- [a.getvarorconst() for a in args_a],
+ [a.forcevarorconst(self) for a in args_a],
v_result)
print 'keep:', op
self.residual_operations.append(op)
@@ -385,8 +419,8 @@
def op_direct_call(self, op, a_func, *args_a):
a_result = LLRuntimeValue(op.result)
- v_func = a_func.getvarorconst()
- if isinstance(v_func, Constant):
+ v_func = a_func.maybe_get_constant()
+ if v_func is not None:
fnobj = v_func.value._obj
if (hasattr(fnobj, 'graph') and
not getattr(fnobj._callable, 'suggested_primitive', False)):
@@ -396,10 +430,9 @@
#print 'SCHEDULE_GRAPH', args_a, '==>', graphstate.copygraph.name
if graphstate.state != "during":
print 'ENTERING', graphstate.copygraph.name, args_a
- graphstate.complete(self.interp)
+ graphstate.complete()
if (graphstate.a_return is not None and
- isinstance(graphstate.a_return.getvarorconst(),
- Constant)):
+ graphstate.a_return.maybe_get_constant() is not None):
a_result = graphstate.a_return
print 'LEAVING', graphstate.copygraph.name, graphstate.a_return
More information about the Pypy-commit
mailing list