Control-flow graph. Node 0 is always assumed to be the entry point. There must be a non-empty set of exits.
| 60 | |
| 61 | |
| 62 | class CFG: |
| 63 | """Control-flow graph. |
| 64 | |
| 65 | Node 0 is always assumed to be the entry point. There must be a |
| 66 | non-empty set of exits. |
| 67 | """ |
| 68 | |
| 69 | def __init__( |
| 70 | self, |
| 71 | succ: dict[BasicBlock, list[BasicBlock]], |
| 72 | pred: dict[BasicBlock, list[BasicBlock]], |
| 73 | exits: set[BasicBlock], |
| 74 | ) -> None: |
| 75 | assert exits |
| 76 | self.succ = succ |
| 77 | self.pred = pred |
| 78 | self.exits = exits |
| 79 | |
| 80 | def __str__(self) -> str: |
| 81 | exits = sorted(self.exits, key=lambda e: int(e.label)) |
| 82 | return f"exits: {exits}\nsucc: {self.succ}\npred: {self.pred}" |
| 83 | |
| 84 | |
| 85 | def get_cfg(blocks: list[BasicBlock], *, use_yields: bool = False) -> CFG: |