def test_data_flow_families(): def snippet_fn(xx, yy): while yy > 0: if 0 < xx: yy = yy - xx else: yy = yy + xx return yy t = TranslationContext() graph = t.buildflowgraph(snippet_fn) operations = [] for block in graph.iterblocks(): operations += block.operations variable_families = DataFlowFamilyBuilder(graph).get_variable_families() # we expect to find xx only once: v_xx = variable_families.find_rep(graph.getargs()[0]) found = 0 for op in operations: if op.opname in ('add', 'sub', 'lt'): assert variable_families.find_rep(op.args[1]) == v_xx found += 1 assert found == 3
def test_simple_loop(): def snippet_fn(x, y): while y > 0: y -= x return y t = TranslationContext() graph = t.buildflowgraph(snippet_fn) if option.view: t.view() loops = find_inner_loops(graph) assert len(loops) == 1 loop = loops[0] assert loop.headblock.operations[0].opname == 'gt' assert len(loop.links) == 2 assert loop.links[0] in loop.headblock.exits assert loop.links[1] in loop.links[0].target.exits assert loop.links[1].target is loop.headblock
def test_simple_compute_reachability(): def f(x): if x < 0: if x == -1: return x + 1 else: return x + 2 else: if x == 1: return x - 1 else: return x - 2 t = TranslationContext() g = t.buildflowgraph(f) reach = compute_reachability(g) assert len(reach[g.startblock]) == 7 assert len(reach[g.startblock.exits[0].target]) == 3 assert len(reach[g.startblock.exits[1].target]) == 3
def test_SSI_to_SSA(): def snippet_fn(v1, v2, v3): if v1: # v4 = is_true(v1) while v3: # v5 = is_true(v3) pass passed_over = 0 else: v6 = snippet_fn(v3, v2, v1) # v6 = simple_call(v3, v2, v1) passed_over = v6 v7 = passed_over # v7 = inputarg return v7+v1 # v8 = add(v7, v1) t = TranslationContext() graph = t.buildflowgraph(snippet_fn) SSI_to_SSA(graph) allvars = [] for block in graph.iterblocks(): allvars += [v.name for v in block.getvariables()] # see comments above for where the 8 remaining variables are expected to be assert len(dict.fromkeys(allvars)) == 8
def test_SSI_to_SSA(): def snippet_fn(v1, v2, v3): if v1: # v4 = is_true(v1) while v3: # v5 = is_true(v3) pass passed_over = 0 else: v6 = snippet_fn(v3, v2, v1) # v6 = simple_call(v3, v2, v1) passed_over = v6 v7 = passed_over # v7 = inputarg return v7 + v1 # v8 = add(v7, v1) t = TranslationContext() graph = t.buildflowgraph(snippet_fn) SSI_to_SSA(graph) allvars = [] for block in graph.iterblocks(): allvars += [v.name for v in block.getvariables()] # see comments above for where the 8 remaining variables are expected to be assert len(dict.fromkeys(allvars)) == 8
def test_measure_median_execution_cost(self): def f(x): x += 1 x += 1 x += 1 while True: x += 1 x += 1 x += 1 if x: break x += 1 x += 1 x += 1 x += 1 x += 1 x += 1 return x t = TranslationContext() graph = t.buildflowgraph(f) res = measure_median_execution_cost(graph) assert round(res, 5) == round(32.333333333, 5)
def test_nested_loops(): def snippet_fn(x, z): y = 0 while y <= 10: while z < y: z += y y += 1 return z t = TranslationContext() graph = t.buildflowgraph(snippet_fn) if option.view: t.view() loops = find_inner_loops(graph) assert len(loops) == 1 loop = loops[0] assert loop.headblock.operations[0].opname == 'lt' assert len(loop.links) == 2 assert loop.links[0] in loop.headblock.exits assert loop.links[1] in loop.links[0].target.exits assert loop.links[1].target is loop.headblock
def test_two_loops(): def snippet_fn(x, y): while y > 0: y -= x while y < 0: y += x return y t = TranslationContext() graph = t.buildflowgraph(snippet_fn) if option.view: t.view() loops = find_inner_loops(graph) assert len(loops) == 2 assert loops[0].headblock is not loops[1].headblock for loop in loops: assert loop.headblock.operations[0].opname in ('gt', 'lt') assert len(loop.links) == 2 assert loop.links[0] in loop.headblock.exits assert loop.links[1] in loop.links[0].target.exits assert loop.links[1].target is loop.headblock
def check(self, f1, expected): t = TranslationContext(list_comprehension_operations=True) graph = t.buildflowgraph(f1) if option.view: graph.show() assert summary(graph) == expected
class Translation(object): def __init__(self, entry_point, argtypes=None, **kwds): self.driver = driver.TranslationDriver(overrides=DEFAULTS) self.config = self.driver.config self.entry_point = export_symbol(entry_point) self.context = TranslationContext(config=self.config) policy = kwds.pop('policy', None) self.update_options(kwds) self.ensure_setup(argtypes, policy) # for t.view() to work just after construction graph = self.context.buildflowgraph(entry_point) self.context._prebuilt_graphs[entry_point] = graph def view(self): self.context.view() def viewcg(self): self.context.viewcg() def ensure_setup(self, argtypes=None, policy=None): standalone = argtypes is None if standalone: assert argtypes is None else: if argtypes is None: argtypes = [] self.driver.setup(self.entry_point, argtypes, policy, empty_translator=self.context) self.ann_argtypes = argtypes self.ann_policy = policy def update_options(self, kwds): gc = kwds.pop('gc', None) if gc: self.config.translation.gc = gc self.config.translation.set(**kwds) def ensure_opt(self, name, value=None, fallback=None): if value is not None: self.update_options({name: value}) return value val = getattr(self.config.translation, name, None) if fallback is not None and val is None: self.update_options({name: fallback}) return fallback if val is not None: return val raise Exception( "the %r option should have been specified at this point" % name) def ensure_type_system(self, type_system=None): if self.config.translation.backend is not None: return self.ensure_opt('type_system') return self.ensure_opt('type_system', type_system, 'lltype') def ensure_backend(self, backend=None): backend = self.ensure_opt('backend', backend) self.ensure_type_system() return backend # disable some goals (steps) def disable(self, to_disable): self.driver.disable(to_disable) def set_backend_extra_options(self, **extra_options): for name in extra_options: backend, option = name.split('_', 1) self.ensure_backend(backend) self.driver.set_backend_extra_options(extra_options) # backend independent def annotate(self, **kwds): self.update_options(kwds) return self.driver.annotate() # type system dependent def rtype(self, **kwds): self.update_options(kwds) ts = self.ensure_type_system() return getattr(self.driver, 'rtype_' + ts)() def backendopt(self, **kwds): self.update_options(kwds) ts = self.ensure_type_system('lltype') return getattr(self.driver, 'backendopt_' + ts)() # backend depedent def source(self, **kwds): self.update_options(kwds) backend = self.ensure_backend() getattr(self.driver, 'source_' + backend)() def source_c(self, **kwds): self.update_options(kwds) self.ensure_backend('c') self.driver.source_c() def source_cl(self, **kwds): self.update_options(kwds) self.ensure_backend('cl') self.driver.source_cl() def compile(self, **kwds): self.update_options(kwds) backend = self.ensure_backend() getattr(self.driver, 'compile_' + backend)() return self.driver.c_entryp def compile_c(self, **kwds): self.update_options(kwds) self.ensure_backend('c') self.driver.compile_c() return self.driver.c_entryp
def test_example(): t = TranslationContext() t.buildflowgraph(example)