git @ Cat's Eye Technologies SixtyPical / b1bcc21
Go slightly further with the serialization. Chris Pressey 3 years ago
3 changed file(s) with 93 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
8383 fa.find_cycles()
8484
8585 routines_list = fa.serialize()
86 #dump('serialization', routines_list)
86 dump('serialization', routines_list)
8787
8888 if options.analyze_only:
8989 return
1717 self.debug = debug
1818
1919 def analyze_program(self, program):
20 self.program = program
2021 fall_in_map = {}
2122 for routine in program.routines:
2223 encountered_gotos = list(routine.encountered_gotos)
5657 for value in values:
5758 assert value not in self.fall_out_map
5859 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
5963
6064 routine_list = []
6165 fall_out_map = copy(self.fall_out_map)
6266 while fall_out_map:
6367 key = fall_out_map.keys()[0]
64 # ...
68 in_set = self.fall_in_map.get(key, [])
6569 # 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
6673 # 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])
6980
7081 return routine_list
6969 | {
7070 | }
7171 = {}
72 = *** serialization:
73 = [
74 = [
75 = "retain",
76 = "main"
77 = ]
78 = ]
7279
7380 If main does a `goto foo`, then it can fall through to `foo`.
7481
8693 = "main"
8794 = ]
8895 = }
96 = *** serialization:
97 = [
98 = [
99 = "fallthru",
100 = "main"
101 = ],
102 = [
103 = "retain",
104 = "foo"
105 = ]
106 = ]
89107
90108 More than one routine can fall through to a routine.
91109
112130 = "main"
113131 = ]
114132 = }
133 = *** serialization:
134 = [
135 = [
136 = "fallthru",
137 = "main"
138 = ],
139 = [
140 = "retain",
141 = "foo"
142 = ],
143 = [
144 = "retain",
145 = "bar"
146 = ]
147 = ]
115148
116149 There is nothing stopping two routines from tail-calling each
117150 other, but we will only be able to make one of them, at most,
151184 = "foo"
152185 = ]
153186 = }
187 = *** serialization:
188 = [
189 = [
190 = "retain",
191 = "main"
192 = ],
193 = [
194 = "fallthru",
195 = "bar"
196 = ],
197 = [
198 = "retain",
199 = "foo"
200 = ]
201 = ]
154202
155203 If a routine does two tail calls (which is possible because they
156204 can be in different branches of an `if`) it cannot fall through to another
175223 | }
176224 | }
177225 = {}
226 = *** serialization:
227 = [
228 = [
229 = "retain",
230 = "main"
231 = ],
232 = [
233 = "retain",
234 = "bar"
235 = ],
236 = [
237 = "retain",
238 = "foo"
239 = ]
240 = ]
178241
179242 Similarly, a tail call to a vector can't be turned into a fallthru,
180243 because we don't necessarily know what actual routine the vector contains.
198261 | goto vec
199262 | }
200263 = {}
264 = *** serialization:
265 = [
266 = [
267 = "retain",
268 = "main"
269 = ],
270 = [
271 = "retain",
272 = "bar"
273 = ],
274 = [
275 = "retain",
276 = "foo"
277 = ]
278 = ]