89 lines
2.5 KiB
Python
Executable File
89 lines
2.5 KiB
Python
Executable File
#!/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()
|