git @ Cat's Eye Technologies SixtyPical / 87a2f70
First cut at constructing a call graph. Chris Pressey 2 years ago
3 changed file(s) with 20 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
4848 if options.dump_exit_contexts:
4949 sys.stdout.write(json.dumps(analyzer.exit_contexts_map, indent=4, sort_keys=True, separators=(',', ':')))
5050 sys.stdout.write("\n")
51
52 if options.dump_callgraph:
53 for routine in program.routines:
54 sys.stdout.write('-----------\n')
55 sys.stdout.write('{}\n'.format(routine.name))
56 for called_routine in routine.called_routines:
57 sys.stdout.write(' {}\n'.format(called_routine.name))
5158
5259 compilation_roster = None
5360 if options.optimize_fallthru:
161168 help="Dump the ordered fallthru map, in JSON, to stdout after analyzing the program."
162169 )
163170 argparser.add_argument(
171 "--dump-callgraph",
172 action="store_true",
173 help="Dump the call graph, in JSON, to stdout after analyzing the program."
174 )
175 argparser.add_argument(
164176 "--parse-only",
165177 action="store_true",
166178 help="Only parse the program; do not analyze or compile it."
142142 for routine in program.routines:
143143 context = self.analyze_routine(routine)
144144 routine.encountered_gotos = list(context.encountered_gotos()) if context else []
145 routine.called_routines = list(context.called_routines) if context else []
145146
146147 def analyze_routine(self, routine):
147148 assert isinstance(routine, Routine)
514515 type = self.get_type(instr.location)
515516 if not isinstance(type, (RoutineType, VectorType)):
516517 raise TypeMismatchError(instr, instr.location.name)
518 context.mark_as_called(instr.location)
517519 if isinstance(type, VectorType):
518520 type = type.of_type
519521 for ref in type.inputs:
3434 self._terminated = False
3535 self._gotos_encountered = set()
3636 self._pointer_assoc = dict()
37 self.called_routines = set()
3738
3839 for ref in inputs:
3940 if self.is_constant(ref):
7879 c._writeable = set(self._writeable)
7980 c._pointer_assoc = dict(self._pointer_assoc)
8081 c._gotos_encountered = set(self._gotos_encountered)
82 c.called_routines = set(self.called_routines)
8183 return c
8284
8385 def update_from(self, other):
9395 self._writeable = set(other._writeable)
9496 self._terminated = other._terminated
9597 self._pointer_assoc = dict(other._pointer_assoc)
98 self.called_routines = set(other.called_routines)
9699
97100 def each_meaningful(self):
98101 for ref in self._range.keys():
325328 return self.symtab.fetch_local_type(self.routine.name, ref.name).max_range
326329 else:
327330 return self.symtab.fetch_global_type(ref.name).max_range
331
332 def mark_as_called(self, routine):
333 self.called_routines.add(routine)