Ejemplo n.º 1
0
def main(**kwargs):
    the_program = programs.IO.read(kwargs['program'])

    subprogram_trace = {}
    for trace_file in kwargs['traces']:
        name = traces.TraceFile.extract_subprogram(the_program, trace_file)
        subprogram_trace[name] = trace_file

    for subprogram in the_program:
        if subprogram.name in subprogram_trace:
            messages.debug_message('Filtering traces for {}'.format(
                subprogram.name))
            subprogram.cfg.dotify()
            ppg = graphs.ProgramPointGraph.create_from_control_flow_graph(
                subprogram.cfg)
            ppg.dotify()

            lnt = graphs.LoopNests(ppg)
            lnt.dotify()

            ipg = graphs.InstrumentationPointGraph.create(ppg, lnt)
            ipg.dotify()
            all_traces = filter_trace(ppg, ipg,
                                      subprogram_trace[subprogram.name])
            all_traces.write(ipg.trace_filename())
Ejemplo n.º 2
0
def main(**kwargs):
    the_program = program.IO.read(kwargs['program'])
    the_program.call_graph.dotify()

    if kwargs['manual']:
        program.IO.read_properties(the_program, kwargs['manual'])

    with database.Database(kwargs['database']) as db:
        db.reset()
        for subprogram in the_program:
            messages.debug_message('Creating data for {}'.format(subprogram.name))
            subprogram.cfg.dotify()
            ppg = graphs.ProgramPointGraph.create_from_control_flow_graph(subprogram.cfg)
            ppg.dotify()
            lnt = graphs.LoopNests(ppg)
            lnt.dotify()

            for v in ppg:
                if isinstance(v.program_point, vertices.Vertex):
                    default = random.randint(0, kwargs['max_wcet'])
                else:
                    default = 0

                if kwargs['manual']:
                    db.add_wcet(v, getattr(v.program_point, program.IO.WCET, default))
                else:
                    db.add_wcet(v, default)

                if lnt.is_header(v):
                    loop = lnt.find_loop(v)
                    if lnt.is_outermost_loop(loop):
                        db.add_global_wfreq(v, 1)
                    else:
                        if kwargs['manual']:
                            local_bound = getattr(v.program_point,
                                                  program.IO.LOCAL_BOUND,
                                                  random.randint(1, kwargs['max_loop_bound']))
                        else:
                            local_bound = random.randint(1, kwargs['max_loop_bound'])

                        (loop_transition,) = [predecessor_edge for predecessor_edge in lnt.predecessors(loop)
                                              if predecessor_edge.direction == edges.LoopTransition.Direction.ENTRY]
                        if loop_transition.predecessor() == lnt.entry:
                            db.add_local_wfreq(v, local_bound)
                            db.add_global_wfreq(v, local_bound)
                        else:
                            if kwargs['manual']:
                                global_bound = getattr(v.program_point,
                                                       program.IO.GLOBAL_BOUND,
                                                       random.randint(local_bound, kwargs['max_loop_bound']))
                            else:
                                global_bound = random.randint(local_bound, kwargs['max_loop_bound'])
                            db.add_local_wfreq(v, local_bound)
                            db.add_global_wfreq(v, global_bound)
Ejemplo n.º 3
0
def main(**kwargs):
    the_program = programs.IO.read(kwargs['filename'])

    for subprogram in the_program:
        messages.debug_message('Analysing CFG for {}'.format(subprogram.name))
        subprogram.cfg.dotify()
        ppg = graphs.ProgramPointGraph.create_from_control_flow_graph(subprogram.cfg)
        ppg.dotify()
        lnt = graphs.LoopNests(ppg)
        lnt.dotify()

        ast = graphs.SyntaxTree(ppg)
        ast.dotify()
Ejemplo n.º 4
0
def add_subprograms(the_program: program.Program, subprograms: int, loops: int,
                    nesting_depth: int, vertices: int, fan_out: int):
    for subprogram_name in [
            's{}'.format(i) for i in range(1, subprograms + 1)
    ]:
        messages.debug_message(
            'Creating CFG with name {}'.format(subprogram_name))
        cfg = create_control_flow_graph(the_program, loops, nesting_depth,
                                        vertices, fan_out, subprogram_name)
        cfg.dotify()
        call_vertex = graph.SubprogramVertex(graph.Vertex.get_vertex_id(),
                                             subprogram_name)
        the_program.add_subprogram(program.Subprogram(cfg, call_vertex))
Ejemplo n.º 5
0
    def induce(self, ppg, header, guarantee_single_exit=False):
        messages.debug_message('Inducing loop subgraph for header {}'.format(header))

        induced_graph = ProgramPointGraph(ppg.program, ppg.name)
        loop = self.find_loop(header)

        # Add program points in the loop body.
        for v in loop:
            induced_graph.add_vertex(v)

        # Add edges between program points in the loop body.
        for v in loop:
            for succcessor_edge in ppg.successors(v):
                if succcessor_edge.successor() in induced_graph and succcessor_edge.successor() != header:
                    induced_graph.add_edge(succcessor_edge)

        # Add program points and edges that model control flow out of loop.
        for transition_edge in self.successors(loop):
            if transition_edge.direction == edges.LoopTransition.Direction.EXIT:
                for edge in transition_edge:
                    if edge.successor() not in induced_graph:
                        induced_graph.add_vertex(edge.successor())
                    induced_graph.add_edge(edge)
            elif transition_edge.direction == edges.LoopTransition.Direction.ENTRY:
                for edge in transition_edge:
                    if edge.successor() not in induced_graph:
                        induced_graph.add_vertex(edge.successor())
                    induced_graph.add_edge(edge)

        # Add program points and edges that model control flow into the loop from inner loops.
        for transition_edge in self.predecessors(loop):
            if transition_edge.direction == edges.LoopTransition.Direction.EXIT:
                for edge in transition_edge:
                    induced_graph.add_edge(edges.TransitionEdge(transition_edge.predecessor().header, edge.successor()))

        # Set the entry of the induced graph.
        induced_graph.entry = header

        if guarantee_single_exit:
            # Set the exit of the induced graph, if instructed.
            exits = [v for v in induced_graph if len(induced_graph.successors(v)) == 0]
            if len(exits) == 1:
                (induced_graph.exit,) = exits
            else:
                dummy_program_point = vertices.ProgramPointVertex(vertices.Vertex.get_vertex_id(True),
                                                                  vertices.Vertex(vertices.Vertex.get_vertex_id()))
                induced_graph.add_vertex(dummy_program_point)
                induced_graph.exit = dummy_program_point
                for exit_program_point in exits:
                    induced_graph.add_edge(edges.TransitionEdge(exit_program_point, dummy_program_point))
        return induced_graph
Ejemplo n.º 6
0
def main(**kwargs):
    kwargs['number_of_runs'] = max(kwargs['number_of_runs'], 1)
    the_program = program.IO.read(kwargs['program'])
    for subprogram in the_program:
        messages.debug_message('Creating traces for {}'.format(subprogram.name))
        subprogram.cfg.dotify()
        ppg = graphs.ProgramPointGraph.create_from_control_flow_graph(subprogram.cfg)
        ppg.dotify()

        all_traces = traces.Traces()
        for trace_number in range(1, kwargs['number_of_runs'] + 1):
            trace = generate_trace(ppg, **kwargs)
            all_traces.append(trace)
        all_traces.write(ppg.trace_filename())
Ejemplo n.º 7
0
def add_subprograms(program: programs.Program, subprograms: int, loops: int,
                    nesting_depth: int, dense: bool, irreducible: bool,
                    number_of_vertices: int, fan_out: int):
    for subprogram_name in [
            's{}'.format(i) for i in range(1, subprograms + 1)
    ]:
        messages.debug_message(
            'Creating CFG with name {}'.format(subprogram_name))
        cfg = create_control_flow_graph(program, loops, nesting_depth, dense,
                                        irreducible, number_of_vertices,
                                        fan_out, subprogram_name)
        call_vertex = vertices.SubprogramVertex(
            vertices.Vertex.get_vertex_id(), subprogram_name)
        program.add_subprogram(programs.Subprogram(cfg, call_vertex))
Ejemplo n.º 8
0
def main(**kwargs):
    kwargs['number_of_runs'] = max(kwargs['number_of_runs'], 1)
    the_program = program.IO.read(kwargs['filename'])
    for subprogram in the_program:
        messages.debug_message('Creating traces for {}'.format(
            subprogram.name))
        ppg = graph.ProgramPointGraph.create_from_control_flow_graph(
            subprogram.cfg)
        ppg.dotify()

        all_traces = traces.Traces()
        for trace_number in range(1, kwargs['number_of_runs'] + 1):
            trace = generate_trace(ppg, **kwargs)
            all_traces.append(trace)
        all_traces.write(ppg.trace_filename())
Ejemplo n.º 9
0
def inter_procedural_analysis(prog: program.Program, policy, reinstrument, traces):
    dfs = graphs.DepthFirstSearch(prog.call_graph, prog.call_graph.root)
    for call_v in dfs.post_order():
        cfg = prog[call_v.name]
        messages.debug_message('Analysing subprogram {}'.format(cfg.name))
        dot.visualise_control_flow_graph(prog, cfg)
        ppg = graphs.ProgramPointGraph(cfg)
        dot.visualise_flow_graph(prog, ppg, '.ppg')
        ipg = graphs.InstrumentationPointGraph.create_from_policy(ppg, policy)
        ipg.reduce()
        dot.visualise_instrumentation_point_graph(prog, ipg)
        prog.add_ipg(ipg)
        for call_e in prog.call_graph.successors(call_v):
            for site in call_e.call_sites:
                print(call_v.name, call_e.successor.name, site)
Ejemplo n.º 10
0
def add_subprograms(the_program: program.Program,
                    subprograms: int,
                    loops: int,
                    nesting_depth: int,
                    number_of_vertices: int,
                    fan_out: int):
    for subprogram_name in ['s{}'.format(i) for i in range(1, subprograms+1)]:
        messages.debug_message('Creating CFG with name {}'.format(subprogram_name))
        cfg = create_control_flow_graph(the_program, loops, nesting_depth, number_of_vertices, fan_out, subprogram_name)
        cfg.dotify()
        ppg = graphs.ProgramPointGraph.create_from_control_flow_graph(cfg)
        lnt = graphs.LoopNests(ppg)
        lnt.dotify()
        call_vertex = vertices.SubprogramVertex(vertices.Vertex.get_vertex_id(), subprogram_name)
        the_program.add_subprogram(program.Subprogram(cfg, call_vertex))
Ejemplo n.º 11
0
def inter_procedural_analysis(prog: program.Program, policy, reinstrument,
                              traces):
    dfs = graph.DepthFirstSearch(prog.call_graph, prog.call_graph.root)
    for call_v in dfs.post_order():
        cfg = prog[call_v.name]
        messages.debug_message('Analysing subprogram {}'.format(cfg.name))
        dot.visualise_control_flow_graph(prog, cfg)
        ppg = graph.ProgramPointGraph(cfg)
        dot.visualise_flow_graph(prog, ppg, '.ppg')
        ipg = graph.InstrumentationPointGraph.create_from_policy(ppg, policy)
        ipg.reduce()
        dot.visualise_instrumentation_point_graph(prog, ipg)
        prog.add_ipg(ipg)
        for call_e in prog.call_graph.successors(call_v):
            for site in call_e.call_sites:
                print(call_v.name, call_e.successor.name, site)
Ejemplo n.º 12
0
def main(**kwargs):
    the_program = program.IO.read(kwargs['filename'])
    properties = program.IO.read_properties(kwargs['filename'])

    with database.Database(kwargs['database']) as db:
        db.reset()
        for subprogram in the_program:
            messages.debug_message('Creating data for {}'.format(
                subprogram.name))
            ppg = graph.ProgramPointGraph.create_from_control_flow_graph(
                subprogram.cfg)
            ppg.dotify()
            lnt = graph.LoopNests(ppg)
            lnt.dotify()

            for v in ppg:
                if not kwargs[
                        'manual_properties'] or v.program_point not in properties:
                    if isinstance(v.program_point, graph.Vertex):
                        add_automatic_wcet(db, v, kwargs['max_wcet'])
                    else:
                        db.add_wcet(v.program_point, 0)
                    add_automatic_wfreq(db, v, lnt, kwargs['max_loop_bound'])
                else:
                    if properties[v.program_point].wcet is not None:
                        db.add_wcet(v.program_point,
                                    properties[v.program_point].wcet)
                    else:
                        add_automatic_wcet(db, v, kwargs['max_wcet'])

                    if properties[v.program_point].bound is not None:
                        db.add_wfreq(v.program_point,
                                     properties[v.program_point].bound)
                    else:
                        add_automatic_wfreq(db, v, lnt,
                                            kwargs['max_loop_bound'])

            if not kwargs['manual_properties']:
                ppg.choose_instrumentation()
                for v in ppg:
                    db.set_instrumentation(v.program_point)
            else:
                for v in ppg:
                    if v.program_point in properties:
                        if properties[v.program_point].instrumentation:
                            db.set_instrumentation(v.program_point)
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
def add_instructions(program: programs.Program):
    messages.debug_message('Adding instructions')
    for subprogram in program:
        for vertex in subprogram.cfg:
            if random() < 0.05:
                number_of_instructions = randint(10, 20)
            else:
                number_of_instructions = randint(3, 8)

            if len(subprogram.cfg.successors(vertex)) == 1:
                (edge, ) = subprogram.cfg.successors(vertex)
                callee = program.call_graph.is_call_site(
                    subprogram.call_vertex, vertex)
                if callee:
                    number_of_instructions -= 1

            for count in range(1, number_of_instructions + 1):
                if len(subprogram.cfg.successors(
                        vertex)) >= 2 and count == number_of_instructions:
                    vertex.instructions.insert(
                        len(vertex.instructions),
                        instructions.BranchInstruction())
                else:
                    # Prefer arithmetic instructions over load-store instructions
                    if random() < 0.33:
                        population = [
                            instructions.LoadInstruction,
                            instructions.StoreInstruction
                        ]
                        weights = [0.5, 0.5]
                    else:
                        population = [
                            instructions.AddInstruction,
                            instructions.SubtractInstruction,
                            instructions.MultiplyInstruction,
                            instructions.DivideInstruction
                        ]
                        weights = [0.55, 0.35, 0.05, 0.05]
                    (instruction, ) = choices(population, weights=weights)
                    vertex.instructions.insert(0, instruction())
Ejemplo n.º 15
0
    def cull_unreachable(self):
        assert self.entry
        # Remove edges known to be unreachable.
        for v in self:
            for e in self.successors(v):
                if e.direction == edges.Direction.UNREACHABLE:
                    messages.debug_message("Edge {} is unreachable in subprogram '{}'".format(e, self.name))
                    self.remove_edge(e)

        # Remove vertices that cannot be reached from the entry vertex.
        dfs = DepthFirstSearch(self, self.entry)
        dead_vertices = [v for v in self if v not in dfs.pre_order()]
        for v in dead_vertices:
            messages.debug_message("Basic block {} is unreachable in subprogram '{}'".format(v, self.name))
            self.remove_vertex(v)

        # Relabel edges of branches that have been flattened.
        for v in self:
            if len(self.successors(v)) == 1:
                (sole_e,) = self.successors(v)
                if sole_e.direction == edges.Direction.ELSE or sole_e.direction == edges.Direction.THEN:
                    sole_e.direction = edges.Direction.CONTINUE
Ejemplo n.º 16
0
def main(**kwargs):
    the_program = program.IO.read(kwargs['program'])

    subprogram_trace = {}
    for trace_file in kwargs['traces']:
        name = traces.TraceFile.extract_subprogram(the_program, trace_file)
        subprogram_trace[name] = trace_file

    for subprogram in the_program:
        if subprogram.name in subprogram_trace:
            messages.debug_message('Filtering traces for {}'.format(subprogram.name))
            subprogram.cfg.dotify()
            ppg = graphs.ProgramPointGraph.create_from_control_flow_graph(subprogram.cfg)
            ppg.dotify()

            lnt = graphs.LoopNests(ppg)
            lnt.dotify()

            ipg = graphs.InstrumentationPointGraph.create(ppg, lnt)
            ipg.dotify()
            all_traces = filter_trace(ppg, ipg, subprogram_trace[subprogram.name])
            all_traces.write(ipg.trace_filename())
Ejemplo n.º 17
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)
Ejemplo n.º 18
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)
Ejemplo n.º 19
0
    def read(cls, filename: str) -> Program:
        messages.debug_message("Reading program from '{}'".format(filename))

        program = Program(filename)
        cfgs = []
        calls = []
        with open(filename) as json_file:
            program_json = json.load(json_file)
            magic_info = program_json[0]
            program.magic = magic_info[1]
            subprograms_json = program_json[1]
            for subprogram_name, (vertices_json,
                                  edges_json) in subprograms_json.items():
                cfg = graphs.ControlFlowGraph(program, subprogram_name)
                cfgs.append(cfg)

                for vertex_json in vertices_json:
                    vertex_id = int(vertex_json[0])
                    vertex = vertices.BasicBlock(int(vertex_id))
                    cfg.add_vertex(vertex)

                    instruction_json = vertex_json[1]
                    for instruction_text in instruction_json:
                        if instruction_text[
                                0] == instructions.CallInstruction.OPCODE:
                            callee = instruction_text[1]
                            calls.append([cfg.name, callee, vertex])
                            vertex.instructions.append(
                                instructions.CallInstruction(callee))
                        elif instruction_text[
                                0] == instructions.BranchInstruction.OPCODE:
                            vertex.instructions.append(
                                instructions.BranchInstruction())
                        elif instruction_text[
                                0] == instructions.StoreInstruction.OPCODE:
                            vertex.instructions.append(
                                instructions.StoreInstruction())
                        elif instruction_text[
                                0] == instructions.LoadInstruction.OPCODE:
                            vertex.instructions.append(
                                instructions.LoadInstruction())
                        elif instruction_text[
                                0] == instructions.AddInstruction.OPCODE:
                            vertex.instructions.append(
                                instructions.AddInstruction())
                        elif instruction_text[
                                0] == instructions.SubtractInstruction.OPCODE:
                            vertex.instructions.append(
                                instructions.SubtractInstruction())
                        elif instruction_text[
                                0] == instructions.MultiplyInstruction.OPCODE:
                            vertex.instructions.append(
                                instructions.MultiplyInstruction())
                        elif instruction_text[
                                0] == instructions.DivideInstruction.OPCODE:
                            vertex.instructions.append(
                                instructions.DivideInstruction())

                for edge_json in edges_json:
                    predecessor_id, successor_id = edge_json
                    predecessor = vertices.Vertex.id_pool[int(predecessor_id)]
                    successor = vertices.Vertex.id_pool[int(successor_id)]
                    cfg.add_edge(edges.ControlFlowEdge(predecessor, successor))

        for cfg in cfgs:
            call = vertices.SubprogramVertex(vertices.Vertex.get_vertex_id(),
                                             cfg.name)
            subprogram = Subprogram(cfg, call)
            program.add_subprogram(subprogram)

            for vertex in cfg:
                if len(cfg.predecessors(vertex)) == 0:
                    assert cfg.entry is None
                    cfg.entry = vertex

                if len(cfg.successors(vertex)) == 0:
                    assert cfg.exit is None
                    cfg.exit = vertex

            cfg.add_edge(edges.ControlFlowEdge(cfg.exit, cfg.entry))

        for caller, callee, site in calls:
            caller = program[caller].call_vertex
            callee = program[callee].call_vertex
            program.call_graph.add_edge(
                edges.CallGraphEdge(caller, callee, site))

        return program
Ejemplo n.º 20
0
def main(program_filename: str, repeat: int,
         subprogram_names: typing.List[str], verify: bool):
    the_program = programs.IO.read(program_filename)
    the_program.cleanup()

    messages.verbose_message(
        "Verification is {}".format("ON" if verify else "OFF"))

    analysable_subprograms = [
        subprogram for subprogram in the_program if not subprogram_names or (
            subprogram_names and subprogram.name in subprogram_names)
    ]

    results = []
    speedups = []
    slowdowns = []
    for subprogram in analysable_subprograms:
        messages.verbose_message("Analysing", subprogram.name)
        subprogram.cfg.dotify()
        betts_times = []
        tarjan_times = []
        cooper_times = []

        for i in range(0, repeat):
            subprogram.cfg.shuffle_edges()

            start = time.time()
            betts_tree = graphs.Betts(subprogram.cfg)
            betts_times.append(time.time() - start)

            start = time.time()
            tarjan_tree = graphs.LengauerTarjan(subprogram.cfg,
                                                subprogram.cfg.entry)
            tarjan_times.append(time.time() - start)

            start = time.time()
            cooper_tree = graphs.Cooper(subprogram.cfg)
            cooper_times.append(time.time() - start)

            if verify:
                messages.debug_message("Betts versus Tarjan")
                do_verification(subprogram.cfg, betts_tree, tarjan_tree)
                messages.debug_message("Cooper versus Tarjan")
                do_verification(subprogram.cfg, cooper_tree, tarjan_tree)
                messages.debug_message("Betts versus Cooper")
                do_verification(subprogram.cfg, betts_tree, cooper_tree)

        betts = Time(Algorithms.Betts, sum(betts_times) / repeat)
        cooper = Time(Algorithms.Cooper, sum(cooper_times) / repeat)
        tarjan = Time(Algorithms.Tarjan, sum(tarjan_times) / repeat)
        times = [betts, cooper, tarjan]
        times.sort(key=lambda t: t.time)
        results.append(times)

        messages.verbose_message(
            '{} vertices={} edges={} branches={} merges={}'.format(
                subprogram.name, subprogram.cfg.number_of_vertices(),
                subprogram.cfg.number_of_edges(),
                subprogram.cfg.number_of_branches(),
                subprogram.cfg.number_of_merges()))
        messages.verbose_message('{}:: {:.4f}'.format(times[0].name.value,
                                                      times[0].time))
        messages.verbose_message('{}:: {:.4f} {:.1f}X faster'.format(
            times[1].name.value, times[1].time, times[1].time / times[0].time))
        messages.verbose_message('{}:: {:.4f} {:.1f}X faster'.format(
            times[2].name.value, times[2].time, times[2].time / times[0].time))

    messages.verbose_message("======> Summary")
    for name in Algorithms:
        first = [r for r in results if r[0].name == name]
        if first:
            messages.verbose_message('{} came first {} times'.format(
                name.value, len(first)))

    for name in Algorithms:
        second = [r for r in results if r[1].name == name]
        if second:
            messages.verbose_message('{} came second {} times'.format(
                name.value, len(second)))

    for name in Algorithms:
        third = [r for r in results if r[2].name == name]
        if third:
            messages.verbose_message('{} came third {} times'.format(
                name.value, len(third)))
Ejemplo n.º 21
0
def main(**kwargs):
    the_program = programs.IO.read(kwargs['program'])
    the_program.call_graph.dotify()

    if kwargs['manual']:
        programs.IO.read_properties(the_program, kwargs['manual'])

    with database.Database(kwargs['database']) as db:
        db.reset()
        for subprogram in the_program:
            messages.debug_message('Creating data for {}'.format(
                subprogram.name))
            subprogram.cfg.dotify()
            ppg = graphs.ProgramPointGraph.create_from_control_flow_graph(
                subprogram.cfg)
            ppg.dotify()
            lnt = graphs.LoopNests(ppg)
            lnt.dotify()

            for v in ppg:
                if isinstance(v.program_point, vertices.Vertex):
                    default = random.randint(0, kwargs['max_wcet'])
                else:
                    default = 0

                if kwargs['manual']:
                    db.add_wcet(
                        v, getattr(v.program_point, programs.IO.WCET, default))
                else:
                    db.add_wcet(v, default)

                if lnt.is_header(v):
                    loop = lnt.find_loop(v)
                    if lnt.is_outermost_loop(loop):
                        db.add_global_wfreq(v, 1)
                    else:
                        if kwargs['manual']:
                            local_bound = getattr(
                                v.program_point, programs.IO.LOCAL_BOUND,
                                random.randint(1, kwargs['max_loop_bound']))
                        else:
                            local_bound = random.randint(
                                1, kwargs['max_loop_bound'])

                        (loop_transition, ) = [
                            predecessor_edge
                            for predecessor_edge in lnt.predecessors(loop)
                            if predecessor_edge.direction ==
                            edges.LoopTransition.Direction.ENTRY
                        ]
                        if loop_transition.predecessor() == lnt.entry:
                            db.add_local_wfreq(v, local_bound)
                            db.add_global_wfreq(v, local_bound)
                        else:
                            if kwargs['manual']:
                                global_bound = getattr(
                                    v.program_point, programs.IO.GLOBAL_BOUND,
                                    random.randint(local_bound,
                                                   kwargs['max_loop_bound']))
                            else:
                                global_bound = random.randint(
                                    local_bound, kwargs['max_loop_bound'])
                            db.add_local_wfreq(v, local_bound)
                            db.add_global_wfreq(v, global_bound)