from dataclasses import dataclass from typing import Dict, List, Optional from gcovreader import GCovFile, GCovLine from opfinderreader import OperationLogReader, OperationLog @dataclass(frozen=True) class UniqueOperation: name: str type_lhs: Optional[str] type_rhs: Optional[str] type_expr: Optional[str] @staticmethod def from_operation_log(op_log: OperationLog) -> "UniqueOperation": return UniqueOperation( op_log.operation, op_log.operand_lhs, op_log.operand_rhs, op_log.operand_result ) if __name__ == "__main__": gcov = GCovFile("./data/gcov.json") ops = OperationLogReader("./data/opfinder.json") gcov.read() ops.read() for file_name in gcov.files: op_counter: Dict[UniqueOperation, int] = {} if file_name not in ops.files: print(f"Couldn't find {file_name} in op-finder output. Skipping.") continue loop_stack: List[int] = [] for gcov_line in gcov.files[file_name]: op_lines = ops.get_lines(file_name, gcov_line.line_number) for opfinder_line in op_lines: # TODO: revise this. Need a special case for for-loop clauses # or branching in general. if opfinder_line.is_fallthrough != gcov_line.is_fallthrough: continue unique_op = UniqueOperation.from_operation_log(opfinder_line) if unique_op in op_counter: op_counter[unique_op] += gcov_line.count else: op_counter[unique_op] = gcov_line.count print(f"Unique operations for file {file_name}:") for uop, count in op_counter.items(): print(f"\t{count}: {uop}")