Exemple #1
0
 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)))
Exemple #2
0
    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
Exemple #3
0
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'])
Exemple #4
0
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'])
Exemple #5
0
 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)
Exemple #6
0
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'])
Exemple #7
0
 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)
Exemple #8
0
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()
Exemple #9
0
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)
Exemple #10
0
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)
Exemple #11
0
    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)
Exemple #12
0
 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()))
Exemple #13
0
 def __init__(self, id_: int):
     try:
         self.id_ = id_
         self.id_pool.register(self)
     except ValueError as e:
         messages.error_message(e)
Exemple #14
0
def check_arguments(args: Namespace):
    if not args.budget and args.policy == InstrumentationPolicy.none:
        error_message('Either choose an instrumentation budget or policy.')
Exemple #15
0
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
Exemple #16
0
 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_))