[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