First cut at serialization of fallthru-optimized routines.
Chris Pressey
6 years ago
58 | 58 |
analyzer.analyze_program(program)
|
59 | 59 |
|
60 | 60 |
if options.optimize_fallthru:
|
|
61 |
from sixtypical.fallthru import FallthruAnalyzer
|
|
62 |
|
61 | 63 |
def dump(label, data):
|
62 | 64 |
import json
|
63 | 65 |
if not options.dump_fallthru_info:
|
|
67 | 69 |
sys.stdout.write(json.dumps(data, indent=4, sort_keys=True))
|
68 | 70 |
sys.stdout.write("\n")
|
69 | 71 |
|
70 | |
from sixtypical.fallthru import FallthruAnalyzer
|
71 | |
|
72 | 72 |
fa = FallthruAnalyzer(debug=options.debug)
|
73 | 73 |
fa.analyze_program(program)
|
74 | 74 |
dump(None, fa.fall_in_map)
|
|
81 | 81 |
fa.break_cycle()
|
82 | 82 |
dump('after breaking cycle', fa.fall_in_map)
|
83 | 83 |
fa.find_cycles()
|
|
84 |
|
|
85 |
routines_list = fa.serialize()
|
|
86 |
#dump('serialization', routines_list)
|
84 | 87 |
|
85 | 88 |
if options.analyze_only:
|
86 | 89 |
return
|
0 | 0 |
# encoding: UTF-8
|
|
1 |
|
|
2 |
from copy import copy
|
1 | 3 |
|
2 | 4 |
from sixtypical.model import RoutineType
|
3 | 5 |
|
|
49 | 51 |
self.fall_in_map = new_fall_in_map
|
50 | 52 |
|
51 | 53 |
def serialize(self):
|
52 | |
raise NotImplementedError
|
|
54 |
self.fall_out_map = {}
|
|
55 |
for key, values in self.fall_in_map.iteritems():
|
|
56 |
for value in values:
|
|
57 |
assert value not in self.fall_out_map
|
|
58 |
self.fall_out_map[value] = key
|
|
59 |
|
|
60 |
routine_list = []
|
|
61 |
fall_out_map = copy(self.fall_out_map)
|
|
62 |
while fall_out_map:
|
|
63 |
key = fall_out_map.keys()[0]
|
|
64 |
# ...
|
|
65 |
# 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.
|
|
66 |
# 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."
|
|
67 |
#
|
|
68 |
del fall_out_map[key]
|
|
69 |
|
|
70 |
return routine_list
|
33 | 33 |
|
34 | 34 |
But they do permit cycles.
|
35 | 35 |
|
36 | |
So, we first break those cycles. We will be left with out() sets which
|
37 | |
are disjoint trees, i.e. if r1 ∈ in(r2), then r1 ∉ in(r3) for all r3 ≠ r2.
|
|
36 |
So, we first break those cycles. (Is there a "best" way to do this?
|
|
37 |
Perhaps. But for now, we just break them arbitrarily; pick a r1 that
|
|
38 |
has a cycle and remove it from in(r2) for all r2. This also means
|
|
39 |
that, now, out(r1) = ∅. Then check if there are still cycles, and keep
|
|
40 |
picking one and breaking it until there are no cycles remaining.)
|
|
41 |
|
|
42 |
We will be left with out() sets which are disjoint trees, i.e.
|
|
43 |
if r1 ∈ in(r2), then r1 ∉ in(r3) for all r3 ≠ r2. Also,
|
|
44 |
out(r1) = ∅ → for all r2, r1 ∉ in(r2).
|
38 | 45 |
|
39 | 46 |
We then follow an algorithm something like this. Treat R as a mutable
|
40 | 47 |
set and start with an empty list L. Then,
|