[pypy-commit] pypy conditional_call_value_3: Random tests for cond_call_value.
arigo
pypy.commits at gmail.com
Mon Sep 12 05:33:00 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: conditional_call_value_3
Changeset: r87024:4eff2cbf173d
Date: 2016-09-12 11:31 +0200
http://bitbucket.org/pypy/pypy/changeset/4eff2cbf173d/
Log: Random tests for cond_call_value.
diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py
--- a/rpython/jit/backend/test/test_ll_random.py
+++ b/rpython/jit/backend/test/test_ll_random.py
@@ -594,7 +594,7 @@
return subset, d['f'], vtableptr
def getresulttype(self):
- if self.opnum == rop.CALL_I:
+ if self.opnum == rop.CALL_I or self.opnum == rop.COND_CALL_VALUE_I:
return lltype.Signed
elif self.opnum == rop.CALL_F:
return lltype.Float
@@ -709,10 +709,13 @@
builder.loop.operations.append(op)
# 6. a conditional call (for now always with no exception raised)
-class CondCallOperation(BaseCallOperation):
+class BaseCondCallOperation(BaseCallOperation):
def produce_into(self, builder, r):
fail_subset = builder.subset_of_intvars(r)
- v_cond = builder.get_bool_var(r)
+ if self.opnum == rop.COND_CALL:
+ v_cond = builder.get_bool_var(r)
+ else:
+ v_cond = r.choice(builder.intvars)
subset = builder.subset_of_intvars(r)[:4]
for i in range(len(subset)):
if r.random() < 0.35:
@@ -724,8 +727,10 @@
seen.append(args)
else:
assert seen[0] == args
+ if self.RESULT_TYPE is lltype.Signed:
+ return len(args) - 42000
#
- TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
+ TP = lltype.FuncType([lltype.Signed] * len(subset), self.RESULT_TYPE)
ptr = llhelper(lltype.Ptr(TP), call_me)
c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
args = [v_cond, c_addr] + subset
@@ -736,6 +741,14 @@
op.setfailargs(fail_subset)
builder.loop.operations.append(op)
+class CondCallOperation(BaseCondCallOperation):
+ RESULT_TYPE = lltype.Void
+ opnum = rop.COND_CALL
+
+class CondCallValueOperation(BaseCondCallOperation):
+ RESULT_TYPE = lltype.Signed
+ opnum = rop.COND_CALL_VALUE_I
+
# ____________________________________________________________
OPERATIONS = test_random.OPERATIONS[:]
@@ -769,6 +782,7 @@
for i in range(2):
OPERATIONS.append(GuardClassOperation(rop.GUARD_CLASS))
OPERATIONS.append(CondCallOperation(rop.COND_CALL))
+ OPERATIONS.append(CondCallValueOperation(rop.COND_CALL_VALUE_I))
OPERATIONS.append(RaisingCallOperation(rop.CALL_N))
OPERATIONS.append(RaisingCallOperationGuardNoException(rop.CALL_N))
OPERATIONS.append(RaisingCallOperationWrongGuardException(rop.CALL_N))
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
@@ -946,11 +946,17 @@
arglocs = [self.loc(args[i]) for i in range(2, len(args))]
gcmap = self.get_gcmap()
if op.type == 'v':
- # a plain COND_CALL
+ # a plain COND_CALL. Calls the function when args[0] is
+ # true. Often used just after a comparison operation.
self.load_condition_into_cc(op.getarg(0))
resloc = None
else:
- # COND_CALL_VALUE_I/R
+ # COND_CALL_VALUE_I/R. Calls the function when args[0]
+ # is equal to 0 or NULL. Returns the result from the
+ # function call if done, or args[0] if it was not 0/NULL.
+ # Implemented by forcing the result to live in the same
+ # register as args[0], and overwriting it if we really do
+ # the call.
condvalue_loc = self.loc(args[0])
assert not isinstance(condvalue_loc, ImmedLoc)
self.assembler.test_location(condvalue_loc)
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -101,6 +101,18 @@
if condbox.getint():
do_call_n(cpu, metainterp, argboxes[1:], descr)
+def do_cond_call_value_i(cpu, metainterp, argboxes, descr):
+ value = argboxes[0].getint()
+ if value == 0:
+ value = do_call_i(cpu, metainterp, argboxes[1:], descr)
+ return value
+
+def do_cond_call_value_r(cpu, metainterp, argboxes, descr):
+ value = argboxes[0].getref_base()
+ if not value:
+ value = do_call_r(cpu, metainterp, argboxes[1:], descr)
+ return value
+
def do_getarrayitem_gc_i(cpu, _, arraybox, indexbox, arraydescr):
array = arraybox.getref_base()
index = indexbox.getint()
More information about the pypy-commit
mailing list