[pypy-svn] r38130 - in pypy/branch/new-jit-codegen: i386 test

arigo at codespeak.net arigo at codespeak.net
Thu Feb 8 00:22:09 CET 2007


Author: arigo
Date: Thu Feb  8 00:21:58 2007
New Revision: 38130

Modified:
   pypy/branch/new-jit-codegen/i386/regalloc.py
   pypy/branch/new-jit-codegen/i386/rgenop.py
   pypy/branch/new-jit-codegen/i386/ri386.py
   pypy/branch/new-jit-codegen/test/rgenop_tests.py
Log:
Fix the logic about places, yet again.  Fix a stupid bug causing a
jitted function to consume more and more stack space if it loops and
contains a flexswitch.

Now this backend seems to be up to running pypy-jits :-)


Modified: pypy/branch/new-jit-codegen/i386/regalloc.py
==============================================================================
--- pypy/branch/new-jit-codegen/i386/regalloc.py	(original)
+++ pypy/branch/new-jit-codegen/i386/regalloc.py	Thu Feb  8 00:21:58 2007
@@ -30,14 +30,13 @@
 
 def write_stack_reserve(mc, stackn):
     addr = mc.tell()
-    offset = WORD * ((StackOpCache.INITIAL_STACK_EBP_OFS+1) - stackn)
-    mc.ADD(esp, IMM32(offset))     # always encode offset on 32 bits
+    mc.SUB(esp, IMM32(WORD * stackn))     # always encode offset on 32 bits
     return addr
 
 def write_stack_adj(mc, stackn):
     addr = mc.tell()
-    offset = WORD * ((StackOpCache.INITIAL_STACK_EBP_OFS+1) - stackn)
-    mc.LEA(esp, fixedsize_esp_ofs(offset))
+    # always encode offset on 32 bits
+    mc.LEA(esp, fixedsize_ebp_ofs(-WORD * stackn))
     return addr
 
 
@@ -546,7 +545,6 @@
     def generate(self, allocator):
         pass
 dead_operation = DeadOperation()
-forget_stack_storage = DeadOperation()
 gv_frame_base = GenVar()
 
 class Place(Operation):
@@ -581,21 +579,24 @@
 
 class StorageInStack(Place):
     def generate(self, allocator):
-        # patch the lifetime of the variable if needed (XXX a bit slow)
-        x = self.x
-        i = allocator.lifetime.get(x, allocator.operationindex)
-        operations = allocator.operations
-        while i < len(operations):
-            if operations[i] is forget_stack_storage:
-                break
-            i += 1
-        allocator.lifetime[x] = i
-        allocator.vars_in_use[x] = i
-        # force it to be in the stack
-        srcop = allocator.get_operand(x)
+        # force the variable to be in the stack
+        srcop = allocator.get_operand(self.x)
         if not isinstance(srcop, MODRM):
             oldop = srcop
-            srcop = allocator._spill(x, srcop)
+            srcop = allocator._spill(self.x, srcop)
             allocator._mark_loc_as_free(oldop)
         # record its location
         self.offset = srcop.ofs_relative_to_ebp()
+        # hack to avoid this instance keeping a lot of memory around
+        self.x = None
+
+class OpTouch(Operation):
+    side_effects = True     # don't remove me!
+    def __init__(self, args_gv):
+        self.args_gv = args_gv
+    def mark_used_vars(self, allocator):
+        for v in self.args_gv:
+            allocator.using(v)
+    def generate(self, allocator):
+        for v in self.args_gv:
+            allocator.release(v)

Modified: pypy/branch/new-jit-codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/new-jit-codegen/i386/rgenop.py	(original)
+++ pypy/branch/new-jit-codegen/i386/rgenop.py	Thu Feb  8 00:21:58 2007
@@ -6,10 +6,9 @@
 from pypy.jit.codegen.model import ReplayBuilder, dummy_var
 from pypy.jit.codegen.i386.codebuf import CodeBlockOverflow
 from pypy.jit.codegen.i386.operation import *
-from pypy.jit.codegen.i386.regalloc import RegAllocator
-from pypy.jit.codegen.i386.regalloc import DEBUG_STACK, forget_stack_storage
+from pypy.jit.codegen.i386.regalloc import RegAllocator, DEBUG_STACK
 from pypy.jit.codegen.i386.regalloc import gv_frame_base, StorageInStack
-from pypy.jit.codegen.i386.regalloc import Place, OpAbsorbPlace
+from pypy.jit.codegen.i386.regalloc import Place, OpAbsorbPlace, OpTouch
 from pypy.jit.codegen.i386.regalloc import write_stack_reserve, write_stack_adj
 from pypy.jit.codegen import conftest
 from pypy.rpython.annlowlevel import llhelper
@@ -213,6 +212,7 @@
     update_defaultcaseaddr_of = None
     paused_alive_gv = None
     order_dependency = None
+    keepalives_gv = None
 
     def __init__(self, rgenop, graphctx, inputargs_gv, inputoperands):
         self.rgenop = rgenop
@@ -226,6 +226,7 @@
 
     def generate_block_code(self, final_vars_gv, final_operands=None,
                                                  renaming=True):
+        self.insert_keepalives()
         if self.order_dependency is not None:
             self.order_dependency.force_generate_code()
             self.order_dependency = None
@@ -251,9 +252,14 @@
         self.inputoperands = [allocator.get_operand(v) for v in final_vars_gv]
         return mc
 
+    def insert_keepalives(self):
+        if self.keepalives_gv is not None:
+            self.operations.append(OpTouch(self.keepalives_gv))
+            self.keepalives_gv = None
+
     def enter_next_block(self, kinds, args_gv):
         # we get better register allocation if we write a single large mc block
-        self.operations.append(forget_stack_storage)
+        self.insert_keepalives()
         for i in range(len(args_gv)):
             op = OpSameAs(args_gv[i])
             args_gv[i] = op
@@ -487,6 +493,9 @@
         result = []
         for v in vars_gv:
             if not v.is_const:
+                if self.keepalives_gv is None:
+                    self.keepalives_gv = []
+                self.keepalives_gv.append(v)
                 sis = StorageInStack(v)
                 self.operations.append(sis)
                 v = sis

Modified: pypy/branch/new-jit-codegen/i386/ri386.py
==============================================================================
--- pypy/branch/new-jit-codegen/i386/ri386.py	(original)
+++ pypy/branch/new-jit-codegen/i386/ri386.py	Thu Feb  8 00:21:58 2007
@@ -271,9 +271,8 @@
     else:
         return cls(0x84, SIB + packimm32(offset))
 
-def fixedsize_esp_ofs(offset):
-    SIB = '\x24'
-    return MODRM(0x84, SIB + packimm32(offset))
+def fixedsize_ebp_ofs(offset):
+    return MODRM(0x80 | EBP.op, packimm32(offset))
 
 def single_byte(value):
     return -128 <= value < 128

Modified: pypy/branch/new-jit-codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/new-jit-codegen/test/rgenop_tests.py	(original)
+++ pypy/branch/new-jit-codegen/test/rgenop_tests.py	Thu Feb  8 00:21:58 2007
@@ -1354,6 +1354,38 @@
         res = fn(-1)
         assert res == 42
 
+    def test_frame_vars_like_the_frontend_direct(self):
+        rgenop = self.RGenOp()
+        sigtoken = rgenop.sigToken(FUNC3)
+        signed_kind = rgenop.kindToken(lltype.Signed)
+        # ------------------------------------------
+        builder0, gv_callable, [v0, v1, v2] = rgenop.newgraph(sigtoken,
+                                                              'fvltf')
+        builder0.start_writing()
+        builder1 = builder0.pause_writing([v1, v0, v2])
+        builder1.start_writing()
+        args_gv = [v1, v0, v2]
+        label0 = builder1.enter_next_block([signed_kind]*3, args_gv)
+        [v3, v4, v5] = args_gv
+        place = builder1.alloc_frame_place(signed_kind, rgenop.genconst(0))
+        v6 = builder1.genop_get_frame_base()
+        c_seven = rgenop.genconst(7)
+        frameinfo = builder1.get_frame_info([v3, v4, c_seven, v5])
+        # here would be a call
+        v8 = builder1.genop_absorb_place(signed_kind, place)
+        args_gv = [v3, v4, v5, v8]
+        label1 = builder1.enter_next_block([signed_kind]*4, args_gv)
+        [v9, v10, v11, v12] = args_gv
+        flexswitch0, builder2 = builder1.flexswitch(v12, [v9, v10, v12])
+        v13 = builder2.genop2("int_add", v9, v10)
+        v14 = builder2.genop2("int_add", v13, v12)
+        builder2.finish_and_return(sigtoken, v14)
+        builder0.end()
+
+        fnptr = self.cast(gv_callable, 3)
+        res = fnptr(40, 2, 8168126)
+        assert res == 42
+
     def test_unaliasing_variables_direct(self):
         # def f(x, y):
         #     if x:



More information about the Pypy-commit mailing list