frompypy.translator.simplifyimportget_funcobjfrompypy.jit.metainterpimporthistoryfrompypy.rpython.lltypesystemimportlltype,rclassfrompypy.tool.udirimportudirimportpy,sysfrompypy.tool.ansi_printimportansi_loglog=py.log.Producer('jitcodewriter')py.log.setconsumer('jitcodewriter',ansi_log)classJitPolicy(object):def__init__(self):self.unsafe_loopy_graphs=set()self.supports_floats=Falseself.supports_longlong=Falsedefset_supports_floats(self,flag):self.supports_floats=flagdefset_supports_longlong(self,flag):self.supports_longlong=flagdefdump_unsafe_loops(self):f=udir.join("unsafe-loops.txt").open('w')strs=[str(graph)forgraphinself.unsafe_loopy_graphs]strs.sort()forgraphinstrs:print>>f,graphf.close()deflook_inside_function(self,func):returnTrue# look into everything by defaultdef_reject_function(self,func):ifhasattr(func,'_jit_look_inside_'):returnnotfunc._jit_look_inside_# explicitly pure functions are always opaqueifgetattr(func,'_pure_function_',False):returnTrue# pypy.rpython.module.* are opaque helpersmod=func.__module__or'?'ifmod.startswith('pypy.rpython.module.'):returnTrueifmod.startswith('pypy.translator.'):# XXX wtf?returnTrue# string builder interfaceifmod=='pypy.rpython.lltypesystem.rbuilder':returnTruereturnFalsedeflook_inside_graph(self,graph):frompypy.translator.backendopt.supportimportfind_backedgescontains_loop=bool(find_backedges(graph))try:func=graph.funcexceptAttributeError:see_function=Trueelse:see_function=(self.look_inside_function(func)andnotself._reject_function(func))contains_loop=contains_loopandnotgetattr(func,'_jit_unroll_safe_',False)unsupported=contains_unsupported_variable_type(graph,self.supports_floats,self.supports_longlong)res=see_functionandnotunsupportedifresandcontains_loop:self.unsafe_loopy_graphs.add(graph)res=resandnotcontains_loopif(see_functionandnotresandgetattr(graph,"access_directly",False)):# This happens when we have a function which has an argument with# the access_directly flag, and the annotator has determined we will# see the function. (See# pypy/annotation/specialize.py:default_specialize) However,# look_inside_graph just decided that we will not see it. (It has a# loop or unsupported variables.) If we return False, the call will# be turned into a residual call, but the graph is access_directly!# If such a function is called and accesses a virtualizable, the JIT# will not notice, and the virtualizable will fall out of sync. So,# we fail loudly now.raiseValueError("access_directly on a function which we don't see %s"%graph)returnresdefcontains_unsupported_variable_type(graph,supports_floats,supports_longlong):getkind=history.getkindtry:forblockingraph.iterblocks():forvinblock.inputargs:getkind(v.concretetype,supports_floats,supports_longlong)foropinblock.operations:forvinop.args:getkind(v.concretetype,supports_floats,supports_longlong)v=op.resultgetkind(v.concretetype,supports_floats,supports_longlong)exceptNotImplementedError,e:log.WARNING('%s, ignoring graph'%(e,))log.WARNING(' %s'%(graph,))returnTruereturnFalse# ____________________________________________________________classStopAtXPolicy(JitPolicy):def__init__(self,*funcs):JitPolicy.__init__(self)self.funcs=funcsdeflook_inside_function(self,func):returnfuncnotinself.funcs