Author: William ML Leslie <william.leslie....@gmail.com> Branch: real-mode-translator-driver Changeset: r89723:b36e251c762f Date: 2017-01-24 21:19 +1100 http://bitbucket.org/pypy/pypy/changeset/b36e251c762f/
Log: More explicit arrangement of tasks diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -3,7 +3,6 @@ import shutil from rpython.translator.translator import TranslationContext -from rpython.translator.tool.taskengine import SimpleTaskEngine from rpython.translator.goal import query from rpython.translator.goal.timing import Timer from rpython.annotator.listdef import s_list_of_strings @@ -18,18 +17,7 @@ log = AnsiLogger("translation") - -def taskdef(deps, title, new_state=None, expected_states=[], - idemp=False, earlycheck=None): - def decorator(taskfunc): - taskfunc.task_deps = deps - taskfunc.task_title = title - taskfunc.task_newstate = None - taskfunc.task_expected_states = expected_states - taskfunc.task_idempotent = idemp - taskfunc.task_earlycheck = earlycheck - return taskfunc - return decorator +class Done(Exception): pass # TODO: # sanity-checks using states @@ -60,16 +48,13 @@ os._exit(0) -class TranslationDriver(SimpleTaskEngine): +class TranslationDriver(object): _backend_extra_options = {} - def __init__(self, setopts=None, default_goal=None, - disable=[], - exe_name=None, extmod_name=None, - config=None, overrides=None): + def __init__(self, setopts=None, default_goal=None, disable=(), + exe_name=None, config=None, overrides=None): from rpython.config import translationoption self.timer = Timer() - SimpleTaskEngine.__init__(self) self.log = log @@ -85,9 +70,8 @@ self.config.set(**setopts) self.exe_name = exe_name - self.extmod_name = extmod_name - self.done = {} + self.done = set() self.disable(disable) @@ -98,40 +82,51 @@ self.default_goal = default_goal self.extra_goals = [] - self.exposed = [] - # expose tasks - def expose_task(task, backend_goal=None): - if backend_goal is None: - backend_goal = task - def proc(): - return self.proceed(backend_goal) - self.exposed.append(task) - setattr(self, task, proc) + def annotate(self): + return self.proceed(['annotate']) - backend, ts = self.get_backend_and_type_system() - for task in self.tasks: - explicit_task = task - if task == 'annotate': - expose_task(task) - else: - task, postfix = task.split('_') - if task in ('rtype', 'backendopt', 'llinterpret', - 'pyjitpl'): - if ts: - if ts == postfix: - expose_task(task, explicit_task) - else: - expose_task(explicit_task) - elif task in ('source', 'compile', 'run'): - if backend: - if backend == postfix: - expose_task(task, explicit_task) - elif ts: - if ts == 'lltype': - expose_task(explicit_task) - else: - expose_task(explicit_task) + def rtype(self): + return self.proceed(['rtype']) + + def backendopt(self): + return self.proceed(['backendopt']) + + def llinterpret(self): + return self.proceed(['llinterpret']) + + def pyjitpl(self): + return self.proceed(['pyjitpl']) + + def rtype_lltype(self): + return self.proceed(['rtype_lltype']) + + def backendopt_lltype(self): + return self.proceed(['backendopt_lltype']) + + def llinterpret_lltype(self): + return self.proceed(['llinterpret_lltype']) + + def pyjitpl_lltype(self): + return self.proceed(['pyjitpl_lltype']) + + def source(self): + return self.proceed(['source']) + + def compile(self): + return self.proceed(['compile']) + + def run(self): + return self.proceed(['run']) + + def source_c(self): + return self.proceed(['source_c']) + + def compile_c(self): + return self.proceed(['compile_c']) + + def run_c(self): + return self.proceed(['run_c']) def set_extra_goals(self, goals): self.extra_goals = goals @@ -148,31 +143,101 @@ backend = self.config.translation.backend return backend, type_system + def run_task(self, name, goals, *args, **kwargs): + if name in self.done or name in self._disabled: + return + task = getattr(self, 'task_%s' % name) + + self.fork_before(name) + + debug_start('translation-task') + debug_print('starting', name) + self.timer.start_event(name) + try: + instrument = False + try: + if name in PROFILE: + res = self._profile(name, func) + else: + res = task(*args, **kwargs) + except Instrument: + instrument = True + if instrument: + self.proceed(['compile_c']) + assert False, 'we should not get here' + finally: + try: + debug_stop('translation-task') + self.timer.end_event(name) + except (KeyboardInterrupt, SystemExit): + raise + except: + pass + #import gc; gc.dump_rpy_heap('rpyheap-after-%s.dump' % goal) + + self.log.info('usession directory: %s' % (udir,)) + + self.done.add(name) + goals.discard(name) + if not goals: + raise Done(res) + return res + + def proceed(self, goals): + try: + self._proceed_inner(goals) + except Done as d: + return d.args[0] + + def _proceed_inner(self, goals): + backend, ts = self.get_backend_and_type_system() + goals = set(self.backend_select_goals(goals + self.extra_goals)) + + if any(cgoal in goals + for bakgoal in ['database', 'source', 'compile'] + for cgoal in [bakgoal, bakgoal + '_c']): + if 'check_for_boehm' not in self.done: + self.possibly_check_for_boehm() + self.done.add('check_for_boehm') + + self.run_task('annotate', goals) + self.run_task('rtype_lltype', goals) + if 'pyjitpl_lltype' in goals or 'jittest_lltype' in goals: + self.run_task('pyjitpl_lltype', goals) + if 'jittest_lltype' in goals: + self.run_task('jittest_lltype', goals) + self.run_task('backendopt_lltype', goals) + self.run_task('stackcheckinsertion_lltype', goals) + if 'llinterpret_lltype' in goals: + self.run_task('llinterpret_lltype', goals) + self.run_task('backend_%s' % backend, goals, goals) + + def task_backend_c(self, goals): + self.run_task('database_c', goals) + self.run_task('source_c', goals) + self.run_task('compile_c', goals) + def backend_select_goals(self, goals): backend, ts = self.get_backend_and_type_system() - postfixes = [''] + ['_'+p for p in (backend, ts) if p] - l = [] + result = [] for goal in goals: - for postfix in postfixes: - cand = "%s%s" % (goal, postfix) - if cand in self.tasks: - new_goal = cand + names = ['task_%s_%s' % (goal, backend), + 'task_%s_%s' % (goal, ts), + 'task_%s' % (goal,)] + if set(names).intersection(self.done): + continue + for name in names: + task = getattr(self, name, None) + if task is not None: + result.append(name[len('task_'):]) break else: raise Exception("cannot infer complete goal from: %r" % goal) - l.append(new_goal) - return l - + return result + def disable(self, to_disable): self._disabled = to_disable - def _maybe_skip(self): - maybe_skip = [] - if self._disabled: - for goal in self.backend_select_goals(self._disabled): - maybe_skip.extend(self._depending_on_closure(goal)) - return dict.fromkeys(maybe_skip).keys() - def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): standalone = inputtypes is None self.standalone = standalone @@ -259,42 +324,6 @@ KCacheGrind(prof).output(open(goal + ".out", "w")) return d['res'] - def _do(self, goal, func, *args, **kwds): - title = func.task_title - if goal in self.done: - self.log.info("already done: %s" % title) - return - else: - self.log.info("%s..." % title) - debug_start('translation-task') - debug_print('starting', goal) - self.timer.start_event(goal) - try: - instrument = False - try: - if goal in PROFILE: - res = self._profile(goal, func) - else: - res = func() - except Instrument: - instrument = True - if not func.task_idempotent: - self.done[goal] = True - if instrument: - self.proceed('compile') - assert False, 'we should not get here' - finally: - try: - debug_stop('translation-task') - self.timer.end_event(goal) - except (KeyboardInterrupt, SystemExit): - raise - except: - pass - #import gc; gc.dump_rpy_heap('rpyheap-after-%s.dump' % goal) - return res - - @taskdef([], "Annotating&simplifying") def task_annotate(self): """ Annotate """ @@ -336,15 +365,12 @@ lost = query.qoutput(query.check_methods_qgen(translator)) assert not lost, "lost methods, something gone wrong with the annotation of method defs" - RTYPE = 'rtype_lltype' - @taskdef(['annotate'], "RTyping") def task_rtype_lltype(self): """ RTyping - lltype version """ rtyper = self.translator.buildrtyper() rtyper.specialize(dont_simplify_again=True) - @taskdef([RTYPE], "JIT compiler generation") def task_pyjitpl_lltype(self): """ Generate bytecodes for JIT and flow the JIT helper functions lltype version @@ -362,7 +388,6 @@ # self.log.info("the JIT compiler was generated") - @taskdef([RTYPE], "test of the JIT on the llgraph backend") def task_jittest_lltype(self): """ Run with the JIT on top of the llgraph backend """ @@ -375,8 +400,6 @@ from rpython.jit.tl import jittest jittest.jittest(self) - BACKENDOPT = 'backendopt_lltype' - @taskdef([RTYPE, '??pyjitpl_lltype', '??jittest_lltype'], "lltype back-end optimisations") def task_backendopt_lltype(self): """ Run all backend optimizations - lltype version """ @@ -384,8 +407,6 @@ backend_optimizations(self.translator, replace_we_are_jitted=True) - STACKCHECKINSERTION = 'stackcheckinsertion_lltype' - @taskdef(['?'+BACKENDOPT, RTYPE, 'annotate'], "inserting stack checks") def task_stackcheckinsertion_lltype(self): from rpython.translator.transform import insert_ll_stackcheck count = insert_ll_stackcheck(self.translator) @@ -402,9 +423,6 @@ i = 'Boehm GC not installed. Try e.g. "translate.py --gc=minimark"' raise Exception(str(e) + '\n' + i) - @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'], - "Creating database for generating c source", - earlycheck = possibly_check_for_boehm) def task_database_c(self): """ Create a database for further backend generation """ @@ -427,14 +445,11 @@ functions=functions, name='libtesting', config=self.config) - if not standalone: # xxx more messy - cbuilder.modulename = self.extmod_name database = cbuilder.build_database() self.log.info("database for generating C source was created") self.cbuilder = cbuilder self.database = database - @taskdef(['database_c'], "Generating c source") def task_source_c(self): """ Create C source files from the generated database """ @@ -506,7 +521,6 @@ self.c_entryp = newexename self.log.info("created: %s" % (self.c_entryp,)) - @taskdef(['source_c'], "Compiling c source") def task_compile_c(self): """ Compile the generated C code using either makefile or translator/platform @@ -523,7 +537,6 @@ else: self.c_entryp = cbuilder.get_entry_point() - @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE], "LLInterpreting") def task_llinterpret_lltype(self): from rpython.rtyper.llinterp import LLInterpreter @@ -537,21 +550,6 @@ log.llinterpret("result -> %s" % v) - def proceed(self, goals): - if not goals: - if self.default_goal: - goals = [self.default_goal] - else: - self.log.info("nothing to do") - return - elif isinstance(goals, str): - goals = [goals] - goals.extend(self.extra_goals) - goals = self.backend_select_goals(goals) - result = self._execute(goals, task_skip = self._maybe_skip()) - self.log.info('usession directory: %s' % (udir,)) - return result - @classmethod def from_targetspec(cls, targetspec_dic, config=None, args=None, empty_translator=None, @@ -588,19 +586,16 @@ prereq_checkpt_rtype_lltype = prereq_checkpt_rtype # checkpointing support - def _event(self, kind, goal, func): - if kind == 'planned' and func.task_earlycheck: - func.task_earlycheck(self) - if kind == 'pre': - fork_before = self.config.translation.fork_before - if fork_before: - fork_before, = self.backend_select_goals([fork_before]) - if not fork_before in self.done and fork_before == goal: - prereq = getattr(self, 'prereq_checkpt_%s' % goal, None) - if prereq: - prereq() - from rpython.translator.goal import unixcheckpoint - unixcheckpoint.restartable_point(auto='run') + def fork_before(self, goal): + fork_before = self.config.translation.fork_before + if fork_before: + fork_before, = self.backend_select_goals([fork_before]) + if not fork_before in self.done and fork_before == goal: + prereq = getattr(self, 'prereq_checkpt_%s' % goal, None) + if prereq: + prereq() + from rpython.translator.goal import unixcheckpoint + unixcheckpoint.restartable_point(auto='run') def mkexename(name): if sys.platform == 'win32': diff --git a/rpython/translator/test/test_driver.py b/rpython/translator/test/test_driver.py --- a/rpython/translator/test/test_driver.py +++ b/rpython/translator/test/test_driver.py @@ -5,9 +5,6 @@ def test_ctr(): td = TranslationDriver() - expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source', - 'compile', 'pyjitpl'] - assert set(td.exposed) == set(expected) assert td.backend_select_goals(['compile_c']) == ['compile_c'] assert td.backend_select_goals(['compile']) == ['compile_c'] @@ -27,10 +24,6 @@ assert td.backend_select_goals(['backendopt_lltype']) == [ 'backendopt_lltype'] - expected = ['annotate', 'backendopt_lltype', 'llinterpret_lltype', - 'rtype_lltype', 'source_c', 'compile_c', 'pyjitpl_lltype', ] - assert set(td.exposed) == set(expected) - td = TranslationDriver({'backend': None, 'type_system': 'lltype'}) assert td.backend_select_goals(['compile_c']) == ['compile_c'] @@ -41,11 +34,6 @@ assert td.backend_select_goals(['backendopt_lltype']) == [ 'backendopt_lltype'] - expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source_c', - 'compile_c', 'pyjitpl'] - - assert set(td.exposed) == set(expected) - def test_create_exe(): if not os.name == 'nt': _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit