From 30e839033c8c4c9a7670afab58fba47795c59a82 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Wed, 4 Apr 2018 15:09:48 +0100 Subject: [PATCH] First cut at serialization of fallthru-optimized routines. --- bin/sixtypical | 7 +++++-- src/sixtypical/fallthru.py | 20 +++++++++++++++++++- tests/SixtyPical Fallthru.md | 11 +++++++++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/bin/sixtypical b/bin/sixtypical index 069b1ba..4934005 100755 --- a/bin/sixtypical +++ b/bin/sixtypical @@ -59,6 +59,8 @@ def process_input_files(filenames, options): analyzer.analyze_program(program) if options.optimize_fallthru: + from sixtypical.fallthru import FallthruAnalyzer + def dump(label, data): import json if not options.dump_fallthru_info: @@ -68,8 +70,6 @@ def process_input_files(filenames, options): sys.stdout.write(json.dumps(data, indent=4, sort_keys=True)) sys.stdout.write("\n") - from sixtypical.fallthru import FallthruAnalyzer - fa = FallthruAnalyzer(debug=options.debug) fa.analyze_program(program) dump(None, fa.fall_in_map) @@ -83,6 +83,9 @@ def process_input_files(filenames, options): dump('after breaking cycle', fa.fall_in_map) fa.find_cycles() + routines_list = fa.serialize() + #dump('serialization', routines_list) + if options.analyze_only: return diff --git a/src/sixtypical/fallthru.py b/src/sixtypical/fallthru.py index fe440cb..00c147d 100644 --- a/src/sixtypical/fallthru.py +++ b/src/sixtypical/fallthru.py @@ -1,5 +1,7 @@ # encoding: UTF-8 +from copy import copy + from sixtypical.model import RoutineType @@ -50,4 +52,20 @@ class FallthruAnalyzer(object): self.fall_in_map = new_fall_in_map def serialize(self): - raise NotImplementedError + self.fall_out_map = {} + for key, values in self.fall_in_map.iteritems(): + for value in values: + assert value not in self.fall_out_map + self.fall_out_map[value] = key + + routine_list = [] + fall_out_map = copy(self.fall_out_map) + while fall_out_map: + key = fall_out_map.keys()[0] + # ... + # Find the longest chain of routines r1,r2,...rn in R where out(r1) = {r2}, out(r2} = {r3}, ... out(rn-1) = {rn}, and rn = r. + # Remove (r1,r2,...,rn) from R and append them to L in that order. Mark (r1,r2,...rn-1) as "will have their final goto removed." + # + del fall_out_map[key] + + return routine_list diff --git a/tests/SixtyPical Fallthru.md b/tests/SixtyPical Fallthru.md index 7c4662a..81d398a 100644 --- a/tests/SixtyPical Fallthru.md +++ b/tests/SixtyPical Fallthru.md @@ -34,8 +34,15 @@ a single routine, the structures we find will be tree-like, not DAG-like. But they do permit cycles. -So, we first break those cycles. We will be left with out() sets which -are disjoint trees, i.e. if r1 ∈ in(r2), then r1 ∉ in(r3) for all r3 ≠ r2. +So, we first break those cycles. (Is there a "best" way to do this? +Perhaps. But for now, we just break them arbitrarily; pick a r1 that +has a cycle and remove it from in(r2) for all r2. This also means +that, now, out(r1) = ∅. Then check if there are still cycles, and keep +picking one and breaking it until there are no cycles remaining.) + +We will be left with out() sets which are disjoint trees, i.e. +if r1 ∈ in(r2), then r1 ∉ in(r3) for all r3 ≠ r2. Also, +out(r1) = ∅ → for all r2, r1 ∉ in(r2). We then follow an algorithm something like this. Treat R as a mutable set and start with an empty list L. Then,