| #!/usr/bin/env python |
| # Copyright 2022 Google LLC |
| # |
| # This source code is licensed under the BSD-style license found in the |
| # LICENSE file in the root directory of this source tree. |
| |
| from pathlib import Path |
| import subprocess |
| |
| |
| # Check if `line` can be found in file. |
| def line_in_file(line, filename): |
| with open(filename) as o: |
| return any(line in l for l in o) |
| |
| |
| # Finds all the JIT generated microkernel cc files. |
| # We could use the JIT_AARCH32_SRCS and JIT_AARCH64_SRCS in BUILD too. |
| def find_jit_files(): |
| paths = list(Path('src').glob('**/*.cc')) |
| return [p for p in paths if line_in_file('Converted from', p)] |
| |
| |
| # Check that file exists. |
| def check_assembly_file_exists(filename): |
| p = Path('.') |
| assert((p / filename).exists()) |
| |
| |
| # JIT microkernel can be converted from a assembly file or a templated assembly file, gets the right "root" file. |
| def get_assembly_file_or_template(converted_from): |
| file = converted_from |
| with open(converted_from) as f: |
| for line in f.readlines(): |
| if 'Template: ' in line: |
| file = line.split()[2] |
| break |
| if file.startswith('/'): |
| file = file[len('/'):] |
| return file |
| |
| |
| # Finds the assembly file associated with the JIT file to write the LINT marker to. |
| def find_assembly_file(jit_file): |
| with jit_file.open() as f: |
| for line in f.readlines(): |
| if 'Converted from' in line: |
| converted_from = line.split()[3] |
| check_assembly_file_exists(converted_from) |
| assembly_file = get_assembly_file_or_template(converted_from) |
| return assembly_file |
| return f'{jit_file} does not have converted from' |
| |
| |
| # Writes LINT markers to `assembly_file`. |
| def write_lint_markers(assembly_file, jit_file): |
| with open(assembly_file) as f: |
| lines = f.readlines() |
| if any('LINT.IfChange' in l for l in lines): |
| # Has lint marker, check that the JIT file is found. |
| if not any(jit_file.name in l for l in lines): |
| print(f'{jit_file.name} not found in {assembly_file}') |
| assert(False) |
| return |
| |
| relative_jit_file = jit_file.name |
| # This sed script will write LINT markers that wraps the function definition in the assembly file. |
| sed_args = [ |
| 'sed', |
| '-i', |
| '-e', |
| '/# void xnn/i# LINT.IfChange', |
| '-e', |
| '/\/\/ void xnn/i# LINT.IfChange', |
| '-e', |
| f'/END_FUNCTION/a# LINT.ThenChange({relative_jit_file})', |
| assembly_file, |
| ] |
| subprocess.run(sed_args) |
| |
| |
| def main(): |
| for f in find_jit_files(): |
| write_lint_markers(find_assembly_file(f), f) |
| |
| |
| if __name__ == '__main__': |
| main() |