Author: Remi Meier <remi.me...@gmail.com> Branch: fix-longevity Changeset: r82444:b5c6184fc5e6 Date: 2016-02-23 16:10 +0100 http://bitbucket.org/pypy/pypy/changeset/b5c6184fc5e6/
Log: (plan_rich,remi) start implementing heuristic for choosing callee vs caller registers diff --git a/rpython/jit/backend/llsupport/regalloc.py b/rpython/jit/backend/llsupport/regalloc.py --- a/rpython/jit/backend/llsupport/regalloc.py +++ b/rpython/jit/backend/llsupport/regalloc.py @@ -671,16 +671,24 @@ return [self.loc(op.getarg(0))] -def compute_vars_longevity(inputargs, operations): +class LiveRanges(object): + def __init__(self, longevity, last_real_usage, dist_to_next_call): + self.longevity = longevity + self.last_real_usage = last_real_usage + self.dist_to_next_call = dist_to_next_call + +def compute_var_live_ranges(inputargs, operations): # compute a dictionary that maps variables to index in # operations that is a "last-time-seen" - # returns a pair longevity/useful. Non-useful variables are ones that + # returns a Longevity object with longevity/useful. Non-useful variables are ones that # never appear in the assembler or it does not matter if they appear on # stack or in registers. Main example is loop arguments that go # only to guard operations or to jump or to finish last_used = {} last_real_usage = {} + dist_to_next_call = [0] * len(operations) + last_call_pos = -1 for i in range(len(operations)-1, -1, -1): op = operations[i] if op.type != 'v': @@ -703,6 +711,9 @@ assert not isinstance(arg, Const) if arg not in last_used: last_used[arg] = i + if op.is_call(): + last_call_pos = i + dist_to_next_call[i] = last_call_pos - i # longevity = {} for i, arg in enumerate(operations): @@ -729,8 +740,8 @@ if not isinstance(arg, Const): assert arg in produced produced[op] = None - - return longevity, last_real_usage + + return LiveRanges(longevity, last_real_usage, dist_to_next_call) def is_comparison_or_ovf_op(opnum): from rpython.jit.metainterp.resoperation import opclasses diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_call.py b/rpython/jit/backend/llsupport/test/test_regalloc_call.py --- a/rpython/jit/backend/llsupport/test/test_regalloc_call.py +++ b/rpython/jit/backend/llsupport/test/test_regalloc_call.py @@ -141,8 +141,9 @@ FPTR = lltype.Ptr(lltype.FuncType([rffi.UINT], rffi.UINT)) func_ptr = llhelper(FPTR, x) calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, EffectInfo.MOST_GENERAL) + targettoken = TargetToken() - ns = {'calldescr': calldescr} + ns = {'calldescr': calldescr, 'targettoken':targettoken} self.namespace = ns def test_allocate_register_into_jump_register(self): @@ -187,3 +188,22 @@ assert trace_alloc.initial_register(i2) != edx assert trace_alloc.move_count() == 1 + def test_call_allocate_first_param_to_callee2(self): + tt, ops = parse_loop(""" + [p0,i0] + + label(p0,i0,descr=targettoken) + + i1 = int_add(i0,i0) + i2 = int_add(i0,i1) + call_n(p0, i1, descr=calldescr) + guard_true(i2) [] + + jump(p0,i1,descr=targettoken) + """, namespace=self.namespace) + i1 = ops.operations[0] + i2 = ops.operations[1] + trace_alloc = TraceAllocation(ops, [eax, edx], [r8, r9], [eax, edx], tt) + assert trace_alloc.initial_register(i1) == edx + assert trace_alloc.initial_register(i2) != edx + assert trace_alloc.move_count() == 1 diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -7,7 +7,7 @@ from rpython.jit.backend.llsupport.descr import CallDescr, unpack_arraydescr from rpython.jit.backend.llsupport.gcmap import allocate_gcmap from rpython.jit.backend.llsupport.regalloc import (FrameManager, BaseRegalloc, - RegisterManager, TempVar, compute_vars_longevity, is_comparison_or_ovf_op, + RegisterManager, TempVar, compute_var_live_ranges, is_comparison_or_ovf_op, valid_addressing_size) from rpython.jit.backend.x86 import rx86 from rpython.jit.backend.x86.arch import (WORD, JITFRAME_FIXED_SIZE, IS_X86_32, @@ -164,10 +164,10 @@ operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, allgcrefs) # compute longevity of variables - longevity, last_real_usage = compute_vars_longevity( - inputargs, operations) - self.longevity = longevity - self.last_real_usage = last_real_usage + live_ranges = compute_var_live_ranges(inputargs, operations) + self.live_ranges = live_ranges + self.longevity = live_ranges.longevity + self.last_real_usage = live_ranges.last_real_usage self.rm = gpr_reg_mgr_cls(self.longevity, frame_manager = self.fm, assembler = self.assembler) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit