Author: William ML Leslie <[email protected]>
Branch: inline-taskengine
Changeset: r89717:a174df0f5b63
Date: 2017-01-24 18:34 +1100
http://bitbucket.org/pypy/pypy/changeset/a174df0f5b63/
Log: Move goal search into translator driver
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,10 +17,12 @@
log = AnsiLogger("translation")
-
def taskdef(deps, title, new_state=None, expected_states=[],
idemp=False, earlycheck=None):
def decorator(taskfunc):
+ name = taskfunc.__name__
+ assert name.startswith('task_')
+ taskfunc.task_name = name[len('task_'):]
taskfunc.task_deps = deps
taskfunc.task_title = title
taskfunc.task_newstate = None
@@ -60,7 +61,7 @@
os._exit(0)
-class TranslationDriver(SimpleTaskEngine):
+class TranslationDriver(object):
_backend_extra_options = {}
def __init__(self, setopts=None, default_goal=None,
@@ -69,7 +70,15 @@
config=None, overrides=None):
from rpython.config import translationoption
self.timer = Timer()
- SimpleTaskEngine.__init__(self)
+ self.tasks = tasks = {}
+
+ for name in dir(self):
+ if name.startswith('task_'):
+ task = getattr(self, name)
+ assert callable(task)
+ task_deps = getattr(task, 'task_deps', [])
+
+ tasks[task.task_name] = task, task_deps
self.log = log
@@ -259,39 +268,37 @@
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)
+ def _do(self, func):
+ if func.task_name in self.done:
+ self.log.info("already done: %s" % func.task_title)
return
else:
- self.log.info("%s..." % title)
+ self.log.info("%s..." % func.task_title)
debug_start('translation-task')
- debug_print('starting', goal)
- self.timer.start_event(goal)
+ debug_print('starting', func.task_name)
+ self.timer.start_event(func.task_name)
try:
instrument = False
try:
- if goal in PROFILE:
- res = self._profile(goal, func)
+ if func.task_name in PROFILE:
+ res = self._profile(func.task_name, func)
else:
res = func()
except Instrument:
instrument = True
- if not func.task_idempotent:
- self.done[goal] = True
+ self.done[func.task_name] = True
if instrument:
self.proceed('compile')
assert False, 'we should not get here'
finally:
try:
debug_stop('translation-task')
- self.timer.end_event(goal)
+ self.timer.end_event(func.task_name)
except (KeyboardInterrupt, SystemExit):
raise
except:
- pass
- #import gc; gc.dump_rpy_heap('rpyheap-after-%s.dump' % goal)
+ pass # don't clobber any exception in progress
+ #import gc; gc.dump_rpy_heap('rpyheap-after-%s.dump' % func.task_name)
return res
@taskdef([], "Annotating&simplifying")
@@ -537,6 +544,38 @@
log.llinterpret("result -> %s" % v)
+ def _gather(self, task_name, result, skip=(), also=()):
+ task_name, = self.backend_select_goals([task_name])
+ if task_name in self.done:
+ return
+ _, deps = self.tasks[task_name]
+ for dep in deps:
+ depname = dep.lstrip('?')
+ if dep.startswith('??'):
+ if depname in also:
+ self._gather(depname, result, skip)
+ elif dep.startswith('?'):
+ if depname not in skip:
+ self._gather(depname, result, skip)
+ else:
+ self._gather(depname, result, skip)
+ result.append(task_name)
+
+ def _plan(self, goals, skip=None, also=()):
+ if skip is None:
+ skip = self._disabled
+ # gather once to determine the tasks to run, another time to
+ # determine their order, which may move a task forward if it
+ # is an optional dependency of something that appears earlier
+ # in the first plan.
+ selected_goals = []
+ for goal in goals:
+ self._gather(goal, selected_goals, skip, goals)
+ plan = []
+ for goal in selected_goals:
+ self._gather(goal, plan, skip, selected_goals)
+ return plan
+
def proceed(self, goals):
if not goals:
if self.default_goal:
@@ -546,9 +585,15 @@
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())
+ goals = self._plan(goals + self.extra_goals)
+ print goals
+ tasks = [self.tasks[goal] for goal in goals]
+ for task, _ in tasks:
+ if task.task_earlycheck:
+ task.task_earlycheck(self)
+ for task, _ in tasks:
+ self.fork_before(task.task_name)
+ result = self._do(task)
self.log.info('usession directory: %s' % (udir,))
return result
@@ -588,19 +633,17 @@
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':
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit