def __getitem__(self, item: edges.Edge or vertices.Vertex): try: if isinstance(item, vertices.Vertex): return self.__program_point_to_vertex[item] else: return self.__program_point_to_vertex[(item.predecessor(), item.successor())] except KeyError: messages.error_message('No vertex in program point graph for program point {}'.format(str(item)))
def __discover_loop_bodies(self, ppg): def do_search(v): visited.add(v) if v != header: for e in ppg.predecessors(v): where_next = containment[e.predecessor()] if where_next not in visited: do_search(where_next) order.append(v) containment = {v: v for v in ppg} data = {v: None for v in ppg} dfs = DepthFirstSearch(ppg, ppg.entry) for v in reversed(dfs.pre_order()): back_edges = [e for e in ppg.predecessors(v) if e in dfs.back_edges] if back_edges: # Sort back edges according to their post-order numbering, then reverse, so that we visit all successors # of a vertex before the vertex itself back_edges.sort(key=lambda e: dfs.post_order_number(e.predecessor()), reverse=True) order = [] visited = set() header = v tails = set() for e in back_edges: if not ppg.pre_dominator_tree().is_ancestor(e.successor(), e.predecessor()): messages.error_message( "Edge {} in '{}' identifies an irreducible loop".format(str(e.predecessor()), ppg.name)) do_search(e.predecessor()) tails.add(e.predecessor()) for w in reversed(order): containment[w] = header data[w] = header if w != header: # Propagate reachability information concerning loop tails to immediate predecessors. # We ignore the loop header so that the information does not spill out to enclosing loop. for e in ppg.predecessors(w): data[containment[e.predecessor()]] = data[w] loop_vertices = {} for w in order: # Do not add an inner loop header to the partition for this header. if w not in [loop.header for loop in self._loops]: if data[w] not in loop_vertices: loop = vertices.LoopBody(vertices.Vertex.get_vertex_id(), header) loop_vertices[data[w]] = loop self.add_vertex(loop) self._headers[header] = loop for tail in tails: self._tails[tail] = loop loop = loop_vertices[data[w]] loop.append(w) # Clear the reachability information in readiness for enclosing loops. data[header] = None
def main(**kwargs): the_program = program.IO.read(kwargs['program']) the_program.cleanup() the_program.call_graph.dotify() if not kwargs['root'] in the_program: messages.error_message("Given root subprogram '{}' does not belong to the program".format(kwargs['root'])) create_instrumentation_point_graphs(the_program) parse_trace(the_program, kwargs['root'], kwargs['trace'])
def main(**kwargs): if kwargs['vertices'] < kwargs['loops'] * 2: messages.error_message( 'The number of vertices in a control flow graph must be at least twice the number of loops' ) prog = program.Program(kwargs['filename']) add_subprograms(prog, kwargs['subprograms'], kwargs['loops'], kwargs['nesting_depth'], kwargs['vertices'], kwargs['fan_out']) if not kwargs['no_calls']: add_calls(prog, kwargs['recursion']) program.IO.write(prog, kwargs['filename'])
def launch_dot(ext): filename = os.path.splitext(dot_filename)[0] + '.' + ext messages.debug_message("Generating file '{}'".format(filename)) try: with open(filename, 'w') as out_file: cmd = ["dot", "-T", ext, dot_filename] p = subprocess.Popen(cmd, stdout=out_file) child_processes.append(p) _, _ = p.communicate() if p.returncode != 0: messages.error_message("Running '{}' failed".format(' '.join(cmd))) else: messages.debug_message("Done with '{}'".format(' '.join(cmd))) except FileNotFoundError as e: messages.debug_message(e)
def main(**kwargs): if kwargs['vertices'] < kwargs['loops'] * 2: messages.error_message( 'The number of vertices in a control flow graph must be at least twice the number of loops') the_program = program.Program(kwargs['program']) add_subprograms(the_program, kwargs['subprograms'], kwargs['loops'], kwargs['nesting_depth'], kwargs['vertices'], kwargs['fan_out']) if not kwargs['no_calls']: add_calls(the_program, kwargs['recursion']) program.IO.write(the_program, kwargs['program'])
def launch_dot(ext): filename = os.path.splitext(dot_filename)[0] + '.' + ext messages.debug_message("Generating file '{}'".format(filename)) try: with open(filename, 'w') as out_file: cmd = ["dot", "-T", ext, dot_filename] p = subprocess.Popen(cmd, stdout=out_file) child_processes.append(p) _, _ = p.communicate() if p.returncode != 0: messages.error_message("Running '{}' failed".format( ' '.join(cmd))) else: messages.debug_message("Done with '{}'".format( ' '.join(cmd))) except FileNotFoundError as e: messages.debug_message(e)
def main(args: Namespace): if args.vertices < args.loops * 2: messages.error_message( 'The number of vertices in a control flow graph must be at least twice the number of loops' ) program = programs.Program(args.program) add_subprograms(program, args.subprograms, args.loops, args.nesting_depth, args.dense, args.irreducible, args.vertices, args.fan_out) if not args.no_calls: add_calls(program, args.recursion) if not args.no_instructions: add_instructions(program) programs.IO.write(program, args.program) program.call_graph.dotify()
def do_verification(cfg: graphs.ControlFlowGraph, candidate_tree, reference_tree): messages.debug_message("Verifying...") differences = set() for v in cfg: if v != cfg.entry: (candidate, ) = candidate_tree.predecessors(v) (reference, ) = reference_tree.predecessors(v) if candidate.predecessor() != reference.predecessor(): differences.add( (v, candidate.predecessor(), reference.predecessor())) message = "Differences ({} vs {}):\n{}".format( candidate_tree.__class__.__name__, reference_tree.__class__.__name__, '\n'.join('{}=>{} {}=>{}'.format(candidate, v, reference, v) for v, candidate, reference in differences)) if differences: messages.error_message(message)
def main(args: Namespace): program = programs.IO.read(args.program) root = program.call_graph.get_root() if args.budget: if args.budget < 2 * len(program): error_message( 'Each subprogram requires at least two instrumentation points; ' 'the given program thus needs at least {}.'.format( len(program) * 2)) max_budget = sum( [subprogram.cfg.number_of_vertices() for subprogram in program]) if args.budget > max_budget: error_message( 'The maximum number of allowed instrumentation points is {}.'. format(max_budget)) with open(args.traces, 'r') as traces_file: line = traces_file.readline() line = line.strip() if line != program.magic: error_message('Traces are not generated by the given program.') verbose_message('Root is {}'.format(root.name)) dfs = graphs.DepthFirstSearch(program.call_graph, root) static_analysis(program, root, dfs) hybrid_analysis(program, root, dfs, args.traces, args.policy, args.budget)
async def define(self, ctx, word='', result=0): if not word: # Parse message arguments if word not provided args = ctx.message.content.split(' ')[1:] # Invalid argument length if len(args) == 0: return await ctx.send( "Define accepts two arguments `!string {word}` and `?int {result}`" ) # Invalid argument order if args[0].isnumeric(): return await ctx.send( "Define requires at least one argument `{word}`") # Parse word and result to return for arg in args: if arg.isnumeric(): result = int(arg) else: word += f" {arg}" # check if the word is cached word_definition = self.cache.get(f"{word}-{result}") if not word_definition: # scrape Word word_definition = scrape_word(word, result) # cache word self.cache[f"{word}-{result}"] = word_definition if "error" in word_definition: embed = error_message(word_definition["error"]) return await ctx.send(embed=embed) else: embed = define_message(word_definition) return await ctx.send(embed=embed)
def set_properties(property_string, program_point_properties): property_string = property_string.strip() property_string = property_string.lower() properties = property_string.split(',') properties = [l.split('=') for l in properties] for a_property in properties: assert len(a_property) == 2 name, value = a_property if name == Properties.INSTRUMENTATION: try: program_point_properties.INSTRUMENTATION = int(value) == 1 except ValueError: messages.error_message('Value of {} for property {} is invalid'.format(value, name.lower())) elif name == Properties.WCET: try: program_point_properties.WCET = int(value) except ValueError: messages.error_message('Value of {} for property {} is invalid'.format(value, name.lower())) elif name == Properties.BOUND: try: program_point_properties.BOUND = int(value) except ValueError: messages.error_message('Value of {} for property {} is invalid'.format(value, name.lower()))
def __init__(self, id_: int): try: self.id_ = id_ self.id_pool.register(self) except ValueError as e: messages.error_message(e)
def check_arguments(args: Namespace): if not args.budget and args.policy == InstrumentationPolicy.none: error_message('Either choose an instrumentation budget or policy.')
def parse_traces(program: programs.Program, root_vertex: vertices.SubprogramVertex, traces_filename: str, labels: Set[int], call_table: Dict[int, str], trace: List, wcet_data: Dict[str, MeasuredData], measured_times: Set[int]): sentinel = 0 root_subprogram = program[root_vertex.name] origin = ParsingPosition( root_subprogram.ipg, root_subprogram.ipg.entry, root_subprogram.lnt, root_subprogram.lnt.loop(root_subprogram.ipg.entry)) call_stack = [] position = origin for label, tick in trace: if label == sentinel and tick == sentinel: pass else: if label == root_subprogram.ipg.entry.label: assert position.vertex == root_subprogram.ipg.entry call_stack.append(position) else: intra_position_a = position chosen_edge = None for edge in position.ipg.successors(position.vertex): candidate = edge.successor() if isinstance(candidate, vertices.InstrumentationVertex): if candidate.label == label: position = ParsingPosition(position.ipg, candidate, position.lnt, position.state) intra_position_b = position chosen_edge = edge elif label in call_table: callee = call_table[label] if callee == candidate.callee: return_position = ParsingPosition( position.ipg, candidate, position.lnt, position.state) call_stack.append(return_position) intra_position_b = return_position callee_subprogram = program[callee] position = ParsingPosition( callee_subprogram.ipg, callee_subprogram.ipg.entry, callee_subprogram.lnt, callee_subprogram.lnt.loop( callee_subprogram.ipg.entry)) chosen_edge = edge if chosen_edge: subprogram_data = wcet_data[intra_position_a.ipg.name] lnt = intra_position_a.lnt loop_a = lnt.loop(intra_position_a.vertex) loop_b = lnt.loop(intra_position_b.vertex) if loop_a != loop_b and lnt.level(loop_b) >= lnt.level( loop_a): subprogram_data.temporary_counts[loop_b] += 1 elapsed = tick - before subprogram_data.times[chosen_edge] = max( subprogram_data.times[chosen_edge], elapsed) break if not chosen_edge: error_message( 'Parsing error at position {} with label {}'.format( position.vertex.id_, label)) if position.vertex == position.ipg.exit: subprogram_data = wcet_data[position.ipg.name] subprogram_data.reset_temporary_counts() position = call_stack.pop() if not call_stack: measured_times.add(tick) before = tick
def _get_vertex_data(self, v: vertices.Vertex) -> VertexData: try: return self._data[v.id_] except KeyError: messages.error_message("No data for vertex with ID {}".format(v.id_))