Skip to content

Commit 8564fd5

Browse files
authored
Remove recursive list intersection (#15622)
We couldn't measure any performance benefit after latest optimizations.
1 parent 59e257d commit 8564fd5

1 file changed

Lines changed: 12 additions & 70 deletions

File tree

lib/elixir/lib/module/types/descr.ex

Lines changed: 12 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6172,70 +6172,6 @@ defmodule Module.Types.Descr do
61726172
bdd_union(bdd_intersection(cd1, bdd_union(cd2, u2)), bdd_intersection(u1, cd2))
61736173
end
61746174

6175-
# Intersections are great because they allow us to cut down
6176-
# the number of nodes in the tree. So whenever we have a leaf,
6177-
# we propagate it throughout the whole tree, cutting down nodes.
6178-
defp bdd_intersection(bdd_leaf(_, _) = leaf1, bdd_leaf(_, _) = leaf2, leaf_intersection) do
6179-
leaf_intersection.(leaf1, leaf2)
6180-
end
6181-
6182-
defp bdd_intersection(bdd, bdd_leaf(tag, _) = leaf, leaf_intersection) when tag != :open do
6183-
bdd_non_open_leaf_intersection(leaf, bdd, leaf_intersection)
6184-
end
6185-
6186-
defp bdd_intersection(bdd_leaf(tag, _) = leaf, bdd, leaf_intersection) when tag != :open do
6187-
bdd_non_open_leaf_intersection(leaf, bdd, leaf_intersection)
6188-
end
6189-
6190-
defp bdd_intersection(bdd1, bdd2, _leaf_intersection) do
6191-
bdd_intersection(bdd1, bdd2)
6192-
end
6193-
6194-
# Take two BDDs, B1 = {a1, C1, U1, D1} and B2 = a2.
6195-
#
6196-
# We have:
6197-
#
6198-
# ((a1 and C1) or U1 or (not a1 and D1)) and a2
6199-
# (a1 and a2 and C1) or (a2 and U1) or (a2 and not a1 and D1)
6200-
#
6201-
# When C1 = :bdd_top, (a1 and a2) or (a2 and U2) or (a2 and not a1 and D2)
6202-
# When C2 = :bdd_bot, (a2 and U2) or (a2 and not a1 and D2)
6203-
defp bdd_non_open_leaf_intersection(leaf1, bdd_leaf(_, _) = leaf2, leaf_intersection) do
6204-
leaf_intersection.(leaf1, leaf2)
6205-
end
6206-
6207-
defp bdd_non_open_leaf_intersection(leaf, {_, a, :bdd_top, u, d}, leaf_intersection) do
6208-
leaf_intersection.(a, leaf)
6209-
|> bdd_union(bdd_non_open_leaf_intersection(leaf, u, leaf_intersection))
6210-
|> case do
6211-
result when d == :bdd_bot ->
6212-
result
6213-
6214-
result ->
6215-
leaf
6216-
|> bdd_non_open_leaf_intersection(d, leaf_intersection)
6217-
|> bdd_difference(a)
6218-
|> bdd_union(result)
6219-
end
6220-
end
6221-
6222-
defp bdd_non_open_leaf_intersection(leaf, {_, a, :bdd_bot, u, d}, leaf_intersection) do
6223-
case bdd_non_open_leaf_intersection(leaf, u, leaf_intersection) do
6224-
result when d == :bdd_bot ->
6225-
result
6226-
6227-
result ->
6228-
leaf
6229-
|> bdd_non_open_leaf_intersection(d, leaf_intersection)
6230-
|> bdd_difference(a)
6231-
|> bdd_union(result)
6232-
end
6233-
end
6234-
6235-
defp bdd_non_open_leaf_intersection(bdd1, bdd2, _leaf_intersection) do
6236-
bdd_intersection(bdd1, bdd2)
6237-
end
6238-
62396175
# {lit, c, u, d} = (lit and c) or u or (not lit and d),
62406176
# so its negation is ((lit and not c) or (not lit and not d)) and not u.
62416177
def bdd_negation(:bdd_top), do: :bdd_bot
@@ -6574,13 +6510,15 @@ defmodule Module.Types.Descr do
65746510
defp opt_list_intersection(bdd_leaf(:term, :term), bdd, _seen), do: bdd
65756511
defp opt_list_intersection(bdd, bdd_leaf(:term, :term), _seen), do: bdd
65766512

6577-
defp opt_list_intersection(bdd1, bdd2, seen) do
6513+
defp opt_list_intersection(bdd_leaf(_, _) = bdd1, bdd_leaf(_, _) = bdd2, seen) do
65786514
case opt_bdd_seen(seen, :list_intersection, bdd1, bdd2) do
65796515
:seen -> list_intersection(bdd1, bdd2)
6580-
{:ok, seen} -> bdd_intersection(bdd1, bdd2, &opt_list_leaf_intersection(&1, &2, seen))
6516+
{:ok, seen} -> opt_list_leaf_intersection(bdd1, bdd2, seen)
65816517
end
65826518
end
65836519

6520+
defp opt_list_intersection(bdd1, bdd2, _seen), do: list_intersection(bdd1, bdd2)
6521+
65846522
defp opt_list_leaf_intersection(bdd_leaf(list1, last1), bdd_leaf(list2, last2), seen) do
65856523
intersection_fun = &opt_intersection(&1, &2, seen)
65866524

@@ -6810,13 +6748,15 @@ defmodule Module.Types.Descr do
68106748
defp opt_map_intersection(bdd_leaf(:open, []), bdd, _seen), do: bdd
68116749
defp opt_map_intersection(bdd, bdd_leaf(:open, []), _seen), do: bdd
68126750

6813-
defp opt_map_intersection(bdd1, bdd2, seen) do
6751+
defp opt_map_intersection(bdd_leaf(_, _) = bdd1, bdd_leaf(_, _) = bdd2, seen) do
68146752
case opt_bdd_seen(seen, :map_intersection, bdd1, bdd2) do
68156753
:seen -> map_intersection(bdd1, bdd2)
6816-
{:ok, seen} -> bdd_intersection(bdd1, bdd2, &opt_map_leaf_intersection(&1, &2, seen))
6754+
{:ok, seen} -> opt_map_leaf_intersection(bdd1, bdd2, seen)
68176755
end
68186756
end
68196757

6758+
defp opt_map_intersection(bdd1, bdd2, _seen), do: map_intersection(bdd1, bdd2)
6759+
68206760
defp opt_map_leaf_intersection(bdd_leaf(tag1, fields1), bdd_leaf(tag2, fields2), seen) do
68216761
try do
68226762
{tag, fields} =
@@ -7137,13 +7077,15 @@ defmodule Module.Types.Descr do
71377077
defp opt_tuple_intersection(bdd_leaf(:open, []), bdd, _seen), do: bdd
71387078
defp opt_tuple_intersection(bdd, bdd_leaf(:open, []), _seen), do: bdd
71397079

7140-
defp opt_tuple_intersection(bdd1, bdd2, seen) do
7080+
defp opt_tuple_intersection(bdd_leaf(_, _) = bdd1, bdd_leaf(_, _) = bdd2, seen) do
71417081
case opt_bdd_seen(seen, :tuple_intersection, bdd1, bdd2) do
71427082
:seen -> tuple_intersection(bdd1, bdd2)
7143-
{:ok, seen} -> bdd_intersection(bdd1, bdd2, &opt_tuple_leaf_intersection(&1, &2, seen))
7083+
{:ok, seen} -> opt_tuple_leaf_intersection(bdd1, bdd2, seen)
71447084
end
71457085
end
71467086

7087+
defp opt_tuple_intersection(bdd1, bdd2, _seen), do: tuple_intersection(bdd1, bdd2)
7088+
71477089
defp opt_tuple_leaf_intersection(bdd_leaf(tag1, elements1), bdd_leaf(tag2, elements2), seen) do
71487090
intersection_fun = &opt_intersection(&1, &2, seen)
71497091

0 commit comments

Comments
 (0)