Skip to content

[lldb] Format Python files in scripts and utils #66053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 42 additions & 24 deletions lldb/scripts/analyze-project-deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@
from use_lldb_suite import lldb_root

parser = argparse.ArgumentParser(
description='Analyze LLDB project #include dependencies.')
parser.add_argument('--show-counts', default=False, action='store_true',
help='When true, show the number of dependencies from each subproject')
parser.add_argument('--discover-cycles', default=False, action='store_true',
help='When true, find and display all project dependency cycles. Note,'
'this option is very slow')
description="Analyze LLDB project #include dependencies."
)
parser.add_argument(
"--show-counts",
default=False,
action="store_true",
help="When true, show the number of dependencies from each subproject",
)
parser.add_argument(
"--discover-cycles",
default=False,
action="store_true",
help="When true, find and display all project dependency cycles. Note,"
"this option is very slow",
)

args = parser.parse_args()

Expand All @@ -24,12 +33,14 @@

src_map = {}

include_regex = re.compile('#include \"((lldb|Plugins|clang)(.*/)+).*\"')
include_regex = re.compile('#include "((lldb|Plugins|clang)(.*/)+).*"')


def is_sublist(small, big):
it = iter(big)
return all(c in it for c in small)


def normalize_host(str):
if str.startswith("lldb/Host"):
return "lldb/Host"
Expand All @@ -39,6 +50,7 @@ def normalize_host(str):
return str.replace("lldb/../../source", "lldb")
return str


def scan_deps(this_dir, file):
global src_map
deps = {}
Expand All @@ -62,7 +74,8 @@ def scan_deps(this_dir, file):
if this_dir not in src_map and len(deps) > 0:
src_map[this_dir] = deps

for (base, dirs, files) in os.walk(inc_dir):

for base, dirs, files in os.walk(inc_dir):
dir = os.path.basename(base)
relative = os.path.relpath(base, inc_dir)
inc_files = [x for x in files if os.path.splitext(x)[1] in [".h"]]
Expand All @@ -71,7 +84,7 @@ def scan_deps(this_dir, file):
inc_path = os.path.join(base, inc)
scan_deps(relative, inc_path)

for (base, dirs, files) in os.walk(src_dir):
for base, dirs, files in os.walk(src_dir):
dir = os.path.basename(base)
relative = os.path.relpath(base, src_dir)
src_files = [x for x in files if os.path.splitext(x)[1] in [".cpp", ".h", ".mm"]]
Expand All @@ -82,6 +95,7 @@ def scan_deps(this_dir, file):
scan_deps(norm_base_path, src_path)
pass


def is_existing_cycle(path, cycles):
# If we have a cycle like # A -> B -> C (with an implicit -> A at the end)
# then we don't just want to check for an occurrence of A -> B -> C in the
Expand All @@ -90,12 +104,13 @@ def is_existing_cycle(path, cycles):
# at the end), then A -> B -> C is also a cycle. This is an important
# optimization which reduces the search space by multiple orders of
# magnitude.
for i in range(0,len(path)):
for i in range(0, len(path)):
if any(is_sublist(x, path) for x in cycles):
return True
path = [path[-1]] + path[0:-1]
return False


def expand(path_queue, path_lengths, cycles, src_map):
# We do a breadth first search, to make sure we visit all paths in order
# of ascending length. This is an important optimization to make sure that
Expand Down Expand Up @@ -127,54 +142,57 @@ def expand(path_queue, path_lengths, cycles, src_map):
path_queue.append(cur_path + [item])
pass


cycles = []

path_queue = [[x] for x in iter(src_map)]
path_lens = [1] * len(path_queue)

items = list(src_map.items())
items.sort(key = lambda A : A[0])
items.sort(key=lambda A: A[0])

for (path, deps) in items:
for path, deps in items:
print(path + ":")
sorted_deps = list(deps.items())
if args.show_counts:
sorted_deps.sort(key = lambda A: (A[1], A[0]))
sorted_deps.sort(key=lambda A: (A[1], A[0]))
for dep in sorted_deps:
print("\t{} [{}]".format(dep[0], dep[1]))
else:
sorted_deps.sort(key = lambda A: A[0])
sorted_deps.sort(key=lambda A: A[0])
for dep in sorted_deps:
print("\t{}".format(dep[0]))


def iter_cycles(cycles):
global src_map
for cycle in cycles:
cycle.append(cycle[0])
zipper = list(zip(cycle[0:-1], cycle[1:]))
result = [(x, src_map[x][y], y) for (x,y) in zipper]
result = [(x, src_map[x][y], y) for (x, y) in zipper]
total = 0
smallest = result[0][1]
for (first, value, last) in result:
for first, value, last in result:
total += value
smallest = min(smallest, value)
yield (total, smallest, result)


if args.discover_cycles:
print("Analyzing cycles...")

expand(path_queue, path_lens, cycles, src_map)

average = sum([len(x)+1 for x in cycles]) / len(cycles)
average = sum([len(x) + 1 for x in cycles]) / len(cycles)

print("Found {} cycles. Average cycle length = {}.".format(len(cycles), average))
counted = list(iter_cycles(cycles))
if args.show_counts:
counted.sort(key = lambda A: A[0])
for (total, smallest, cycle) in counted:
counted.sort(key=lambda A: A[0])
for total, smallest, cycle in counted:
sys.stdout.write("{} deps to break: ".format(total))
sys.stdout.write(cycle[0][0])
for (first, count, last) in cycle:
for first, count, last in cycle:
sys.stdout.write(" [{}->] {}".format(count, last))
sys.stdout.write("\n")
else:
Expand All @@ -186,8 +204,8 @@ def iter_cycles(cycles):
islands = []
outgoing_counts = defaultdict(int)
incoming_counts = defaultdict(int)
for (total, smallest, cycle) in counted:
for (first, count, last) in cycle:
for total, smallest, cycle in counted:
for first, count, last in cycle:
outgoing_counts[first] += count
incoming_counts[last] += count
for cycle in cycles:
Expand All @@ -201,8 +219,8 @@ def iter_cycles(cycles):
sorted = []
for node in island:
sorted.append((node, incoming_counts[node], outgoing_counts[node]))
sorted.sort(key = lambda x: x[1]+x[2])
for (node, inc, outg) in sorted:
sorted.sort(key=lambda x: x[1] + x[2])
for node, inc, outg in sorted:
print(" {} [{} in, {} out]".format(node, inc, outg))
sys.stdout.flush()
pass
Loading