Skip to content

Commit

Permalink
[lldb] Format Python files in scripts and utils (#66053)
Browse files Browse the repository at this point in the history
Using:
black --exclude "third_party/" ./lldb/
  • Loading branch information
DavidSpickett authored Sep 14, 2023
1 parent a1ef5a9 commit 602e47c
Show file tree
Hide file tree
Showing 17 changed files with 754 additions and 613 deletions.
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

0 comments on commit 602e47c

Please sign in to comment.