def set_entry_and_exit(self): without_predecessors = [] without_successors = [] for v in self: if v.number_of_successors() == 0: without_successors.append(v.vertexID) if v.number_of_predecessors() == 0: without_predecessors.append(v.vertexID) entryID = None if len(without_predecessors) == 0: debug.exit_message("CFG '%s' does not have an entry point" % self.name) elif len(without_predecessors) > 1: debug_info = "" for bbID in without_predecessors: bb = self.getVertex(bbID) debug_info += bb.__str__() debug.exit_message("CFG '%s' has too many entry points: %s" % (self.name, debug_info)) else: entryID = self.getNextVertexID() entryv = vertices.CFGVertex(entryID, True) self.addVertex(entryv) self.set_entryID(entryID) self.addEdge(entryID, without_predecessors[0]) exitID = None if len(without_successors) == 0: debug.exit_message("CFG '%s' does not have an exit point" % self.name) elif len(without_successors) > 1: debug_info = "" for bbID in without_successors: bb = self.getVertex(bbID) debug_info += bb.__str__() debug.exit_message("CFG '%s' has too many exit points: %s" % (self.name, debug_info)) else: exitID = self.getNextVertexID() exitv = vertices.CFGVertex(exitID, True) self.addVertex(exitv) self.set_exitID(exitID) self.addEdge(without_successors[0], exitID) assert entryID, "Unable to set entry ID" assert exitID, "Unable to set exit ID" self.addEdge(exitID, entryID)
def add_vertices(self, number_of_vertices): global next_vertexID for i in xrange(1,number_of_vertices+1): v = vertices.CFGVertex(next_vertexID) self.whole_program_CFG.addVertex(v) self.directedg.addVertex(v) self.disconnected_vertices.append(next_vertexID) next_vertexID += 1
def second_pass(filename, program): # Build the CFGs data = database.Database() cfg = None bb = None with open(filename) as the_file: for line in the_file: line = line.lower() if line.startswith(cfg_lexeme): names = name_regex.findall(line) assert len( names) == 2, "Too many names found '%s'" % ' '.join(names) cfg = program.cfgs[names[1]] data.function_data[cfg.name] = database.FunctionData() elif line.startswith(basic_block_lexeme): assert cfg, "Found basic block but current CFG is null" ids = int_regex.findall(line) assert len( ids ) == 1, "Too many identifiers found '%s'" % ' '.join(ids) assert ids[0].isdigit( ), "Vertex identifier '%s' is not an integer" % ids[0] bb = vertices.CFGVertex(int(ids[0])) cfg.addVertex(bb) elif line.startswith(successors_lexeme): assert bb, "Found edge but current basic block is null" edges = edges_regex.findall(line) for edge in edges: a_tuple = edge_tuple_regex.findall(edge) assert len( a_tuple ) == 2, "Too many components in edge tuple: %s" % edge assert a_tuple[1].isdigit( ), "Successor identifier '%s' is not an integer" % a_tuple[ 1] if a_tuple[0] == cfg.name: bb.add_successor(int(a_tuple[1])) else: program.callg.addEdge(cfg.name, a_tuple[0], bb.vertexID) cfg.add_call_site(bb.vertexID, a_tuple[0]) elif line.startswith(wcet_lexeme): values = int_regex.findall(line) assert len( values ) == 1, "Too many values found '%s'" % ' '.join(values) assert values[0].isdigit( ), "WCET value '%s' is not an integer" % values[0] data.function_data[cfg.name].basic_block_WCETs[ bb.vertexID] = int(values[0]) elif line.startswith(upper_bound_lexeme): bound_tuple = int_regex.findall(line) data.function_data[cfg.name].upper_bounds_on_headers[ bb.vertexID] = map(int, bound_tuple) return data
def parse_file(): program = programs.Program() icfg = None bb = None with open(config.Arguments.program_file) as f: for line in f: line = line.lower() if line.startswith('cfg:'): lexemes = shlex.split(line) assert len(lexemes) == 2, "Unable to parse CFG line %s" % line icfg = cfgs.ICFG() function_name = lexemes[-1] icfg.name = function_name debug.debug_message("Found new ICFG '%s'" % function_name, __name__, 1) elif line.startswith('bb:'): assert icfg, "Found basic block but current ICFG is null" lexemes = shlex.split(line) assert len(lexemes) == 2, "Unable to parse basic block line %s" % line vertexID = lexemes[-1] assert vertexID.isdigit(), "Vertex identifier '%s' is not an integer" % vertexID bb = vertices.CFGVertex(int(vertexID), False) icfg.addVertex(bb) elif line.startswith('ipoint'): assert bb, "Trying to add an Ipoint to a basic block but current basic block is null" index = line.index(':') position = line[index+1:].replace(' ', '').strip().lower() icfg.ipoint_positions[bb.vertexID] = position elif line.startswith('succ:'): assert bb, "Found edge but current basic block is null" index = line.index(':') line = line[index+1:] splitter = shlex.shlex(line) splitter.whitespace += ')' splitter.whitespace += '(' splitter.whitespace_split = False lexemes = list(splitter) assert len(lexemes) % 3 == 0, "Unable to parse edge information '%s'" % line if len(lexemes) > 1: index = 0 for lex in lexemes: if index % 3 == 0: function_name = lexemes[index] assert function_name == icfg.name, "Call edge found which is currently not handled" elif index % 3 == 2: succID = lexemes[index] assert succID.isdigit(), "Successor identifier '%s' is not an integer" % succID bb.add_successor(int(succID)) index += 1 assert icfg, "Attempting to analyse ICFG but current ICFG is null" icfg.add_predecessor_edges() icfg.set_entry_and_exit() program.add_ICFG(icfg) return program
def instrument_using_depth_first_spanning_tree(self): dfs = trees.DepthFirstSearch(self, self.entryID) edges_to_remove = set() for v in self: for succID in v.successors.keys(): if not dfs.hasEdge(v.vertexID, succID) \ and (v.vertexID, succID) != (self.exitID, self.entryID): edges_to_remove.add((v.vertexID, succID)) new_vertexID = self.getNextVertexID() newv = vertices.CFGVertex(new_vertexID, True) self.the_vertices[new_vertexID] = newv self.addEdge(v.vertexID, new_vertexID) self.addEdge(new_vertexID, succID) for predID, succID in edges_to_remove: self.removeEdge(predID, succID)
def add_edges_between_ipoints(self): bb_to_ipoint = {} for v in self: if v.vertexID in self.ipoint_positions: new_vertexID = self.getNextVertexID() newv = vertices.CFGVertex(new_vertexID, True) self.the_vertices[new_vertexID] = newv bb_to_ipoint[v] = newv for bb, ipoint in bb_to_ipoint.items(): if self.ipoint_positions[bb.vertexID] == vertices.ipoint_at_start: for predID in bb.predecessors.keys(): self.addEdge(predID, ipoint.vertexID) self.removeEdge(predID, bb.vertexID) self.addEdge(ipoint.vertexID, bb.vertexID) else: for succID in bb.successors.keys(): self.addEdge(ipoint.vertexID, succID) self.removeEdge(bb.vertexID, succID) self.addEdge(bb.vertexID, ipoint.vertexID)
def __init__(self, cfg): directed_graphs.FlowGraph.__init__(self) self.name = cfg.name for v in cfg: newv = vertices.CFGVertex(v.vertexID, v.is_ipoint) self.the_vertices[v.vertexID] = newv if v.vertexID == cfg.get_entryID(): self.entryID = v.vertexID if v.vertexID == cfg.get_exitID(): self.exitID = v.vertexID assert self.entryID != vertices.dummyID assert self.exitID != vertices.dummyID newVertexID = 0 for v in cfg: for succID in v.successors.keys(): newVertexID -= 1 newv = vertices.CFGEdge(newVertexID, v.vertexID, succID) self.the_vertices[newVertexID] = newv self.addEdge(v.vertexID, newVertexID) self.addEdge(newVertexID, succID)
def add_vertices(self, icfg): for v in icfg: if v.is_ipoint: newv = vertices.CFGVertex(v.vertexID, True) self.the_vertices[v.vertexID] = newv