[pypy-commit] pypy spaceops-are-variables: various fixes in the backend optimizations
cfbolz
noreply at buildbot.pypy.org
Sun Oct 26 14:43:37 CET 2014
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: spaceops-are-variables
Changeset: r74250:ecd4cb25f0a6
Date: 2014-10-26 14:43 +0100
http://bitbucket.org/pypy/pypy/changeset/ecd4cb25f0a6/
Log: various fixes in the backend optimizations
diff --git a/rpython/translator/backendopt/constfold.py b/rpython/translator/backendopt/constfold.py
--- a/rpython/translator/backendopt/constfold.py
+++ b/rpython/translator/backendopt/constfold.py
@@ -26,7 +26,7 @@
pass
else:
if not op.sideeffects and len(args) == len(vargs):
- RESTYPE = spaceop.result.concretetype
+ RESTYPE = spaceop.concretetype
try:
result = op(RESTYPE, *args)
except TypeError:
@@ -41,7 +41,7 @@
# success in folding this space operation
if spaceop.opname in fixup_op_result:
result = fixup_op_result[spaceop.opname](result)
- constants[spaceop.result] = Constant(result, RESTYPE)
+ constants[spaceop] = Constant(result, RESTYPE)
folded_count += 1
continue
# failed to fold an operation, exit early if requested
@@ -51,11 +51,10 @@
if vargsmodif:
if (spaceop.opname == 'indirect_call'
and isinstance(vargs[0], Constant)):
- spaceop = SpaceOperation('direct_call', vargs[:-1],
- spaceop.result)
+ spaceop.opname = 'direct_call'
+ spaceop.args = vargs[:-1]
else:
- spaceop = SpaceOperation(spaceop.opname, vargs,
- spaceop.result)
+ spaceop.args = vargs
newops.append(spaceop)
# end
if exit_early:
@@ -70,19 +69,22 @@
if constants:
if block.exitswitch in constants:
switch = constants[block.exitswitch].value
- remaining_exits = [link for link in block.exits
- if link.llexitcase == switch]
- if not remaining_exits:
- assert block.exits[-1].exitcase == 'default'
- remaining_exits = [block.exits[-1]]
- assert len(remaining_exits) == 1
- remaining_exits[0].exitcase = None
- remaining_exits[0].llexitcase = None
- block.exitswitch = None
- block.recloseblock(*remaining_exits)
+ constant_fold_exitswitch(block, switch)
for link in block.exits:
link.args = [constants.get(v, v) for v in link.args]
+def constant_fold_exitswitch(block, constswitch):
+ remaining_exits = [link for link in block.exits
+ if link.llexitcase == constswitch]
+ if not remaining_exits:
+ assert block.exits[-1].exitcase == 'default'
+ remaining_exits = [block.exits[-1]]
+ assert len(remaining_exits) == 1
+ remaining_exits[0].exitcase = None
+ remaining_exits[0].llexitcase = None
+ block.exitswitch = None
+ block.recloseblock(*remaining_exits)
+
def fixup_solid(p):
# Operations returning pointers to inlined parts of a constant object
@@ -241,15 +243,19 @@
else:
diffuse.append((i, c))
diffuse.reverse()
- same_as = []
+ block_count = 0
+ mapping = {}
for i, c in diffuse:
for lnk in links:
del lnk.args[i]
v = block.inputargs.pop(i)
- same_as.append(SpaceOperation('same_as', [c], v))
- count += 1
- block.operations = same_as + block.operations
- if same_as:
+ mapping[v] = c
+ block_count += 1
+ count += block_count
+ if block.exitswitch in mapping:
+ constant_fold_exitswitch(block, mapping[block.exitswitch].value)
+ block.renamevariables(mapping)
+ if block_count:
constant_fold_block(block)
return count
diff --git a/rpython/translator/backendopt/inline.py b/rpython/translator/backendopt/inline.py
--- a/rpython/translator/backendopt/inline.py
+++ b/rpython/translator/backendopt/inline.py
@@ -101,9 +101,9 @@
return None, None
op = ops[i]
i -= 1
- if op.opname in ("same_as", "cast_pointer") and op.result is currvar:
+ if op.opname in ("same_as", "cast_pointer") and op is currvar:
currvar = op.args[0]
- elif op.opname == "malloc" and op.result is currvar:
+ elif op.opname == "malloc" and op is currvar:
return Ptr(op.args[0].value), block.exits[0]
def does_raise_directly(graph, raise_analyzer):
@@ -236,19 +236,20 @@
if isinstance(var, Constant):
return var
if var not in self.varmap:
- self.varmap[var] = var.copy()
+ self.varmap[var] = var.copy_as_var()
return self.varmap[var]
def passon_vars(self, cache_key):
if cache_key in self._passon_vars:
return self._passon_vars[cache_key]
- result = [var.copy() for var in self.original_passon_vars]
+ result = [var.copy_as_var() for var in self.original_passon_vars]
self._passon_vars[cache_key] = result
return result
def copy_operation(self, op):
args = [self.get_new_name(arg) for arg in op.args]
- result = SpaceOperation(op.opname, args, self.get_new_name(op.result))
+ result = SpaceOperation(op.opname, args, concretetype=op.concretetype)
+ self.varmap[op] = result
return result
def copy_block(self, block):
@@ -361,16 +362,15 @@
exc_match.concretetype = typeOf(exc_match.value)
blocks = []
for i, link in enumerate(afterblock.exits[1:]):
- etype = copiedexceptblock.inputargs[0].copy()
- evalue = copiedexceptblock.inputargs[1].copy()
+ etype = copiedexceptblock.inputargs[0].copy_as_var()
+ evalue = copiedexceptblock.inputargs[1].copy_as_var()
passon_vars = self.passon_vars(i)
block = Block([etype, evalue] + passon_vars)
- res = Variable()
- res.concretetype = Bool
cexitcase = Constant(link.llexitcase)
cexitcase.concretetype = typeOf(cexitcase.value)
args = [exc_match, etype, cexitcase]
- block.operations.append(SpaceOperation("direct_call", args, res))
+ res = SpaceOperation("direct_call", args, concretetype=Bool)
+ block.operations.append(res)
block.exitswitch = res
linkargs = self.find_args_in_exceptional_case(link, link.target,
etype, evalue, afterblock,
@@ -423,7 +423,9 @@
#rewire blocks
linktoinlined.target = copiedstartblock
linktoinlined.args = passon_args
- afterblock.inputargs = [self.op.result] + afterblock.inputargs
+ result_var = self.op.copy_as_var()
+ afterblock.inputargs = [result_var] + afterblock.inputargs
+ afterblock.renamevariables({self.op: result_var})
if self.graph_to_inline.returnblock in self.entrymap:
self.rewire_returnblock(afterblock)
if self.graph_to_inline.exceptblock in self.entrymap:
@@ -599,10 +601,9 @@
if candidate(graph):
tag = Constant('inline', Void)
label = Constant(n, Signed)
- dummy = Variable()
- dummy.concretetype = Void
count = SpaceOperation('instrument_count',
- [tag, label], dummy)
+ [tag, label],
+ concretetype=Void)
ops.insert(i + 1, count)
n += 1
log.inlining("%d call sites instrumented" % n)
diff --git a/rpython/translator/backendopt/merge_if_blocks.py b/rpython/translator/backendopt/merge_if_blocks.py
--- a/rpython/translator/backendopt/merge_if_blocks.py
+++ b/rpython/translator/backendopt/merge_if_blocks.py
@@ -13,7 +13,7 @@
# note: 'llong_eq', 'ullong_eq' have been removed, as it's not
# strictly C-compliant to do a switch() on a long long. It also
# crashes the JIT, and it's very very rare anyway.
- or op.result != block.exitswitch):
+ or op != block.exitswitch):
return False
if isinstance(op.args[0], Variable) and isinstance(op.args[1], Variable):
return False
@@ -78,7 +78,7 @@
# False link
checkvar = [var for var in current.operations[-1].args
if isinstance(var, Variable)][0]
- resvar = current.operations[-1].result
+ resvar = current.operations[-1]
case = [var for var in current.operations[-1].args
if isinstance(var, Constant)][0]
checkvars.append(checkvar)
diff --git a/rpython/translator/backendopt/raisingop2direct_call.py b/rpython/translator/backendopt/raisingop2direct_call.py
--- a/rpython/translator/backendopt/raisingop2direct_call.py
+++ b/rpython/translator/backendopt/raisingop2direct_call.py
@@ -37,7 +37,7 @@
if op.opname not in seen:
seen[op.opname] = 0
seen[op.opname] += 1
- op.args.insert(0, annotate(translator, func, op.result, op.args))
+ op.args.insert(0, annotate(translator, func, op, op.args))
op.opname = 'direct_call'
#statistics...
diff --git a/rpython/translator/backendopt/removenoops.py b/rpython/translator/backendopt/removenoops.py
--- a/rpython/translator/backendopt/removenoops.py
+++ b/rpython/translator/backendopt/removenoops.py
@@ -14,7 +14,7 @@
positions.append((block, i))
while positions:
block, index = positions.pop()
- op_result = block.operations[index].result
+ op_result = block.operations[index]
op_arg = block.operations[index].args[0]
# replace the new variable (op_result) with the old variable
# (from all subsequent positions)
@@ -57,15 +57,15 @@
if op.opname == "cast_pointer":
if op.args[0] in comes_from:
from_var = comes_from[op.args[0]]
- comes_from[op.result] = from_var
- if from_var.concretetype == op.result.concretetype:
+ comes_from[op] = from_var
+ if from_var.concretetype == op.concretetype:
op.opname = "same_as"
op.args = [from_var]
num_removed += 1
else:
op.args = [from_var]
else:
- comes_from[op.result] = op.args[0]
+ comes_from[op] = op.args[0]
if num_removed:
remove_same_as(graph)
# remove duplicate casts
@@ -73,13 +73,13 @@
available = {}
for op in block.operations:
if op.opname == "cast_pointer":
- key = (op.args[0], op.result.concretetype)
+ key = (op.args[0], op.concretetype)
if key in available:
op.opname = "same_as"
op.args = [available[key]]
num_removed += 1
else:
- available[key] = op.result
+ available[key] = op
if num_removed:
remove_same_as(graph)
# remove casts with unused results
@@ -89,7 +89,7 @@
for arg in link.args:
used[arg] = True
for i, op in list(enumerate(block.operations))[::-1]:
- if op.opname == "cast_pointer" and op.result not in used:
+ if op.opname == "cast_pointer" and op not in used:
del block.operations[i]
num_removed += 1
else:
diff --git a/rpython/translator/backendopt/tailrecursion.py b/rpython/translator/backendopt/tailrecursion.py
--- a/rpython/translator/backendopt/tailrecursion.py
+++ b/rpython/translator/backendopt/tailrecursion.py
@@ -6,7 +6,7 @@
print "removing tail call"
assert len(block.exits) == 1
assert block.exits[0].target is graph.returnblock
- assert block.operations[-1].result == block.exits[0].args[0]
+ assert block.operations[-1] == block.exits[0].args[0]
op = block.operations[-1]
block.operations = block.operations[:-1]
block.exits[0].args = op.args[1:]
@@ -20,7 +20,7 @@
if (len(block.exits) == 1 and
len(block.operations) > 0 and
block.operations[-1].opname == 'direct_call' and
- block.operations[-1].result == link.args[0]):
+ block.operations[-1] == link.args[0]):
print "getgraph", graph
if graph is graph:
_remove_tail_call(translator, graph, block)
diff --git a/rpython/translator/backendopt/test/test_inline.py b/rpython/translator/backendopt/test/test_inline.py
--- a/rpython/translator/backendopt/test/test_inline.py
+++ b/rpython/translator/backendopt/test/test_inline.py
@@ -26,7 +26,7 @@
for op in node.operations:
for v in op.args:
assert hasattr(v, 'concretetype')
- assert hasattr(op.result, 'concretetype')
+ assert hasattr(op, 'concretetype')
for node in graph.iterlinks():
if node.exitcase is not None:
assert hasattr(node, 'llexitcase')
diff --git a/rpython/translator/backendopt/writeanalyze.py b/rpython/translator/backendopt/writeanalyze.py
--- a/rpython/translator/backendopt/writeanalyze.py
+++ b/rpython/translator/backendopt/writeanalyze.py
@@ -78,14 +78,14 @@
while pendingblocks:
block = pendingblocks.pop()
for op in block.operations:
- self.allvariables.add(op.result)
+ self.allvariables.add(op)
if (op.opname == 'malloc' or op.opname == 'malloc_varsize'
or op.opname == 'new'):
continue
elif op.opname in ('cast_pointer', 'same_as'):
if self.is_fresh_malloc(op.args[0]):
continue
- self.nonfresh.add(op.result)
+ self.nonfresh.add(op)
for link in block.exits:
self.nonfresh.update(link.getextravars())
self.allvariables.update(link.getextravars())
diff --git a/rpython/translator/exceptiontransform.py b/rpython/translator/exceptiontransform.py
--- a/rpython/translator/exceptiontransform.py
+++ b/rpython/translator/exceptiontransform.py
@@ -250,7 +250,7 @@
block.exits[0].target is graph.returnblock and
len(block.operations) and
(block.exits[0].args[0].concretetype is lltype.Void or
- block.exits[0].args[0] is block.operations[-1].result) and
+ block.exits[0].args[0] is block.operations[-1]) and
block.operations[-1].opname not in ('malloc', 'malloc_varsize')): # special cases
last_operation -= 1
lastblock = block
@@ -290,7 +290,7 @@
if block is None:
continue
for op in block.operations[::-1]:
- if v is op.result:
+ if v is op:
if op.opname == 'cast_pointer':
v = op.args[0]
else:
@@ -303,22 +303,17 @@
def transform_jump_to_except_block(self, graph, entrymap, link):
reraise = self.comes_from_last_exception(entrymap, link)
- result = Variable()
- result.concretetype = lltype.Void
- block = Block([v.copy() for v in graph.exceptblock.inputargs])
+ block = Block([v.copy_as_var() for v in graph.exceptblock.inputargs])
+ op = SpaceOperation("direct_call",
+ [self.rpyexc_reraise_ptr] + block.inputargs,
+ concretetype=lltype.Void)
if reraise:
- block.operations = [
- SpaceOperation("direct_call",
- [self.rpyexc_reraise_ptr] + block.inputargs,
- result),
- ]
+ block.operations = [op]
else:
block.operations = [
- SpaceOperation("direct_call",
- [self.rpyexc_raise_ptr] + block.inputargs,
- result),
+ op,
SpaceOperation('debug_record_traceback', [],
- varoftype(lltype.Void)),
+ concretetype=lltype.Void),
]
link.target = block
RETTYPE = graph.returnblock.inputargs[0].concretetype
@@ -344,7 +339,6 @@
inlined, the correct exception matching blocks are produced."""
# XXX slightly annoying: construct a graph by hand
# but better than the alternative
- result = op.result.copy()
opargs = []
inputargs = []
callargs = []
@@ -359,12 +353,12 @@
ARGTYPES.append(var.concretetype)
else:
opargs.append(var)
- newop = SpaceOperation(op.opname, opargs, result)
+ newop = SpaceOperation(op.opname, opargs, concretetype=op.concretetype)
startblock = Block(inputargs)
startblock.operations.append(newop)
newgraph = FunctionGraph("dummy_exc1", startblock)
- startblock.closeblock(Link([result], newgraph.returnblock))
- newgraph.returnblock.inputargs[0].concretetype = op.result.concretetype
+ startblock.closeblock(Link([newop], newgraph.returnblock))
+ newgraph.returnblock.inputargs[0].concretetype = op.concretetype
self.gen_exc_check(startblock, newgraph.returnblock)
excblock = Block([])
@@ -384,8 +378,9 @@
excblock.closeblock(Link([var_type, var_value], newgraph.exceptblock))
startblock.exits[True].target = excblock
startblock.exits[True].args = []
- fptr = self.constant_func("dummy_exc1", ARGTYPES, op.result.concretetype, newgraph)
- return newgraph, SpaceOperation("direct_call", [fptr] + callargs, op.result)
+ fptr = self.constant_func("dummy_exc1", ARGTYPES, op.concretetype, newgraph)
+ import pdb; pdb.set_trace()
+ return newgraph, SpaceOperation("direct_call", [fptr] + callargs, op)
def gen_exc_check(self, block, returnblock, normalafterblock=None):
llops = rtyper.LowLevelOpList(None)
@@ -394,7 +389,7 @@
alloc_shortcut = self.check_for_alloc_shortcut(spaceop)
if alloc_shortcut:
- var_no_exc = self.gen_nonnull(spaceop.result, llops)
+ var_no_exc = self.gen_nonnull(spaceop, llops)
else:
v_exc_type = self.gen_getfield('exc_type', llops)
var_no_exc = self.gen_isnull(v_exc_type, llops)
@@ -404,8 +399,9 @@
block.exitswitch = var_no_exc
#exception occurred case
b = Block([])
- b.operations = [SpaceOperation('debug_record_traceback', [],
- varoftype(lltype.Void))]
+ op = SpaceOperation('debug_record_traceback', [])
+ op.concretetype = lltype.Void
+ b.operations = [op]
l = Link([error_constant(returnblock.inputargs[0].concretetype)], returnblock)
b.closeblock(l)
l = Link([], b)
@@ -429,13 +425,12 @@
if insert_zeroing_op:
if normalafterblock is None:
normalafterblock = insert_empty_block(None, l0)
- v_result = spaceop.result
- if v_result in l0.args:
- result_i = l0.args.index(v_result)
+ if spaceop in l0.args:
+ result_i = l0.args.index(spaceop)
v_result_after = normalafterblock.inputargs[result_i]
else:
- v_result_after = v_result.copy()
- l0.args.append(v_result)
+ v_result_after = spaceop.copy_as_var()
+ l0.args.append(spaceop)
normalafterblock.inputargs.append(v_result_after)
if true_zero:
opname = "zero_everything_inside"
@@ -443,7 +438,7 @@
opname = "zero_gc_pointers_inside"
normalafterblock.operations.insert(
0, SpaceOperation(opname, [v_result_after],
- varoftype(lltype.Void)))
+ concretetype=lltype.Void))
def setup_excdata(self):
EXCDATA = lltype.Struct('ExcData',
diff --git a/rpython/translator/transform.py b/rpython/translator/transform.py
--- a/rpython/translator/transform.py
+++ b/rpython/translator/transform.py
@@ -233,9 +233,8 @@
insert_in.add(block)
for block in insert_in:
- v = Variable()
- v.concretetype = lltype.Void
- unwind_op = SpaceOperation('direct_call', [stack_check_ptr_const], v)
+ unwind_op = SpaceOperation('direct_call', [stack_check_ptr_const],
+ concretetype=lltype.Void)
block.operations.insert(0, unwind_op)
# prevents cycles of tail calls from occurring -- such cycles would
# not consume any stack, so would turn into potentially infinite loops
More information about the pypy-commit
mailing list