Branch based on a value. If op is BOOL, branch based on a bit/bool value: if [not] r1 goto L1 else goto L2 If op is IS_ERROR, branch based on whether there is an error value: if [not] is_error(r1) goto L1 else goto L2
| 425 | |
| 426 | @final |
| 427 | class Branch(ControlOp): |
| 428 | """Branch based on a value. |
| 429 | |
| 430 | If op is BOOL, branch based on a bit/bool value: |
| 431 | if [not] r1 goto L1 else goto L2 |
| 432 | |
| 433 | If op is IS_ERROR, branch based on whether there is an error value: |
| 434 | if [not] is_error(r1) goto L1 else goto L2 |
| 435 | """ |
| 436 | |
| 437 | # Branch ops never raise an exception. |
| 438 | error_kind = ERR_NEVER |
| 439 | |
| 440 | BOOL: Final = 100 |
| 441 | IS_ERROR: Final = 101 |
| 442 | |
| 443 | def __init__( |
| 444 | self, |
| 445 | value: Value, |
| 446 | true_label: BasicBlock, |
| 447 | false_label: BasicBlock, |
| 448 | op: int, |
| 449 | line: int = -1, |
| 450 | *, |
| 451 | rare: bool = False, |
| 452 | ) -> None: |
| 453 | super().__init__(line) |
| 454 | # Target value being checked |
| 455 | self.value = value |
| 456 | # Branch here if the condition is true |
| 457 | self.true = true_label |
| 458 | # Branch here if the condition is false |
| 459 | self.false = false_label |
| 460 | # Branch.BOOL (boolean check) or Branch.IS_ERROR (error value check) |
| 461 | self.op = op |
| 462 | # If True, the condition is negated |
| 463 | self.negated = False |
| 464 | # If not None, the true label should generate a traceback entry (func name, line number) |
| 465 | self.traceback_entry: tuple[str, int] | None = None |
| 466 | # If True, we expect to usually take the false branch (for optimization purposes); |
| 467 | # this is implicitly treated as true if there is a traceback entry |
| 468 | self.rare = rare |
| 469 | |
| 470 | def targets(self) -> Sequence[BasicBlock]: |
| 471 | return (self.true, self.false) |
| 472 | |
| 473 | def set_target(self, i: int, new: BasicBlock) -> None: |
| 474 | assert i == 0 or i == 1 |
| 475 | if i == 0: |
| 476 | self.true = new |
| 477 | else: |
| 478 | self.false = new |
| 479 | |
| 480 | def sources(self) -> list[Value]: |
| 481 | return [self.value] |
| 482 | |
| 483 | def set_sources(self, new: list[Value]) -> None: |
| 484 | (self.value,) = new |
no outgoing calls
searching dependent graphs…