Go slightly further with the serialization.
Chris Pressey
4 years ago
83 | 83 |
fa.find_cycles()
|
84 | 84 |
|
85 | 85 |
routines_list = fa.serialize()
|
86 | |
#dump('serialization', routines_list)
|
|
86 |
dump('serialization', routines_list)
|
87 | 87 |
|
88 | 88 |
if options.analyze_only:
|
89 | 89 |
return
|
17 | 17 |
self.debug = debug
|
18 | 18 |
|
19 | 19 |
def analyze_program(self, program):
|
|
20 |
self.program = program
|
20 | 21 |
fall_in_map = {}
|
21 | 22 |
for routine in program.routines:
|
22 | 23 |
encountered_gotos = list(routine.encountered_gotos)
|
|
56 | 57 |
for value in values:
|
57 | 58 |
assert value not in self.fall_out_map
|
58 | 59 |
self.fall_out_map[value] = key
|
|
60 |
for routine in self.program.routines:
|
|
61 |
if routine.name not in self.fall_out_map:
|
|
62 |
self.fall_out_map[routine.name] = None
|
59 | 63 |
|
60 | 64 |
routine_list = []
|
61 | 65 |
fall_out_map = copy(self.fall_out_map)
|
62 | 66 |
while fall_out_map:
|
63 | 67 |
key = fall_out_map.keys()[0]
|
64 | |
# ...
|
|
68 |
in_set = self.fall_in_map.get(key, [])
|
65 | 69 |
# 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.
|
|
70 |
# TODO implement this
|
|
71 |
routines = [key]
|
|
72 |
|
66 | 73 |
# 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]
|
|
74 |
for r in routines:
|
|
75 |
del fall_out_map[r]
|
|
76 |
if r == routines[-1]:
|
|
77 |
routine_list.append(['retain', r])
|
|
78 |
else:
|
|
79 |
routine_list.append(['fallthru', r])
|
69 | 80 |
|
70 | 81 |
return routine_list
|
69 | 69 |
| {
|
70 | 70 |
| }
|
71 | 71 |
= {}
|
|
72 |
= *** serialization:
|
|
73 |
= [
|
|
74 |
= [
|
|
75 |
= "retain",
|
|
76 |
= "main"
|
|
77 |
= ]
|
|
78 |
= ]
|
72 | 79 |
|
73 | 80 |
If main does a `goto foo`, then it can fall through to `foo`.
|
74 | 81 |
|
|
86 | 93 |
= "main"
|
87 | 94 |
= ]
|
88 | 95 |
= }
|
|
96 |
= *** serialization:
|
|
97 |
= [
|
|
98 |
= [
|
|
99 |
= "fallthru",
|
|
100 |
= "main"
|
|
101 |
= ],
|
|
102 |
= [
|
|
103 |
= "retain",
|
|
104 |
= "foo"
|
|
105 |
= ]
|
|
106 |
= ]
|
89 | 107 |
|
90 | 108 |
More than one routine can fall through to a routine.
|
91 | 109 |
|
|
112 | 130 |
= "main"
|
113 | 131 |
= ]
|
114 | 132 |
= }
|
|
133 |
= *** serialization:
|
|
134 |
= [
|
|
135 |
= [
|
|
136 |
= "fallthru",
|
|
137 |
= "main"
|
|
138 |
= ],
|
|
139 |
= [
|
|
140 |
= "retain",
|
|
141 |
= "foo"
|
|
142 |
= ],
|
|
143 |
= [
|
|
144 |
= "retain",
|
|
145 |
= "bar"
|
|
146 |
= ]
|
|
147 |
= ]
|
115 | 148 |
|
116 | 149 |
There is nothing stopping two routines from tail-calling each
|
117 | 150 |
other, but we will only be able to make one of them, at most,
|
|
151 | 184 |
= "foo"
|
152 | 185 |
= ]
|
153 | 186 |
= }
|
|
187 |
= *** serialization:
|
|
188 |
= [
|
|
189 |
= [
|
|
190 |
= "retain",
|
|
191 |
= "main"
|
|
192 |
= ],
|
|
193 |
= [
|
|
194 |
= "fallthru",
|
|
195 |
= "bar"
|
|
196 |
= ],
|
|
197 |
= [
|
|
198 |
= "retain",
|
|
199 |
= "foo"
|
|
200 |
= ]
|
|
201 |
= ]
|
154 | 202 |
|
155 | 203 |
If a routine does two tail calls (which is possible because they
|
156 | 204 |
can be in different branches of an `if`) it cannot fall through to another
|
|
175 | 223 |
| }
|
176 | 224 |
| }
|
177 | 225 |
= {}
|
|
226 |
= *** serialization:
|
|
227 |
= [
|
|
228 |
= [
|
|
229 |
= "retain",
|
|
230 |
= "main"
|
|
231 |
= ],
|
|
232 |
= [
|
|
233 |
= "retain",
|
|
234 |
= "bar"
|
|
235 |
= ],
|
|
236 |
= [
|
|
237 |
= "retain",
|
|
238 |
= "foo"
|
|
239 |
= ]
|
|
240 |
= ]
|
178 | 241 |
|
179 | 242 |
Similarly, a tail call to a vector can't be turned into a fallthru,
|
180 | 243 |
because we don't necessarily know what actual routine the vector contains.
|
|
198 | 261 |
| goto vec
|
199 | 262 |
| }
|
200 | 263 |
= {}
|
|
264 |
= *** serialization:
|
|
265 |
= [
|
|
266 |
= [
|
|
267 |
= "retain",
|
|
268 |
= "main"
|
|
269 |
= ],
|
|
270 |
= [
|
|
271 |
= "retain",
|
|
272 |
= "bar"
|
|
273 |
= ],
|
|
274 |
= [
|
|
275 |
= "retain",
|
|
276 |
= "foo"
|
|
277 |
= ]
|
|
278 |
= ]
|