Ejemplo n.º 1
0
    def produce_into(self, builder, r):
        fail_subset = builder.subset_of_intvars(r)
        if self.opnum == rop.COND_CALL:
            RESULT_TYPE = lltype.Void
            v_cond = builder.get_bool_var(r)
        else:
            RESULT_TYPE = lltype.Signed
            v_cond = r.choice(builder.intvars)
        subset = builder.subset_of_intvars(r)[:4]
        for i in range(len(subset)):
            if r.random() < 0.35:
                subset[i] = ConstInt(r.random_integer())
        #
        seen = []

        def call_me(*args):
            if len(seen) == 0:
                seen.append(args)
            else:
                assert seen[0] == args
            if RESULT_TYPE is lltype.Signed:
                return len(args) - 42000

        #
        TP = lltype.FuncType([lltype.Signed] * len(subset), RESULT_TYPE)
        ptr = llhelper(lltype.Ptr(TP), call_me)
        c_addr = ConstInt(ptr2int(ptr))
        args = [v_cond, c_addr] + subset
        descr = self.getcalldescr(builder, TP)
        self.put(builder, args, descr)
        op = ResOperation(rop.GUARD_NO_EXCEPTION, [],
                          descr=builder.getfaildescr())
        op.setfailargs(fail_subset)
        builder.loop.operations.append(op)
Ejemplo n.º 2
0
    def produce_into(self, builder, r):
        fail_subset = builder.subset_of_intvars(r)
        v_cond = builder.get_bool_var(r)
        subset = builder.subset_of_intvars(r)[:4]
        for i in range(len(subset)):
            if r.random() < 0.35:
                subset[i] = ConstInt(r.random_integer())
        #
        seen = []

        def call_me(*args):
            if len(seen) == 0:
                seen.append(args)
            else:
                assert seen[0] == args

        #
        TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
        ptr = llhelper(lltype.Ptr(TP), call_me)
        c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
        args = [v_cond, c_addr] + subset
        descr = self.getcalldescr(builder, TP)
        self.put(builder, args, descr)
        op = ResOperation(rop.GUARD_NO_EXCEPTION, [],
                          descr=builder.getfaildescr())
        op.setfailargs(fail_subset)
        builder.loop.operations.append(op)
Ejemplo n.º 3
0
 def create_op(self, opnum, args, res, descr, fail_args):
     res = ResOperation(opnum, args, descr)
     if fail_args is not None:
         res.setfailargs(fail_args)
     if self._postproces:
         self._postproces(res)
     return res
Ejemplo n.º 4
0
    def transitive_imply(self, other, opt, loop):
        if self.op.getopnum() != other.op.getopnum():
            # stronger restriction, intermixing e.g. <= and < would be possible
            return None
        if self.getleftkey() is not other.getleftkey():
            return None
        if not self.rhs.is_identity():
            # stronger restriction
            return None
        # this is a valid transitive guard that eliminates the loop guard
        opnum = self.transitive_cmpop(self.cmp_op.getopnum())
        box_rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
        other_rhs = self.emit_varops(opt, other.rhs, other.cmp_op.getarg(1))
        compare = ResOperation(opnum, [box_rhs, other_rhs])
        opt.emit_operation(compare)
        # guard
        descr = CompileLoopVersionDescr()
        descr.copy_all_attributes_from(self.op.getdescr())
        descr.rd_vector_info = None # do not copy the accum list
        assert isinstance(descr, AbstractFailDescr)
        guard = ResOperation(self.op.getopnum(), [compare], descr=descr)
        guard.setfailargs(loop.label.getarglist_copy())
        opt.emit_operation(guard)

        return guard
Ejemplo n.º 5
0
 def create_op(self, opnum, args, res, descr, fail_args):
     res = ResOperation(opnum, args, descr)
     if fail_args is not None:
         res.setfailargs(fail_args)
     if self._postproces:
         self._postproces(res)
     return res
Ejemplo n.º 6
0
    def transitive_imply(self, other, opt, loop):
        if self.op.getopnum() != other.op.getopnum():
            # stronger restriction, intermixing e.g. <= and < would be possible
            return None
        if self.getleftkey() is not other.getleftkey():
            return None
        if not self.rhs.is_identity():
            # stronger restriction
            return None
        # this is a valid transitive guard that eliminates the loop guard
        opnum = self.transitive_cmpop(self.cmp_op.getopnum())
        box_rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
        other_rhs = self.emit_varops(opt, other.rhs, other.cmp_op.getarg(1))
        compare = ResOperation(opnum, [box_rhs, other_rhs])
        opt.emit_operation(compare)
        # guard
        descr = CompileLoopVersionDescr()
        descr.copy_all_attributes_from(self.op.getdescr())
        descr.rd_vector_info = None  # do not copy the accum list
        assert isinstance(descr, AbstractFailDescr)
        guard = ResOperation(self.op.getopnum(), [compare], descr=descr)
        guard.setfailargs(loop.label.getarglist_copy())
        opt.emit_operation(guard)

        return guard
Ejemplo n.º 7
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     v_cond = builder.get_bool_var(r)
     subset = builder.subset_of_intvars(r)[:4]
     for i in range(len(subset)):
         if r.random() < 0.35:
             subset[i] = ConstInt(r.random_integer())
     #
     seen = []
     def call_me(*args):
         if len(seen) == 0:
             seen.append(args)
         else:
             assert seen[0] == args
     #
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), call_me)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [v_cond, c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 8
0
 def store_final_boxes_in_guard(self, op, pendingfields):
     assert pendingfields is not None
     descr = op.getdescr()
     assert isinstance(descr, compile.ResumeGuardDescr)
     modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
     try:
         newboxes = modifier.finish(self, pendingfields)
         if len(newboxes) > self.metainterp_sd.options.failargs_limit:
             raise resume.TagOverflow
     except resume.TagOverflow:
         raise compile.giveup()
     descr.store_final_boxes(op, newboxes)
     #
     if op.getopnum() == rop.GUARD_VALUE:
         if self.getvalue(op.getarg(0)) in self.bool_boxes:
             # Hack: turn guard_value(bool) into guard_true/guard_false.
             # This is done after the operation is emitted to let
             # store_final_boxes_in_guard set the guard_opnum field of the
             # descr to the original rop.GUARD_VALUE.
             constvalue = op.getarg(1).getint()
             if constvalue == 0:
                 opnum = rop.GUARD_FALSE
             elif constvalue == 1:
                 opnum = rop.GUARD_TRUE
             else:
                 raise AssertionError("uh?")
             newop = ResOperation(opnum, [op.getarg(0)], op.result, descr)
             newop.setfailargs(op.getfailargs())
             return newop
         else:
             # a real GUARD_VALUE.  Make it use one counter per value.
             descr.make_a_counter_per_value(op)
     return op
Ejemplo n.º 9
0
 def exc_handling(guard_op):
     # operations need to start with correct GUARD_EXCEPTION
     if guard_op._exc_box is None:
         op = ResOperation(rop.GUARD_NO_EXCEPTION, [])
     else:
         op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box])
     op.setdescr(self.builder.getfaildescr())
     op.setfailargs([])
     return op
Ejemplo n.º 10
0
 def exc_handling(guard_op):
     # operations need to start with correct GUARD_EXCEPTION
     if guard_op._exc_box is None:
         op = ResOperation(rop.GUARD_NO_EXCEPTION, [])
     else:
         op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box])
     op.setdescr(self.builder.getfaildescr())
     op.setfailargs([])
     return op
Ejemplo n.º 11
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(),
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 12
0
 def emit_operations(self, opt):
     # create trace instructions for the index
     lhs = self.emit_varops(opt, self.lhs, self.cmp_op.getarg(0))
     rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
     opnum = self.cmp_op.getopnum()
     cmp_op = ResOperation(opnum, [lhs, rhs])
     opt.emit_operation(cmp_op)
     # emit that actual guard
     guard = ResOperation(self.op.getopnum(), [cmp_op], self.op.getdescr())
     guard.setfailargs(self.op.getfailargs()[:])
     opt.emit_operation(guard)
     self.setindex(opt.operation_position()-1)
     self.setoperation(guard)
     self.setcmp(cmp_op)
Ejemplo n.º 13
0
 def emit_operations(self, opt):
     # create trace instructions for the index
     lhs = self.emit_varops(opt, self.lhs, self.cmp_op.getarg(0))
     rhs = self.emit_varops(opt, self.rhs, self.cmp_op.getarg(1))
     opnum = self.cmp_op.getopnum()
     cmp_op = ResOperation(opnum, [lhs, rhs])
     opt.emit_operation(cmp_op)
     # emit that actual guard
     guard = ResOperation(self.op.getopnum(), [cmp_op], self.op.getdescr())
     guard.setfailargs(self.op.getfailargs()[:])
     opt.emit_operation(guard)
     self.setindex(opt.operation_position() - 1)
     self.setoperation(guard)
     self.setcmp(cmp_op)
Ejemplo n.º 14
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f = self.non_raising_func_code(builder, r)
     RES = self.getresulttype()
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [],
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 15
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box],
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 16
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f = self.non_raising_func_code(builder, r)
     RES = self.getresulttype()
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstInt(ptr2int(ptr))
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [],
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 17
0
 def produce_into(self, builder, r):
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstInt(ptr2int(ptr))
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [],
                       descr=builder.getfaildescr())
     op._exc_box = ConstInt(ptr2int(exc))
     op.setfailargs(builder.subset_of_intvars(r))
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f = self.non_raising_func_code(builder, r)
     if len(subset) == 0:
         RES = lltype.Void
     else:
         RES = lltype.Signed
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
                       descr=builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 19
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     builder.fakemetainterp.ovf_flag = False
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.fakemetainterp.ovf_flag:  # overflow detected
         op = ResOperation(rop.GUARD_OVERFLOW, [])
         # the overflowed result should not be used any more, but can
         # be used on the failure path: recompute fail_subset including
         # the result, and then remove it from builder.intvars.
         fail_subset = builder.subset_of_intvars(r)
         builder.intvars[:] = original_intvars
     else:
         op = ResOperation(rop.GUARD_NO_OVERFLOW, [])
     op.setdescr(builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 20
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     builder.fakemetainterp.ovf_flag = False
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.fakemetainterp.ovf_flag:   # overflow detected
         op = ResOperation(rop.GUARD_OVERFLOW, [])
         # the overflowed result should not be used any more, but can
         # be used on the failure path: recompute fail_subset including
         # the result, and then remove it from builder.intvars.
         fail_subset = builder.subset_of_intvars(r)
         builder.intvars[:] = original_intvars
     else:
         op = ResOperation(rop.GUARD_NO_OVERFLOW, [])
     op.setdescr(builder.getfaildescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Ejemplo n.º 21
0
 def produce_into(self, builder, r):
     subset, f = self.non_raising_func_code(builder, r)
     RES = self.getresulttype()
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     _, vtableptr = builder.get_random_structure_type_and_vtable(r)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box],
                       descr=builder.getfaildescr())
     op.setfailargs(builder.subset_of_intvars(r))
     op._exc_box = None
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 22
0
 def create_op(self, opnum, args, result, descr, fail_args):
     if opnum == ESCAPE_OP.OPNUM:
         op = ESCAPE_OP(result)
         op.initarglist(args)
         assert descr is None
         return op
     if opnum == FORCE_SPILL.OPNUM:
         op = FORCE_SPILL(result)
         op.initarglist(args)
         assert descr is None
         return op
     else:
         res = ResOperation(opnum, args, result, descr)
         if fail_args is not None:
             res.setfailargs(fail_args)
         if self._postproces:
             self._postproces(res)
         return res
Ejemplo n.º 23
0
 def produce_into(self, builder, r):
     subset, f = self.non_raising_func_code(builder, r)
     RES = self.getresulttype()
     TP = lltype.FuncType([lltype.Signed] * len(subset), RES)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     _, vtableptr = builder.get_random_structure_type_and_vtable(r)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box],
                       descr=builder.getfaildescr())
     op.setfailargs(builder.subset_of_intvars(r))
     op._exc_box = None
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 24
0
 def create_op(self, opnum, args, result, descr, fail_args):
     if opnum == ESCAPE_OP.OPNUM:
         op = ESCAPE_OP(result)
         op.initarglist(args)
         assert descr is None
         return op
     if opnum == FORCE_SPILL.OPNUM:
         op = FORCE_SPILL(result)
         op.initarglist(args)
         assert descr is None
         return op
     else:
         res = ResOperation(opnum, args, result, descr)
         if fail_args is not None:
             res.setfailargs(fail_args)
         if self._postproces:
             self._postproces(res)
         return res
Ejemplo n.º 25
0
 def produce_into(self, builder, r):
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     while True:
         _, vtableptr = builder.get_random_structure_type_and_vtable(r)
         if vtableptr != exc:
             break
     other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [other_box],
                       descr=builder.getfaildescr())
     op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op.setfailargs(builder.subset_of_intvars(r))
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 26
0
 def produce_into(self, builder, r):
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     while True:
         _, vtableptr = builder.get_random_structure_type_and_vtable(r)
         if vtableptr != exc:
             break
     other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr(),
                       descr=builder.getfaildescr())
     op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op.setfailargs(builder.subset_of_intvars(r))
     builder.should_fail_by = op
     builder.guard_op = op
     builder.loop.operations.append(op)
Ejemplo n.º 27
0
 def store_final_boxes_in_guard(self, op, pendingfields):
     assert pendingfields is not None
     if op.getdescr() is not None:
         descr = op.getdescr()
         assert isinstance(descr, compile.ResumeAtPositionDescr)
     else:
         descr = compile.invent_fail_descr_for_op(op.getopnum(), self)
         op.setdescr(descr)
     assert isinstance(descr, compile.ResumeGuardDescr)
     assert isinstance(op, GuardResOp)
     modifier = resume.ResumeDataVirtualAdder(descr, op,
                                              self.resumedata_memo)
     try:
         newboxes = modifier.finish(self, pendingfields)
         if len(newboxes) > self.metainterp_sd.options.failargs_limit:
             raise resume.TagOverflow
     except resume.TagOverflow:
         raise compile.giveup()
     descr.store_final_boxes(op, newboxes, self.metainterp_sd)
     #
     if op.getopnum() == rop.GUARD_VALUE:
         if self.getvalue(op.getarg(0)) in self.bool_boxes:
             # Hack: turn guard_value(bool) into guard_true/guard_false.
             # This is done after the operation is emitted to let
             # store_final_boxes_in_guard set the guard_opnum field of the
             # descr to the original rop.GUARD_VALUE.
             constvalue = op.getarg(1).getint()
             if constvalue == 0:
                 opnum = rop.GUARD_FALSE
             elif constvalue == 1:
                 opnum = rop.GUARD_TRUE
             else:
                 raise AssertionError("uh?")
             newop = ResOperation(opnum, [op.getarg(0)], op.result, descr)
             newop.setfailargs(op.getfailargs())
             return newop
         else:
             # a real GUARD_VALUE.  Make it use one counter per value.
             descr.make_a_counter_per_value(op)
     return op