<s> from pypy . objspace . flow . model import Variable , Constant , Block , Link <EOL> from pypy . objspace . flow . model import SpaceOperation , traverse <EOL> from pypy . tool . algo . unionfind import UnionFind <EOL> from pypy . rpython . lltypesystem import lltype <EOL> from pypy . rpython . ootypesystem import ootype <EOL> from pypy . translator import simplify <EOL> from pypy . translator . backendopt import removenoops <EOL> from pypy . translator . backendopt . support import log <EOL> class LifeTime : <EOL> def __init__ ( self , ( block , var ) ) : <EOL> assert isinstance ( var , Variable ) <EOL> self . variables = { ( block , var ) : True } <EOL> self . creationpoints = { } <EOL> self . usepoints = { } <EOL> def absorb ( self , other ) : <EOL> self . variables . update ( other . variables ) <EOL> self . creationpoints . update ( other . creationpoints ) <EOL> self . usepoints . update ( other . usepoints ) <EOL> class BaseMallocRemover ( object ) : <EOL> IDENTITY_OPS = ( '<STR_LIT>' , ) <EOL> SUBSTRUCT_OPS = ( ) <EOL> MALLOC_OP = None <EOL> FIELD_ACCESS = { } <EOL> SUBSTRUCT_ACCESS = { } <EOL> CHECK_ARRAY_INDEX = { } <EOL> def __init__ ( self , verbose = True ) : <EOL> self . verbose = verbose <EOL> def check_malloc ( self , op ) : <EOL> return op . opname == self . MALLOC_OP <EOL> def recreate_malloc ( self , c , v ) : <EOL> return SpaceOperation ( self . MALLOC_OP , [ c ] , v ) <EOL> def get_STRUCT ( self , TYPE ) : <EOL> raise NotImplementedError <EOL> def visit_substruct_op ( self , node , union , op ) : <EOL> raise NotImplementedError <EOL> def do_substruct_access ( self , op ) : <EOL> raise NotImplementedError <EOL> def union_wrapper ( self , S ) : <EOL> return False <EOL> def RTTI_dtor ( self , STRUCT ) : <EOL> return False <EOL> def flatten ( self , S ) : <EOL> raise NotImplementedError <EOL> def key_for_field_access ( self , S , fldname ) : <EOL> raise NotImplementedError <EOL> def inline_type ( self , TYPE ) : <EOL> raise NotImplementedError <EOL> def flowin ( self , block , count , vars , newvarsmap ) : <EOL> self . last_removed_access = None <EOL> def list_newvars ( ) : <EOL> return [ newvarsmap [ key ] for key in self . flatnames ] <EOL> assert block . operations != ( ) <EOL> self . newops = [ ] <EOL> for op in block . operations : <EOL> for arg in op . args [ <NUM_LIT:1> : ] : <EOL> assert arg not in vars <EOL> if op . args and op . args [ <NUM_LIT:0> ] in vars : <EOL> self . flowin_op ( op , vars , newvarsmap ) <EOL> elif op . result in vars : <EOL> assert op . opname == self . MALLOC_OP <EOL> progress = True <EOL> newvarsmap = self . flatconstants . copy ( ) <EOL> for key in self . needsubmallocs : <EOL> v = Variable ( ) <EOL> v . concretetype = self . newvarstype [ key ] <EOL> c = Constant ( v . concretetype . TO , lltype . Void ) <EOL> if c . value == op . args [ <NUM_LIT:0> ] . value : <EOL> progress = False <EOL> newop = self . recreate_malloc ( c , v ) <EOL> self . newops . append ( newop ) <EOL> newvarsmap [ key ] = v <EOL> count [ <NUM_LIT:0> ] += progress <EOL> else : <EOL> self . newops . append ( op ) <EOL> assert block . exitswitch not in vars <EOL> for link in block . exits : <EOL> appended = False <EOL> newargs = [ ] <EOL> for arg in link . args : <EOL> if arg in vars : <EOL> if not appended : <EOL> newargs += list_newvars ( ) <EOL> appended = True <EOL> else : <EOL> newargs . append ( arg ) <EOL> link . args [ : ] = newargs <EOL> self . insert_keepalives ( list_newvars ( ) ) <EOL> block . operations [ : ] = self . newops <EOL> def compute_lifetimes ( self , graph ) : <EOL> """<STR_LIT>""" <EOL> lifetimes = UnionFind ( LifeTime ) <EOL> def set_creation_point ( block , var , * cp ) : <EOL> _ , _ , info = lifetimes . find ( ( block , var ) ) <EOL> info . creationpoints [ cp ] = True <EOL> def set_use_point ( block , var , * up ) : <EOL> _ , _ , info = lifetimes . find ( ( block , var ) ) <EOL> info . usepoints [ up ] = True <EOL> def union ( block1 , var1 , block2 , var2 ) : <EOL> if isinstance ( var1 , Variable ) : <EOL> lifetimes . union ( ( block1 , var1 ) , ( block2 , var2 ) ) <EOL> elif isinstance ( var1 , Constant ) : <EOL> set_creation_point ( block2 , var2 , "<STR_LIT>" , var1 ) <EOL> else : <EOL> raise TypeError ( var1 ) <EOL> for var in graph . startblock . inputargs : <EOL> set_creation_point ( graph . startblock , var , "<STR_LIT>" ) <EOL> set_use_point ( graph . returnblock , graph . returnblock . inputargs [ <NUM_LIT:0> ] , "<STR_LIT>" ) <EOL> set_use_point ( graph . exceptblock , graph . exceptblock . inputargs [ <NUM_LIT:0> ] , "<STR_LIT>" ) <EOL> set_use_point ( graph . exceptblock , graph . exceptblock . inputargs [ <NUM_LIT:1> ] , "<STR_LIT>" ) <EOL> def visit ( node ) : <EOL> if isinstance ( node , Block ) : <EOL> for op in node . operations : <EOL> if op . opname in self . IDENTITY_OPS : <EOL> union ( node , op . args [ <NUM_LIT:0> ] , node , op . result ) <EOL> continue <EOL> if op . opname in self . SUBSTRUCT_OPS : <EOL> if self . visit_substruct_op ( node , union , op ) : <EOL> continue <EOL> for i in range ( len ( op . args ) ) : <EOL> if isinstance ( op . args [ i ] , Variable ) : <EOL> set_use_point ( node , op . args [ i ] , "<STR_LIT>" , node , op , i ) <EOL> set_creation_point ( node , op . result , "<STR_LIT>" , node , op ) <EOL> if isinstance ( node . exitswitch , Variable ) : <EOL> set_use_point ( node , node . exitswitch , "<STR_LIT>" , node ) <EOL> if isinstance ( node , Link ) : <EOL> if isinstance ( node . last_exception , Variable ) : <EOL> set_creation_point ( node . prevblock , node . last_exception , <EOL> "<STR_LIT>" ) <EOL> if isinstance ( node . last_exc_value , Variable ) : <EOL> set_creation_point ( node . prevblock , node . last_exc_value , <EOL> "<STR_LIT>" ) <EOL> d = { } <EOL> for i , arg in enumerate ( node . args ) : <EOL> union ( node . prevblock , arg , <EOL> node . target , node . target . inputargs [ i ] ) <EOL> if isinstance ( arg , Variable ) : <EOL> if arg in d : <EOL> set_use_point ( node . prevblock , arg , "<STR_LIT>" , node , i ) <EOL> else : <EOL> d [ arg ] = True <EOL> traverse ( visit , graph ) <EOL> return lifetimes . infos ( ) <EOL> def _try_inline_malloc ( self , info ) : <EOL> """<STR_LIT>""" <EOL> lltypes = { } <EOL> for cp in info . creationpoints : <EOL> if cp [ <NUM_LIT:0> ] != "<STR_LIT>" : <EOL> return False <EOL> op = cp [ <NUM_LIT:2> ] <EOL> if not self . check_malloc ( op ) : <EOL> return False <EOL> if not self . inline_type ( op . args [ <NUM_LIT:0> ] . value ) : <EOL> return False <EOL> lltypes [ op . result . concretetype ] = True <EOL> if len ( lltypes ) != <NUM_LIT:1> : <EOL> return False <EOL> STRUCT = self . get_STRUCT ( lltypes . keys ( ) [ <NUM_LIT:0> ] ) <EOL> self . accessed_substructs = { } <EOL> for up in info . usepoints : <EOL> if up [ <NUM_LIT:0> ] != "<STR_LIT>" : <EOL> return False <EOL> kind , node , op , index = up <EOL> if index != <NUM_LIT:0> : <EOL> return False <EOL> if op . opname in self . CHECK_ARRAY_INDEX : <EOL> if not isinstance ( op . args [ <NUM_LIT:1> ] , Constant ) : <EOL> return False <EOL> if op . opname in self . FIELD_ACCESS : <EOL> pass <EOL> elif op . opname in self . SUBSTRUCT_ACCESS : <EOL> self . do_substruct_access ( op ) <EOL> else : <EOL> return False <EOL> if self . RTTI_dtor ( STRUCT ) : <EOL> return False <EOL> if self . union_wrapper ( STRUCT ) : <EOL> return False <EOL> self . flatnames = [ ] <EOL> self . flatconstants = { } <EOL> self . needsubmallocs = [ ] <EOL> self . newvarstype = { } <EOL> self . direct_fieldptr_key = { } <EOL> self . flatten ( STRUCT ) <EOL> assert len ( self . direct_fieldptr_key ) <= <NUM_LIT:1> <EOL> variables_by_block = { } <EOL> for block , var in info . variables : <EOL> vars = variables_by_block . setdefault ( block , { } ) <EOL> vars [ var ] = True <EOL> count = [ <NUM_LIT:0> ] <EOL> for block , vars in variables_by_block . items ( ) : <EOL> newvarsmap = None <EOL> newinputargs = [ ] <EOL> inputvars = { } <EOL> for var in block . inputargs : <EOL> if var in vars : <EOL> inputvars [ var ] = None <EOL> if newvarsmap is None : <EOL> newvarsmap = { } <EOL> for key in self . flatnames : <EOL> newvar = Variable ( ) <EOL> newvar . concretetype = self . newvarstype [ key ] <EOL> newvarsmap [ key ] = newvar <EOL> newinputargs . append ( newvar ) <EOL> else : <EOL> newinputargs . append ( var ) <EOL> block . inputargs [ : ] = newinputargs <EOL> if inputvars : <EOL> self . flowin ( block , count , inputvars , newvarsmap ) <EOL> vars_created_here = [ ] <EOL> for op in block . operations : <EOL> if self . check_malloc ( op ) and op . result in vars : <EOL> vars_created_here . append ( op . result ) <EOL> for var in vars_created_here : <EOL> self . flowin ( block , count , { var : True } , newvarsmap = None ) <EOL> return count [ <NUM_LIT:0> ] <EOL> def remove_mallocs_once ( self , graph ) : <EOL> """<STR_LIT>""" <EOL> simplify . remove_identical_vars ( graph ) <EOL> lifetimes = self . compute_lifetimes ( graph ) <EOL> progress = <NUM_LIT:0> <EOL> for info in lifetimes : <EOL> progress += self . _try_inline_malloc ( info ) <EOL> return progress <EOL> def remove_simple_mallocs ( self , graph ) : <EOL> """<STR_LIT>""" <EOL> tot = <NUM_LIT:0> <EOL> while True : <EOL> count = self . remove_mallocs_once ( graph ) <EOL> if count : <EOL> if self . verbose : <EOL> log . malloc ( '<STR_LIT>' % ( count , graph . name ) ) <EOL> else : <EOL> log . dot ( ) <EOL> tot += count <EOL> else : <EOL> break <EOL> return tot <EOL> class LLTypeMallocRemover ( BaseMallocRemover ) : <EOL> IDENTITY_OPS = ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> SUBSTRUCT_OPS = ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> MALLOC_OP = "<STR_LIT>" <EOL> FIELD_ACCESS = dict . fromkeys ( [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] ) <EOL> SUBSTRUCT_ACCESS = dict . fromkeys ( [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] ) <EOL> CHECK_ARRAY_INDEX = dict . fromkeys ( [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] ) <EOL> def check_malloc ( self , op ) : <EOL> if op . opname == '<STR_LIT>' : <EOL> flags = op . args [ <NUM_LIT:1> ] . value <EOL> if flags == { '<STR_LIT>' : '<STR_LIT>' } : <EOL> return True <EOL> return False <EOL> def recreate_malloc ( self , c , v ) : <EOL> return SpaceOperation ( self . MALLOC_OP , [ c , <EOL> Constant ( { '<STR_LIT>' : '<STR_LIT>' } , <EOL> lltype . Void ) ] , <EOL> v ) <EOL> def get_STRUCT ( self , TYPE ) : <EOL> STRUCT = TYPE . TO <EOL> assert isinstance ( STRUCT , lltype . GcStruct ) <EOL> return STRUCT <EOL> def visit_substruct_op ( self , node , union , op ) : <EOL> S = op . args [ <NUM_LIT:0> ] . concretetype . TO <EOL> if self . equivalent_substruct ( S , op . args [ <NUM_LIT:1> ] . value ) : <EOL> union ( node , op . args [ <NUM_LIT:0> ] , node , op . result ) <EOL> return True <EOL> return False <EOL> def do_substruct_access ( self , op ) : <EOL> S = op . args [ <NUM_LIT:0> ] . concretetype . TO <EOL> name = op . args [ <NUM_LIT:1> ] . value <EOL> if not isinstance ( name , str ) : <EOL> name = '<STR_LIT>' % ( name , ) <EOL> self . accessed_substructs [ S , name ] = True <EOL> def inline_type ( self , TYPE ) : <EOL> return True <EOL> def equivalent_substruct ( self , S , fieldname ) : <EOL> if not isinstance ( S , lltype . GcStruct ) : <EOL> return False <EOL> if fieldname != S . _names [ <NUM_LIT:0> ] : <EOL> return False <EOL> FIELDTYPE = S . _flds [ fieldname ] <EOL> if isinstance ( FIELDTYPE , lltype . GcStruct ) : <EOL> if FIELDTYPE . _hints . get ( '<STR_LIT>' ) : <EOL> return False <EOL> return True <EOL> if len ( S . _names ) == <NUM_LIT:1> : <EOL> return True <EOL> return False <EOL> def union_wrapper ( self , S ) : <EOL> if not isinstance ( S , lltype . GcStruct ) : <EOL> return False <EOL> assert not S . _hints . get ( '<STR_LIT>' ) <EOL> return ( len ( S . _names ) == <NUM_LIT:1> and <EOL> isinstance ( S . _flds [ S . _names [ <NUM_LIT:0> ] ] , lltype . Struct ) and <EOL> S . _flds [ S . _names [ <NUM_LIT:0> ] ] . _hints . get ( '<STR_LIT>' ) ) <EOL> def RTTI_dtor ( self , STRUCT ) : <EOL> try : <EOL> destr_ptr = lltype . getRuntimeTypeInfo ( STRUCT ) . _obj . destructor_funcptr <EOL> if destr_ptr : <EOL> return True <EOL> except ( ValueError , AttributeError ) , e : <EOL> pass <EOL> return False <EOL> def flatten ( self , S ) : <EOL> start = <NUM_LIT:0> <EOL> if S . _names and self . equivalent_substruct ( S , S . _names [ <NUM_LIT:0> ] ) : <EOL> SUBTYPE = S . _flds [ S . _names [ <NUM_LIT:0> ] ] <EOL> if isinstance ( SUBTYPE , lltype . Struct ) : <EOL> self . flatten ( SUBTYPE ) <EOL> start = <NUM_LIT:1> <EOL> else : <EOL> ARRAY = lltype . FixedSizeArray ( SUBTYPE , <NUM_LIT:1> ) <EOL> self . direct_fieldptr_key [ ARRAY , '<STR_LIT>' ] = S , S . _names [ <NUM_LIT:0> ] <EOL> for name in S . _names [ start : ] : <EOL> key = S , name <EOL> FIELDTYPE = S . _flds [ name ] <EOL> if key in self . accessed_substructs : <EOL> self . needsubmallocs . append ( key ) <EOL> self . flatnames . append ( key ) <EOL> self . newvarstype [ key ] = lltype . Ptr ( lltype . GcStruct ( '<STR_LIT>' , <EOL> ( '<STR_LIT:data>' , FIELDTYPE ) ) ) <EOL> elif not isinstance ( FIELDTYPE , lltype . ContainerType ) : <EOL> example = FIELDTYPE . _defl ( ) <EOL> constant = Constant ( example ) <EOL> constant . concretetype = FIELDTYPE <EOL> self . flatconstants [ key ] = constant <EOL> self . flatnames . append ( key ) <EOL> self . newvarstype [ key ] = FIELDTYPE <EOL> def key_for_field_access ( self , S , fldname ) : <EOL> if isinstance ( S , lltype . FixedSizeArray ) : <EOL> if not isinstance ( fldname , str ) : <EOL> fldname = '<STR_LIT>' % ( fldname , ) <EOL> try : <EOL> return self . direct_fieldptr_key [ S , fldname ] <EOL> except KeyError : <EOL> pass <EOL> return S , fldname <EOL> def handle_unreachable ( self , v_result ) : <EOL> from pypy . rpython . lltypesystem . rstr import string_repr <EOL> msg = "<STR_LIT>" <EOL> ll_msg = string_repr . convert_const ( msg ) <EOL> c_msg = Constant ( ll_msg , lltype . typeOf ( ll_msg ) ) <EOL> return SpaceOperation ( "<STR_LIT>" , [ c_msg ] , v_result ) <EOL> def flowin_op ( self , op , vars , newvarsmap ) : <EOL> if op . opname in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> S = op . args [ <NUM_LIT:0> ] . concretetype . TO <EOL> fldname = op . args [ <NUM_LIT:1> ] . value <EOL> key = self . key_for_field_access ( S , fldname ) <EOL> if key not in newvarsmap : <EOL> newop = self . handle_unreachable ( op . result ) <EOL> elif key in self . accessed_substructs : <EOL> c_name = Constant ( '<STR_LIT:data>' , lltype . Void ) <EOL> newop = SpaceOperation ( "<STR_LIT>" , <EOL> [ newvarsmap [ key ] , c_name ] , <EOL> op . result ) <EOL> else : <EOL> newop = SpaceOperation ( "<STR_LIT>" , <EOL> [ newvarsmap [ key ] ] , <EOL> op . result ) <EOL> self . newops . append ( newop ) <EOL> self . last_removed_access = len ( self . newops ) <EOL> elif op . opname in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> S = op . args [ <NUM_LIT:0> ] . concretetype . TO <EOL> fldname = op . args [ <NUM_LIT:1> ] . value <EOL> key = self . key_for_field_access ( S , fldname ) <EOL> if key not in newvarsmap : <EOL> newop = self . handle_unreachable ( op . result ) <EOL> self . newops . append ( newop ) <EOL> elif key in self . accessed_substructs : <EOL> c_name = Constant ( '<STR_LIT:data>' , lltype . Void ) <EOL> newop = SpaceOperation ( "<STR_LIT>" , <EOL> [ newvarsmap [ key ] , c_name , op . args [ <NUM_LIT:2> ] ] , <EOL> op . result ) <EOL> self . newops . append ( newop ) <EOL> else : <EOL> newvarsmap [ key ] = op . args [ <NUM_LIT:2> ] <EOL> self . last_removed_access = len ( self . newops ) <EOL> elif op . opname in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> vars [ op . result ] = True <EOL> elif op . opname == '<STR_LIT>' : <EOL> self . last_removed_access = len ( self . newops ) <EOL> elif op . opname in ( "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" ) : <EOL> S = op . args [ <NUM_LIT:0> ] . concretetype . TO <EOL> fldname = op . args [ <NUM_LIT:1> ] . value <EOL> if op . opname == "<STR_LIT>" : <EOL> fldname = '<STR_LIT>' % fldname <EOL> equiv = self . equivalent_substruct ( S , fldname ) <EOL> if equiv : <EOL> assert op . result not in vars <EOL> vars [ op . result ] = True <EOL> else : <EOL> if op . opname == "<STR_LIT>" : <EOL> opname = "<STR_LIT>" <EOL> else : <EOL> opname = "<STR_LIT>" <EOL> try : <EOL> v = newvarsmap [ S , fldname ] <EOL> except KeyError : <EOL> newop = self . handle_unreachable ( op . result ) <EOL> else : <EOL> cname = Constant ( '<STR_LIT:data>' , lltype . Void ) <EOL> newop = SpaceOperation ( opname , <EOL> [ v , cname ] , <EOL> op . result ) <EOL> self . newops . append ( newop ) <EOL> elif op . opname in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> c = Constant ( op . opname == "<STR_LIT>" , lltype . Bool ) <EOL> newop = SpaceOperation ( '<STR_LIT>' , [ c ] , op . result ) <EOL> self . newops . append ( newop ) <EOL> else : <EOL> raise AssertionError , op . opname <EOL> def insert_keepalives ( self , newvars ) : <EOL> if self . last_removed_access is not None : <EOL> keepalives = [ ] <EOL> for v in newvars : <EOL> T = v . concretetype <EOL> if isinstance ( T , lltype . Ptr ) and T . _needsgc ( ) : <EOL> v0 = Variable ( ) <EOL> v0 . concretetype = lltype . Void <EOL> newop = SpaceOperation ( '<STR_LIT>' , [ v ] , v0 ) <EOL> keepalives . append ( newop ) <EOL> self . newops [ self . last_removed_access : self . last_removed_access ] = keepalives <EOL> class OOTypeMallocRemover ( BaseMallocRemover ) : <EOL> IDENTITY_OPS = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> SUBSTRUCT_OPS = ( ) <EOL> MALLOC_OP = '<STR_LIT>' <EOL> FIELD_ACCESS = dict . fromkeys ( [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ] ) <EOL> SUBSTRUCT_ACCESS = { } <EOL> CHECK_ARRAY_INDEX = { } <EOL> def get_STRUCT ( self , TYPE ) : <EOL> return TYPE <EOL> def union_wrapper ( self , S ) : <EOL> return False <EOL> def RTTI_dtor ( self , STRUCT ) : <EOL> return False <EOL> def inline_type ( self , TYPE ) : <EOL> return isinstance ( TYPE , ( ootype . Record , ootype . Instance ) ) <EOL> def _get_fields ( self , TYPE ) : <EOL> if isinstance ( TYPE , ootype . Record ) : <EOL> return TYPE . _fields <EOL> elif isinstance ( TYPE , ootype . Instance ) : <EOL> return TYPE . _allfields ( ) <EOL> else : <EOL> assert False <EOL> def flatten ( self , TYPE ) : <EOL> for name , ( FIELDTYPE , default ) in self . _get_fields ( TYPE ) . iteritems ( ) : <EOL> key = self . key_for_field_access ( TYPE , name ) <EOL> constant = Constant ( default ) <EOL> constant . concretetype = FIELDTYPE <EOL> self . flatconstants [ key ] = constant <EOL> self . flatnames . append ( key ) <EOL> self . newvarstype [ key ] = FIELDTYPE <EOL> def key_for_field_access ( self , S , fldname ) : <EOL> CLS , TYPE = S . _lookup_field ( fldname ) <EOL> return CLS , fldname <EOL> def flowin_op ( self , op , vars , newvarsmap ) : <EOL> if op . opname == "<STR_LIT>" : <EOL> S = op . args [ <NUM_LIT:0> ] . concretetype <EOL> fldname = op . args [ <NUM_LIT:1> ] . value <EOL> key = self . key_for_field_access ( S , fldname ) <EOL> newop = SpaceOperation ( "<STR_LIT>" , <EOL> [ newvarsmap [ key ] ] , <EOL> op . result ) <EOL> self . newops . append ( newop ) <EOL> last_removed_access = len ( self . newops ) <EOL> elif op . opname == "<STR_LIT>" : <EOL> S = op . args [ <NUM_LIT:0> ] . concretetype <EOL> fldname = op . args [ <NUM_LIT:1> ] . value <EOL> key = self . key_for_field_access ( S , fldname ) <EOL> assert key in newvarsmap <EOL> newvarsmap [ key ] = op . args [ <NUM_LIT:2> ] <EOL> last_removed_access = len ( self . newops ) <EOL> elif op . opname in ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ) : <EOL> vars [ op . result ] = True <EOL> elif op . opname in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> c = Constant ( op . opname == "<STR_LIT>" , lltype . Bool ) <EOL> newop = SpaceOperation ( '<STR_LIT>' , [ c ] , op . result ) <EOL> self . newops . append ( newop ) <EOL> else : <EOL> raise AssertionError , op . opname <EOL> def insert_keepalives ( self , newvars ) : <EOL> pass <EOL> def remove_simple_mallocs ( graph , type_system = '<STR_LIT>' , verbose = True ) : <EOL> if type_system == '<STR_LIT>' : <EOL> remover = LLTypeMallocRemover ( verbose ) <EOL> else : <EOL> remover = OOTypeMallocRemover ( verbose ) <EOL> return remover . remove_simple_mallocs ( graph ) <EOL> def remove_mallocs ( translator , graphs = None , type_system = "<STR_LIT>" ) : <EOL> if graphs is None : <EOL> graphs = translator . graphs <EOL> tot = <NUM_LIT:0> <EOL> for graph in graphs : <EOL> count = remove_simple_mallocs ( graph , type_system = type_system , verbose = translator . config . translation . verbose ) <EOL> if count : <EOL> removenoops . remove_same_as ( graph ) <EOL> simplify . eliminate_empty_blocks ( graph ) <EOL> simplify . transform_dead_op_vars ( graph , translator ) <EOL> tot += count <EOL> log . malloc ( "<STR_LIT>" % tot ) <EOL> return tot </s>
