def setup(self, func): """ setup all nodes create c file for externs create ll file for c file create codewriter """ if self.standalone: func = augment_entrypoint(self.translator, func) # XXX please dont ask! from pypy.translator.c.genc import CStandaloneBuilder cbuild = CStandaloneBuilder(self.translator, func, config=self.config) c_db = cbuild.generate_graphs_for_llinterp() self.db = Database(self, self.translator) self.db.gcpolicy = GcPolicy.new(self.db, self.config) self.db.gctransformer = c_db.gctransformer # get entry point entry_point = self.get_entry_point(func) self._checkpoint('get_entry_point') # set up all nodes self.db.setup_all() self.entrynode = self.db.set_entrynode(entry_point) self._checkpoint('setup_all all nodes') # set up externs nodes self.setup_externs(c_db, self.db) self.db.setup_all() self._checkpoint('setup_all externs') self._print_node_stats() # open file & create codewriter codewriter, self.filename = self.create_codewriter() self._checkpoint('open file and create codewriter') # create ll file from c code self.generate_ll_externs(codewriter) return codewriter
def setup(self, func): """ setup all nodes create c file for externs create ll file for c file create codewriter """ # XXX please dont ask! from pypy.translator.c.genc import CStandaloneBuilder cbuild = CStandaloneBuilder(self.translator, func, config=self.config) #cbuild.stackless = self.stackless c_db = cbuild.generate_graphs_for_llinterp() self.db = Database(self, self.translator) # XXX hardcoded for now self.db.gcpolicy = GcPolicy.new(self.db, 'boehm') # get entry point entry_point = self.get_entry_point(func) self._checkpoint('get_entry_point') # set up all nodes self.db.setup_all() self.entrynode = self.db.set_entrynode(entry_point) self._checkpoint('setup_all all nodes') # set up externs nodes self.extern_decls = setup_externs(c_db, self.db) self.translator.rtyper.specialize_more_blocks() self.db.setup_all() self._checkpoint('setup_all externs') for node in self.db.getnodes(): node.post_setup_transform() self._print_node_stats() # create ll file from c code self.generate_ll_externs() self._checkpoint('setup_externs') # open file & create codewriter codewriter, self.filename = self.create_codewriter() self._checkpoint('open file and create codewriter') return codewriter
class GenLLVM(object): # see create_codewriter() below function_count = {} def __init__(self, translator, standalone): # reset counters LLVMNode.nodename_count = {} self.standalone = standalone self.translator = translator self.config = translator.config def gen_source(self, func): self._checkpoint() codewriter = self.setup(func) # write top part of llvm file self.write_headers(codewriter) codewriter.startimpl() # write bottom part of llvm file self.write_implementations(codewriter) self._checkpoint('done') codewriter.close() return self.filename def setup(self, func): """ setup all nodes create c file for externs create ll file for c file create codewriter """ # XXX please dont ask! from pypy.translator.c.genc import CStandaloneBuilder cbuild = CStandaloneBuilder(self.translator, func, config=self.config) #cbuild.stackless = self.stackless c_db = cbuild.generate_graphs_for_llinterp() self.db = Database(self, self.translator) # XXX hardcoded for now self.db.gcpolicy = GcPolicy.new(self.db, 'boehm') # get entry point entry_point = self.get_entry_point(func) self._checkpoint('get_entry_point') # set up all nodes self.db.setup_all() self.entrynode = self.db.set_entrynode(entry_point) self._checkpoint('setup_all all nodes') # set up externs nodes self.extern_decls = setup_externs(c_db, self.db) self.translator.rtyper.specialize_more_blocks() self.db.setup_all() self._checkpoint('setup_all externs') for node in self.db.getnodes(): node.post_setup_transform() self._print_node_stats() # create ll file from c code self.generate_ll_externs() self._checkpoint('setup_externs') # open file & create codewriter codewriter, self.filename = self.create_codewriter() self._checkpoint('open file and create codewriter') return codewriter def _set_wordsize(self, s): s = s.replace('UWORD', self.db.get_machine_uword()) s = s.replace( 'WORD', self.db.get_machine_word()) s = s.replace('POSTFIX', postfix()) return s def write_headers(self, codewriter): # write external function headers codewriter.header_comment('External Function Headers') codewriter.write_lines(self.llexterns_header) codewriter.header_comment("Type Declarations") # write extern type declarations self.write_extern_decls(codewriter) self._checkpoint('write externs type declarations') # write node type declarations for typ_decl in self.db.getnodes(): typ_decl.writedatatypedecl(codewriter) self._checkpoint('write data type declarations') codewriter.header_comment("Global Data") # write pbcs for typ_decl in self.db.getnodes(): typ_decl.writeglobalconstants(codewriter) self._checkpoint('write global constants') codewriter.header_comment("Function Prototypes") # write external protos codewriter.write_lines(self._set_wordsize(extdeclarations)) # write node protos for typ_decl in self.db.getnodes(): typ_decl.writedecl(codewriter) self._checkpoint('write function prototypes') def write_implementations(self, codewriter): codewriter.header_comment("Function Implementation") # write external function implementations codewriter.header_comment('External Function Implementation') codewriter.write_lines(self.llexterns_functions) codewriter.write_lines(self._set_wordsize(extfunctions)) if self.standalone: codewriter.write_lines(self._set_wordsize(extfunctions_standalone)) self.write_extern_impls(codewriter) self.write_setup_impl(codewriter) self._checkpoint('write support implentations') # write exception implementaions from pypy.translator.llvm.exception import llvm_implcode codewriter.write_lines(llvm_implcode(self.entrynode)) # write all node implementations for typ_decl in self.db.getnodes(): typ_decl.writeimpl(codewriter) self._checkpoint('write node implementations') # write entry point if there is one codewriter.comment("End of file") def get_entry_point(self, func): assert func is not None self.entrypoint = func bk = self.translator.annotator.bookkeeper ptr = getfunctionptr(bk.getdesc(func).getuniquegraph()) c = inputconst(lltype.typeOf(ptr), ptr) self.db.prepare_arg_value(c) self.entry_func_name = func.func_name return c.value._obj def generate_ll_externs(self): self.llexterns_header, self.llexterns_functions = \ generate_llfile(self.db, self.extern_decls, self.entrynode, self.standalone) def create_codewriter(self): # prevent running the same function twice in a test if self.entry_func_name in self.function_count: postfix = '_%d' % self.function_count[self.entry_func_name] self.function_count[self.entry_func_name] += 1 else: postfix = '' self.function_count[self.entry_func_name] = 1 filename = udir.join(self.entry_func_name + postfix).new(ext='.ll') f = open(str(filename), 'w') return CodeWriter(f, self.db), filename def write_extern_decls(self, codewriter): for c_name, obj in self.extern_decls: if isinstance(obj, lltype.LowLevelType): if isinstance(obj, lltype.Ptr): obj = obj.TO l = "%%%s = type %s" % (c_name, self.db.repr_type(obj)) codewriter.write_lines(l) def write_extern_impls(self, codewriter): for c_name, obj in self.extern_decls: if c_name.startswith("RPyExc_"): c_name = c_name[1:] exc_repr = self.db.repr_constant(obj)[1] write_raise_exc(c_name, exc_repr, codewriter) def write_setup_impl(self, codewriter): open_decl = "sbyte* %LLVM_RPython_StartupCode()" codewriter.openfunc(open_decl) for node in self.db.getnodes(): node.writesetupcode(codewriter) codewriter.ret("sbyte*", "null") codewriter.closefunc() def compile_module(self): assert not self.standalone modname, dirpath = buildllvm.Builder(self).make_module() mod, wrap_fun = self.get_module(modname, dirpath) return mod, wrap_fun def get_module(self, modname, dirpath): if self.config.translation.llvm.isolate: mod = Isolate((dirpath, modname)) else: from pypy.translator.tool.cbuild import import_module_from_directory mod = import_module_from_directory(dirpath, modname) wrap_fun = getattr(mod, 'pypy_' + self.entry_func_name + "_wrapper") return mod, wrap_fun def compile_standalone(self, exe_name): assert self.standalone return buildllvm.Builder(self).make_standalone(exe_name) def _checkpoint(self, msg=None): if not self.config.translation.llvm.logging: return if msg: t = (time.time() - self.starttime) log('\t%s took %02dm%02ds' % (msg, t/60, t%60)) else: log('GenLLVM:') self.starttime = time.time() def _print_node_stats(self): # disable node stats output if not self.config.translation.llvm.logging: return nodecount = {} for node in self.db.getnodes(): typ = type(node) try: nodecount[typ] += 1 except: nodecount[typ] = 1 stats = [(count, str(typ)) for typ, count in nodecount.iteritems()] stats.sort() for s in stats: log('STATS %s' % str(s))
class GenLLVM(object): # see create_codewriter() below function_count = {} def __init__(self, translator, standalone): # reset counters Node.nodename_count = {} self.eci = ExternalCompilationInfo() self.standalone = standalone self.translator = translator self.config = translator.config def gen_source(self, func): self._checkpoint("before gen source") codewriter = self.setup(func) codewriter.header_comment("Extern code") codewriter.write_lines(self.llcode) codewriter.header_comment("Type declarations") for typ_decl in self.db.gettypedefnodes(): typ_decl.writetypedef(codewriter) codewriter.header_comment("Function prototypes") for node in self.db.getnodes(): if hasattr(node, 'writedecl'): node.writedecl(codewriter) codewriter.header_comment("Prebuilt constants") for node in self.db.getnodes(): # XXX tmp if hasattr(node, "writeglobalconstants"): node.writeglobalconstants(codewriter) self._checkpoint("before definitions") codewriter.header_comment('Suppport definitions') codewriter.write_lines(extfunctions, patch=True) codewriter.header_comment('Startup definition') self.write_startup_impl(codewriter) codewriter.header_comment("Function definitions") for node in self.db.getnodes(): if hasattr(node, 'writeimpl'): node.writeimpl(codewriter) self._debug(codewriter) codewriter.comment("End of file") codewriter.close() self._checkpoint('done') return self.filename def setup(self, func): """ setup all nodes create c file for externs create ll file for c file create codewriter """ if self.standalone: func = augment_entrypoint(self.translator, func) # XXX please dont ask! from pypy.translator.c.genc import CStandaloneBuilder cbuild = CStandaloneBuilder(self.translator, func, config=self.config) c_db = cbuild.generate_graphs_for_llinterp() self.db = Database(self, self.translator) self.db.gcpolicy = GcPolicy.new(self.db, self.config) self.db.gctransformer = c_db.gctransformer # get entry point entry_point = self.get_entry_point(func) self._checkpoint('get_entry_point') # set up all nodes self.db.setup_all() self.entrynode = self.db.set_entrynode(entry_point) self._checkpoint('setup_all all nodes') # set up externs nodes self.setup_externs(c_db, self.db) self.db.setup_all() self._checkpoint('setup_all externs') self._print_node_stats() # open file & create codewriter codewriter, self.filename = self.create_codewriter() self._checkpoint('open file and create codewriter') # create ll file from c code self.generate_ll_externs(codewriter) return codewriter def setup_externs(self, c_db, db): # XXX this should be done via augmenting entrypoint exctransformer = c_db.exctransformer for obj in [ exctransformer.rpyexc_occured_ptr.value, exctransformer.rpyexc_fetch_type_ptr.value, exctransformer.rpyexc_clear_ptr.value ]: db.prepare_constant(lltype.typeOf(obj), obj) def get_entry_point(self, func): assert func is not None self.entrypoint = func bk = self.translator.annotator.bookkeeper ptr = getfunctionptr(bk.getdesc(func).getuniquegraph()) c = inputconst(lltype.typeOf(ptr), ptr) self.db.prepare_arg(c) # ensure unqiue entry node name for testing entry_node = self.db.obj2node[c.value._obj] name = entry_node.name if name in self.function_count: self.function_count[name] += 1 Node.nodename_count[name] = self.function_count[name] + 1 name += '_%d' % self.function_count[name] entry_node.name = name else: self.function_count[name] = 1 self.entry_name = name[6:] return c.value._obj def generate_ll_externs(self, codewriter): all = [] for node in self.db.getnodes(): eci = getattr(node, 'compilation_info', None) if eci: all.append(eci) self.eci = self.eci.merge(*all) ccode = generate_c(self.db, self.entrynode, self.eci, self.standalone) self.llcode = generate_ll(ccode, self.eci) self.eci = self.eci.convert_sources_to_files(being_main=True) def create_codewriter(self): # prevent running the same function twice in a test filename = udir.join(self.entry_name).new(ext='.ll') f = open(str(filename), 'w') if self.standalone: return CodeWriter(f, self.db), filename else: return CodeWriter(f, self.db, linkage=''), filename def write_startup_impl(self, codewriter): open_decl = "i8* @LLVM_RPython_StartupCode()" codewriter.openfunc(open_decl) for node in self.db.getnodes(): node.writesetupcode(codewriter) codewriter.ret("i8*", "null") codewriter.closefunc() def compile_module(self): assert not self.standalone modname, dirpath = buildllvm.Builder(self).make_module() mod, wrap_fun = self.get_module(modname, dirpath) return mod, wrap_fun def get_module(self, modname, dirpath): if self.config.translation.llvm.isolate: mod = Isolate((dirpath, modname)) else: from pypy.translator.tool.cbuild import import_module_from_directory mod = import_module_from_directory(dirpath, modname) wrap_fun = getattr(mod, 'entrypoint') return mod, wrap_fun def compile_standalone(self, exe_name): assert self.standalone return buildllvm.Builder(self).make_standalone(exe_name) def _checkpoint(self, msg=None): if not self.config.translation.llvm.logging: return if msg: t = (time.time() - self.starttime) log('\t%s took %02dm%02ds' % (msg, t / 60, t % 60)) else: log('GenLLVM:') self.starttime = time.time() def _print_node_stats(self): # disable node stats output if not self.config.translation.llvm.logging: return nodecount = {} for node in self.db.getnodes(): typ = type(node) try: nodecount[typ] += 1 except: nodecount[typ] = 1 stats = [(count, str(typ)) for typ, count in nodecount.iteritems()] stats.sort() for s in stats: log('STATS %s' % str(s)) def _debug(self, codewriter): if self.config.translation.llvm.debug: if self.db.debugstringnodes: codewriter.header_comment("Debug string") for node in self.db.debugstringnodes: node.writeglobalconstants(codewriter) print "Start" print self.db.dump_pbcs() print "End"