Skip to content

Commit

Permalink
Check CFG successors in reverse order
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-koch committed Jan 18, 2024
1 parent aa00df7 commit afe8a02
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions guppylang/checker/cfg_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"""

import collections
from collections.abc import Sequence
from collections.abc import Iterator, Sequence
from dataclasses import dataclass
from typing import TypeVar

from guppylang.ast_util import line_col
from guppylang.cfg.bb import BB
Expand Down Expand Up @@ -76,7 +77,9 @@ def check_cfg(
# We do BFS instead of DFS to get a better error ordering.
queue = collections.deque(
(checked_cfg.entry_bb, i, succ)
for i, succ in enumerate(cfg.entry_bb.successors)
# We enumerate the successor starting from the back, so we start with the `True`
# branch. This way, we find errors in a more natural order
for i, succ in reverse_enumerate(cfg.entry_bb.successors)
)
while len(queue) > 0:
pred, num_output, bb = queue.popleft()
Expand All @@ -92,7 +95,12 @@ def check_cfg(
else:
# Otherwise, check the BB and enqueue its successors
checked_bb = check_bb(bb, checked_cfg, input_row, return_ty, globals)
queue += [(checked_bb, i, succ) for i, succ in enumerate(bb.successors)]
queue += [
# We enumerate the successor starting from the back, so we start with
# the `True` branch. This way, we find errors in a more natural order
(checked_bb, i, succ)
for i, succ in reverse_enumerate(bb.successors)
]
compiled[bb] = checked_bb

# Link up BBs in the checked CFG
Expand Down Expand Up @@ -218,3 +226,16 @@ def check_rows_match(row1: VarRow, row2: VarRow, bb: BB) -> None:
bb.containing_cfg.live_before[bb][v1.name].vars.used[v1.name],
[v1.defined_at, v2.defined_at],
)


T = TypeVar("T")


def reverse_enumerate(xs: list[T]) -> Iterator[tuple[int, T]]:
"""Enumerates a list in reverse order.
Equivalent to `reversed(list(enumerate(data)))` without creating an intermediate
list.
"""
for i in range(len(xs) - 1, -1, -1):
yield i, xs[i]

0 comments on commit afe8a02

Please sign in to comment.