Skip to content

Dominance

dominance

DominanceInfo

Computes and exposes the dominance relation amongst blocks of a region.

See external documentation.

Source code in xdsl/irdl/dominance.py
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class DominanceInfo:
    """
    Computes and exposes the dominance relation amongst blocks of a region.

    See external [documentation](https://en.wikipedia.org/w/index.php?title=Dominator_(graph_theory)&oldid=1189814332).
    """

    _dominance: dict[Block, set[Block]]

    def __init__(self, region: Region):
        """
        Compute (improper) dominance.

        See external [documentation](https://en.wikipedia.org/w/index.php?title=Dominator_(graph_theory)&oldid=1189814332).
        """

        self._dominance = {}

        # No block, no work
        if not (region.blocks):
            return

        # Build the preceding relationship
        pred: dict[Block, set[Block]] = {}
        for b in region.blocks:
            pred[b] = set()
        for b in region.blocks:
            if b.last_op is not None:
                for s in b.last_op.successors:
                    pred[s].add(b)

        # Get entry and other blocks
        entry, *blocks = region.blocks

        # The entry block is only dominated by itself
        self._dominance[entry] = {entry}

        # Instantiate other blocks dominators to all blocks
        for b in blocks:
            self._dominance[b] = set(region.blocks)

        # Iteratively filter out dominators until it converges
        changed = True
        while changed:
            changed = False
            for b in blocks:
                old = self._dominance[b].copy()
                self._dominance[b] = {b} | (
                    set[Block].intersection(*(self._dominance[p] for p in pred[b]))
                    if pred[b]
                    else set()
                )
                if old != self._dominance[b]:
                    changed = True

    def strictly_dominates(self, a: Block, b: Block) -> bool:
        """
        Return if `a` *strictly* dominates `b`.
        i.e., if it dominates `b` and is not `b`.
        """
        if a is b:
            return False
        return self.dominates(a, b)

    def dominates(self, a: Block, b: Block) -> bool:
        """
        Return if `a` dominates `b`.
        """
        return a in self._dominance[b]

__init__(region: Region)

Compute (improper) dominance.

See external documentation.

Source code in xdsl/irdl/dominance.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def __init__(self, region: Region):
    """
    Compute (improper) dominance.

    See external [documentation](https://en.wikipedia.org/w/index.php?title=Dominator_(graph_theory)&oldid=1189814332).
    """

    self._dominance = {}

    # No block, no work
    if not (region.blocks):
        return

    # Build the preceding relationship
    pred: dict[Block, set[Block]] = {}
    for b in region.blocks:
        pred[b] = set()
    for b in region.blocks:
        if b.last_op is not None:
            for s in b.last_op.successors:
                pred[s].add(b)

    # Get entry and other blocks
    entry, *blocks = region.blocks

    # The entry block is only dominated by itself
    self._dominance[entry] = {entry}

    # Instantiate other blocks dominators to all blocks
    for b in blocks:
        self._dominance[b] = set(region.blocks)

    # Iteratively filter out dominators until it converges
    changed = True
    while changed:
        changed = False
        for b in blocks:
            old = self._dominance[b].copy()
            self._dominance[b] = {b} | (
                set[Block].intersection(*(self._dominance[p] for p in pred[b]))
                if pred[b]
                else set()
            )
            if old != self._dominance[b]:
                changed = True

strictly_dominates(a: Block, b: Block) -> bool

Return if a strictly dominates b. i.e., if it dominates b and is not b.

Source code in xdsl/irdl/dominance.py
59
60
61
62
63
64
65
66
def strictly_dominates(self, a: Block, b: Block) -> bool:
    """
    Return if `a` *strictly* dominates `b`.
    i.e., if it dominates `b` and is not `b`.
    """
    if a is b:
        return False
    return self.dominates(a, b)

dominates(a: Block, b: Block) -> bool

Return if a dominates b.

Source code in xdsl/irdl/dominance.py
68
69
70
71
72
def dominates(self, a: Block, b: Block) -> bool:
    """
    Return if `a` dominates `b`.
    """
    return a in self._dominance[b]

strictly_dominates(a: Block, b: Block) -> bool

Returns true if block a strictly dominates block b, assuming they are in the same region.

Source code in xdsl/irdl/dominance.py
92
93
94
95
96
97
def strictly_dominates(a: Block, b: Block) -> bool:
    """
    Returns true if block `a` strictly dominates block `b`, assuming they are in the
    same region.
    """
    return _strictly_dominates_block(a, b)