[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