[pypy-svn] r63585 - pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86
fijal at codespeak.net
fijal at codespeak.net
Fri Apr 3 22:41:40 CEST 2009
Author: fijal
Date: Fri Apr 3 22:41:37 2009
New Revision: 63585
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
Log:
a bit of progress. mostly removing/commenting out unnecessary code
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py Fri Apr 3 22:41:37 2009
@@ -60,7 +60,6 @@
self.counter -= 1
class Assembler386(object):
- generic_return_addr = 0
log_fd = -1
mc = None
mc2 = None
@@ -108,7 +107,6 @@
self._exception_bck)
self.mc = self.mcstack.next_mc()
self.mc2 = self.mcstack.next_mc()
- self.generic_return_addr = self.assemble_generic_return()
# the address of the function called by 'new': directly use
# Boehm's GC_malloc function.
if self.malloc_func_addr == 0:
@@ -149,7 +147,7 @@
",".join(reprs)))
os.write(self._log_fd, 'xxxxxxxxxx\n')
- def log_call(self, name, valueboxes):
+ def log_call(self, valueboxes):
if self._log_fd == -1:
return
return # XXX
@@ -158,10 +156,25 @@
os.write(self._log_fd, "CALL\n")
os.write(self._log_fd, "%s %s\n" % (name, args_s))
+ def _compute_longest_fail_op(self, ops):
+ max_so_far = 0
+ for op in ops:
+ if op.opnum == rop.FAIL:
+ max_so_far = max(max_so_far, len(op.args))
+ if op.is_guard():
+ max_so_far = max(max_so_far, self._compute_longest_fail_op(
+ op.suboperations))
+ return max_so_far
+
def assemble(self, tree):
# the last operation can be 'jump', 'return' or 'guard_pause';
# a 'jump' can either close a loop, or end a bridge to some
# previously-compiled code.
+ num = self._compute_longest_fail_op(tree.operations)
+ fail_boxes = lltype.malloc(rffi.CArray(lltype.Signed), num,
+ flavor='raw')
+ self.fail_box_addr = self.cpu.cast_ptr_to_int(fail_boxes)
+ tree.fail_boxes = fail_boxes
self.make_sure_mc_exists()
inputargs = tree.inputargs
op0 = tree.operations[0]
@@ -209,29 +222,30 @@
finally:
Box._extended_display = _prev
- def assemble_comeback_bootstrap(self, position, arglocs, stacklocs):
- entry_point_addr = self.mc2.tell()
- for i in range(len(arglocs)):
- argloc = arglocs[i]
- if isinstance(argloc, REG):
- self.mc2.MOV(argloc, stack_pos(stacklocs[i]))
- elif not we_are_translated():
- # debug checks
- if not isinstance(argloc, (IMM8, IMM32)):
- assert repr(argloc) == repr(stack_pos(stacklocs[i]))
- self.mc2.JMP(rel32(position))
- self.mc2.done()
- return entry_point_addr
-
- def assemble_generic_return(self):
- # generate a generic stub that just returns, taking the
- # return value from *esp (i.e. stack position 0).
- addr = self.mc.tell()
- self.mc.MOV(eax, mem(esp, 0))
- self.mc.ADD(esp, imm(FRAMESIZE))
- self.mc.RET()
- self.mc.done()
- return addr
+# def assemble_comeback_bootstrap(self, position, arglocs, stacklocs):
+# return
+# entry_point_addr = self.mc2.tell()
+# for i in range(len(arglocs)):
+# argloc = arglocs[i]
+# if isinstance(argloc, REG):
+# self.mc2.MOV(argloc, stack_pos(stacklocs[i]))
+# elif not we_are_translated():
+# # debug checks
+# if not isinstance(argloc, (IMM8, IMM32)):
+# assert repr(argloc) == repr(stack_pos(stacklocs[i]))
+# self.mc2.JMP(rel32(position))
+# self.mc2.done()
+# return entry_point_addr
+
+# def assemble_generic_return(self):
+# # generate a generic stub that just returns, taking the
+# # return value from *esp (i.e. stack position 0).
+# addr = self.mc.tell()
+# self.mc.MOV(eax, mem(esp, 0))
+# self.mc.ADD(esp, imm(FRAMESIZE))
+# self.mc.RET()
+# self.mc.done()
+# return addr
def regalloc_load(self, from_loc, to_loc):
self.mc.MOV(to_loc, from_loc)
@@ -520,8 +534,8 @@
def make_merge_point(self, tree, locs, stacklocs):
pos = self.mc.tell()
tree.position = pos
- tree.comeback_bootstrap_addr = self.assemble_comeback_bootstrap(pos,
- locs, stacklocs)
+ #tree.comeback_bootstrap_addr = self.assemble_comeback_bootstrap(pos,
+ # locs, stacklocs)
def genop_discard_return(self, op, locs):
if op.args:
@@ -601,8 +615,18 @@
self.mc = oldmc
return addr
- def genop_discard_fail(self, op, arglocs):
+ def genop_fail(self, op, locs, guard_index):
+ for i in range(len(locs)):
+ loc = locs[i]
+ if isinstance(loc, REG):
+ self.mc.MOV(addr_add(imm(self.fail_box_addr), imm(i)), loc)
+ for i in range(len(locs)):
+ loc = locs[i]
+ if not isinstance(loc, REG):
+ self.mc.MOV(eax, loc)
+ self.mc.MOV(addr_add(imm(self.fail_box_addr), imm(i)), eax)
self.mc.ADD(esp, imm(FRAMESIZE))
+ self.mc.MOV(eax, imm(guard_index))
self.mc.RET()
@specialize.arg(2)
@@ -673,7 +697,7 @@
print "not implemented operation with res: %s" % op.getopname()
raise NotImplementedError
- def not_implemented_op_guard(self, op, arglocs, resloc, descr):
+ def not_implemented_op_guard(self, op, regalloc, arglocs, resloc, descr):
print "not implemented operation (guard): %s" % op.getopname()
raise NotImplementedError
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py Fri Apr 3 22:41:37 2009
@@ -47,8 +47,10 @@
raise ValueError("convert_to_imm: got a %s" % c)
class RegAlloc(object):
+ guard_index = -1
+
def __init__(self, assembler, tree, translate_support_code=False,
- regalloc=None, suboperations=None):
+ regalloc=None, guard_op=None):
# variables that have place in register
self.assembler = assembler
self.translate_support_code = translate_support_code
@@ -68,7 +70,7 @@
self.loop_consts = loop_consts
self.current_stack_depth = sd
else:
- inp = self._compute_vars_longevity_backwards(suboperations)
+ inp = guard_op.inputargs
self.reg_bindings = {}
self.stack_bindings = {}
self.dirty_stack = {}
@@ -83,16 +85,17 @@
self.free_regs = [v for v in REGS if v not in allocated_regs]
self.loop_consts = regalloc.loop_consts # should never change
self.current_stack_depth = regalloc.current_stack_depth
- # XXXX think about this, since we might jump somewhere else
- # entirely
- self.jump_reg_candidates = regalloc.jump_reg_candidates
- self.inputargs = inp
+ # XXX think what to do if there is actually a jump
+ self.jump_reg_candidates = {}
+ self.longevity = guard_op.longevity
+ #self.jump_reg_candidates = regalloc.jump_reg_candidates
- def copy(self, suboperations):
+ def copy(self, guard_op):
return RegAlloc(self.assembler, None, self.translate_support_code,
- self, suboperations)
+ self, guard_op)
def _start_from_guard_op(self, guard_op, mp, jump):
+ xxx
rev_stack_binds = {}
self.jump_reg_candidates = {}
j = 0
@@ -220,7 +223,7 @@
# first pass - walk along the operations in order to find
# load/store places
operations = tree.operations
- self.position = 0
+ self.position = -1
self.process_inputargs(tree)
self._walk_operations(operations)
@@ -267,16 +270,25 @@
if isinstance(arg, Box):
longevity[arg] = (start_live[arg], i)
if op.is_guard():
- for arg in op.suboperations[-1].args:
- assert isinstance(arg, Box)
- longevity[arg] = (start_live[arg], i)
+ self._compute_inpargs(op)
+ for arg in op.inputargs:
+ if isinstance(arg, Box):
+ longevity[arg] = (start_live[arg], i)
self.longevity = longevity
- def _compute_vars_longevity_backwards(self, operations):
+ def _compute_inpargs(self, guard):
+ if guard.inputargs is not None:
+ return
+ operations = guard.suboperations
longevity = {}
end = {}
for i in range(len(operations)-1, -1, -1):
op = operations[i]
+ if op.is_guard():
+ self._compute_inpargs()
+ for arg in op.inputargs:
+ if arg not in longevity:
+ end[arg] = i
for arg in op.args:
if arg not in longevity:
end[arg] = i
@@ -285,8 +297,8 @@
del end[op.result]
for v, e in end.items():
longevity[v] = (0, e)
- self.longevity = longevity
- return end.keys()
+ guard.longevity = longevity
+ guard.inputargs = end.keys()
def try_allocate_reg(self, v, selected_reg=None):
if isinstance(v, Const):
@@ -378,10 +390,10 @@
self.Store(v_to_spill, loc, newloc)
return loc
- def _locs_from_liveboxes(self, guard_op, inpargs):
+ def _locs_from_liveboxes(self, guard_op):
stacklocs = []
locs = []
- for arg in inpargs:
+ for arg in guard_op.inputargs:
assert isinstance(arg, Box)
if arg not in self.stack_bindings:
self.dirty_stack[arg] = True
@@ -548,8 +560,8 @@
def consider_fail(self, op, ignored):
# make sure all vars are on stack
- locs = [self.make_sure_var_on_stack(arg) for arg in op.args]
- self.PerformDiscard(op, locs)
+ locs = [self.loc(arg) for arg in op.args]
+ self.assembler.genop_fail(op, locs, self.guard_index)
self.eventually_free_vars(op.args)
def consider_guard_nonvirtualized(self, op, ignored):
@@ -727,13 +739,16 @@
loc = self.force_allocate_reg(op.result, op.args)
self.Perform(op, arglocs, loc)
else:
- regalloc = self.copy(guard_op.suboperations)
- locs = self._locs_from_liveboxes(guard_op, regalloc.inputargs)
+ regalloc = self.copy(guard_op)
+ fop = guard_op.suboperations[-1]
+ assert fop.opnum == rop.FAIL # XXX also JUMP
+ regalloc.guard_index = self.assembler.cpu.make_guard_index(fop)
+ locs = self._locs_from_liveboxes(guard_op)
self.position += 1
- self.eventually_free_var(op.result)
- self.eventually_free_vars(regalloc.inputargs)
self.perform_with_guard(op, guard_op, regalloc, arglocs + locs,
None)
+ self.eventually_free_var(op.result)
+ self.eventually_free_vars(guard_op.inputargs)
consider_int_lt = _consider_compop
consider_int_gt = _consider_compop
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py Fri Apr 3 22:41:37 2009
@@ -183,13 +183,13 @@
def compile_operations(self, tree):
self.assembler.assemble(tree)
- def get_bootstrap_code(self, startmp):
+ def get_bootstrap_code(self, loop):
# key is locations of arguments
- key = ','.join([str(i) for i in startmp.arglocs])
+ key = ','.join([str(i) for i in loop.arglocs])
try:
func = self._bootstrap_cache[key]
except KeyError:
- arglocs = startmp.arglocs
+ arglocs = loop.arglocs
addr = self.assembler.assemble_bootstrap_code(arglocs)
# arguments are as follows - address to jump to,
# and a list of args
@@ -213,13 +213,11 @@
else:
raise ValueError('get_box_value_as_int, wrong arg')
- def get_valuebox_from_int(self, type, x):
- if type == INT:
- return history.BoxInt(x)
- elif type == PTR:
- return history.BoxPtr(self.cast_int_to_gcref(x))
- else:
- raise ValueError('get_valuebox_from_int: %s' % (type,))
+ def set_value_of_box(self, box, index, fail_boxes):
+ if isinstance(box, BoxInt):
+ box.value = fail_boxes[index]
+ elif isinstance(box, BoxPtr):
+ xxx
def _get_mp_for_call(self, argnum, calldescr):
try:
@@ -238,9 +236,6 @@
def execute_operations(self, loop, valueboxes):
func = self.get_bootstrap_code(loop)
- import pdb
- pdb.set_trace()
- startmp = operations[0]
# turn all the values into integers
TP = rffi.CArray(lltype.Signed)
oldindex = self.keepalives_index
@@ -254,22 +249,19 @@
# values_repr = ", ".join([str(values_as_int[i]) for i in
# range(len(valueboxes))])
# llop.debug_print(lltype.Void, 'exec:', name, values_repr)
- self.assembler.log_call(name, valueboxes)
-
+ self.assembler.log_call(valueboxes)
self.keepalives_index = len(self.keepalives)
- res = self.execute_call(startmp, func, values_as_int)
- if self.return_value_type == VOID:
- #self.assembler.log_void_result()
- res = None
- else:
- #self.assembler.log_result(res)
- res = self.get_valuebox_from_int(self.return_value_type, res)
+ guard_index = self.execute_call(loop, func, values_as_int)
keepalive_until_here(valueboxes)
self.keepalives_index = oldindex
del self.keepalives[oldindex:]
- return res
+ op = self._guard_list[guard_index]
+ for i in range(len(op.args)):
+ box = op.args[i]
+ self.set_value_of_box(box, i, loop.fail_boxes)
+ return op
- def execute_call(self, startmp, func, values_as_int):
+ def execute_call(self, loop, func, values_as_int):
# help flow objspace
prev_interpreter = None
if not self.translate_support_code:
@@ -278,7 +270,7 @@
res = 0
try:
self.caught_exception = None
- res = func(startmp.position, values_as_int)
+ res = func(loop.position, values_as_int)
self.reraise_caught_exception()
finally:
if not self.translate_support_code:
@@ -319,22 +311,22 @@
else:
raise ValueError(valuebox.type)
- def getvaluebox(self, frameadr, guard_op, argindex):
- # XXX that's plain stupid, do we care about the return value???
- box = guard_op.liveboxes[argindex]
- frame = getframe(frameadr)
- pos = guard_op.stacklocs[argindex]
- intvalue = frame[pos]
- if isinstance(box, history.BoxInt):
- return history.BoxInt(intvalue)
- elif isinstance(box, history.BoxPtr):
- return history.BoxPtr(self.cast_int_to_gcref(intvalue))
- else:
- raise AssertionError('getvalue: box = %s' % (box,))
-
- def setvaluebox(self, frameadr, mp, argindex, valuebox):
- frame = getframe(frameadr)
- frame[mp.stacklocs[argindex]] = self.convert_box_to_int(valuebox)
+# def getvaluebox(self, frameadr, guard_op, argindex):
+# # XXX that's plain stupid, do we care about the return value???
+# box = guard_op.liveboxes[argindex]
+# frame = getframe(frameadr)
+# pos = guard_op.stacklocs[argindex]
+# intvalue = frame[pos]
+# if isinstance(box, history.BoxInt):
+# return history.BoxInt(intvalue)
+# elif isinstance(box, history.BoxPtr):
+# return history.BoxPtr(self.cast_int_to_gcref(intvalue))
+# else:
+# raise AssertionError('getvalue: box = %s' % (box,))
+
+# def setvaluebox(self, frameadr, mp, argindex, valuebox):
+# frame = getframe(frameadr)
+# frame[mp.stacklocs[argindex]] = self.convert_box_to_int(valuebox)
def sizeof(self, S):
size = symbolic.get_size(S, self.translate_support_code)
@@ -591,32 +583,32 @@
x += 0x100000000
return hex(x)
-class GuardFailed(object):
- return_value_type = 0
+# class GuardFailed(object):
+# return_value_type = 0
- def __init__(self, cpu, frame, guard_op):
- self.cpu = cpu
- self.frame = frame
- self.guard_op = guard_op
-
- def make_ready_for_return(self, return_value_box):
- self.cpu.assembler.make_sure_mc_exists()
- if return_value_box is not None:
- frame = getframe(self.frame)
- frame[0] = self.cpu.convert_box_to_int(return_value_box)
- if (isinstance(return_value_box, ConstInt) or
- isinstance(return_value_box, BoxInt)):
- self.return_value_type = INT
- else:
- self.return_value_type = PTR
- else:
- self.return_value_type = VOID
- self.return_addr = self.cpu.assembler.generic_return_addr
-
- def make_ready_for_continuing_at(self, merge_point):
- # we need to make sure here that return_addr points to a code
- # that is ready to grab coorect values
- self.return_addr = merge_point.comeback_bootstrap_addr
+# def __init__(self, cpu, frame, guard_op):
+# self.cpu = cpu
+# self.frame = frame
+# self.guard_op = guard_op
+
+# def make_ready_for_return(self, return_value_box):
+# self.cpu.assembler.make_sure_mc_exists()
+# if return_value_box is not None:
+# frame = getframe(self.frame)
+# frame[0] = self.cpu.convert_box_to_int(return_value_box)
+# if (isinstance(return_value_box, ConstInt) or
+# isinstance(return_value_box, BoxInt)):
+# self.return_value_type = INT
+# else:
+# self.return_value_type = PTR
+# else:
+# self.return_value_type = VOID
+# self.return_addr = self.cpu.assembler.generic_return_addr
+
+# def make_ready_for_continuing_at(self, merge_point):
+# # we need to make sure here that return_addr points to a code
+# # that is ready to grab coorect values
+# self.return_addr = merge_point.comeback_bootstrap_addr
def getframe(frameadr):
return rffi.cast(rffi.CArrayPtr(lltype.Signed), frameadr)
More information about the Pypy-commit
mailing list